---
title: "GrassEndophyteVignette"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{GrassEndophyteVignette}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
bibliography: grassEndo.bib
link-citations: true
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

**Study background** This vignette involves perennial grasses with and
without endophytes.  We use the size-structured matrix model for
*Elymus villosus* from @2024:fowle.ziegl.whitn.ea, which includes
transition matrices for 13 years.  The model is in turn based on data
from a long-term symbiont removal experiment at Lilly-Dickey Woods in
Indiana, USA [@2023:mille.fowle.ziegl.ea].

*I think maybe the variable descriptions can just go as comments in
 the code?*

*Also, how should I include the figures that the code produces?
 Should I include a static image or should it be generated by the
 code?  I'd say the latter but some of this code is pretty slow.*

**Variables**:

* PlistAllEndo: a list of lists containing the yearly transition
matrices: PlistAllEndo[[1]] is a list of yearly transition matrices
for plants with endophytes and PlistAllEndo[[2]] is the same for
plants without endophytes

* FlistAllEndo: a list of lists containing the yearly fecundity
matrices, with the same structure as PlistAllEndo

* Q: the transition matrix between year types.  (Here we assume that year
types are drawn randomly with replacement.)

* c0: The initial size distribution.  (Here all individuals are born
  into size class 1, the seedling size class, so c0[1] = 1 and all
  other entries are 0.)

* maxClutchSize: the maximum number of offspring that can be produced
  in a single reproductive bout

* maxLRO: the maximum lifetime reproductive output

* traitDist: the probability distribution for trait values.  Here we
  assume that plants are equally likely to have endophytes or not, so
  traitDist = c(0.5, 0.5).

* Fdist: the probability distribution for the clutch size, with
  current options "Poisson" and "Bernoulli".  Here we assume
  "Poisson". 

One question we may wish to ask is how certain we are of an
individual's endophyte status based on their lifetime reproductive
output (LRO).  In order to make the code less glacially slow,
we use an abridged version of the model, with only three year
types.  (WARNING: this code is still slow.)  For this species, not
having endophytes produces higher LRO, but even if we observe an
individual with 6 offspring (which is well into the 90th percentile),
we can't be very confident that that individual lacked endophytes.
For more details on the math behind this calculation, see
@2018:snyde.ellne and @2024:snyde.ellne.

```{r, echo=FALSE, fig.align="center", out.width="70%"} 
knitr::include_graphics("probXCondR.png")
```

```{r, eval=FALSE}
library ("luckieR")
maxClutchSize = 24
maxLRO = 24
groupDist = rep (0.5, 2)

## read in matrices
PlistAllEndo = readRDS ("ELRIPMatrices.rds")
FlistAllEndo = readRDS ("ELRIFMatrices.rds")

## find number of year types
numEnv = length(PlistAllEndo[[1]])

## Assume that all env. are equally likely and the sequence is
## temporally uncorrelated.  You can make other choices if you have
## more information.
Q = matrix (1/numEnv, numEnv, numEnv)

## How many states do we have in each env.?
mz = dim(PlistAllEndo[[1]][[1]])[1]

bigmz = mz * numEnv

## Initial state distrib.
c0 = rep (0, mz); c0[1] = 1

## Clutch size distribution
Fdist = "Poisson"

## Equally likely to have endophytes or not
traitDist = rep (0.5, 2)

out = probTraitCondLRO (PlistAllEndo, FlistAllEndo, Q,
                        c0, maxClutchSize, maxLRO,
                        traitDist, Fdist)

probXCondR = out$probXCondR

matplot (0:6, probXCondR[1:7,], xlab="LRO",
         ylab="Probability", type="l", col=c("black", "red"), lwd=2,
         lty=1, main="ELRI", ylim=c(0,1))

legend (x="topleft", col=c("black", "red"),
        legend=c("With endophytes", "Without endophytes"),
        lwd=2, bty="n", cex=1.3)
```

Alternatively, we may wish to focus on what forms of luck are most
important and at what ages.  If we partition the variance in LRO into
a within-endophyte-status contribution and a between-endophyte-status
contribution, we can think of the within-endophyte-status contribution
as the contribution of luck [@2018:snyde.ellne].  We can further
partition that luck contribution into contributions from individual
demographic transitions at different ages.  Did you survive from age 2
to age 3 and how much does knowing the outcome reduce the overall
variance?  If you lived, how much did you grow or shrink and how much
does knowing the outcome reduce the overall variance?  And so forth.
The amount that knowing the outcome of each of these demographic
transitions reduces the overall variance is the contribution that
transition makes.

We see that early survival luck is key and this makes sense: if you
die young, it doesn't matter how lucky you would have been later.  We
also see that growing quickly at ages 2 and 3 is important.  Survival
rises rapidly with size for this species, so this too, makes sense.
(Note: in order to make the code slow, we use an abridged version of
the model, with only three year types.)  For the mathematical details
behind this calculation, see @2024:snyde.ellne.

```{r, echo=FALSE, fig.align="center", out.width="70%"} 
knitr::include_graphics("varPartition.png")
```

```{r, eval=FALSE}
library ("luckieR")
maxClutchSize = 24
maxLRO = 24
groupDist = rep (0.5, 2)

## read in matrices
PlistAllEndo = readRDS ("ELRIPMatrices.rds")
FlistAllEndo = readRDS ("ELRIFMatrices.rds")

## find number of year types
numEnv = length(PlistAllEndo[[1]])

## Assume that all env. are equally likely and the sequence is
## temporally uncorrelated.  You can make other choices if you have
## more information.
Q = matrix (1/numEnv, numEnv, numEnv)

## How many states do we have in each env.?
mz = dim(PlistAllEndo[[1]][[1]])[1]

bigmz = mz * numEnv

## Initial state distrib.
c0 = rep (0, mz); c0[1] = 1
## Initial env. distrib.  Should probably be the stationary distribution.
u0 = rep (1/numEnv, numEnv)

## We have two traits: endophyte-positive and -negative
numTraits=2
## Maximum age
maxAge = 25

## Equally likely to have endophytes or not
traitDist = rep (0.5, 2)

out = partitionVarSkewnessEnvVarAndTraits (PlistAllEndo,
                                           FlistAllEndo,
                                           Q, c0, traitDist, maxAge,
                                           survThreshold=0.05)

varTrajecResults = array (NA, dim=c(numTraits, 4, maxAge))
varTrajecResults[,1,] = out$survTrajecVarCondX
varTrajecResults[,2,] = out$growthTrajecVarCondX
varTrajecResults[,3,] = out$envTrajecVarCondX
varTrajecResults[,4,] = out$fecVarCondX

colorVec = colorVecAll6[2:5]
matplot (1:9, t(varTrajecResults[1,,1:9]),
         xlab="Age", ylab="Contrib. to Var(R)", type="l",
         main="ELRI with endophytes", lwd=2,
	 col=c("black", "orange", "forest green", "turquoise"),
	 lty=1, cex.lab=1.3)

legend (x="topright", lwd=2,
        col=c("black", "orange", "forest green", "turquoise"),
        legend=c("Survival", "Growth", "Environment", "Fecundity"),
        lty=1, cex=1.4, bty="n")
```

As a final example, let us plot survival fraction and average size vs
age for those destined to have at least one offspring and for those
who will never have any offspring, as a way of understanding what is
different about successful breeders.  To do this, we need to calculate
the survival/growth transition matrices conditional on having at least
one offspring.  We see that that most of those who never breed fail
because they do not survive the seedling stage (age 0), and of those
that do, those that never breed do not grow as large as those who do.
Survival increases sharply with size for this species, so growing
large quickly increases survival, not just fecundity.  For the
mathematical details behind this calculation, see @2018:snyde.ellne.

```{r, echo=FALSE, fig.align="center", out.width="100%"} 
knitr::include_graphics("condKernelPlots.png")
```

```{r, eval=FALSE}
library ("luckieR")
maxClutchSize = 24
maxLRO = 24
groupDist = rep (0.5, 2)

## read in matrices
PlistAllEndo = readRDS ("ELRIPMatrices.rds")
FlistAllEndo = readRDS ("ELRIFMatrices.rds")

## Work with endophyte-positive individuals for this example.
Plist = PlistAllEndo[[1]]
Flist = FlistAllEndo[[1]]

## find number of year types
numEnv = length(PlistAllEndo[[1]])

## Assume that all env. are equally likely and the sequence is
## temporally uncorrelated.  You can make other choices if you have
## more information.
Q = matrix (1/numEnv, numEnv, numEnv)

## How many states do we have in each env.?
mz = dim(PlistAllEndo[[1]][[1]])[1]

bigmz = mz * numEnv

## Initial state distrib.
c0 = rep (0, mz); c0[1] = 1
## Initial env. distrib.  Should probably be the stationary distribution.
u0 = rep (1/numEnv, numEnv)
## Initial cross-classified state (size x env.)
m0 = matrix (outer (c0, as.vector(u0)), bigmz, 1)

## Maximum age
maxAge = 15

aveSizeCondBreedAndSurv = aveSizeCondNeverBreedAndSurv =
  fracSurvCondBreed = fracSurvCondNeverBreed = rep (0, maxAge+1)

## Calculate fecundity and size/growth transition matrices for
## cross-classified states (size x env.)
F = M = matrix (0, bigmz, bigmz)
for (i in 1:numEnv) {
  for (j in 1:numEnv) {
    M[(i-1)*mz + 1:mz, (j-1)*mz + 1:mz] = Plist[[j]]*Q[i,j]
    F[(i-1)*mz + 1:mz, (j-1)*mz + 1:mz] = Flist[[j]]*Q[i,j]
  }
}

## Find M conditional on having at least one offspring
out = makePCondBreedDef3 (M, F, m0)

## Kernel conditional on breeding
MCondBreed = out$PCondBreed
## Kernel conditional on never breeding
MCondNeverBreed = out$PCondNeverBreed
## Initial state conditional on breeding
esM0CondBreed = out$bigc0CondBreed
## Initial state conditional on neverbreeding
esM0CondNeverBreed = out$bigc0CondNeverBreed

## State distrib. at age a. (Here a = 0.)
MaM0CondBreed = esM0CondBreed
MaM0CondNeverBreed = esM0CondNeverBreed

sizeVec = rep(0:(mz-1), numEnv)
esSizeVec = rep(sizeVec, 3)
## Loop over ages
for (a in 0:maxAge) {
  ## What fraction of the population is alive?
  fracSurvCondBreed[a+1] = sum(MaM0CondBreed)
  fracSurvCondNeverBreed[a+1] = sum(MaM0CondNeverBreed)
  ## What is the average size?
  aveSizeCondBreedAndSurv[a+1] = sum(MaM0CondBreed * esSizeVec) /
    fracSurvCondBreed[a+1]
  aveSizeCondNeverBreedAndSurv[a+1] = sum(MaM0CondNeverBreed * sizeVec) /
    fracSurvCondNeverBreed[a+1]
  ## Update state distribution
  MaM0CondBreed = MCondBreed %*% MaM0CondBreed
  MaM0CondNeverBreed = MCondNeverBreed %*% MaM0CondNeverBreed
}

## which age is closest to having 10% of the population left?
fewLeftCondBreed = which.min (abs (fracSurvCondBreed - 0.1))
fewLeftCondNeverBreed = which.min (abs (fracSurvCondNeverBreed -
                                             0.1))

xmax = max(fewLeftCondNeverBreed, fewLeftCondBreed)
pdf (height=6, width=12, file="condKernelPlots.pdf")
par (cex.lab=1.9, cex.axis=1.8, lwd=2, mfrow=c(1,2),
     oma=c(0,0,1,0), mar=c(5.1,4.5,4.1,2.1))
plot (0:(xmax-1), fracSurvCondNeverBreed[1:xmax], type="l", xlab="Age",
      ylab="Survival to age a", xaxt="n")
lines (0:(xmax-1), fracSurvCondBreed[1:xmax], col="red")
axis (side=1, at=0:(xmax-1), labels=0:(xmax-1))
legend (x="topright", col=c("black", "red"),
        legend=c("Never breed", "Breed"), lwd=2, bty="n",
        cex=1.8)

ymax = max (aveSizeCondNeverBreedAndSurv, aveSizeCondBreedAndSurv)
plot (0:(xmax - 1), aveSizeCondNeverBreedAndSurv[1:xmax],
      type="l", xlab="Age", xaxt="n",
      ylab="Ave. size if survive",
      ylim=c(0, ymax))
axis (side=1, at=0:(xmax-1), labels=0:(xmax-1))
lines (0:(xmax-1), aveSizeCondBreedAndSurv[1:xmax],
       type="l", col="red")
```
