# basic plotting functions for assessing output

require('fields')

temp.colors=function(n=25){
      m <- floor(n/2)
        blues <- hsv(h=.65, s=seq(1,0,length=m+1)[1:m])
        reds <- hsv(h=0, s=seq(1,0,length=m+1)[1:m])
        c(blues,if(n%%2!=0) "#FFFFFF", reds[m:1])
    }

f.clr=function(vec){
  return(log(vec)-mean(log(vec)))
}

# rIts: space, taxon, time, iteration?
# rMean: space, taxon, time (mean across iterations? )
# p: taxon number?
spatialEOFbyTaxon=function(p,rMean,rIts,transform='asin'){
  # this returns EOFs for a specific taxon where the patterns are with respect to the locations (so true eofs) and there is a score for each time for each of the nT patterns (where nT is the number of time points)
  # since we work with a single taxon, the clr transformation doesn't make sense as the transformation is based on having all P taxa, and if one applied it and then took only the transformed data for the taxon of interet, one will have different data values even if the abundance of beech, say, were 24% in two different time periods because the abundunace of the other taxa changed between the two times
  # scoreMean is the mean of the scores on the patterns (eofs) for each time point, averaging over the scores for each iteration; each row is one pattern and each column a time point
  # scoreUpper is the 97.5th percentile and scoreLower the 2.5th percentile of the scores for a given time and pattern; each row is one pattern and each column a time point
  # scoreIts is the entire set of scores by iteration: patterns X times X iterations
  # scoresOnMeans are the scores calculated on rMean rather than by iteration - note that the EOFs are computed based on rMean so that the patterns are the same for every iteration; otherwise the meaning of the scores would change between iterations; each row is one pattern and each column a time point
  # loadings are the weights on the locations for each pattern - each column is a pattern and each row is a grid cell
  # eigenvals are the variances associated with each pattern with higher variance meaning more variability explained by that pattern
  nT=dim(rIts)[3]
  S=dim(rIts)[1]
  nIts=dim(rIts)[4]

  calcScores=function(data){
    return((lm(data~mysvd$u-1))$coef)
  }

  data=asin(sqrt(rMean[,p,]))

  locMeans=rowMeans(data)
  data=data-locMeans

  mysvd=svd(data)

  workItsMat=matrix(c(asin(sqrt(rIts[,p,,]))),S,nT*nIts)-locMeans

  tmp=lm(workItsMat~mysvd$u-1)$coef
  scoreIts=array(tmp,c(nT,nT,nIts))  # there are only 31 patterns because only 31 time points, so this is the score on each pattern for each time point for each iteration
  scoreMean=apply(scoreIts,c(1,2),mean)  # mean score on each pattern for each time point
  scoreUpper=apply(scoreIts,c(1,2),quantile,.975)  # quantiles of scores on each pattern for each time point
  scoreLower=apply(scoreIts,c(1,2),quantile,.025)

  scoresOnMeans=diag(mysvd$d)%*%t(mysvd$v)

  return(list(scoreMean=scoreMean,scoreUpper=scoreUpper,scoreLower=scoreLower,scoreIts=scoreIts,loadings=mysvd$u,eigenvals=mysvd$d,scoresOnMeans=scoresOnMeans))
}

spatialEOFallTaxa=function(rMean,rIts,transform='clr'){ # could also do transform='asin' or transform='none'
  # this returns spatial EOFs where they are calculated based on all taxa
  # the patterns are with respect to the locations (so true eofs) and there is a score for taxon for each time for each of the S=256 patterns
  # one can either invoke the clr transformation that deals with having proportions or one could invoke 'asin' for the arcsin sqrt transformation. I assume that the EOFs based on the covariance are desired, but to change this, just change the line below that does the svd (mysvd=svd(....
  # scoreMean is the mean of the scores on the patterns (eofs) for each taxon and time point, averaging over the scores for each iteration; each row is one pattern and each column a time point
  # scoreUpper is the 97.5th percentile and scoreLower the 2.5th percentile of the scores for a given taxon and time; each row is one pattern
  # scoreIts is the entire set of scores by iteration: patterns X taxa X times X iterations
  # scoresOnMeans are the scores calculated on rMean rather than by iteration - note that the EOFs are computed based on rMean so that the patterns are the same for every iteration; otherwise the meaning of the scores would change between iterations; each row is one pattern
  # loadings are the weights on the locations for each pattern - each column is a pattern and each row is a grid cell
  # eigenvals are the variances associated with each pattern with higher variance meaning more variability explained by that pattern
  nT   = dim(rIts)[3]
  S    = dim(rIts)[1]
  P    = dim(rIts)[2]
  nIts = dim(rIts)[4]

  calcScores=function(data){
    return((lm(data~mysvd$u-1))$coef)
  }

  print('Got dimensions!')

  if(transform=='asin'){
    data=asin(sqrt(rMean))
    workItsMat=matrix(c(asin(sqrt(rIts))),S,P*nT*nIts)
  }

  if(transform=='clr'){
    tmp=apply(rMean,c(1,3),f.clr)
    data=array(NA,c(S,P,nT))
    for(p in 1:P){
      data[,p,]=tmp[p,,]
    }
    workIts=apply(rIts,c(1,3,4),f.clr)
    tmp=array(NA,c(S,P,nT,nIts))
    for(p in 1:P){
      tmp[,p,,]=workIts[p,,,]
    }
    workItsMat=matrix(c(tmp),S,P*nT*nIts)
  }

  print('Transformed!')

  tmp=data
  data=matrix(c(data),S,P*nT)

  locMeans=rowMeans(data)
  data=data-locMeans

  mysvd=svd(data)

  workItsMat=workItsMat-locMeans

  tmp        = lm(workItsMat~mysvd$u-1)$coef
  scoreIts   = array(tmp,c(S,P,nT,nIts))  # there are 256 patterns, and this is the score on each pattern for each taxon and each time point for each iteration
  scoreMean  = apply(scoreIts,c(1,2,3),mean)  # mean score on each pattern for each taxon and time point
  scoreUpper = apply(scoreIts,c(1,2,3),quantile,.975)  # quantiles of scores on each pattern for each taxon and time point
  scoreLower = apply(scoreIts,c(1,2,3),quantile,.025)

  scoresOnMeans=array(diag(mysvd$d)%*%t(mysvd$v),c(S,P,nT))

  return(list(scoreMean=scoreMean,scoreUpper=scoreUpper,scoreLower=scoreLower,scoreIts=scoreIts,loadings=mysvd$u,eigenvals=mysvd$d,scoresOnMeans=scoresOnMeans))
}

taxaEOFs=function(rMean,rIts){
  # this returns EOFs where the patterns are with respect to the taxa and there is a score for each grid cell at each time for each of the 9 patterns (the 10th is meaningless because of sum to one constraint
  # scoreMean is the mean of the scores on the patterns (eofs) for each grid cell by time, averaging over the scores for each iteration
  # scoreUpper is the 97.5th percentile and scoreLower the 2.5th percentile of the scores for a given cell and time and pattern
  # scoreIts is the entire set of scores by iteration
  # scoresOnMeans are the scores calculated on rMean rather than by iteration - note that the EOFs are computed based on rMean so that the patterns are the same for every iteration; otherwise the meaning of the scores would change between iterations
  # loadings are the weights on the taxa for each pattern - each column is a pattern and each row is a taxon
  # eigenvals are the variances associated with each pattern with higher variance meaning more variability explained by that pattern
  nT=dim(rIts)[3]
  S=dim(rIts)[1]
  nIts=dim(rIts)[4]
  P=dim(rIts)[2]
  mymat=matrix(0,nr=S*nT,nc=P)
  for(p in 1:P){
    mymat[,p]=c(rMean[,p,])
  }

#   f.clr=function(vec){
#     return(log(vec)-mean(log(vec)))
#   }

  data=apply(mymat,1,f.clr) # transformation to account for proportional data
  taxaMeans=rowMeans(data)
  data=data-taxaMeans # this puts rMean output into a P=10 by n= S*nT matrix; n is the number of 'observations' or 'replicates'

  mysvd=svd(data)

  calcScores=function(data){
    return((lm(data~mysvd$u-1))$coef)
  }

  workIts=array(NA,c(P,S,nT,nIts))
  for(p in 1:P){
    workIts[p,,,]=rIts[,p,,]
  }
  workItsMat=matrix(c(workIts),P,S*nT*nIts)
  workItsMat=apply(workItsMat,2,f.clr)-taxaMeans

  tmp=lm(workItsMat~mysvd$u-1)$coef

  scoreIts=array(tmp,c(P,S,nT,nIts))
  scoreMean=apply(scoreIts,c(1,2,3),mean)
  scoreUpper=apply(scoreIts,c(1,2,3),quantile,.975)
  scoreLower=apply(scoreIts,c(1,2,3),quantile,.025)

  scoresOnMeans=array(diag(mysvd$d)%*%t(mysvd$v),c(P,S,nT))  # scores on the rMean values at each location and time

  tmp1=tmp2=tmp3=tmp4=array(NA,c(S,P,nT))
  tmp5=array(NA,c(S,P,nT,nIts))
  for(p in 1:P){
    tmp1[,p,]=scoreMean[p,,]
    tmp2[,p,]=scoreLower[p,,]
    tmp3[,p,]=scoreUpper[p,,]
    tmp4[,p,]=scoresOnMeans[p,,]
    tmp5[,p,,]=scoreIts[p,,,]
  }

  return(list(scoreMean=tmp1,scoreUpper=tmp3,scoreLower=tmp2,scoreIts=tmp5,loadings=mysvd$u,eigenvals=mysvd$d,scoresOnMeans=tmp4))
}

addPondLocs=function(tNew,tOld=NULL){
# plots black circles for ponds with pollen data and green open circles for ponds without
# use tOld argument if you want to plot information for two time points
  points(pondLocs[pondsUsed[[tNew]],],pch=16,cex=.8)
  points(pondLocs[pondsNotUsed[[tNew]],],col='green')
  if(!is.null(tOld)){
    points(pondLocs[pondsUsed[[tOld]],],pch=16,cex=.8)
    points(pondLocs[pondsNotUsed[[tOld]],],col='green')
  }
}

taxaSignif=function(p1,p2,rIts,locs,restrict=FALSE,inputRestricted=FALSE,ylab='',xlab=''){
# compares significance of differences in composition between two predictions
# red colors indicate more of the taxon in the older time period; blue in the newer
  nComparisons=length(rIts[1,1,])
  less=rIts[,p1,]<rIts[,p2,]
  less=matrix(apply(less,1,sum),sqrt(S),sqrt(S))
  more=nComparisons-less
  if(!restrict){
    used=1:S
    m1=m2=sqrt(S)
    rows=1:16
  } else{
    if(inputRestricted){
      m1=16;m2=9;
      used=1:(m1*m2)
      rows=1:9
    } else{
      used=49:(256-64)
      m1=16;m2=9
      rows=4:12
    }
  }

  xs=sort(unique(locs[,1]))
  ys=sort(unique(locs[,2]))[rows]
  image(xs,ys,more[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,col=tim.colors(32)[21:32],xaxt='n',yaxt='n')
  image(xs,ys,less[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,col=tim.colors(32)[12:1],add=TRUE,xaxt='n',yaxt='n')

  lines(ma$x,ma$y,lwd=1)
  lines(ct$x,ct$y,lwd=1)
  lines(ri$x,ri$y,lwd=1)
  lines(ny$x,ny$y,lwd=1)
  lines(nh$x,nh$y,lwd=1)
}

timeSignifSynch=function(p1,p2,rItsNew,rItsOld,locs,restrict=FALSE,inputRestricted=FALSE,ylab='',xlab=''){
# compares synchrony of significance of differences in composition between two predictions in time and two taxa
# blue colors indicate both taxa show lower abundance in the newer time period; red both higher abundance in the newer; green that the first taxa shows higher in the older and second higher in the newer, and brown that the first shows higher in the new and second higher in the older
  nComparisons=length(rItsNew[1,1,])

  bothLess=rItsNew[,p1,]<rItsOld[,p1,] & rItsNew[,p2,]<rItsOld[,p2,]
  bothLess=matrix(apply(bothLess,1,sum),sqrt(S),sqrt(S))
  bothMore=rItsNew[,p1,]>rItsOld[,p1,] & rItsNew[,p2,]>rItsOld[,p2,]
  bothMore=matrix(apply(bothMore,1,sum),sqrt(S),sqrt(S))
  firstLess=rItsNew[,p1,]<rItsOld[,p1,] & rItsNew[,p2,]>rItsOld[,p2,]
  firstLess=matrix(apply(firstLess,1,sum),sqrt(S),sqrt(S))
  secondLess=rItsNew[,p1,]>rItsOld[,p1,] & rItsNew[,p2,]<rItsOld[,p2,]
  secondLess=matrix(apply(secondLess,1,sum),sqrt(S),sqrt(S))

  #more=nComparisons-less

  if(!restrict){
    used=1:S
    m1=m2=sqrt(S)
    rows=1:16
  } else{
    if(inputRestricted){
      m1=16;m2=9;
      used=1:(m1*m2)
      rows=1:9
    } else{
      used=49:(256-64)
      m1=16;m2=9
      rows=4:12
    }
  }

  xs=sort(unique(locs[,1]))
  ys=sort(unique(locs[,2]))[rows]
  more=nComparisons-bothLess
  image(xs,ys,bothMore[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=tim.colors(32)[21:32])
  image(xs,ys,bothLess[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=tim.colors(32)[12:1],add=TRUE)

  ramp <- colorRamp(c("lightgreen", "darkgreen"))
  greens=rgb( ramp(seq(0, 1, length =12)), max = 255)

  ramp <- colorRamp(c("wheat", "chocolate4"))
  browns=rgb( ramp(seq(0, 1, length =12)), max = 255)

  image(xs,ys,firstLess[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,col=greens,add=T)
  image(xs,ys,secondLess[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,col=browns,add=TRUE)

  lines(ma$x,ma$y,lwd=1)
  lines(ct$x,ct$y,lwd=1)
  lines(ri$x,ri$y,lwd=1)
  lines(ny$x,ny$y,lwd=1)
  lines(nh$x,nh$y,lwd=1)
}

timeDiffs=function(p,rItsNew,rItsOld,locs,lowCut=0.9,highCut=0.95,maxDiff=0.225,nColors=4,restrict=FALSE,inputRestricted=FALSE,ylab='',xlab='',nIncr=50,lwd=2,legend=TRUE){
# compares differences in composition between two predictions, at two levels of significance
# red colors indicate more of the taxon in the newer time period; red in the newer
# hashing indicates lower level of significance
# it's good to make maxDiff=(nColors*2+1)*value/2 where value is a roundish number such as .05,.10 that is the size of the interval for each color in the color bar, e.g., maxDiff=.225 when nColors=4 and you want intervals of .05, which gives the intervals (-.225,-.175),(-.175,-.125),(-.125,-.075),(-.075,-.025),(-.025,.025),...,(.175,.225)

  # nColors*2+1 is the number of different colors plotted
  # maxDiff is the maximum difference in abundance plotted; other values are thresholded to maxDiff and negative maxDiff
  # nIncr and lwd control the diagonal hashing (poorly...)
  # lowCut and highCut are the posterior probability cutoffs
  nComparisons=length(rItsNew[1,1,])
  less=rItsNew[,p,]<rItsOld[,p,]
  less=matrix(apply(less,1,sum),sqrt(S),sqrt(S))
  more=nComparisons-less
  meanNew=rowMeans(rItsNew[,p,])
  meanOld=rowMeans(rItsOld[,p,])
  if(!restrict){
    used=1:S
    m1=m2=sqrt(S)
    rows=1:16
  } else{
    if(inputRestricted){
      m1=16;m2=9;
      used=1:(m1*m2)
      rows=1:9
    } else{
      used=49:(256-64)
      m1=16;m2=9
      rows=4:12
    }
  }

  lessProp=less/nComparisons
  moreProp=more/nComparisons
  lowSignif=lessProp>=lowCut | moreProp>=lowCut
  highSignif=lessProp>=highCut | moreProp>=highCut

  diff=meanNew-meanOld
  diff[!lowSignif]=0
  diff=matrix(thresh(diff,maxDiff,-maxDiff),sqrt(S),sqrt(S))

  xs=sort(unique(locs[,1]))
  ys=sort(unique(locs[,2]))[rows]
  if(legend){
    image.plot(xs,ys,diff[,rows],zlim=c(-maxDiff,maxDiff),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=temp.colors(nColors*2+1))
  } else{
    image(xs,ys,diff[,rows],zlim=c(-maxDiff,maxDiff),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=temp.colors(nColors*2+1))
  }
  xincr=diff(range(xs))/(2*length(xs))
  yincr=diff(range(ys))/(2*length(ys))
  xrg=range(xs)+c(-1,1)*xincr
  yrg=range(ys)+c(-1,1)*yincr

  incr=(yrg[2]-xrg[1]-yrg[1]+xrg[2])/nIncr
  for(i in 1:nIncr){
    abline(a=yrg[1]-xrg[2]+incr*(i-1),b=1,col='white',lwd=2,lty=1)
  }
  box()
  diff[!highSignif]=NA
  if(legend){
    largeplot=image.plot.cp(xs,ys,diff[,rows],zlim=c(-maxDiff,maxDiff),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=temp.colors(nColors*2+1),add=T)
    par(plt=largeplot)
  } else{
    image(xs,ys,diff[,rows],zlim=c(-maxDiff,maxDiff),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=temp.colors(nColors*2+1),add=T)
  }
  lines(ma$x,ma$y,lwd=1)
  lines(ct$x,ct$y,lwd=1)
  lines(ri$x,ri$y,lwd=1)
  lines(ny$x,ny$y,lwd=1)
  lines(nh$x,nh$y,lwd=1)
  box()
}

image.plot.cp=function (..., add = FALSE, nlevel = 64, legend.shrink = 0.9,
    legend.width = 0.05, graphics.reset = FALSE, horizontal = FALSE,
    offset = 2 * legend.width, bigplot = NULL, smallplot = NULL,
    legend.only = FALSE, col = tim.colors(nlevel))
{
    old.par <- par(no.readonly = TRUE)
    info <- image.plot.info(...)
    if (add)
        big.plot <- old.par$plt
    if (legend.only)
        graphics.reset <- TRUE
    temp <- image.plot.plt(add = add, legend.shrink = legend.shrink,
        legend.width = legend.width, horizontal = horizontal,
        offset = offset, bigplot = bigplot, smallplot = smallplot)
    smallplot <- temp$smallplot
    bigplot <- temp$bigplot
    if (!legend.only) {
        if (!add) {
            par(plt = bigplot)
        }
        image(..., add = add, col = col)
        big.par <- par(no.readonly = TRUE)
    }
    if ((smallplot[2] < smallplot[1]) | (smallplot[4] < smallplot[3])) {
        par(old.par)
        stop("plot region too small to add legend\n")
    }
    temp <- list(...)
    iy <- seq(info$zlim[1], info$zlim[2], , nlevel)
    iz <- matrix(iy, nrow = 1, ncol = length(iy))
    ix <- 1
    if (!horizontal) {
        par(new = TRUE, pty = "m", plt = smallplot, err = -1)
        image(ix, iy, iz, xaxt = "n", yaxt = "n", xlab = "",
            ylab = "", col = col)
        axis(4, mgp = c(3, 1, 0), las = 2)
        box()
    }
    else {
        par(new = TRUE, pty = "m", plt = smallplot, err = -1)
        image(iy, ix, t(iz), yaxt = "n", xlab = "", ylab = "",
            col = col)
        box()
    }
    mfg.save <- par()$mfg
    if (graphics.reset | add) {
        par(old.par)
        par(mfg = mfg.save, new = FALSE)
        return(bigplot)
        #invisible()
    }
    else {
        par(big.par)
        par(plt = big.par$plt, xpd = FALSE)
        par(mfg = mfg.save, new = FALSE)
        return(bigplot)
        #invisible()
    }
}

timeSignif=function(p,rItsNew,rItsOld,locs,restrict=FALSE,inputRestricted=FALSE,ylab='',xlab=''){
# compares significance of differences in composition between two predictions
# red colors indicate more of the taxon in the newer time period; blue in the older
  nComparisons=length(rItsNew[1,1,])
  less=rItsNew[,p,]<rItsOld[,p,]
  less=matrix(apply(less,1,sum),sqrt(S),sqrt(S))
  more=nComparisons-less
  if(!restrict){
    used=1:S
    m1=m2=sqrt(S)
    rows=1:16
  } else{
    if(inputRestricted){
      m1=16;m2=9;
      used=1:(m1*m2)
      rows=1:9
    } else{
      used=49:(256-64)
      m1=16;m2=9
      rows=4:12
    }
  }

  xs=sort(unique(locs[,1]))
  ys=sort(unique(locs[,2]))[rows]
  image(xs,ys,more[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=tim.colors(32)[21:32])
  image(xs,ys,less[,rows],zlim=c(.9*nComparisons,nComparisons),xlab=xlab,ylab=ylab,xaxt='n',yaxt='n',col=tim.colors(32)[12:1],add=TRUE)

  lines(ma$x,ma$y,lwd=1)
  lines(ct$x,ct$y,lwd=1)
  lines(ri$x,ri$y,lwd=1)
  lines(ny$x,ny$y,lwd=1)
  lines(nh$x,nh$y,lwd=1)
}

feature=function(p,less,locs,restrict=FALSE,inputRestricted=FALSE,nComparisons=10000){
  # plots feature significance for one prediction for one taxon
  par.old=par()
  less=less[[p]]
  more=nComparisons-less
  diag(more)=0
  if(!restrict){
    used=1:S
    m1=m2=sqrt(S)
    rows=1:16
  } else{
    if(inputRestricted){
      m1=16;m2=9;
      used=1:(m1*m2)
      rows=1:9
    } else{
      used=49:(256-64)
      m1=16;m2=9
      rows=4:12
    }
  }

  par(mfrow=c(m2,m1),mai=c(0,0,0,0),xaxt='n',yaxt='n')
  for(row in rowseq){
    for(col in 1:16){
      image(1:m1,1:m2,matrix(more[((row-1)*16+col),][used],m1,m2),zlim=c(.9*nComparisons,nComparisons),xlab='',ylab='',col=tim.colors(32)[21:32],cex.axis=2,yaxt='n',xaxt='n')
      image(1:m1,1:m2,matrix(less[((row-1)*16+col),][used],m1,m2),zlim=c(.9*nComparisons,nComparisons),xlab='',ylab='',col=tim.colors(32)[12:1],cex.axis=2,yaxt='n',xaxt='n',add=TRUE)
      text(col,row-min(rowseq)+1.001,'x',cex=1.4)  # can't figure out why this is not printing 'x's on bottom row
    }
  }
  par(par.old)
}

# modify this to deal better with input format
timePlot=function(times,mean,lower=NULL,upper=NULL,ylim=NULL,xlab='',ylab=''){
  # plots time series with confidence bars (e.g., to plot coefficient values over time)
  par(mfrow=c(2,5))
  for(p in 1:ncol(mean)){
    plot(-1*times,mean[,p],type='l',ylim=range(c(lower,upper,mean)),ylab=ylab,xlab=xlab)
    points(-1*times,mean[,p],pch=16,cex=.8)
    lines(-1*times,lower[,p],col=2,lty=2)
    lines(-1*times,upper[,p],col=2,lty=2)
    abline(h=0,col='gray',lty=3)
    title(taxa[p])
  }
}

timePlotDecomp=function(times,mean,lower=NULL,upper=NULL,its=NULL,ylim=NULL,xlab='',ylab=''){
  # plots time series with confidence bars (e.g., to plot coefficient values over time)
  mns=its
  tmp=apply(its,c(2,3),mean)
  for(t in 1:length(times)){
    mns[t,,]=tmp
  }
  its=its-mns
  devMean=apply(its,c(1,2),mean)
  devLower=apply(its,c(1,2),quantile,.025)
  devUpper=apply(its,c(1,2),quantile,.975)

  par(mfrow=c(2,5))
  for(p in 1:ncol(mean)){
    plot(-1*times,mean[,p],type='n',ylim=range(c(lower,upper,mean)),ylab=ylab,xlab=xlab)
#    points(-1*times,mean[,p],pch=16,cex=.8)
    polygon(c(rev(-1*times),-1*times),c(rev(lower[,p]),upper[,p]),col='gray80',border='gray80')
    lines(-1*times,mean[,p])
    lines(-1*times,devLower[,p]+mean(mean[,p]),col=2)
    lines(-1*times,devUpper[,p]+mean(mean[,p]),col=2)
    abline(h=0,col='gray50',lty=3)
    title(taxa[p])
  }
}

# modify to deal better with input format
vegDiagram=function(cell,times){
  # analogous to a pollen diagram - plots vegetation predictions over time
  mean=matrix(0,nr=length(times),nc=P)
  lower=upper=mean
  for(tt in 1:length(times)){
    mean[tt,]=eval(as.name(paste('rMean',times[tt],sep='')))[cell,]
    lower[tt,]=eval(as.name(paste('rLow',times[tt],sep='')))[cell,]
    upper[tt,]=eval(as.name(paste('rUp',times[tt],sep='')))[cell,]
  }
  maxvals=apply(upper,2,max)
  maxvals=signif(maxvals,digits=1)+.1
  for(p in 1:P){
    if(maxvals[p]<.2){maxvals[p]=.2}
  }
  par(mfrow=c(1,P),mai=c(0.4,0.15,0.4,0.05),mgp=c(0,0.3,0))
  p=1
  plot(mean[,p],-1*times,type='p',xlim=c(0,maxvals[p]),pch=16,cex=.3,xlab='',ylab='',tck=-.04)
  title(taxaNames[p])
  for(vv in seq(.1,.9,by=.1)){
    abline(v=vv,lty=2,col='grey')
  }
  lines(mean[,p],-1*times,pch=16,cex=0.3)
  lines(lower[,p],-1*times,col=2)
  lines(upper[,p],-1*times,col=2)
  par(mai=c(0.4,0.15,0.4,0.05))
  for(p in 2:P){
    plot(mean[,p],-1*times,type='p',xlim=c(0,maxvals[p]),yaxt='n',pch=16,cex=.3,xlab='',ylab='',tck=-.04)
    title(taxaNames[p])
    for(vv in seq(.1,.9,by=.1)){
      abline(v=vv,lty=2,col='grey')
    }
    lines(mean[,p],-1*times)
    lines(lower[,p],-1*times,col=2)
    lines(upper[,p],-1*times,col=2)
  }
}

vegPlusPollenDiagram=function(cell,times,pollenAges,pollenProp,lwd=1){
  # analogous to a pollen diagram - plots vegetation predictions over time with pollen overlaid; pollen might go outside figure limits...
  # pollenProp should have rows equal ages and columns be the 10 taxa with the data being proportions
  mean=matrix(0,nr=length(times),nc=P)
  lower=upper=mean
  for(tt in 1:length(times)){
    mean[tt,]=eval(as.name(paste('rMean',times[tt],sep='')))[cell,]
    lower[tt,]=eval(as.name(paste('rLow',times[tt],sep='')))[cell,]
    upper[tt,]=eval(as.name(paste('rUp',times[tt],sep='')))[cell,]
  }
  maxvals=apply(upper,2,max)
  maxvals=signif(maxvals,digits=1)+.1
  for(p in 1:P){
    if(maxvals[p]<.2){maxvals[p]=.2}
  }
  par(mfrow=c(1,P),mai=c(0.4,0.15,0.4,0.05),mgp=c(0,0.3,0))
  p=1
  plot(mean[,p],-1*times,type='p',xlim=c(0,maxvals[p]),pch=16,cex=.3,xlab='',ylab='',tck=-.04)
  title(taxaNames[p])
  for(vv in seq(.1,.9,by=.1)){
    abline(v=vv,lty=2,col='grey',lwd=lwd)
  }
  lines(mean[,p],-1*times,pch=16,cex=0.3,lwd=lwd)
  lines(lower[,p],-1*times,col=2,lwd=lwd)
  lines(upper[,p],-1*times,col=2,lwd=lwd)
  lines(pollenProp[,p],pollenAges,col='blue',lwd=lwd)
  par(mai=c(0.4,0.15,0.4,0.05))
  for(p in 2:P){
    plot(mean[,p],-1*times,type='p',xlim=c(0,maxvals[p]),yaxt='n',pch=16,cex=.3,xlab='',ylab='',tck=-.04)
    title(taxaNames[p])
    for(vv in seq(.1,.9,by=.1)){
      abline(v=vv,lty=2,col='grey',lwd=lwd)
    }
    lines(mean[,p],-1*times,lwd=lwd)
    lines(lower[,p],-1*times,col=2,lwd=lwd)
    lines(upper[,p],-1*times,col=2,lwd=lwd)
    lines(pollenProp[,p],pollenAges,col='blue',lwd=lwd)
  }
}

vegPlusPollenDiagramDecomp=function(cell,timeInd,times,pollenAges,pollenProp,maxvals=NULL,lwd=1){
  # analogous to a pollen diagram - plots vegetation predictions over time with pollen overlaid but now with long-term avg + deviations; pollen might go outside figure limits...
  # pollenProp should have rows equal ages and columns be the 10 taxa with the data being proportions

  smps=rIts[cell,,timeInd,]
  lterm=matrix(0,nr=P,nc=3)
  lterm[,1]=apply(smps,1,mean)
  lterm[,2]=apply(smps,1,quantile,c(.025))
  lterm[,3]=apply(smps,1,quantile,c(.975))

  mns=smps
  for(t in 1:length(times)){
    mns[,t,]=apply(smps,c(1,3),mean)
  }
  smps=smps-mns
  tv=array(0,c(P,length(times),3))
  tv[,,1]=apply(smps,c(1,2),mean)
  tv[,,2]=apply(smps,c(1,2),quantile,.025)
  tv[,,3]=apply(smps,c(1,2),quantile,.975)

  mean=rMean[cell,,timeInd]
  lower=rLow[cell,,timeInd]
  upper=rUp[cell,,timeInd]

  if(is.null(maxvals)){
    pollMax=apply(tmp,2,max)
    maxvals=apply(upper,1,max)
    maxvals=apply(cbind(pollMax,maxvals),1,max)
    maxvals=signif(maxvals,digits=1)+.1
    for(p in 1:P){
      if(maxvals[p]<.2){maxvals[p]=.2}
    }
  }
  par(mfrow=c(1,P),mai=c(0.4,0.15,0.4,0.05),mgp=c(0,0.3,0))
  p=1
  plot(mean[p,],-1*times,type='n',xlim=c(0,maxvals[p]),pch=16,cex=.3,xlab='',ylab='',tck=-.04)
  title(taxaNames[p])
#  lines(lower[,p],-1*times,col=2)
#  lines(upper[,p],-1*times,col=2)
  polygon(c(rev(lower[p,]),upper[p,]),c(rev(-1*times),-1*times),col='gray80',border='gray80')
  for(vv in seq(.1,.9,by=.1)){
    abline(v=vv,lty=2,col='gray50',lwd=lwd)
  }
  lines(mean[p,],-1*times,pch=16,cex=0.3,lwd=lwd)
#  points(mean[p,],-1*times,pch=16,cex=0.3)
  lines(lterm[p,1]+tv[p,,1],-1*times,pch=16,cex=0.3,lwd=lwd)
  lines(lterm[p,1]+tv[p,,2],-1*times,col=2,lwd=lwd)
  lines(lterm[p,1]+tv[p,,3],-1*times,col=2,lwd=lwd)
  lines(pollenProp[,p],pollenAges,col='blue',lwd=lwd)
  points(pollenProp[,p],pollenAges,col='blue',pch=16,cex=.3)
  par(mai=c(0.4,0.15,0.4,0.05))
  for(p in 2:P){
    plot(mean[p,],-1*times,type='n',xlim=c(0,maxvals[p]),yaxt='n',pch=16,cex=.3,xlab='',ylab='',tck=-.04)
    title(taxaNames[p])
    polygon(c(rev(lower[p,]),upper[p,]),c(rev(-1*times),-1*times),col='gray80',border='gray80')
     for(vv in seq(.1,.9,by=.1)){
      abline(v=vv,lty=2,col='grey50',lwd=lwd)
    }
    lines(mean[p,],-1*times,lwd=lwd)
   #  points(mean[p,],-1*times,pch=16,cex=0.3)
   #lines(lower[,p],-1*times,col=2)
    #lines(upper[,p],-1*times,col=2)
    lines(lterm[p,1]+tv[p,,1],-1*times,lwd=lwd)
    lines(lterm[p,1]+tv[p,,2],-1*times,col=2,lwd=lwd)
    lines(lterm[p,1]+tv[p,,3],-1*times,col=2,lwd=lwd)
    lines(pollenProp[,p],pollenAges,col='blue',lwd=lwd)
    points(pollenProp[,p],pollenAges,col='blue',pch=16,cex=.3)
  }

}

thresh=function(vec,up=NULL,lo=NULL){
  if(!is.null(up)){
    vec[vec>up]=up
  }
  if(!is.null(lo)){
    vec[vec<lo]=lo
  }
  return(vec)
}

surfMap=function(p,rMat,locs,max=0.4,min=0,restrict=FALSE,inputRestricted=FALSE,legend=TRUE,statelwd=2){
  # surface map for a single taxon
  if(!restrict){
    used=1:S
    m1=m2=sqrt(S)
    rows=1:16
  } else{
    if(inputRestricted){
      m1=16;m2=9;
      used=1:(m1*m2)
      rows=1:9
    } else{
      used=49:(256-64)
      m1=16;m2=9
      rows=4:12
    }
  }

  tmp=list()
  tmp$x=unique(locs[used,1])
  tmp$y=unique(locs[used,2])
  m1=length(tmp$x)
  m2=length(tmp$y)
  tmp$z=matrix(rMat[used,p],m1,m2)
  tmp$z=thresh(tmp$z,max)
  if(legend){
    image.plot(tmp$x,tmp$y,tmp$z,xaxt='n',yaxt='n',col=tim.colors(32),zlim=c(min,max),xlab="",ylab="")
  } else{
    image(tmp$x,tmp$y,tmp$z,col=tim.colors(32),xaxt='n',yaxt='n',xlab="",ylab="",zlim=c(min,max))
  }
  lines(ma$x,ma$y,lwd=statelwd)
  lines(ct$x,ct$y,lwd=statelwd)
  lines(ri$x,ri$y,lwd=statelwd)
  lines(nh$x,nh$y,lwd=statelwd)
  lines(ny$x,ny$y,lwd=statelwd)
}

pieMap=function(proportions,centers,restrict=FALSE,inputRestricted=FALSE,xlim=c(629000-6000,809000+6000),ylim=c(4621000-6000,4801000+6000),radius=NULL,scale=1,xlab='x',ylab='y',...){
# plots multiple pie composition charts as a map
  if(!restrict){
    used=1:nrow(centers)
  } else{ # assumes subset of grid
    if(inputRestricted){
      used=1:144
    } else{
      used=49:(256-64)
    }
  }
  centers=as.matrix(centers[used,])
  proportions=as.matrix(proportions[used,])
  if(is.null(xlim)){
    rg=range(centers[,1])
    df=(scale-1)*diff(range(centers[,1]))
    xlim=c(rg[1]-df,rg[2]+df)
  }
  if(is.null(ylim)){
    rg=range(centers[,2])
    df=(scale-1)*diff(range(centers[,2]))
    ylim=c(rg[1]-df,rg[2]+df)
  }
  plot(centers,type='n',xlim=xlim,ylim=ylim,xlab=xlab,ylab=ylab,...)
  n=length(centers[,1])
  if(is.null(radius)){
    radius=.025*diff(range(centers[,1]))
  }
  minVal=min(proportions)
 # eps=1e-10*max(proportions)
 # if(minVal==0){
 #   warning("Some proportions are zero; proceeding with jittering.")
 #   proportions=proportions+eps
 # }
  if(minVal<0){
    stop("Some proportions are less than zero.")
  }
  if(length(radius)==1){ radius=rep(radius,n)}
  for(i in 1:n){
    if(sum(proportions[i,])>0){
      minVal=min(proportions[i,])
      if(minVal==0){
        warning("Some proportions are zero; proceeding with jittering.")
        eps=1e-10*max(proportions[i,])
        proportions[i,]=proportions[i,]+eps
      }
      pieAdd(as.vector(proportions[i,]),as.vector(centers[i,]),radius=radius[i],...)
    } else{
      points(centers[i,],pch='X')
    }
  }
  lines(ma$x,ma$y,lwd=1)
  lines(ct$x,ct$y,lwd=1)
  lines(ri$x,ri$y,lwd=1)
  lines(ny$x,ny$y,lwd=1)
  lines(nh$x,nh$y,lwd=1)
}

pieAdd= function (x, center, labels = names(x), edges = 200, radius = 0.8, density = NULL, angle = 45, col = NULL, border = NULL, lty = NULL, ...) # modified from the pie() function in R
{
    if (!is.numeric(x) || any(is.na(x) | x <= 0))
        stop("pie: `x' values must be positive.")
    if (is.null(labels))
        labels <- rep("",length(x))
    x <- c(0, cumsum(x)/sum(x))
    dx <- diff(x)

    pin <- par("pin")
    nx <- length(dx)
    if (is.null(col))
        col <- if (is.null(density))
            c("white", "black","lightblue", "red","darkblue","yellow",
              "purple","orange","lightgreen","darkgreen")
        else par("fg")
    col <- rep(col, length.out = nx)
    border <- rep(border, length.out = nx)
    lty <- rep(lty, length.out = nx)
    angle <- rep(angle, length.out = nx)
    density <- rep(density, length.out = nx)
    for (i in 1:nx) {
        n <- max(2, floor(edges * dx[i]))
        t2p <- 2 * pi * seq(x[i], x[i + 1], length = n)
        xc <- c(cos(t2p), 0) * radius + center[1]
        yc <- c(sin(t2p), 0) * radius + center[2]
        polygon(xc, yc, density = density[i], angle = angle[i],
            border = border[i], col = col[i], lty = lty[i],...)
        t2p <- 2 * pi * mean(x[i + 0:1])
        xc <- cos(t2p) * radius + center[1]
        yc <- sin(t2p) * radius + center[2]
        if (!is.na(lab <- labels[i]) && lab != "") {
            lines(c(1, 1.05) * xc, c(1, 1.05) * yc)
            text(1.1 * xc, 1.1 * yc, lab, xpd = TRUE, adj = ifelse(xc <
                0, 1, 0), ...)
        }
    }
    invisible(NULL)
}

# template code for using above functions to analyze output

if(FALSE){

# piemap of predictions for third time point (500 in 300-3000 predictions), restricting to approximate region with ponds
pieMap(rMean[,,3],gridLocs,restrict=TRUE)
# piemap of aggregated pollen for third time point
pieMap(cMat[,,3],pondLocs)

# surface maps for third time point
surfMap(1,rMean[,,3],gridLocs,max=0.6,restrict=TRUE)

par(mfrow=c(3,3),mar=c(2.1,2.1,3.1,1.1))
  for(p in 1:(P-1)){
    surfMap(p,rMean[,,3],gridLocs,max=0.6,restrict=TRUE)
    title(taxa[p])
  }

# feature significance map

feature(2,less[[3]],gridLocs,restrict=TRUE,nComparisons=nComparisons) # 2nd taxon, 3rd time period
# ignore the 'graphical parameter' warning messages

# maps of significant differences between two time periods (the third and fourth time periods) for 2nd taxon

# pure significance
timeSignif(2,rIts[,,3,],rIts[,,4,],gridLocs,restrict=TRUE)
# actual mean differences with only significant ones shown
timeDiffs(p=1,rIts[,,3,],rIts[,,4,],gridLocs,restrict=T,nColors=4,maxDiff=.225)

# putting all taxa on a page
 par(mfrow=c(3,3),mar=c(2.1,2.1,3.1,1.1))
  for(p in 1:(P-1)){
    timeSignif(p,rIts[,,3,],rIts[,,4,],gridLocs,restrict=TRUE)
    title(taxa[p])
  }

# map of significant sychrony between two taxa (pine and oak) between two time periods (the third and fourth time periods)
timeSignifSynch(8,7,rIts[,,3,],rIts[,,4,],gridLocs,restrict=TRUE)

# time series plots of coefficients
whichts=1:23 # use 300-2500 time interval (if the output is for 300-3000 time period)
timePlotDecomp(times[whichts],b1sMean[whichts,],b1sLow[whichts,],b1sUp[whichts,],b1s[whichts,,])

# maps of significant differences between two taxa (2nd and 7th here) for 3rd time period
taxaSignif(2,7,rIts[,,3,],gridLocs,restrict=TRUE)

# vegetation + pollen diagam for 300-2500 time interval for cell 139 (Snake Pond I think)
dat=read.table('PollenTimeSeries.csv',sep=',',header=T)
i=20
subdat=dat[dat$sitenumber==i,]
age=-subdat$'cal.age'
tmp=subdat[,5:14]
tmp=tmp/apply(tmp,1,sum)
whichTimeIndices=1:23
vegPlusPollenDiagramDecomp(139,whichTimeIndices,seq(300,2500,by=100),age,tmp)

# example calculation of taxa eofs and uncertainty

myTaxaEOFs=taxaEOFs(rMean,rItsSub)
# some plotting ideas
# map of scores on first EOF for 12th time point
surfMap(1,myTaxaEOFs$scoreMean[,,12],gridLocs,restrict=T)
# time series plot of first EOF at 80th grid point for all time points, with uncertainty
tsplot(myTaxaEOFs$scoreMean[80,1,],ylim=c(-12,12),xlab='time',ylab='scores')
lines(myTaxaEOFs$scoreUpper[80,1,],lty=2)
lines(myTaxaEOFs$scoreLower[80,1,],lty=2)

# example of spatial EOFs specific to a taxon

beechEOF=spatialEOFbyTaxon(1,rMean,rItsSub)
# plot the first eof
surfMap(1,beechEOF$loadings,gridLocs,max=0.2,min=-0.2,restrict=T)    # here '1' is the pattern desired not the taxon
# plot time series and uncertainty of scores for first eof
tsplot(beechEOF$scoreMean[1,],ylim=c(-4,4),xlab='time',ylab='scores')
lines(beechEOF$scoreUpper[1,],lty=2)
lines(beechEOF$scoreLower[1,],lty=2)

# spatial EOFs for all taxa
allEOF=spatialEOFallTaxa(rMean,rItsSub,transform='clr')
# plot the first eof
surfMap(1,allEOF$loadings,gridLocs,max=0.2,min=-0.2,restrict=T)    # here '1' is the pattern desired not the taxon
# plot time series and uncertainty of scores for first eof, second taxon (birch)
tsplot(allEOF$scoreMean[1,2,],ylim=c(-60,60),xlab='time',ylab='scores')
lines(allEOF$scoreUpper[1,2,],lty=2)
lines(allEOF$scoreLower[1,2,],lty=2)
# plot time series of posterior mean scores for first eof, all taxa
for(p in 1:P){
  if(p==1){
    tsplot(allEOF$scoreMean[1,p,],ylim=c(-40,40),xlab='time',ylab='scores')
  } else{
    lines(allEOF$scoreMean[1,p,],col=p)
  }
}

}


library(Diagnostics)

learn <- function(cases) {
  # order: P(Pn), P(Te |Pn), P(VTB), P(TB| VTB), P(Sm), P(LC |Sm), P(BR |Sm), P(XR |Pn, VTB, LC), P(Dy |LC, BR)
  pn = table(cases$Pn) + 1
  pn = pn / sum(pn)

  #special handling for temperature
  te__pn = generate_te_model(cases)

  vtb = table(cases$VTB) + 1
  vtb = vtb / sum(vtb)

  tb__vtb = table(cases$VTB, cases$TB) + 1
  for (i in 1:2) {
    tb__vtb[i, ] = tb__vtb[i, ] / sum(tb__vtb[i, ])
  }

  sm = table(cases$Sm) + 1
  sm = sm / sum(sm)

  lc__sm =  table(cases$Sm, cases$LC)  + 1
  for (i in 1:2) {
    lc__sm[i, ] = lc__sm[i, ] / sum(lc__sm[i, ])
  }

  br__sm = table(cases$Sm, cases$Br)  + 1
  for (i in 1:2) {
    br__sm[i, ] = br__sm[i, ] / sum(br__sm[i, ])
  }

  xr__pn_tb_lc = table(cases$Pn, cases$TB, cases$LC, cases$XR)  + 1
  for (i in 1:2) {
    for (j in 1:2) {
      for (k in 1:2) {
        xr__pn_tb_lc[i, j, k, ] = xr__pn_tb_lc[i, j, k, ] / sum(xr__pn_tb_lc[i, j, k, ])
      }
    }
  }

  dy__lc_br = table(cases$LC, cases$Br, cases$Dy) + 1
  for (i in 1:2) {
    for (j in 1:2) {
      dy__lc_br[i, j, ] = dy__lc_br[i, j, ] / sum(dy__lc_br[i, j, ])
    }
  }

  model = list()
  model$pn = pn
  model$te__pn = te__pn
  model$vtb = vtb
  model$tb__vtb = tb__vtb
  model$sm = sm
  model$lc__sm = lc__sm
  model$br__sm  = br__sm
  model$xr__pn_tb_lc = xr__pn_tb_lc
  model$dy__lc_br = dy__lc_br

  return(model)
}

generate_te_model <- function(cases) {
  cases0 = list()
  cases1 = list()

  for (i in 1:length(cases$Te)) {
    if (cases$Pn[i] == 0) {
      cases0 = append(cases0, cases$Te[i])
    } else{
      cases1 = append(cases1, cases$Te[i])
    }
  }
  cases0 = as.vector(unlist(cases0))
  cases1 =  as.vector(unlist(cases1))

  l0 = list()
  l0$mean = mean(cases0)
  l0$sd = sd(cases0)
  l1 = list()
  l1$mean = mean(cases1)
  l1$sd = sd(cases1)

  return(list(l0, l1)) # access with var_name[[1]]$sd, var_name[[2]]$sd, etc
}

diagnose <- function(model, cases) {
  samples_number = 1500
  burn_period = 0.1

  for (i in 1:length(cases[,1])){
    case = cases[i,]
    samples = generate_samples(cases[i,], samples_number, burn_period, model)
    case = make_predictions(case, samples)
    cases[i,] = case
  }
  return((c(cases$Pn, cases$TB, cases$LC, cases$Br)))
}

evaluate_var_prob <- function(samples, var_name) {
  samples_count = length(samples[,1])
  var_column = samples[var_name]
  var_true_count = sum(var_column)
  true_prob = var_true_count / samples_count
  return(true_prob)
}

make_predictions <- function(case, samples) {

  case["Pn"] = evaluate_var_prob(samples, "Pn")
  case["TB"] = evaluate_var_prob(samples, "TB")
  case["LC"] = evaluate_var_prob(samples, "LC")
  case["Br"] = evaluate_var_prob(samples, "Br")

  return(case)
}

invert <- function(val) {
  if (val == 0) {
    return(1)
  } else {
    return(0)
  }
}

calc_conditional_probs <- function(sample, model) {
  Pn = sample$Pn
  Te = sample$Te
  VTB = sample$VTB
  TB = sample$TB
  Sm = sample$Sm
  LC = sample$LC
  Br = sample$Br
  XR = sample$XR
  Dy = sample$Dy
  return(
    model$pn[Pn + 1] *
      dnorm(
        mean = model$te__pn[[Pn + 1]]$mean,
        sd = model$te__pn[[Pn + 1]]$sd,
        x = Te
      ) *
      model$vtb[VTB + 1] *
      model$tb__vtb[VTB + 1, TB + 1] *
      model$sm[Sm + 1] *
      model$lc__sm[Sm + 1, LC + 1] *
      model$br__sm[Sm + 1, Br + 1] *
      model$xr__pn_tb_lc[Pn + 1, TB + 1, LC + 1, XR + 1] *
      model$dy__lc_br[LC + 1, Br + 1, Dy + 1]
  )
}

propose_value_for_unknown <- function(sample, unknown_var, model) {
  old_sample = sample
  new_sample = sample
  new_sample[unknown_var] = invert(new_sample[unknown_var])
  p_old = calc_conditional_probs(old_sample, model)
  p_new = calc_conditional_probs(new_sample, model)

  if (p_new > p_old) {
    return(new_sample)
  } else {
    threshold = p_new / p_old
    random = runif(1, 0, 1)
    if (random < threshold) {
      return(new_sample)
    } else {
      return(old_sample)
    }
  }

}

generate_one_sample <- function(samples, number, model) {
  sample = samples[number,]
  if (number == 1) {  #first sample, assign unknown variables to random values
    sample$Pn = sample(0:1, 1)
    sample$TB = sample(0:1, 1)
    sample$LC = sample(0:1, 1)
    sample$Br = sample(0:1, 1)
  } else {
    prev_sample = samples[number - 1,]
    sample$Pn = prev_sample$Pn
    sample$TB = prev_sample$TB
    sample$LC = prev_sample$LC
    sample$Br = prev_sample$Br
  }

  sample = propose_value_for_unknown(sample, "Pn", model)
  sample = propose_value_for_unknown(sample, "TB", model)
  sample = propose_value_for_unknown(sample, "LC", model)
  sample = propose_value_for_unknown(sample, "Br", model)

  return(sample)
}

generate_samples <- function(case, samples_number, burn_period, model) {

  samples = hist
  samples = samples[1:samples_number,]  # samples_number cannot be more than hist size, maybe fix it later
  samples$Te = case$Te
  samples$VTB = case$VTB
  samples$Sm = case$Sm
  samples$XR = case$XR
  samples$Dy = case$Dy

  for (i in 1:samples_number) {
    samples[i,] = generate_one_sample(samples, i, model)
  }

  samples_burned = samples_number * burn_period
  samples = samples[samples_burned:length(samples[,1]),]

  return(samples)
}
#run_count = 10
#runs = vector(length = run_count)
runDiagnostics(learn, diagnose, verbose = 2)
#for (i in 1:run_count) {
#  runs[i] = runDiagnostics(learn, diagnose, verbose = 2)
#}
# print("Result: ")
# cat("mean: ", mean(runs), "\n")
# cat("sd: ", sd(runs), "\n")
# cat("worse than 0.01345: ", length(runs[runs > 0.01345]), "\n")
# cat("worse than 0.013375: ", length(runs[runs > 0.013375]), "\n")


#' Plot annual SPR targets
#'
#' Computes and plots SPR targets using selectivity, M, WAA, and maturity by year.
#' @param asap name of the variable that read in the asap.rdat file
#' @param pspr user defined value(s) of spr, e.g. 0.4 or c(0.4, 0.43, 0.46); if empty (default), calculated at seq(0.2, 0.5, by=0.1)
#' @param save.plots save individual plots
#' @param od output directory for plots and csv files
#' @param plotf type of plot to save
#' @export

PlotAnnualSPRtargets <- function(asap, pspr=c(), save.plots,od,plotf){

  if(length(pspr)>0) spr.targ.values <- pspr
  if(length(pspr)==0) spr.targ.values <- seq(0.2, 0.5, by=0.1)
  n.spr <- length(spr.targ.values)
  nages<- asap$parms$nages
  nyears <- asap$parms$nyears
  years <- seq(asap$parms$styr,asap$parms$endyr)
  fec.age <- asap$WAA.mats$WAA.ssb
  mat.age <- asap$maturity
  wgt.age <- asap$WAA.mats$WAA.catch.all
  M.age <- asap$M.age
  sel.age <- asap$F.age/apply(asap$F.age,1,max)

  spawn.time <- asap$options$frac.yr.spawn

  spr0.vals<- asap$SR.annual.parms$s.per.r.vec
  F.start <-0.11  # starting guess for optimization routine to find F_SPR%

  f.spr.vals <- matrix(NA, nyears, n.spr)
  ypr.spr.vals <- matrix(NA, nyears, n.spr)
  conv.vals <- matrix(NA, nyears, n.spr)

  for (i in 1:n.spr) {
    for (j in 1:nyears) {
      t.spr <- spr.targ.values[i]

      spr.f <- function(F.start) {
        abs(s.per.recr(nages=nages, fec.age=fec.age[j,], mat.age=mat.age[j,], M.age= M.age[j,], F.mult=F.start, sel.age=sel.age[j,], spawn.time=spawn.time)/spr0.vals[j] - t.spr )
      }
      yyy <- nlminb(start=F.start, objective=spr.f, lower=0, upper=3)
      f.spr.vals[j,i] <- yyy$par
      ypr.spr.vals[j,i] <- ypr(nages, wgt.age=wgt.age[j,], M.age=M.age[j,],  F.mult=f.spr.vals[j,i], sel.age=sel.age[j,] )
      conv.vals[j,i] <- ifelse(yyy$convergence==0, TRUE, FALSE)
    }  # end j-loop over nyears
  }  #end i-loop over SPR values

 # if(length(pspr)==0) {
  par(mfrow=c(1,1), mar=c(4,4,2,4) )
  lty.seq=c(1,2,4,6)
  plot(years, f.spr.vals[,1], type='n', xlab="Year", ylab="Full F (%SPR)", lwd=2,
       col="blue3", ylim=c(0,1.2*max(f.spr.vals)) )
  for (i in 1:n.spr) {
    lines(years, f.spr.vals[,i], lwd=2, col=i, lty=lty.seq[i] )
  }
  if(length(pspr)==0) legend('top', legend=c("F20%", "F30%", "F40%", "F50%"), col=seq(1,4), lty=lty.seq,
         horiz=T,lwd=rep(2,4), cex=0.9)
  if(length(pspr)>0) legend('top', legend=c(paste0("F", round(100*pspr,0), "%")), col=seq(1,4), lty=lty.seq,
                             horiz=T,lwd=rep(2,4), cex=0.9)

  title (main="Annual F(%SPR) Reference Points", outer=T, line=-1 )

  if (save.plots) savePlot(paste0(od, "Annual.FSPR.", plotf), type=plotf)

  plot(years, ypr.spr.vals[,1], type='n', xlab="Year", ylab="YPR (%SPR)", lwd=2,
       col="blue3", ylim=c(0,1.2*max(ypr.spr.vals)) )
  for (i in 1:n.spr) {
    lines(years, ypr.spr.vals[,i], lwd=2, col=i, lty=lty.seq[i] )
  }
  if(length(pspr)==0) legend('top', legend=c("YPR20%", "YPR30%", "YPR40%", "YPR50%"), col=seq(1,4), lty=lty.seq,
         horiz=T,lwd=rep(2,4), cex=0.9)
  if(length(pspr)>0) legend('top', legend=c(paste0("YPR", round(100*pspr,0), "%")), col=seq(1,4), lty=lty.seq,
                             horiz=T,lwd=rep(2,4), cex=0.9)

  title (main="Annual YPR(%SPR) Reference Points", outer=T, line=-1 )

  if (save.plots) savePlot(paste0(od, "Annual.YPR.", plotf), type=plotf)

  if(length(pspr)==0) {
  f.hist.20 <- hist(f.spr.vals[,1], plot=F)
  f.hist.30 <- hist(f.spr.vals[,2], plot=F)
  f.hist.40 <- hist(f.spr.vals[,3], plot=F)
  f.hist.50 <- hist(f.spr.vals[,4], plot=F)

  par(mfrow=c(2,2), mar=c(4,4,2,2), oma=c(0,0,2,0) )

  plot(f.hist.20$mids, f.hist.20$counts, xlab="Full F20%", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(f.hist.20$counts)), col='blue4'  )
  lines(f.hist.20$mids, f.hist.20$counts, lwd=2, col='blue4')
  plot(f.hist.30$mids, f.hist.30$counts, xlab="Full F30%", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(f.hist.30$counts)), col='blue4'  )
  lines(f.hist.30$mids, f.hist.30$counts, lwd=2, col='blue4')
  plot(f.hist.40$mids, f.hist.40$counts, xlab="Full F40%", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(f.hist.40$counts)), col='blue4'  )
  lines(f.hist.40$mids, f.hist.40$counts, lwd=2, col='blue4')
  plot(f.hist.50$mids, f.hist.50$counts, xlab="Full F50%", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(f.hist.50$counts)), col='blue4'  )
  lines(f.hist.50$mids, f.hist.50$counts, lwd=2, col='blue4')

  title (main="Annual F (%SPR) Reference Points", outer=T, line=-1 )

  if (save.plots) savePlot(paste0(od, "Annual.F_SPR.4panel.hist.", plotf), type=plotf)

  ypr.hist.20 <- hist(ypr.spr.vals[,1], plot=F)
  ypr.hist.30 <- hist(ypr.spr.vals[,2], plot=F)
  ypr.hist.40 <- hist(ypr.spr.vals[,3], plot=F)
  ypr.hist.50 <- hist(ypr.spr.vals[,4], plot=F)

  par(mfrow=c(2,2), mar=c(4,4,2,2), oma=c(0,0,2,0) )

  plot(ypr.hist.20$mids, ypr.hist.20$counts, xlab="YPR (F20%)", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(ypr.hist.20$counts)), col='blue4'  )
  lines(ypr.hist.20$mids, ypr.hist.20$counts, lwd=2, col='blue4')
  plot(ypr.hist.30$mids, ypr.hist.30$counts, xlab="YPR (F30%)", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(ypr.hist.30$counts)), col='blue4'  )
  lines(ypr.hist.30$mids, ypr.hist.30$counts, lwd=2, col='blue4')
  plot(ypr.hist.40$mids, ypr.hist.40$counts, xlab="YPR (F40%)", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(ypr.hist.40$counts)), col='blue4'  )
  lines(ypr.hist.40$mids, ypr.hist.40$counts, lwd=2, col='blue4')
  plot(ypr.hist.50$mids, ypr.hist.50$counts, xlab="YPR (F50%)", ylab="Frequency", type='h', lwd=2,
       ylim=c(0, max(ypr.hist.50$counts)), col='blue4'  )
  lines(ypr.hist.50$mids, ypr.hist.50$counts, lwd=2, col='blue4')

  title (main="Annual YPR (%SPR) Reference Points", outer=T, line=-1 )

  if (save.plots) savePlot(paste0(od, "Annual.YPR_SPR.4panel.hist.", plotf), type=plotf)
  par(mfrow=c(1,1), mar=c(5.1,4.1,4.1,2.1), oma=c(0,0,0,0))
  } # end test if pspr has length 0

  spr.list <- list(f.spr.vals=f.spr.vals, ypr.spr.vals=ypr.spr.vals, conv.vals=conv.vals)
  return(spr.list)
} # end function


###############################################################################
# "Infection Rate Models for COVID-19:
#  Model Risk and Public Health News Sentiment Exposure Adjustments"
#
#  Ioannis Chalkiadakis, Kevin Hongxuan Yan, Gareth W. Peters, Pavel V. Shevchenko
#
#  Kevin Hongxuan Yan
#  March 2021
###############################################################################

for (k in 1:7){

D_GM=c("Jan/27","Mar/17","May/05","Jun/25","Jul/17")
D_IT=c("Jan/31","Mar/13","May/09","Jun/29","Jul/17")
D_JP=c("Jan/22","Mar/12","Apr/30","Jun/19","Jul/17")
D_SP=c("Feb/01","Mar/20","May/10","Jun/30","Jul/17")
D_UK=c("Jan/31","Mar/21","May/09","Jun/29","Jul/17")
D_US=c("Jan/22","Mar/12","Apr/30","Jun/19","Jul/17")
D_AU=c("Jan/26","Mar/16","May/04","Jun/24","Jul/17")

Date=c(D_GM,D_IT,D_JP,D_SP,D_UK,D_US,D_AU)

name=c("Germany","Italy","Japan","Spain","U.K.","U.S.","Australia")
abn=c("GM","IT","JP","SP","UK","US","AU")

setwd("./covid19modelrisk/output/M4")

load(paste("M2_",abn[k],".RData",sep=""))

Epars_m <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(6+N):(5+2*N)] , 2 , mean )
Epars_5 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(6+N):(5+2*N)] , 2 , quantile, probs=0.05 )
Epars_9 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(6+N):(5+2*N)] , 2 , quantile, probs=0.95 )

y=log(y)
Epars_m=log(Epars_m)
Epars_9=log(Epars_9)
Epars_5=log(Epars_5)

setwd("./covid19modelrisk/output/plot")

pdf(paste("M2_",abn[k],"_log.pdf",sep=""), width = 16.5, height = 8.50)

m=length(y)

newx=c(1:m)
par(cex.axis=2.5,cex.lab=2.5,cex.main=2.5,mar=c(5, 5, 3, 0.5))
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M2 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)

polygon(c(rev(newx), newx), c(rev(Epars_9[1:m]), Epars_5[1:m]), col = "grey80", border = NA)

lines(newx,Epars_9[1:m], lty = 'dashed', col = 'red',lwd = 2)
lines(newx, Epars_5[1:m], lty = 'dashed', col = 'red',lwd = 2)
par(new=TRUE)
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M2 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)
plot.ts(Epars_m[1:m],col="red",ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M2 model for ",name[k],sep=""),lwd = 2,xaxt = 'n')
legend("bottomright", legend=c("Observed data", "Fitted data"), col=c("black", "red"), lty=c(1,1), lwd = 3,cex=2)
axis(1, at=c(0,50,100,150,180), labels=c(Date[(k-1)*5+1],Date[(k-1)*5+2],Date[(k-1)*5+3],Date[(k-1)*5+4],Date[(k-1)*5+5]))
dev.off()

setwd("./covid19modelrisk/output/M2")

load(paste("M4_",abn[k],".RData",sep=""))

Epars_m <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , mean )
Epars_5 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.05 )
Epars_9 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.95 )

y=log(y)
Epars_m=log(Epars_m)
Epars_9=log(Epars_9)
Epars_5=log(Epars_5)

setwd("./covid19modelrisk/output/plot")

pdf(paste("M4_",abn[k],"_log.pdf",sep=""), width = 16.5, height = 8.50)

m=length(y)

newx=c(1:m)
par(cex.axis=2.5,cex.lab=2.5,cex.main=2.5,mar=c(5, 5, 3, 0.5))
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M4 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)

polygon(c(rev(newx), newx), c(rev(Epars_9[1:m]), Epars_5[1:m]), col = "grey80", border = NA)

lines(newx,Epars_9[1:m], lty = 'dashed', col = 'red',lwd = 2)
lines(newx, Epars_5[1:m], lty = 'dashed', col = 'red',lwd = 2)
par(new=TRUE)
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M4 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)
plot.ts(Epars_m[1:m],col="red",ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M4 model for ",name[k],sep=""),lwd = 2,xaxt = 'n')
legend("bottomright", legend=c("Observed data", "Fitted data"), col=c("black", "red"), lty=c(1,1), lwd = 3,cex=2)
axis(1, at=c(0,50,100,150,180), labels=c(Date[(k-1)*5+1],Date[(k-1)*5+2],Date[(k-1)*5+3],Date[(k-1)*5+4],Date[(k-1)*5+5]))
dev.off()

setwd("./covid19modelrisk/output/M7")

load(paste("M7_",abn[k],".RData",sep=""))

Epars_m <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , mean )
Epars_5 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.05 )
Epars_9 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.95 )

y=log(y)
Epars_m=log(Epars_m)
Epars_9=log(Epars_9)
Epars_5=log(Epars_5)

setwd("./covid19modelrisk/output/plot")

pdf(paste("M7_",abn[k],"_log.pdf",sep=""), width = 16.5, height = 8.50)

m=length(y)

newx=c(1:m)
par(cex.axis=2.5,cex.lab=2.5,cex.main=2.5,mar=c(5, 5, 3, 0.5))
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M7 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)

polygon(c(rev(newx), newx), c(rev(Epars_9[1:m]), Epars_5[1:m]), col = "grey80", border = NA)

lines(newx,Epars_9[1:m], lty = 'dashed', col = 'red',lwd = 2)
lines(newx, Epars_5[1:m], lty = 'dashed', col = 'red',lwd = 2)
par(new=TRUE)
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M7 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)
plot.ts(Epars_m[1:m],col="red",ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M7 model for ",name[k],sep=""),lwd = 2,xaxt = 'n')
legend("bottomright", legend=c("Observed data", "Fitted data"), col=c("black", "red"), lty=c(1,1), lwd = 3,cex=2)
axis(1, at=c(0,50,100,150,180), labels=c(Date[(k-1)*5+1],Date[(k-1)*5+2],Date[(k-1)*5+3],Date[(k-1)*5+4],Date[(k-1)*5+5]))
dev.off()

setwd("./covid19modelrisk/output/M12")

load(paste("M12_",abn[k],".RData",sep=""))

Epars_m <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , mean )
Epars_5 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.05 )
Epars_9 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.95 )

y=log(y)
Epars_m=log(Epars_m)
Epars_9=log(Epars_9)
Epars_5=log(Epars_5)

setwd("./covid19modelrisk/output/plot")

pdf(paste("M12_",abn[k],"_log.pdf",sep=""), width = 16.5, height = 8.50)

m=length(y)

newx=c(1:m)
par(cex.axis=2.5,cex.lab=2.5,cex.main=2.5,mar=c(5, 5, 3, 0.5))
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M12 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)

polygon(c(rev(newx), newx), c(rev(Epars_9[1:m]), Epars_5[1:m]), col = "grey80", border = NA)

lines(newx,Epars_9[1:m], lty = 'dashed', col = 'red',lwd = 2)
lines(newx, Epars_5[1:m], lty = 'dashed', col = 'red',lwd = 2)
par(new=TRUE)
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M12 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)
plot.ts(Epars_m[1:m],col="red",ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M12 model for ",name[k],sep=""),lwd = 2,xaxt = 'n')
legend("bottomright", legend=c("Observed data", "Fitted data"), col=c("black", "red"), lty=c(1,1), lwd = 3,cex=2)
axis(1, at=c(0,50,100,150,180), labels=c(Date[(k-1)*5+1],Date[(k-1)*5+2],Date[(k-1)*5+3],Date[(k-1)*5+4],Date[(k-1)*5+5]))
dev.off()

D_GM=c("Jan/27","May/05","Aug/13","Nov/21","Jan/10")
D_IT=c("Jan/31","May/09","Aug/17","Nov/25","Jan/14")
D_JP=c("Jan/22","Apr/30","Aug/08","Nov/16","Jan/5")
D_SP=c("Feb/01","May/10","Aug/18","Nov/26","Jan/15")
D_UK=c("Jan/31","May/09","Aug/17","Nov/25","Jan/14")
D_US=c("Jan/22","Apr/30","Aug/08","Nov/16","Jan/5")
D_AU=c("Jan/26","May/04","Aug/12","Nov/20","Jan/9")

Date=c(D_GM,D_IT,D_JP,D_SP,D_UK,D_US,D_AU)

name=c("Germany","Italy","Japan","Spain","U.K.","U.S.","Australia")
abn=c("GM","IT","JP","SP","UK","US","AU")

setwd("./covid19modelrisk/output/M2_extra")

load(paste("M2_",abn[k],".RData",sep=""))

Epars_m <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(6+N):(5+2*N)] , 2 , mean )
Epars_5 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(6+N):(5+2*N)] , 2 , quantile, probs=0.05 )
Epars_9 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(6+N):(5+2*N)] , 2 , quantile, probs=0.95 )

y=log(y)
Epars_m=log(Epars_m)
Epars_9=log(Epars_9)
Epars_5=log(Epars_5)

setwd("./covid19modelrisk/output/plot")

pdf(paste("M2_",abn[k],"_log_LONG.pdf",sep=""), width = 16.5, height = 8.50)

m=length(y)

newx=c(1:m)
par(cex.axis=2.5,cex.lab=2.5,cex.main=2.5,mar=c(5, 5, 3, 0.5))
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M2 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)

polygon(c(rev(newx), newx), c(rev(Epars_9[1:m]), Epars_5[1:m]), col = "grey80", border = NA)

lines(newx,Epars_9[1:m], lty = 'dashed', col = 'red',lwd = 2)
lines(newx, Epars_5[1:m], lty = 'dashed', col = 'red',lwd = 2)
par(new=TRUE)
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M2 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)
plot.ts(Epars_m[1:m],col="red",ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M2 model for ",name[k],sep=""),lwd = 2,xaxt = 'n')
legend("bottomright", legend=c("Observed data", "Fitted data"), col=c("black", "red"), lty=c(1,1), lwd = 3,cex=2)
axis(1, at=c(0,100,200,300,350), labels=c(Date[(k-1)*5+1],Date[(k-1)*5+2],Date[(k-1)*5+3],Date[(k-1)*5+4],Date[(k-1)*5+5]))

dev.off()

setwd("./covid19modelrisk/output/M7_extra")

load(paste("M7_",abn[k],".RData",sep=""))

Epars_m <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , mean )
Epars_5 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.05 )
Epars_9 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.95 )

y=log(y)
Epars_m=log(Epars_m)
Epars_9=log(Epars_9)
Epars_5=log(Epars_5)

setwd("./covid19modelrisk/output/plot")

pdf(paste("M7_",abn[k],"_log_LONG.pdf",sep=""), width = 16.5, height = 8.50)

m=length(y)

newx=c(1:m)
par(cex.axis=2.5,cex.lab=2.5,cex.main=2.5,mar=c(5, 5, 3, 0.5))
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M7 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)

polygon(c(rev(newx), newx), c(rev(Epars_9[1:m]), Epars_5[1:m]), col = "grey80", border = NA)

lines(newx,Epars_9[1:m], lty = 'dashed', col = 'red',lwd = 2)
lines(newx, Epars_5[1:m], lty = 'dashed', col = 'red',lwd = 2)
par(new=TRUE)
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M7 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)
plot.ts(Epars_m[1:m],col="red",ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M7 model for ",name[k],sep=""),lwd = 2,xaxt = 'n')
legend("bottomright", legend=c("Observed data", "Fitted data"), col=c("black", "red"), lty=c(1,1), lwd = 3,cex=2)
axis(1, at=c(0,100,200,300,350), labels=c(Date[(k-1)*5+1],Date[(k-1)*5+2],Date[(k-1)*5+3],Date[(k-1)*5+4],Date[(k-1)*5+5]))

dev.off()

setwd("./covid19modelrisk/output/M12_extra")

load(paste("M12_",abn[k],".RData",sep=""))

Epars_m <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , mean )
Epars_5 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.05 )
Epars_9 <- apply( as.data.frame(fit@sim[[1]][[1]])[10001:100000,(7+N):(6+2*N)] , 2 , quantile, probs=0.95 )

y=log(y)
Epars_m=log(Epars_m)
Epars_9=log(Epars_9)
Epars_5=log(Epars_5)

setwd("./covid19modelrisk/output/plot")

pdf(paste("M12_",abn[k],"_log_LONG.pdf",sep=""), width = 16.5, height = 8.50)

m=length(y)

newx=c(1:m)
par(cex.axis=2.5,cex.lab=2.5,cex.main=2.5,mar=c(5, 5, 3, 0.5))
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M12 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)

polygon(c(rev(newx), newx), c(rev(Epars_9[1:m]), Epars_5[1:m]), col = "grey80", border = NA)

lines(newx,Epars_9[1:m], lty = 'dashed', col = 'red',lwd = 2)
lines(newx, Epars_5[1:m], lty = 'dashed', col = 'red',lwd = 2)
par(new=TRUE)
plot(y[1:m],ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M12 model for ",name[k],sep=""),pch=19,xaxt = 'n')
par(new=TRUE)
plot.ts(Epars_m[1:m],col="red",ylim=c(min(y[1:m]),max(y[1:m],Epars_9[1:m])),ylab="Count",xlab="Time",main=paste("In-sample fit results of M12 model for ",name[k],sep=""),lwd = 2,xaxt = 'n')
legend("bottomright", legend=c("Observed data", "Fitted data"), col=c("black", "red"), lty=c(1,1), lwd = 3,cex=2)
axis(1, at=c(0,100,200,300,350), labels=c(Date[(k-1)*5+1],Date[(k-1)*5+2],Date[(k-1)*5+3],Date[(k-1)*5+4],Date[(k-1)*5+5]))

dev.off()

}


# Functions for Multifractal analysis

## p-model

# Calculates pmodel using the C++ compiled program
# the output is a file in "sed" format
#
# I use the following to have only one parameter:
# $p2=p3=p4=(1-p1)/3$
#
# fname: output file name
# p1: p1 parameter for pmodel
# iter: (default=9) gives the image size $lado = 2^iter$
# rnd: how I assign p at each step S->random with reposition
#

calc_pmodel1 <- function(fname,p1,iter=9,rnd="S")
  {
  if(p1==0 | iter<2) stop("p1 == 0 or iter<2")
  if(file.exists(fname))
    file.remove(fname)
  p2 <- p3 <- p4 <- (1-p1)/3
  syst.txt <- paste("./pmodel", p1,p2,p3,p4,iter,fname,rnd)
  system(syst.txt)
  }

# Plot a sed file from pmodel using lattice
#
# fname: sed file with pmodel output
# p1: parameter for title
#
plot_pmodel1 <- function(fname,p1)
  {
  require(lattice)
  per <- read.table(fname, skip=2,header=F)
  per <-data.matrix(per)*(2^(2*iter))
  col.l <- colorRampPalette(c('white', 'green', 'purple', 'yellow', 'brown'))(64)
  levelplot(per, scales = list(draw = FALSE),xlab =NULL, ylab = NULL,col.regions=col.l,
            useRaster=T,
            main=list( paste("p1=",p1),cex=1))
  }

# Plot a sed file
#
# fname: file name
# gname: graph title
# dX: range in columns to plot
# col: vector of colors to make the color palette
# shf: shift in the vector of colors
#
plot_image <- function(fname,gname,dX=0,col=0,shf=0)
  {
  require(lattice)
  require(RColorBrewer)
  per <-data.matrix(read.table(fname, skip=2,header=F))
  if(length(dX)>1) per <- per[,dX]
  mp = max(per)
  if(mp<50) {
    mp = 50
    seqat = seq( min(per),max(per),(max(per)-min(per))/50)
  }
  else
  {
    seqat = seq( min(per),mp,5)
  }
  if(length(col)==1) col.l <- colorRampPalette(c('white', 'green', 'purple', 'yellow', 'brown'))(mp)
  else col.l <- colorRampPalette(col)(mp)
  if( shf>0) col.l = col.l[shf:mp]
  levelplot(per, scales = list(draw = FALSE),xlab =NULL, ylab = NULL,col.regions=col.l,
            useRaster=T,at=seqat,
            main=list( gname,cex=1))
  }

# Read a sed file in a matrix
#
#
read_sed <- function(fname)
{
  per <-data.matrix(read.table(fname, skip=2,header=F))
}

# Calculates the multifractal spectrum and
# put the result in a frame
#
calcDq_mfSBA <- function(fname,recalc=FALSE)
  {
  sname <- paste0("s.", fname)
  if((!file.exists(sname)) | recalc)
    {
    syst.txt <- paste("./mfSBA ",fname, "q.sed 2 512 20 S")
    system(syst.txt)
    }
  pp <- read.table(sname, header=T)

  pp$Dq  <- with(pp,ifelse(q==1,alfa,Tau/(q-1)))
  pp$SD.Dq  <- with(pp,ifelse(q==1,SD.alfa,abs(SD.Tau/(q-1))))
  pp$R.Dq <- with(pp,ifelse(q==1,R.alfa,R.Tau))
  return(pp[,c("q","Dq","SD.Dq","R.Dq")])
  }

# Calc mfSBA
# draw histogram
# add to a dataframe dq with a new variable site = siten
#
addDqRHist <- function(fname,dq=0,siten="")
{
  # Extract site label
  if( nchar(siten)==0 ){
    siten <- strsplit(fname,".sed")[[1]][1]
  }

  # Make multifractal analysis

  dqnew <- calcDq_mfSBA(fname)
  dqnew$Site <- siten

  require(ggplot2)

  #print(ggplot(dqnew, aes(x=R.Dq)) + geom_histogram() + ggtitle(siten))
  hist(dqnew$R.Dq)
  if(is.data.frame(dq))
    return(rbind(dq,dqnew))
  else
    return(dqnew)
}

# Do repeated simulations of pmodel and store the results in a dataframe.
#
repeat_pmodel <- function(p1,fname,reps) {

  for(i in 1:reps)
  {
    calc_pmodel1(fname,p1)
    #plot_pmodel1(fname,p1)
    s_Dq <- calcDq_mfSBA(fname,T) # recalc = TRUE
    s_Dq$p1 <- p1
    s_Dq <-na.omit(s_Dq)
    a_Dq <-if(!exists("a_Dq")) s_Dq else rbind(a_Dq,s_Dq)
    }
  #plot_pmodel1(fname,p1)
  return(a_Dq)
}

# Auxiliar function for boot
#
mediaDq <- function(dq,i) mean(dq[i])

# Calculates CI using boot
#
#             sp: frame to put Dq|q
#             the following are to identify the output
#             p1: the value of p1 used in p-model
#             type: the type of the run
calcDq_bootCI <- function(sp,p1,type)
  {
  require(boot)
  require(plyr)
  sp <- na.omit(sp)
  testBoot <- with(sp,by(Dq,q,boot, mediaDq, R=1000))
  # boot pg 331
  bt <-boot.ci(testBoot[[1]])
  testCI <-  sapply(testBoot, boot.ci)
  compCI1<-data.frame(matrix(unlist(testCI),ncol=21,byrow=T)[,c(2,15,16)])
  names(compCI1)=c("Dq","LowCI","HighCI")
  compCI1$q<-as.numeric(names(testBoot))
  compCI1$p1 <-p1
  compCI1$Type <-type
  compCI1$SD.Dq <-ldply(testBoot, function(e) sd(e$t))$V1
  return(compCI1)
  }

# Function to graph multifractal spectra with CI
#
# El error dinnames es que no todas las variables son numéricas
# Usa Type como variable de grupo y LowCI,HighCI para el CI
#
plot_DqCI <- function(DqCI, tit="Type")
  {
  require(lattice)
  require(Hmisc)
  with(DqCI,
    xYplot(Cbind(Dq,LowCI,HighCI) ~ q, data=DqCI, nx=FALSE, groups=Type, type="l",
           scales=list(tck=-1),
           cap=.01,
           ylim=c(min(DqCI$LowCI)-.01,max(DqCI$HighCI)+.01),
    	     panel=function(...){
  		     panel.abline(h=2, col="grey", lty=2)
  		     panel.xYplot(...)},
  		     ylab=expression(italic(D[q])),
  		     xlab=expression(italic(q)),
           label.curves=F,
           auto.key=list(x=.65,y=.9,title=tit,cex.title=.9, lines=T,points=F,cex=.7),
           )
       )
  }

# Calculates theoretic Dq from pmodel
#
calcDqTeor <- function(q,p1) {
  if( q==1)
    q <- q+1e-10
  p2 <- p3 <- p4 <- (1-p1)/3
  f1 <- p1/(p1+p2+p3+p4)
  f2 <- p2/(p1+p2+p3+p4)
  f3 <- p3/(p1+p2+p3+p4)
  f4 <- p4/(p1+p2+p3+p4)
  dq <- log2(f1^q+f2^q+f3^q+f4^q)/(1-q)
  return(dq)
  }

# Function for CI from SD
#
calcCI <- function(dat,n,p) qt(1-p/2,n-1)*sqrt(dat*dat/n)

# Function to plot Dq fit from t* files generated by mfSBA
# Beware! Is fixed for q interval -5 to 5
#
plotDqFit <- function(fname,wtitle="")
{

  zq <- read.table(fname, sep="\t", skip=1,
                   col.names=c("BoxSize","logBox","Xminus5","Xminus4.5","Xminus4","Xminus3.5","Xminus3","Xminus2.5","Xminus2","Xminus1.5","Xminus1","Xminus0.5","X0","X0.5","X1","X1.5","X2","X2.5","X3","X3.5","X4","X4.5","X5")
  )
  #cna=seq(-5,5,by=0.5)
  cna =c(-5,-4.5,-4,-3.5,-3,-2.5,-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5)
  zq0=reshape(zq, timevar="q",times=cna,v.names=c("logTr"),
              varying=list(c("Xminus5","Xminus4.5","Xminus4","Xminus3.5","Xminus3","Xminus2.5","Xminus2","Xminus1.5","Xminus1","Xminus0.5","X0","X0.5","X1","X1.5","X2","X2.5","X3","X3.5","X4","X4.5","X5")),
              direction="long")

  library(lattice)
  zq1 <- subset(zq0, q==1 | q==2 | q==3 | q==4 | q==5 | q==0 | q==-1 | q==-2 | q==-3 | q==-4 | q==-5 )

#  oname <- paste("lsaravia_figS_W",sem,"_",wnro,".tif",sep="")

#  tiff(oname, width=4.86,height=4.86,units="in",res=600,compression=c("lzw"))
  #devAskNewPage(TRUE)

  trellis.par.set(superpose.symbol=list(pch=c(0,1,2,3,4,5,6,8,15,16,17)))
  trellis.par.set(superpose.symbol=list(cex=c(rep(0.6,11))))
  trellis.par.set(superpose.line=list(lty=3))

  #show.settings()

  print(xyplot(logTr~logBox , data =zq1, groups=q, type=c("r","p"), scales=list(tck=-1),
               main=list(wtitle,cex=0.9),
               auto.key=list(space = "right",title=expression(italic("q")),cex.title=.7, points=TRUE,cex=.7),
               ylab=expression(italic(paste("log ",  Z[q](epsilon) ))) , xlab=expression(italic(paste("log ",epsilon)))
  ))
#  dev.off()
}

# Calculates Dq from a data.frame read from the output of neutral model
# auxiliar function for the next one
#
calcDq_frame <- function(pp)
  {
  pp$Dq  <- with(pp,ifelse(q==1,alfa,Tau/(q-1)))
  pp$SD.Dq  <- with(pp,ifelse(q==1,SD.alfa,abs(SD.Tau/(q-1))))
  pp$R.Dq <- with(pp,ifelse(q==1,R.alfa,R.Tau))
  return(pp[,c(1:5,15:17)])
  }

# Reads the output of multifractal spectra of neutral model
# an calculates Dq
#
readNeutral_calcDq <-function(fname)
{
  md1 <- read.table(fname,header=F,skip=1)
  md1 <- md1[,c(2:4, 6:16)]
  names(md1)<-c("MortalityRate","DispersalDistance","ColonizationRate","Time","q","Tau","alfa","f(alfa)","R.Tau","R.alfa","R.f","SD.Tau","SD.alfa","SD.f")

  md1 <-calcDq_frame(md1)
}

# Save a matrix as a sed file with type BI (floating point)
#
save_matrix_as_sed <- function(mat,fname)
{
  header <- paste(nrow(mat),ncol(mat),"BI")
  write.table(header,file=fname,row.names=F,col.names=F,quote=F)
  write.table(mat,file=fname,row.names=F,col.names=F,quote=F,append=T)
}


LISP Interpreter Run

[[[[[

 A LISP expression that asserts that it itself is unprovable!

 Let g(x): x -> (is-unprovable (value-of (('x)('x))))

 Then (is-unprovable (value-of (('g)('g))))
 asserts that it itself is not a theorem!

]]]]]

define (g x)
   let (L x y) cons x cons y nil [Makes x and y into list.]
   (L is-unprovable (L value-of (L (L "' x) (L "' x))))

define      g
value       (lambda (x) ((' (lambda (L) (L is-unprovable (L va
            lue-of (L (L ' x) (L ' x)))))) (' (lambda (x y) (c
            ons x (cons y nil))))))

[Here we try g:]

(g x)

expression  (g x)
value       (is-unprovable (value-of ((' x) (' x))))

[
 Here we calculate the LISP expression
 that asserts its own unprovability:
]

(g g)

expression  (g g)
value       (is-unprovable (value-of ((' (lambda (x) ((' (lamb
            da (L) (L is-unprovable (L value-of (L (L ' x) (L
            ' x)))))) (' (lambda (x y) (cons x (cons y nil))))
            ))) (' (lambda (x) ((' (lambda (L) (L is-unprovabl
            e (L value-of (L (L ' x) (L ' x)))))) (' (lambda (
            x y) (cons x (cons y nil))))))))))

[Here we extract the part that it uses to name itself:]

cadr cadr (g g)

expression  (car (cdr (car (cdr (g g)))))
value       ((' (lambda (x) ((' (lambda (L) (L is-unprovable (
            L value-of (L (L ' x) (L ' x)))))) (' (lambda (x y
            ) (cons x (cons y nil))))))) (' (lambda (x) ((' (l
            ambda (L) (L is-unprovable (L value-of (L (L ' x)
            (L ' x)))))) (' (lambda (x y) (cons x (cons y nil)
            )))))))

[Here we evaluate the name to get back the entire expression:]

eval cadr cadr (g g)

expression  (eval (car (cdr (car (cdr (g g))))))
value       (is-unprovable (value-of ((' (lambda (x) ((' (lamb
            da (L) (L is-unprovable (L value-of (L (L ' x) (L
            ' x)))))) (' (lambda (x y) (cons x (cons y nil))))
            ))) (' (lambda (x) ((' (lambda (L) (L is-unprovabl
            e (L value-of (L (L ' x) (L ' x)))))) (' (lambda (
            x y) (cons x (cons y nil))))))))))

[Here we check that it worked:]

= (g g) eval cadr cadr (g g)

expression  (= (g g) (eval (car (cdr (car (cdr (g g)))))))
value       true

End of LISP Run

Elapsed time is 0 seconds.


#' Calculates several measures of fit for Linear Mixel Models
#' based on Lou and Azen (2013) text.
#' Models could be lmer or lme models
#' @param m.null Null model (only with random intercept effects)
#' @param m.full Full model
#' @return lmmR2 class
#' @export
lmmR2<-function(m.null, m.full) {
	if(is(m.null,"lme"))	 {
		return(lmmR2.lme(m.null,m.full))
	} else if (class(m.null)=="mer" | class(m.null)=="lmerMod" | class(m.null)=="lmerTest") {
		return(lmmR2.mer(m.null,m.full))
	} else {
		stop("Not implemented for other classes than lme or lmer")
	}
}

# Calcula los cuatro R^2 presentes en el texto de Lou y Azen (2013).
# Debo extraer los interceptos para los modelos
lmmR2.mer<-function(m.null,m.full) {
	# Primero, verifico que tengan la misma estructura de grupos. Si
	# no, estoy puro leseando
	v.0<-lme4::VarCorr(m.null)
	v.1<-lme4::VarCorr(m.full)
	if(!all.equal(names(v.0),names(v.1))) {
		stop("Groups should be equal")
	}
	n.b<-length(names(v.0))
	# recojo los sigmas
	sigmas=c(sigma(m.null)^2,sigma(m.full)^2)
	# recojo los thetas
	thetas.0=sapply(v.0,function(x) {x[1,1]})
	thetas.1=sapply(v.1,function(x) {x[1,1]})
	# recojo el largo promedio
	nn=sapply(m.null@flist,function(x) {
		length(levels(x)) / sum(1/table(x))
	})
	rb.r2.1<-1-(sigmas[2]/sigmas[1])
	rb.r2.2<-1-(sum(thetas.1)/sum(thetas.0))
	sb.r2.1<-1-((sigmas[2]+sum(thetas.1))/(sigmas[1]+sum(thetas.0)))
	sb.r2.2<-1-(  sigmas[2]+sum(thetas.1*nn)) / (sigmas[1]+sum(thetas.0*nn))
	out<-list(sigmas=sigmas,t0=thetas.0,t1=thetas.1, nn=nn, rb.r2.1=rb.r2.1, rb.r2.2=rb.r2.2, sb.r2.1=sb.r2.1, sb.r2.2=sb.r2.2)
	class(out)<-"lmmR2"
	out
}
# Extractor de varianzas para nlme
vars.lme<-function(x) {
	vv<-nlme::VarCorr(x)
	# Si tiene solo dos filas, recoge un solo factor
	if(nrow(vv)==2) {
		out=list()
		out[[colnames(x$groups)]]=as.numeric(vv[1,1])
		return(out)
	} else {
		out=list()
		vv.n<-rownames(vv)
		current.var=NULL
		for(i in 1:nrow(vv)) {
			c.name=vv.n[i]
			#print(vv.n[i])
			aa=grep("(.+) =",c.name,value=T)
			if(length(aa)) {
				aa=sub(" =","",aa)
				current.var=aa
			} else if(!is.null(current.var) & c.name=="(Intercept)") {
				out[[current.var]]=vv[i,1]
			}
		}
		out
	}
}
# Debo extraer los interceptos para los modelos
lmmR2.lme<-function(m.null,m.full) {
	# Primero, verifico que tengan la misma estructura de grupos. Si
	# no, estoy puro leseando
	v.0<-vars.lme(m.null)
	v.1<-vars.lme(m.full)
	if(!all.equal(names(v.0),names(v.1))) {
		stop("Groups should be equal")
	}

	n.b<-length(names(v.0))
	# recojo los sigmas
	sigmas=c(m.null$sigma^2,m.full$sigma^2)
	# recojo los thetas
	thetas.0=sapply(v.0,function(x) {as.numeric(x[1])})
	thetas.1=sapply(v.1,function(x) {as.numeric(x[1])})
	#print(thetas.0)
	#print(thetas.1)
	# recojo el largo promedio
	nn=sapply(m.null$groups,function(x) {
		length(levels(x)) / sum(1/table(x))
	})

	rb.r2.1<-1-(sigmas[2]/sigmas[1])
	rb.r2.2<-1-(sum(thetas.1)/sum(thetas.0))
	sb.r2.1<-1-((sigmas[2]+sum(thetas.1))/(sigmas[1]+sum(thetas.0)))
	sb.r2.2<-1-(  sigmas[2]+sum(thetas.1*nn)) / (sigmas[1]+sum(thetas.0*nn))
	out<-list(sigmas=sigmas,t0=thetas.0,t1=thetas.1, nn=nn,rb.r2.1=rb.r2.1, rb.r2.2=rb.r2.2, sb.r2.1=sb.r2.1, sb.r2.2=sb.r2.2)
	class(out)<-"lmmR2"
	out
}

#' @export
print.lmmR2<-function(x) {
	print(summary.lmmR2(x))
}

#' @export
print.summary.lmmR2<-function(xx) {
	cat("Explanatory power of Multilevel Model\n")
	cat("=====================================\n")
	cat("Variances:\n")
	print(xx$m1)
	cat("Indexes:\n")
	print(xx$m2,row.names=F)
	cat("\n")

}

#' @export
summary.lmmR2<-function(x) {

  v.null<-c(x$sigmas[1],x$t0)
  v.full<-c(x$sigmas[2],x$t1)

	m1<-data.frame(avg.size=c(1,x$nn),null=v.null, null.r=v.null/(sum(v.null)),  full=v.full, pseudo.r2= 1-(v.full/v.null) )
	#cat("Variances:\n")
	rownames(m1)[1]<-"Residual"
	#print(m1)
	#cat("Indexes:\n")
	m2<-with(x, data.frame(indexes=c("R & B R1","R & B R2","S & B R1","S & B R2"),
	meaning=c("Within-cluster variance(relative)",
	"Between-cluster variance(relative)",
	"Reduce individual error(total)",
	"Reduce cluster error(total)"
	),
	vals=c(rb.r2.1,rb.r2.2,sb.r2.1,sb.r2.2)))
	#print(m2, row.names=F)
	out=list(m1=m1,m2=m2)

	class(out)<-"summary.lmmR2"
	return(out)
}


GrayEncode <- function(binary) {
	gray <- substr(binary,1,1)
	repeat {
	if  (substr(binary,1,1) != substr(binary,2,2)) gray <- paste(gray,"1",sep="")
	else gray <- paste(gray,"0",sep="")
	binary <- substr(binary,2,nchar(binary))
	if (nchar(binary) <=1) {
		break
		}
	}
return (gray)
}
GrayDecode <- function(gray) {
	binary <- substr(gray,1,1)
	repeat {
	if  (substr(binary,nchar(binary),nchar(binary)) != substr(gray,2,2)) binary <- paste(binary ,"1",sep="")
	else binary <- paste(binary ,"0",sep="")
	gray <- substr(gray,2,nchar(gray))

	if (nchar(gray) <=1) {
		break
		}
	}
return (binary)
}


## LOOP FOR:

# Los "loops" ("lazos" o "bucles" en español) son comandos especiales que
# sirven para hacer ejecutar una tarea una cantidad arbitraria de veces; se
# llama iteración a cada una de estas repeticiones. Sirven para hacer en
# segundos lo que manualmente llevaría horas, días o sería simplemente demasiado.

# Los comandos más universales para hacer loops en programación son "for" y
# "while", y en R esto no es distinto.

# Se puede acceder a la ayuda de R con varios comandos, por ejemplo (no correr):
?Control
?"for"

## SINTAXIS

# Empecemos con un ejemplo muy sencillo:

for (i in 1:4) {
  print(i)
}

# Analicemos lo que ocurre:
# En la consola vemos que se imprimen los números 1, 2, 3 y 4. Esto ocurre
# porque dentro del loop se puso el comando print(i). En este caso i es un
# objeto, al cual llamaremos la "variable" o "variable de iteración". Cuando
# miramos en el paréntesis del for, vemos que dice "i in 1:4". Esto quiere
# decir que la variable i va a tomar los valores contenidos en el vector 1:4,
# es decir que en la primer iteración i vale 1, luego 2 y así. En suma, es
# equivalente a escribir:
i <- 1
print(i)
i <- 2
print(i)
i <- 3
print(i)
i <- 4
print(i)
# ... pero por supuesto que es mucho más económico y elegante.

# Nota: debido a que hay una sola expresión dentro del loop (print(i)), no es
# necesario usar las llaves para delimitar el loop; son equivalentes estas dos
# opciones:
for (i in 1:4)
  print(i)
# ó
for (i in 1:4) print(i)

# Nota: puede verificar que i es además un objeto que existe en su sesión y
# cuyo valor es el último asignado por el loop for. En este caso i == 4:
i

# Por supuesto que este es uno de los ejemplos más elementales que se pueden
# imaginar de un loop for, pero hay un par de detalles que por costumbre o
# convención se repiten casi siempre:
# - El usar el nombre "i" para la variable de iteración. No es necesario que
#   tenga este nombre, eso es un valor arbitrario (puede llamarse, j, k o carlos
#   sin problemas), pero es aconsejable mantener este criterio para facilitar la
#   comprensión del código.
# - El utilizar números naturales para el vector de valores que va a tomar i,
#   en este caso 1:4. Aquí tampoco hay límites en cuanto a los valores o clase
#   de vector que se elige. A continuación veremos porqué es más común y
#   conveniente utilizar estos tipos de vectores.

# Un ejemplo un poco más ilustrativo: consideremos que existe un vector v
# definido así:
v <- c(5, 2, -2, 3)
# Ahora, supongamos que queremos imprimirlo en la consola, un valor a la vez.
# Podemos recurrir a este código:
for (i in v)
  print(i)

# Como puede ver, ahora la variable i va tomando los valores del vector v y
# print(i) los va imprimiendo en la consola. Es equivalente a:
i <- v[1]
print(i)
i <- v[2]
print(i)
i <- v[3]
print(i)
i <- v[4]
print(i)

# De todas formas, este ejemplo *no refleja el uso más frecuente* de la
# variable i. Usualmente lo que se hace es utilizar i para indizar al vector v,
# así:
for (i in 1:4)
  print(v[i])

# A través de los corchetes estamos usando i para imprimir el iésimo elemento
# de v en cada iteración. Parece un camino más largo y por lo tanto
# inconveniente. Sin embargo en la práctica rara vez se va a utilizar la
# variable i para indizar solamente un vector, si no que suele usarse
# repetidamente para indizar diferentes objetos, incluyendo matrices,
# data.frames o listas. Veamos un ejemplo:

# Preparación:
m <- matrix(rpois(12, 8), 4, 3) # Una matriz de 4x3
s <- numeric(4) # Un vector de longitud 4, valores == 0
# Loop:
for (i in 1:4)
  s[i] <- sum(m[i,])
s
# Aquí se creo un vector s, inicialmente todos sus valores 0, cuyo objetivo
# era contener los valores de las sumas por fila de la matriz m. Adentro del
# loop se utilizó i en dos ocasiones:
# (1) para indicar el número de fila de m al cual se debía aplicar la
#     función sum ("sum(m[i,])") y
# (2) para indicar el iésimo valor de s, en donde se almacenó el resultado de
#     la operación anterior ("s[i] <- ...").

# Nota: el vector s es idéntico al obtenido con el comando:
rowSums(m)

# Nota 2: es un error muy común definir s *adentro* del loop, en lugar de
# *afuera*. Al cometer este error le estamos indicando a R que s se debe
# *reiniciar* en cada iteración, de forma que borra todo lo hecho en
# iteraciones anteriores. Veamos esto en un ejemplo:
m <- matrix(rpois(12, 8), 4, 3) # Una matriz de 4x3
# Loop:
for (i in 1:4) {
  s <- numeric(4) # Un vector de longitud 4, valores == 0
  s[i] <- sum(m[i,])
} # Se agregan las llaves porque hay más de 1 comando
s

# Como se muestra en la observación anterior (s == rowSums(m) para el loop
# correcto), no siempre es necesario hacer un loop para hacer estas operaciones
# (aquí rowSums puede hacer lo mismo). En general en R es conveniente saber
# cuándo podemos evitar hacer un loop, no sólo para "simplificar" la sintaxis,
# si no porque puede haber una pérdida de eficiencia que, en caso de hacer
# cálculos pesados, se paga con mucho tiempo perdido. En general el término que
# refiere a optar por alternativas a los loops es "vectorización" (ver lección
# 6.2-loop-for-extra.r por más detalles relativos a la vectorización a la
# eficiencia del uso de recursos). Nótese que la vectorización no es posible en
# todos los lenguajes de programación y que en lenguajes más tradicionales (como
# pueden ser C o FORTRAN) es necesario usar loops para las operaciones más
# simples (como, por ejemplo, sumar dos vectores de igual longitud).

# Hay casos en los que usar loops en R es sencillamente inevitable. Vamos a ver
# ahora uno de estos casos.

## EJEMPLO: SERIE DE FIBONACCI

# La serie de Fibonacci se puede definir de la siguiente manera: se trata de una
# secuencia de valores que cumplen la regla general:
# F_{i} == F_{i - 1} + F_{i - 2}

# (Aquí F_{n} es el enésimo elemento de la serie F.)

# Esto implica que es necesario definir de manera arbitraria los dos primeros
# valores (F_{1} y F_{2}) para poder definir el resto de la serie. Si los
# primeros valores son 0 y 1 entonces la serie es (hasta el octavo valor):
# F = [0, 1, 1, 2, 3, 5, 8, 13]

# Vamos entonces a crear un loop en R que permita calcular la serie de Fibonacci
# hasta el enésimo valor. Crearemos la función fibo para este objetivo:
fibo <- function(n = 20, inicio = 0:1) {
  # n e inicio tienen valores por defecto, por comodidad

}
# ... por ahora la función no hace nada, veamos cómo debemos completarla ...

# Traduciendo la regla general a R, nos quedaría algo así:
out[i] <- out[i - 1] + out[i - 2]
# donde out es un vector en el cual vamos a almacenar todos los valores de la
# serie. Nótese que esto implica que i no puede ser menor que 3; si i fuera 2,
# por ejemplo, entonces out[i - 2] sería out[0], lo cual es un valor no definido
# en R. A su vez, esto implica que out tiene al menos i elementos y que out[1] y
# out[2] están definidos de antemano.

# Estas condicionantes nos llevan a definir lo que llamamos la Preparación del
# loop. Por un lado, out tiene que existir y tener al menos 3 elementos, pero de
# hecho ya decidimos que tendrá n elementos. El valor n está definido como uno
# de los argumentos de la función, así que no lo definiremos de vuelta. Por
# otro lado, los dos primeros valores de out se definen con el otro argumento:
# inicio. De esta forma la preparación sería algo así (no ejecutar):
out <- numeric(n)
out[1:2] <- inicio

# Como puede confirmar, si asigna valores a n y a inicio (inicio debe ser un
# vector de 2 elementos), out ya es un vector viable para aplicar la fórmula
# general. Pero para eso tenemos que agregar el loop en sí (no ejecutar):
for (i in 3:n) {
  out[i] <- out[i - 1] + out[i - 2]
}

# Es imporante notar que el rango de valores de i es 3:n; 3 porque ya vimos que
# i no puede ser menor y n porque es la cantidad de elementos de out.

# Tenemos entonces todo para definir correctamente la función fibo:
fibo <- function(n = 20, inicio = 0:1) {
  # Preparación:
  out <- numeric(n)
  out[1:2] <- inicio
  # Loop:
  for (i in 3:n) {
    out[i] <- out[i - 1] + out[i - 2]
  }
  out # La salida de la función
}

# Podemos comprobar de que fibo hace correctamente su tarea:
fibo()
fibo(22)

# Es importante destacar los puntos claves a tener en cuenta en el proceso de
# crear fibo:
# 1. El vector out debe estar correctamente definido antes de empezar el loop.
#    Generalmente la Preparación es necesaria para aprontar vectores como out,
#    en el cual se almacenan los valores que nos interesan.
# 2. La variable i debe estar contenida en el rango correcto de valores, en
#    este caso 3:n. Este es un punto en el cual es frecuente comenter errores.

# Pero ¿por qué es que es inevitable usar un loop para este problema?
# Se puede responder con un ejemplo: ¿qué ocurre al tratar de calcular el
# cuarto elemento de out? Para obtener este valor es necesario primero definir
# el tercer elemento de out, ya que out[4] = out[3] + out[2]. El mismo problema
# surgirá cuando se trate de obtener out[5] y los demás valores, por lo que no
# queda opción que "ir calculando de a uno" los valores de la serie de
# Fibonacci. En general es fácil ver que siempre que los valores de una
# secuencia dependen de los anteriores es necesario hacer un loop para poder
# calcularlos. Dicho de otra forma, los loops son inevitables para calcular
# secuencias definidas por Relaciones de Recurrencia
# (https://es.wikipedia.org/wiki/Relaci%C3%B3n_de_recurrencia).
# Nota: muchas veces estas relaciones de recurrencia también tienen soluciones
# cerradas, lo que implica que en esos casos tampoco es estrictamente necesario
# usar un loop (en R) para calcular los valores de la sucesión.

## LOOPS FOR ANIDADOS:

# Nada impide que adentro de un for (o un while) se escriba otro loop. Esto es
# lo que llamamos un loop anidado. Las reglas que siguen son las mismas que antes,
# pero hay que tener la precaución de utilizar diferentes nombres para las
# variables de iteración. En el siguiente ejemplo se usan i y j como variables:

m <- matrix(rpois(4, 8), 2, 2) # Una matriz de 2x2
for (i in 1:nrow(m)) {
  for (j in 1:ncol(m)) {
    print(m[i, j])
  }
}

# Como fácilmente se puede comprobar, este código simplemente imprime todos los
# elementos de la matriz m. Nótese: que la variable i se usa para las filas y
# la variable j para las columnas.

## RESUMEN
# Hemos visto el tipo de loop más comunmente utilizado en programación. El loop
# 'for' se utiliza cuando "sabemos" de antemano el número de iteraciones que
# necesitamos.
# Dado que la sintaxis es relativamente elaborada, hay que tener especial
# atención a los errores, particularmente los más comunes: omisión de una llave,
# escribir mál la secuencia de números (1:n) o confundir el nombre de las
# variables (i, j, k, etc ...).
# En general siempre va a ser necesario tener una Preparación, es decir líneas
# de código anteriores al loop en las que se definen correctamente uno o varios
# objetos que serán utilizados dentro del mismo. Un error común es definir
# alguno de estos objetos (como el out en la función fibo) *adentro* del loop,
# cuando es necesario que esto se haga **afuera**, en la preparación.
# Los ejemplos empleados dan cuenta de situaciones comunes en que podemos
# utilizar esta herramienta, pero no está limitada a éstas. Siendo particular-
# mente útil al realizar simulaciones con modelos o aplicar análisis a grandes
# series de datos, su combinación dentro de funciones y con otras estructuras
# de control (ej: condicionales) se hace más importante, y resulta fundamental
# como herramienta para cualquier programador.


model_gaimean <- function (gAI = 0.0,
         tTWindowForPTQ = 0.0,
         deltaTT = 0.0,
         pastMaxAI_t1 = 0.0,
         listTTShootWindowForPTQ1_t1 = c(0.0),
         listGAITTWindowForPTQ_t1 = c(0.0)){
    #'- Name: GAImean -Version: 1.0, -Time step: 1
    #'- Description:
    #'            * Title: Average GAI on a specific thermal time window
    #'            * Author: Loïc Manceau
    #'            * Reference: -
    #'            * Institution: INRA
    #'            * Abstract: -
    #'- inputs:
    #'            * name: gAI
    #'                          ** description : Green Area Index of the day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : m2 leaf m-2 ground
    #'                          ** uri :
    #'            * name: tTWindowForPTQ
    #'                          ** description : Thermal Time window for average
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : °C d
    #'                          ** uri :
    #'            * name: deltaTT
    #'                          ** description : Thermal time increase of the day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 100.0
    #'                          ** unit : °C d
    #'                          ** uri :
    #'            * name: pastMaxAI_t1
    #'                          ** description : Maximum Leaf Area Index reached the current day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : m2 leaf m-2 ground
    #'                          ** uri :
    #'            * name: listTTShootWindowForPTQ1_t1
    #'                          ** description : List of daily shoot thermal time in the window dedicated to average
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLELIST
    #'                          ** default : [0.0]
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : °C d
    #'                          ** uri :
    #'            * name: listGAITTWindowForPTQ_t1
    #'                          ** description : List of daily Green Area Index in the window dedicated to average
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLELIST
    #'                          ** default : [0.0]
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : m2 leaf m-2 ground
    #'                          ** uri :
    #'- outputs:
    #'            * name: gAImean
    #'                          ** description : Mean Green Area Index
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : m2 leaf m-2 ground
    #'                          ** uri :
    #'            * name: pastMaxAI
    #'                          ** description : Maximum Leaf Area Index reached the current day
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : m2 leaf m-2 ground
    #'                          ** uri :
    #'            * name: listTTShootWindowForPTQ1
    #'                          ** description : List of daily shoot thermal time in the window dedicated to average
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLELIST
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : °C d
    #'                          ** uri :
    #'            * name: listGAITTWindowForPTQ
    #'                          ** description : List of daily Green Area Index in the window dedicated to average
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLELIST
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : m2 leaf m-2 ground
    #'                          ** uri :
    listTTShootWindowForPTQ1 <- vector()
    listGAITTWindowForPTQ <- vector()
    TTList <- vector()
    GAIList <- vector()
    count <- 0
    gai_ <- 0.0
    gaiMean_ <- 0.0
    countGaiMean <- 0
    for( i in seq(0, length(listTTShootWindowForPTQ1_t1)-1, 1)){
        TTList <- c(TTList, listTTShootWindowForPTQ1_t1[i+1])
        GAIList <- c(GAIList, listGAITTWindowForPTQ_t1[i+1])
    }
    TTList <- c(TTList, deltaTT)
    GAIList <- c(GAIList, gAI)
    SumTT <- sum(TTList)
    while( SumTT > tTWindowForPTQ){
        SumTT <- SumTT - TTList[count+1]
        count <- count + 1}
    for( i in seq(count, length(TTList)-1, 1)){
        listTTShootWindowForPTQ1 <- c(listTTShootWindowForPTQ1, TTList[i+1])
        listGAITTWindowForPTQ <- c(listGAITTWindowForPTQ, GAIList[i+1])
    }
    for( i in seq(0, length(listGAITTWindowForPTQ)-1, 1)){
        gaiMean_ <- gaiMean_ + listGAITTWindowForPTQ[i+1]
        countGaiMean <- countGaiMean + 1
    }
    gaiMean_ <- gaiMean_ / countGaiMean
    gai_ <- max(pastMaxAI_t1, gaiMean_)
    pastMaxAI <- gai_
    gAImean <- gai_
    return (list ("gAImean" = gAImean,"pastMaxAI" = pastMaxAI,"listTTShootWindowForPTQ1" = listTTShootWindowForPTQ1,"listGAITTWindowForPTQ" = listGAITTWindowForPTQ))
}


#Solve for optimal lobby effort under DGH97-style model with obj fcn W + e

#reserve space for loop output
tau = seq(0.001,.166,0.001) #this will be counter variable in loop
PSx = matrix(NA,length(tau),1)
CSx = matrix(NA,length(tau),1)
TR = matrix(NA,length(tau),1)
PSy = matrix(NA,length(tau),1)
CSy = matrix(NA,length(tau),1)

#calculate producer surplus, consumer surplus, tariff revenue for each possible
#value of the tariff on the grid (just above zero to prohibitive tariff 1/6)
for (j in 1:length(tau)) {
  t = tau[j]

  PSx[j] = ((2 +2*t)^2)/49
  CSx[j] = .5*((3 -4*t)^2)/49
  TR[j] = (t - 6*t^2)/7
  CSy[j] = ((3 +3*t)^2)/98
  PSy[j] = ((4 -3*t)^2)/98
}

#Calculations for when lobby has all the bargaining power

#calculate government welfare when tau = 0 (baseline)
b = ((2 +2*0)^2)/49 + .5*((3 -4*0)^2)/49 + (0 - 6*0^2)/7 + ((3 +3*0)^2)/98 + ((4 -3*0)^2)/98
W = PSx + CSx + TR + CSy + PSy  #social welfare
e = ((b - W)/PSx)^5             #gov't indifference condition when WG = W + e
pi = PSx - e                    #net profits

value = max(pi) #the value at which profits are maximized (over non-negative values)
ind = which.max(pi) #the location at which profits are maximized
RC = arrayInd(ind,c(dim(pi),dim(pi))) #row/column version of maximand location

#Calculations for when government has all the bargaining power
bl = ((2 +2*0)^2)/49           #baseline for lobby: profits when tau = 0
e = PSx - bl                   #effort level giving all excess profits over tau=0 to gov't

g = e^1.2                       #little g(e) function to add to social welfare
G = W + g                      #gov't welfare a la DGH97
plot(G)

value = max(G) #the value at which profits are maximized (over non-negative values)
ind = which.max(G) #the location at which profits are maximized
RC = arrayInd(ind,c(dim(G),dim(G))) #row/column version of maximand location


# CLUSTER GLEDE NA ZADOVOLJSTVO PREBIVALCEV, ZAPOSLENOST, BDP TER STEVILO PREBIVALCEV

cluster_evropa <- function(){
  evropa1 <- uvozi.svet() %>% filter (continent == 'Europe')
  zadovoljstvo <- uvozi.rating() %>% filter(leto == 2018)
  brezposelnost_cluster <- uvozi.zaposlenost()
  bdp <- uvozi.BDP() %>% filter(leto == 2018) %>% select('Drzava', 'BDP per capita')
  evropa2 <- merge(x = evropa1, y = zadovoljstvo, by.y = 'Drzava', by.x = 'name')
  evropa3 <- merge(x = evropa2, y = brezposelnost_cluster, by.y = 'name', by.x = 'name')
  evropa4 <- merge(x = evropa3, y = bdp, by.y = 'Drzava', by.x = 'name')
  podatki_cluster <- evropa4 %>% filter (leto == 2018) %>% select('name', 'pop_est','BDP per capita', 'Ocena','Brezposelnost')
  podatki_cluster2 <- podatki_cluster
  podatki_cluster$geometry = NULL
  cluster <- podatki_cluster %>% select(-name) %>% scale()
  rownames(cluster) <- podatki_cluster$name
  k <- kmeans(cluster, 5, nstart=1000)
  skupine <- data.frame(name=podatki_cluster2$name, skupina=factor(k$cluster))
  podatki_za_risat <- merge(podatki_cluster2, skupine, by ='name')
  zemljevid <- tm_shape(podatki_za_risat) + tm_polygons('skupina')
  zemljevid
  tmap_mode('view')
  return(zemljevid)
}
cluster <- cluster_evropa()

# GRAF KI PRIKAZUJE GIBANJE REALNEGA BDP SLOVENIJE TER EVROPE NA PREBIVALCA IN NAPOVEDUJE PRIHODNOST

napovedovanje_BDP <- function(){
  BDP <- uvozi.BDP()
  bdp_po_letih_eu <- aggregate(BDP$'BDP per capita', by=list(leto=BDP$leto), FUN=mean)
  bdp_po_letih_eu$x <- as.numeric(bdp_po_letih_eu$x)
  bdp_po_letih_eu$leto <- as.numeric(bdp_po_letih_eu$leto)
  bdp_po_letih_eu$z <- 'evropa'

  bdp_po_letih_slo <- BDP %>% filter(Drzava == 'Slovenia') %>% select('leto', 'BDP per capita')
  bdp_po_letih_slo <- bdp_po_letih_slo %>% rename(x = 'BDP per capita')
  bdp_po_letih_slo$x <- as.numeric(bdp_po_letih_slo$x)
  bdp_po_letih_slo$leto <- as.numeric(bdp_po_letih_slo$leto)
  bdp_po_letih_slo$z <- 'slovenija'

  bdp_po_letih <- rbind(bdp_po_letih_eu, bdp_po_letih_slo)
  colnames(bdp_po_letih)[3] <- "Legenda"

  h <- ggplot(bdp_po_letih, aes(leto, x, shape=Legenda, colour=Legenda, fill=Legenda)) +
        geom_smooth(method="lm", fullrange=TRUE) +
        geom_point(size=3) +
        fte_theme() +
        xlab("Leto") +
        ylab("€") +
        ggtitle("Gibanje realnega BDP v € na prebivalca") +
        scale_x_continuous(breaks = 2013:2022) +
        expand_limits(x = 2020) +
        geom_hline(yintercept=0, size=0.4, color="black") +
        theme(legend.position="right")
  return(h)
}
napovedovanje <- napovedovanje_BDP()


## Exercicio 1
## Prof. James Hunter
## from: https://rstudio.cloud/project/1177204
## 11 de maio de 2020

# 1 - Fazer o cálculo
((42 * 95^2) + 6)/(16 - 3.5)

# 2 - Atribuir à variável calc
calc <- ((42 * 95^2) + 6)/(16 - 3.5)

# 3 - arrondar a 1 casa decimal
round(calc, digits = 1)