<%@meta language="R-vignette" content="--------------------------------
  DIRECTIVES FOR R:

  %\VignetteIndexEntry{Example 2: A model with a limit cycle}
  %\VignetteAuthor{Christopher Stieha, Christopher Moore}
  %\VignetteEngine{R.rsp::rsp}
--------------------------------------------------------------------"%>
<%##### preparation #####
	# 0.0.1 write a function to create a legend for contour plots
	legend.col <- function(col, lev, xadj){ 
		opar <- par
		n <- length(col)
		bx <- par("usr")
		box.cx <- c(bx[2] + (bx[2] - bx[1]) / 1000 + 0, bx[2] + (bx[2] - bx[1]) / 1000 + (bx[2] - bx[1]) / 50)
		box.cy <- c(bx[3], bx[3])
		box.sy <- (bx[4] - bx[3]) / n
		xx <- rep(box.cx, each = 2) + xadj
		par(xpd = TRUE)
		for(i in 1:n){
			yy <- c(box.cy[1] + (box.sy * (i - 1)),
			box.cy[1] + (box.sy * (i)),
			box.cy[1] + (box.sy * (i)),
			box.cy[1] + (box.sy * (i - 1)))
			polygon(xx, yy, col = col[i], border = col[i])
		}
		par(new = TRUE)
		plot(0, 0, type = "n", ylim = c(min(lev), max(lev)), yaxt = "n", ylab = "",
		xaxt = "n", xlab = "", frame.plot = FALSE)
		axis(side = 4, las = 2, tick = FALSE, line = (.25 + xadj))
		par <- opar
	}
	# 0.0.2 preset color palettes for controus
	tsdens.col <- c("lightsteelblue", "white", "indianred")
	qp.col <- c("#FDE725FF", "#E3E418FF", "#C7E020FF", "#ABDC32FF", "#8FD744FF", "#75D054FF", "#5DC963FF", "#47C06FFF", "#35B779FF", "#28AE80FF", "#20A486FF", "#1F9A8AFF", "#21908CFF", "#24868EFF", "#287C8EFF", "#2C728EFF", "#31688EFF", "#355D8DFF", "#3B528BFF", "#404688FF", "#443A83FF", "#472D7BFF", "#481F71FF","#471163FF", "#440154FF")
%>


In this vignette, we will extend example 2 from the R article and include the code to produce the figures.

### Example 2: A model with a limit cycle
<br>
```R
	library(QPot)
	var.eqn.x <- "-(y-beta) + mu*(x-alpha)*(1-(x-alpha)^2-(y-beta)^2) "
	var.eqn.y <- "(x-alpha) + mu*(y-beta)*(1-(x-alpha)^2-(y-beta)^2)"
	model.parms <- c(alpha = 4, beta = 5, mu = 0.2)
	parms.eqn.x <- Model2String(var.eqn.x, parms = model.parms, supress.print = TRUE)
	parms.eqn.y <- Model2String(var.eqn.y, parms = model.parms, supress.print = TRUE) 
```
	
<%
	require(QPot)
	require(R.devices)
	require(R.rsp)
	require(viridis)
	var.eqn.x <- "-(y-beta) + mu*(x-alpha)*(1-(x-alpha)^2-(y-beta)^2) "
	var.eqn.y <- "(x-alpha) + mu*(y-beta)*(1-(x-alpha)^2-(y-beta)^2)"
	model.parms <- c(alpha = 4, beta = 5, mu = 0.2)
	parms.eqn.x <- Model2String(var.eqn.x, parms = model.parms, supress.print = TRUE)
	parms.eqn.y <- Model2String(var.eqn.y, parms = model.parms, supress.print = TRUE) 
%>

### Step 1: Analyze the deterministic skeleton
<br>
To analyze our system of differential equations, we use the package phaseR, which requires the system of equations to be implemented as a function.  Our function Model2String() was made to help users of QPot transition from their use of previous packages requiring this function format.

```R
	require(phaseR)
model.ex2 <- function(t, y, parameters){
	x <- y[1]
	y <- y[2]
	alpha <- parameters["alpha"]
	beta <- parameters["beta"]
	delta <- parameters["delta"]
	kappa <- parameters["kappa"]
	gamma <- parameters["gamma"]
	mu <- parameters["mu"]
	dx <- -(y-beta) + mu*(x-alpha)*(1-(x-alpha)^2-(y-beta)^2)
	dy <- (x-alpha) + mu*(y-beta)*(1-(x-alpha)^2-(y-beta)^2)
	list(c(dx,dy))
}
```
<%
	require(phaseR)
model.ex2 <- function(t, y, parameters){
	x <- y[1]
	y <- y[2]
	alpha <- parameters["alpha"]
	beta <- parameters["beta"]
	delta <- parameters["delta"]
	kappa <- parameters["kappa"]
	gamma <- parameters["gamma"]
	mu <- parameters["mu"]
	dx <- -(y-beta) + mu*(x-alpha)*(1-(x-alpha)^2-(y-beta)^2)
	dy <- (x-alpha) + mu*(y-beta)*(1-(x-alpha)^2-(y-beta)^2)
	list(c(dx,dy))
}
%>


```R
	# draws the vector field
	flowField(deriv = model.ex2, xlim = c(2, 7), ylim = c(2, 7), parameters = model.parms, 
		add = F, points = 30, col = "grey70", ann = F, arrow.head = 0.025, frac = 1.1, 
		xaxs = "i", yaxs = "i", las = 1)
	# draw the nullclines and suppress the output by assigning it to a variable
	supp.print <- nullclines(deriv = model.ex2, xlim = c(2, 7), ylim = c(2, 7), 
		parameters = model.parms, col = c("blue", "red"), points = 250)
	# draw and label the equilibria
	# open circles are unstable, black are stable
	points(4,5 , pch = 21 , col = "black" , bg = "white" , cex = 1.5)
	text(4,5 , labels = expression(italic(e[0])) , adj = c(0,-.25) , cex = 1.5)
	traj <- trajectory(model.ex2,y0=c(runif(1,2,7),runif(1,2,7)) , tlim = c(2,7), xlim = c(2,7) , ylim = c(2,7) , parameters = model.parms , t.end = 250, lwd = 1.5 , pch = 16)
	traj <- trajectory(model.ex2,y0=c(runif(1,2,7),runif(1,2,7)) , tlim = c(2,7), xlim = c(2,7) , ylim = c(2,7) , parameters = model.parms , t.end = 250, lwd = 1.5 , pch = 16)
	traj <- trajectory(model.ex2,y0=c(runif(1,2,7),runif(1,2,7)) , tlim = c(2,7), xlim = c(2,7) , ylim = c(2,7) , parameters = model.parms , t.end = 250, lwd = 1.5 , pch = 16)
	# label the x and y axis
	mtext(expression(italic(x)), side = 1, line = 2.5)
	mtext(expression(italic(y)), side = 2, line = 2.5)
```
<%toPNG("EX2vectordiagram", {
	# draws the vector field
	flowField(deriv = model.ex2, xlim = c(2, 7), ylim = c(2, 7), parameters = model.parms, 
		add = F, points = 30, col = "grey70", ann = F, arrow.head = 0.025, frac = 1.1, 
		xaxs = "i", yaxs = "i", las = 1)
	# draw the nullclines and suppress the output by assigning it to a variable
	supp.print <- nullclines(deriv = model.ex2, xlim = c(2, 7), ylim = c(2, 7), 
		parameters = model.parms, col = c("blue", "red"), points = 250)
	# draw and label the equilibria
	# open circles are unstable, black are stable
	points(4,5 , pch = 21 , col = "black" , bg = "white" , cex = 1.5)
	text(4,5 , labels = expression(italic(e[0])) , adj = c(0,-.25) , cex = 1.5)
	traj <- trajectory(model.ex2,y0=c(runif(1,2,7),runif(1,2,7)) , tlim = c(2,7), xlim = c(2,7) , ylim = c(2,7) , parameters = model.parms , t.end = 250, lwd = 1.5 , pch = 16)
	traj <- trajectory(model.ex2,y0=c(runif(1,2,7),runif(1,2,7)) , tlim = c(2,7), xlim = c(2,7) , ylim = c(2,7) , parameters = model.parms , t.end = 250, lwd = 1.5 , pch = 16)
	traj <- trajectory(model.ex2,y0=c(runif(1,2,7),runif(1,2,7)) , tlim = c(2,7), xlim = c(2,7) , ylim = c(2,7) , parameters = model.parms , t.end = 250, lwd = 1.5 , pch = 16)
	# label the x and y axis
	mtext(expression(italic(x)), side = 1, line = 2.5)
	mtext(expression(italic(y)), side = 2, line = 2.5)
})
%>

![Null clines of the current system of equations](figures/EX2vectordiagram.png)




### Step 2: Stochastic simulation
<br>
	In order to simulate the stochastic equations, we need:
	
```R
	model.state <- c(x = 3, y = 3) 	# initial condition
	model.sigma <- 0.1				# the level of noise
	model.time <- 500		#2500		# the length of the simulation
	model.deltat <- 0.005			# the time step
```
<%
	model.state <- c(x = 3, y = 3)
	model.sigma <- 0.1
	model.time <- 500 #2500
	model.deltat <- 0.005
	rcat("\n")
%>
<br>
	Then we can simulate the equations using TSTraj():
	
```R
	ts.ex2 <- TSTraj(y0 = model.state, time = model.time, 
		deltat = model.deltat, x.rhs = var.eqn.x, y.rhs = var.eqn.y, 
		parms = model.parms, sigma = model.sigma)
```
<%	
	ts.ex2 <- TSTraj(y0 = model.state, time = model.time, 
		deltat = model.deltat, x.rhs = var.eqn.x, y.rhs = var.eqn.y, 
		parms = model.parms, sigma = model.sigma)
	rcat("\n")
%>

The function TSPlot allows us to easily view the output from TSTraj().
The default plot is the time series plotted through time with a histogram:
```R
	TSPlot(ts.ex2, deltat = model.deltat)
```

<%toPNG("EX2timeseriesFig1", {TSPlot(ts.ex2, deltat = model.deltat)})%>
![Stochastic simulation of a time series](figures/EX2timeseriesFig1.png)

We can view the times series plotted along on the state variables by setting dim = 2: 
```R
	TSPlot(ts.ex2, deltat = model.deltat, dim = 2)
```
<%toPNG("EX2timeseriesFig2", {TSPlot(ts.ex2, deltat = model.deltat, dim = 2)})%>
<img src="figures/EX2timeseriesFig2.png">
	
If we only want to see the histograms, we can see them in one dimensional space
```R
	TSDensity(ts.ex2, dim = 1)
```
<%toPNG("EX2timeseriesFig3", {TSDensity(ts.ex2, dim = 1)})%>
<img src="figures/EX2timeseriesFig3.png">

or in two-dimensional space with 
```R
	TSDensity(ts.ex2, dim = 2)
```

<% 
	k2 <- MASS::kde2d(ts.ex2[,2], ts.ex2[,3], n = 200)
	k2dns <- k2$z/sum(k2$z)
	k2cut <- cut(k2dns, 100, label = FALSE)
	crramp <- colorRampPalette(tsdens.col)
	colr <- crramp(100)
%>
<%toPNG("EX2timeseriesFig4", {
		holdthese <- par(no.readonly = TRUE)
		par(mar = c(4, 4, 5 , 5))
		TSDensity(ts.ex2, dim = 2, xlab  ="", ylab = "", xlim = c(2.5, 6.5), ylim = c(2.5, 6.5), contour.levels = 25, contour.lines = T, las = 1, col2d = tsdens.col, contour.lwd = 0.25, kde2d.n = 200, xaxs = "i", yaxs = "i");
		legend.col(col = colr, lev = k2dns, xadj = 0.1)
		par(holdthese)
	})
%>

<img src="figures/EX2timeseriesFig4.png">


### Step 3: Local quasi-potential calculations
<br>
To calculate the quasi-potential for a system of equations, we first need to define some initial conditions and parameter values.

```R	
	bounds.x = c(-0.5, 11.5) 	# upper and lower limit of X
	bounds.y = c(-0.5, 11.5) 	# upper and lower limit of Y
	step.number.x = 2000 #4000 	# number of division between upper and lower limit
	step.number.y = 2000 #4000 	# number of division between upper and lower limit
	xinit = 4.15611				# x value to start computing quasi-potential
	yinit = 5.987774			# y value to start computing quasi-potential
```
<%
	bounds.x = c(-0.5, 11.5)
	bounds.y = c(-0.5, 11.5)
	step.number.x = 2000 # 4000
	step.number.y = 2000 # 4000
	xinit = 4.15611
	yinit = 5.987774
%>


With these values defined, we can now compute the quasi-potential starting at the initial point.  Note that we don't have to start at the equilibrium, but this ensures that we quickly find the lowest quasi-potential and work up from there.
```R
	eq1.qp <- QPotential(x.rhs = parms.eqn.x, x.start = xinit, x.bound = bounds.x, 
					x.num.steps = step.number.x, y.rhs = parms.eqn.y, y.start = yinit, 
					y.bound = bounds.y, y.num.steps = step.number.y)
```
<%
	eq1.qp <- QPotential(x.rhs = parms.eqn.x, x.start = xinit, x.bound = bounds.x, 
					x.num.steps = step.number.x, y.rhs = parms.eqn.y, y.start = yinit, 
					y.bound = bounds.y, y.num.steps = step.number.y)
%>

### Step 4: Global quasi-potential calculation
<br>
In this example, the global quasi-potential is the same as the local quasi-potential computed above.

### Step 5: Global quasi-potential visualization

```R
	QPContour(eq1.qp, dens = c(1000, 1000), x.bound = bounds.x, y.bound = bounds.y, 
				c.parm = 10, xlab=expression(italic(x)), ylab=expression(italic(y)))
```

<%

		k2dns <- seq(min(eq1.qp, na.rm = T), max(eq1.qp, na.rm = T), 0.01)
		k2cut <- cut(k2dns, 100, label = FALSE)
		crramp <- colorRampPalette(qp.col)
		colr <- crramp(100)
%>


<%toPNG("EX1globalvisualizationFig5", {
		holdthese <- par(no.readonly = TRUE)
		par(oma = c(0,1,0,2))
		QPContour(surface = eq1.qp , dens = c(1000, 1000), x.bound = bounds.x, y.bound = bounds.y, 
					c.parm = 1, xlab = expression(italic("x")), ylab = "");
		legend.col(col = colr, lev = k2dns, xadj = 0.1)
		par(holdthese)
	})
%>

![Global quasi-potential visualization](figures/EX1globalvisualizationFig5.png)



In case you want to view the quasipotential in three dimensions, we can use the R package plot3D:

```R
	require(plot3D); require(viridis)
	
	#first, we have to subset the x and y axis because it is scaled from 0 to 1
	frac.x <- c(0.2,0.5)
    frac.y <- c(0.3,0.6)
    
    #then we reduce the global quasi-potential matrix to contain only these values
    ex1.global <- eq1.qp	
    global.sub <- ex1.global[round(dim(ex1.global)[1]*frac.x[1]):round(dim(ex1.global)[1]*frac.x[2]),
        round(dim(ex1.global)[2]*frac.y[1]):round(dim(ex1.global)[2]*frac.y[2])]

	#regular data, can see the valley for the limit cycle
    dens.sub <- c(200, 200)	#pull only 200 rows and columns to speed up graphing
    global.sub <- global.sub[round(seq(1,nrow(global.sub),length.out=dens.sub[1])) , 
							 round(seq(1,ncol(global.sub),length.out=dens.sub[2]))]
    global.sub[global.sub > 0.01] <- NA # limit the z axis to give the best shot
    persp3D(z = global.sub, theta = 25, phi = 55, col = viridis(100, option = "C"), shade = 0.1, 
        colkey = list(side = 4, length = 0.85), contour = list(levels = c(0.01, 0.001, 0.0001, 0.00005 ) ),
        zlim = c(-0.01, .011), zlab = intToUtf8(0x03A6))
    #spend lots of time playing with theta, phi, zlim, contour levels, etc. to produce a decent graph
```

<%
	require(plot3D)
	
	#first, we have to subset the x and y axis because it is scaled from 0 to 1
	frac.x <- c(0.2,0.5)
    frac.y <- c(0.3,0.6)
    
    #then we reduce the global quasi-potential matrix to contain only these values
    ex1.global <- eq1.qp	
    global.sub <- ex1.global[round(dim(ex1.global)[1]*frac.x[1]):round(dim(ex1.global)[1]*frac.x[2]),
        round(dim(ex1.global)[2]*frac.y[1]):round(dim(ex1.global)[2]*frac.y[2])]

	#regular data, can see the valley for the limit cycle
    dens.sub <- c(200, 200)	#pull only 200 rows and columns to speed up graphing
    global.sub <- global.sub[round(seq(1,nrow(global.sub),length.out=dens.sub[1])) , round(seq(1,ncol(global.sub),length.out=dens.sub[2]))]
    global.sub[global.sub > 0.01] <- NA # limit the z axis to give the best shot
%>
<%toPNG("EX2globalvisualization3D", {
    persp3D(z = global.sub, theta = 25, phi = 55, col = viridis(100, option = "C"), shade = 0.1, 
        colkey = list(side = 4, length = 0.85), contour = list(levels = c(0.01, 0.001, 0.0001, 0.00005 ) ), zlim = c(-0.01, .011), 
        zlab = intToUtf8(0x03A6))
    #spend lots of time playing with theta, phi, zlim, contour levels, etc. to produce a decent graph
})
%>

![Three dimensional quasi-potential visualization using package plot3D](figures/EX2globalvisualization3D.png)


To better see the valley for the limit cycle, we can ln-transform the quasi-potential and plot. 

```R
#natural log transformation
    global.sub <- log(global.sub)
    persp3D(z = global.sub, theta = 25, phi = 60, col = viridis(100, option = "C"), shade = 0.1, 
        colkey = list(side = 4, length = 0.85), contour = list(levels = seq(-10,-4,1) ), zlim = c(-15, -4), 
        zlab = paste("ln(",intToUtf8(0x03A6), ")", sep="")) # zlim = c(-10,-4)
```
<%
	#natural log transformation
    global.sub <- log(global.sub)
%>
<%toPNG("EX2visualization3Dln", {
    persp3D(z = global.sub, theta = 25, phi = 60, col = viridis(100, option = "C"), shade = 0.1, 
        colkey = list(side = 4, length = 0.85), contour = list(levels = seq(-10,-4,1) ), zlim = c(-15, -4), 
        zlab = intToUtf8(0x03A6)) # zlim = c(-10,-4)
})
%>

![Three dimensional quasi-potential visualization using package plot3D - ln-transformed data](figures/EX2visualization3Dln.png)


### Step 6: Vector field decomposition
<br>
	Taking the global quasi-potential, we can visualize the vector field, specifically the gradient and the remainder.  First we calculate the vector field decomposition, which gives us the deterministic skeleton, the gradient vector field, and the remainder vector field for both state variables X and Y. 

```R
	VDAll <- VecDecomAll(surface = eq1.qp, x.rhs = parms.eqn.x, 
				y.rhs = parms.eqn.y, x.bound = bounds.x, y.bound = bounds.y)
```
<%
VDAll <- VecDecomAll(surface = eq1.qp, x.rhs = parms.eqn.x, y.rhs = parms.eqn.y, x.bound = bounds.x, y.bound = bounds.y)
%>


We can then plot the deterministic skeleton
```R
	VecDecomPlot(x.field = VDAll[,,1], y.field = VDAll[,,2], dens = c(25, 25), 
			x.bound = bounds.x, y.bound = bounds.y, xlim = c(0, 11), ylim = c(0, 11), 
			arrow.type = "equal", tail.length = 0.25, head.length = 0.025)
```
<%toPNG("EX1vectorfielddecompDETSKEL", {
VecDecomPlot(x.field = VDAll[,,1], y.field = VDAll[,,2], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, xlim = c(0, 11), ylim = c(0, 11), arrow.type = "equal", tail.length = 0.25, head.length = 0.025)
})
%>
![Global quasi-potential visualization](figures/EX1vectorfielddecompDETSKEL.png)


followed by the gradient vector field

```R
VecDecomPlot(x.field = VDAll[,,3], y.field = VDAll[,,4], dens = c(25, 25), x.bound = bounds.x, 
		y.bound = bounds.y, arrow.type = "proportional", tail.length = 0.25, head.length = 0.025)
```
<%toPNG("EX1vectorfielddecompGRAD", {
VecDecomPlot(x.field = VDAll[,,3], y.field = VDAll[,,4], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, arrow.type = "proportional", tail.length = 0.25, head.length = 0.025)
})
%>
![Global quasi-potential visualization](figures/EX1vectorfielddecompGRAD.png)


and the remainder vector field, which is the "force that causes trajectories to circulate around level sets of the quasi-potential."  In this example, arrow.type = "proportional" and "equal" visually convey different aspects of the quasi-potential, where "equal" showcases the limit cycle and "proportional" showcases the variation in the gradient.
First, the arrow.type = "proportional":
```R
VecDecomPlot(x.field = VDAll[,,5], y.field = VDAll[,,6], dens = c(25, 25), x.bound = bounds.x, 
		y.bound = bounds.y, arrow.type = "proportional", tail.length = 0.35, head.length = 0.025)
```
<%toPNG("EX1vectorfielddecompREMprop", {
VecDecomPlot(x.field = VDAll[,,5], y.field = VDAll[,,6], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, arrow.type = "proportional", tail.length = 0.35, head.length = 0.025)
})
%>
![Global quasi-potential visualization](figures/EX1vectorfielddecompREMprop.png)


Followed by the arrow.type = "equal": 
```R
VecDecomPlot(x.field = VDAll[,,5], y.field = VDAll[,,6], dens = c(25, 25), x.bound = bounds.x, 
		y.bound = bounds.y, arrow.type = "equal", tail.length = 0.35, head.length = 0.025)
```
<%toPNG("EX1vectorfielddecompREMequal", {
VecDecomPlot(x.field = VDAll[,,5], y.field = VDAll[,,6], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, arrow.type = "equal", tail.length = 0.35, head.length = 0.025)
})
%>
![Global quasi-potential visualization](figures/EX1vectorfielddecompREMequal.png)



The force arrows can be drawn equal size or can be drawn proportional to their value by setting arrow.type to "equal" or "proportional".

<%toPNG("EX1vectorfielddecompFig8", {
			holdthese <- par(no.readonly = TRUE)
			par(mfrow = c(2,2), mar = c(2,2,1,1), oma = c(3,3,1,1))
			VecDecomPlot(x.field = VDAll[,,3], y.field = VDAll[,,4], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, arrow.type = "proportional", tail.length = 0.25, head.length = 0.025)
			mtext(side = 3, text = expression(Gradient~field~(-nabla~phi(x, y))))
			mtext(side = 2, text = "Proportional arrow lengths", line = 3.75)
			mtext(side = 2, text = expression(italic(y)), line = 2.25)
			VecDecomPlot(x.field = VDAll[,,5], y.field = VDAll[,,6], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, arrow.type = "proportional", tail.length = 0.35, head.length = 0.025)
			mtext(side = 3, text = expression(Remainder~field~(bold(r)(x, y))))
			VecDecomPlot(x.field = VDAll[,,3], y.field = VDAll[,,4], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, arrow.type = "equal", tail.length = 0.15, head.length = 0.025)
			mtext(side = 2, text = "Equal arrow lengths", line = 3.75)
			mtext(side = 2, text = expression(italic(y)), line = 2.25)
			mtext(side = 1, text = expression(italic(x)), line = 2.25)	
			VecDecomPlot(x.field = VDAll[,,5], y.field = VDAll[,,6], dens = c(25, 25), x.bound = bounds.x, y.bound = bounds.y, arrow.type = "equal", tail.length = 0.15, head.length = 0.025)
			mtext(side = 1, text = expression(italic(x)), line = 2.25)
			par(holdthese)
})
%>
![Global quasi-potential visualization](figures/EX1vectorfielddecompFig8.png)


