# With this skript I intend to analyze whether there is a significant
#  difference between the populations in the control (absolute gene
#  expression) samples and between the two stress temperatures (28°C
#  and 32°C)

error.bar <- function(x, y, upper, lower=upper, length=0.05,...){
        if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper))
        stop("vectors must be same length")
        arrows(x,upper, x, lower, angle=90, code=3, length=length, ...)
        }

error.bar2 <- function(x, y, upper, lower=upper, length=0.05,...){
        if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper))
        stop("vectors must be same length")
        arrows(x,y+upper, x, y-lower, angle=90, code=3, length=length, ...)
        }

#####################################################################
#####################################################################
########## Absolute expression of control samples ###################
#####################################################################
#####################################################################
library("nparLD")

Alldata32 <- read.table("/home/alj/Documents/org_files/data/ScientificJournal/2012ScientificJournal/Dec/2012-12-18-Fs_32_NormalizedAmount_OutliersRemoved.txt",header=TRUE)

Alldata28 <- read.table("/home/alj/Documents/org_files/data/ScientificJournal/2012ScientificJournal/Dec/2012-12-18-Fs_28_NormalizedAmount_OutliersRemoved.txt",header=TRUE)

library(vegan)

# Remove all data with FoldChange==NA
# At this step I decide whether to take AllOutliersRemoved or AllBoxplotOutliersRemoved
FT32All <- as.data.frame(as.matrix(Alldata32[is.na(Alldata32$NormalizedAmount)!=TRUE,]))
Data32.2 <- tapply(FT32All$MeanCT,list(FT32All$Gene,FT32All$Population,FT32All$Treatment),length)

FT28All <- as.data.frame(as.matrix(Alldata28[is.na(Alldata28$NormalizedAmount)!=TRUE,]))
Data28.2 <- tapply(FT28All$MeanCT,list(FT28All$Gene,FT28All$Population,FT28All$Treatment),length)

############################################################################
############### Statistical analysis #######################################
############################################################################

# Do the analysis for the 32°C and the 28°C stress experiment and put
# the results for the three Hsps in a list.

FT <- rbind(FT28All,FT32All)
# Combine the stress data
FT$NormalizedAmount=as.numeric(as.vector(FT$NormalizedAmount))
FT$Population=as.factor(FT$Population)
FT$Treatment=as.factor(FT$Treatment)
################### HSP70

HSP70Compare <- subset(FT,FT$Gene=="HSP70")
HSP90Compare <- subset(FT,FT$Gene=="HSP90")
sHSPCompare <- subset(FT,FT$Gene=="sHSP")

HSPs <- c("HSP70Compare","HSP90Compare","sHSPCompare")

Meanslist28 <- vector("list",length(HSPs))
SElist28upper <- vector("list",length(HSPs))
SElist28lower <- vector("list",length(HSPs))
significancelist28 <- vector("list",length(HSPs))
Meanslist32 <- vector("list",length(HSPs))
SElist32upper <- vector("list",length(HSPs))
SElist32lower <- vector("list",length(HSPs))
significancelist32 <- vector("list",length(HSPs))

#########################################
######### Log transformation and ANOVA ##
#########################################
library("lawstat") # Provides the levene test to test for heteroscedasticity

# The sHSP expression in the control samples from Spain (28°C) are
# higher than for the other populations. I want to see if a
# transformation of the data, followed by a normal ANOVA indicates
# here a significant difference, since the PERMANOVA analysis does
# not. I tested it and a log-transformation gives a statistical
# significance if I apply an ANOVA on it.

# I regard the normal ANOVA analysis only to be problematic when there
# is an indication for non-normality or heteroscedasticity with a p-value<0.01

# I do log-transformation only when necessary and then back-transform the data with exp(result)

# Here I can change which gene shall be analyzed
l=1
###########
### HSP 70
###########

d <- get(HSPs[l])
Hs.Pop0 <- subset(d,d$Treatment==0,drop=TRUE)

# 28°C
shapiro.test(log(Hs.Pop0$NormalizedAmount))
levene.test(log(Hs.Pop0$NormalizedAmount),Hs.Pop0$Population)
# log-transformation necessary!
model <- aov(log(Hs.Pop0$NormalizedAmount) ~ Hs.Pop0$Population*Hs.Pop0$Temperature)
summary(model)
significances <- TukeyHSD(model)[[3]][,4]

significancesTrue <- significances<0.05
names(significancesTrue) <- c("28F-28D",
                              "28N-28D",
                              "28S-28D",
                              "32D-28D",
                              "32F-28D",
                              "32N-28D",
                              "32S-28D",
                              "28N-28F",
                              "28S-28F",
                              "32D-28F",
                              "32F-28F",
                              "32N-28F",
                              "32S-28F",
                              "28S-28N",
                              "32D-28N",
                              "32F-28N",
                              "32N-28N",
                              "32S-28N",
                              "32D-28S",
                              "32F-28S",
                              "32N-28S",
                              "32S-28S",
                              "32F-32D",
                              "32N-32D",
                              "32S-32D",
                              "32N-32F",
                              "32S-32F",
                              "32S-32N")
library("multcompView")
Comparisons <- c("28N","28D","28F","28S","32N","32D","32F","32S")
Letters <- multcompLetters(significancesTrue)$Letters[match(c("28N","28D","28F","28S","32N","32D","32F","32S"),names(multcompLetters(significancesTrue)$Letters))]

# Calculating the Means and SEs

d28 <- d[d$Temperature==28,]
d32 <- d[d$Temperature==32,]

d28.Means <- as.matrix(tapply(as.numeric(as.vector(log(d28$NormalizedAmount))),list(as.factor(as.vector(d28$Population)),as.vector(d28$Treatment)),mean))
d28.Means <- as.matrix(rbind(d28.Means[3,c(1,2,4,3)],d28.Means[1,c(1,2,4,3)],d28.Means[2,c(1,2,4,3)],d28.Means[4,c(1,2,4,3)]))
rownames(d28.Means) <- c("Norway","Denmark","France","Spain")
#Back-transformation
d28.Means2 <- d28.Means
d28.Means <- exp(d28.Means)

Meanslist28[[l]] <- d28.Means

library(plotrix)

d28.SEs <- tapply(as.numeric(as.vector(log(d28$NormalizedAmount))),list(as.factor(as.vector(d28$Population)),as.vector(d28$Treatment)),std.error)
d28.SEs <- as.matrix(rbind(d28.SEs[3,c(1,2,4,3)],d28.SEs[1,c(1,2,4,3)],d28.SEs[2,c(1,2,4,3)],d28.SEs[4,c(1,2,4,3)]))
rownames(d28.SEs) <- c("Norway","Denmark","France","Spain")
#Back-transformation

d28.UpperSEs <- exp(d28.Means2+d28.SEs)
d28.LowerSEs <- exp(d28.Means2-d28.SEs)

SElist28upper[[l]] <- d28.UpperSEs
SElist28lower[[l]] <- d28.LowerSEs

d32.Means <- as.matrix(tapply(as.numeric(as.vector(log(d32$NormalizedAmount))),list(as.factor(as.vector(d32$Population)),as.vector(d32$Treatment)),mean))
d32.Means <- as.matrix(rbind(d32.Means[3,c(1,2,4,3)],d32.Means[1,c(1,2,4,3)],d32.Means[2,c(1,2,4,3)],d32.Means[4,c(1,2,4,3)]))
rownames(d32.Means) <- c("Norway","Denmark","France","Spain")
#Back-transformation
d32.Means2 <- d32.Means
d32.Means <- exp(d32.Means)

Meanslist32[[l]] <- d32.Means

library(plotrix)

d32.SEs <- tapply(as.numeric(as.vector(log(d32$NormalizedAmount))),list(as.factor(as.vector(d32$Population)),as.vector(d32$Treatment)),std.error)
d32.SEs <- as.matrix(rbind(d32.SEs[3,c(1,2,4,3)],d32.SEs[1,c(1,2,4,3)],d32.SEs[2,c(1,2,4,3)],d32.SEs[4,c(1,2,4,3)]))
rownames(d32.SEs) <- c("Norway","Denmark","France","Spain")
#Back-transformation

d32.UpperSEs <- exp(d32.Means2+d32.SEs)
d32.LowerSEs <- exp(d32.Means2-d32.SEs)

SElist32upper[[l]] <- d32.UpperSEs
SElist32lower[[l]] <- d32.LowerSEs

significancelist28[[l]] <-  Letters[1:4]
significancelist32[[l]] <-  Letters[5:8]

# Here I can change which gene shall be analyzed
l=2
###########
### HSP 90
###########

d <- get(HSPs[l])
Hs.Pop0 <- subset(d,d$Treatment==0,drop=TRUE)

shapiro.test(log(Hs.Pop0$NormalizedAmount))
levene.test(log(Hs.Pop0$NormalizedAmount),Hs.Pop0$Population)
# log-transformation necessary!
model <- aov(log(Hs.Pop0$NormalizedAmount) ~ Hs.Pop0$Population*Hs.Pop0$Temperature)
summary(model)
significances <- TukeyHSD(model)[[3]][,4]

significancesTrue <- significances<0.05
names(significancesTrue) <- c("28F-28D",
                              "28N-28D",
                              "28S-28D",
                              "32D-28D",
                              "32F-28D",
                              "32N-28D",
                              "32S-28D",
                              "28N-28F",
                              "28S-28F",
                              "32D-28F",
                              "32F-28F",
                              "32N-28F",
                              "32S-28F",
                              "28S-28N",
                              "32D-28N",
                              "32F-28N",
                              "32N-28N",
                              "32S-28N",
                              "32D-28S",
                              "32F-28S",
                              "32N-28S",
                              "32S-28S",
                              "32F-32D",
                              "32N-32D",
                              "32S-32D",
                              "32N-32F",
                              "32S-32F",
                              "32S-32N")
library("multcompView")
Comparisons <- c("28N","28D","28F","28S","32N","32D","32F","32S")
Letters <- multcompLetters(significancesTrue)$Letters[match(c("28N","28D","28F","28S","32N","32D","32F","32S"),names(multcompLetters(significancesTrue)$Letters))]

# Calculating the Means and SEs

d28 <- d[d$Temperature==28,]
d32 <- d[d$Temperature==32,]

d28.Means <- as.matrix(tapply(as.numeric(as.vector(log(d28$NormalizedAmount))),list(as.factor(as.vector(d28$Population)),as.vector(d28$Treatment)),mean))
d28.Means <- as.matrix(rbind(d28.Means[3,c(1,2,4,3)],d28.Means[1,c(1,2,4,3)],d28.Means[2,c(1,2,4,3)],d28.Means[4,c(1,2,4,3)]))
rownames(d28.Means) <- c("Norway","Denmark","France","Spain")
#Back-transformation
d28.Means2 <- d28.Means
d28.Means <- exp(d28.Means)

Meanslist28[[l]] <- d28.Means

library(plotrix)

d28.SEs <- tapply(as.numeric(as.vector(log(d28$NormalizedAmount))),list(as.factor(as.vector(d28$Population)),as.vector(d28$Treatment)),std.error)
d28.SEs <- as.matrix(rbind(d28.SEs[3,c(1,2,4,3)],d28.SEs[1,c(1,2,4,3)],d28.SEs[2,c(1,2,4,3)],d28.SEs[4,c(1,2,4,3)]))
rownames(d28.SEs) <- c("Norway","Denmark","France","Spain")
#Back-transformation

d28.UpperSEs <- exp(d28.Means2+d28.SEs)
d28.LowerSEs <- exp(d28.Means2-d28.SEs)

SElist28upper[[l]] <- d28.UpperSEs
SElist28lower[[l]] <- d28.LowerSEs

d32.Means <- as.matrix(tapply(as.numeric(as.vector(log(d32$NormalizedAmount))),list(as.factor(as.vector(d32$Population)),as.vector(d32$Treatment)),mean))
d32.Means <- as.matrix(rbind(d32.Means[3,c(1,2,4,3)],d32.Means[1,c(1,2,4,3)],d32.Means[2,c(1,2,4,3)],d32.Means[4,c(1,2,4,3)]))
rownames(d32.Means) <- c("Norway","Denmark","France","Spain")
#Back-transformation
d32.Means2 <- d32.Means
d32.Means <- exp(d32.Means)

Meanslist32[[l]] <- d32.Means

library(plotrix)

d32.SEs <- tapply(as.numeric(as.vector(log(d32$NormalizedAmount))),list(as.factor(as.vector(d32$Population)),as.vector(d32$Treatment)),std.error)
d32.SEs <- as.matrix(rbind(d32.SEs[3,c(1,2,4,3)],d32.SEs[1,c(1,2,4,3)],d32.SEs[2,c(1,2,4,3)],d32.SEs[4,c(1,2,4,3)]))
rownames(d32.SEs) <- c("Norway","Denmark","France","Spain")
#Back-transformation

d32.UpperSEs <- exp(d32.Means2+d32.SEs)
d32.LowerSEs <- exp(d32.Means2-d32.SEs)

SElist32upper[[l]] <- d32.UpperSEs
SElist32lower[[l]] <- d32.LowerSEs

significancelist28[[l]] <-  Letters[1:4]
significancelist32[[l]] <-  Letters[5:8]

# Here I can change which gene shall be analyzed
l=3
###########
### sHSP
###########

d <- get(HSPs[l])
Hs.Pop0 <- subset(d,d$Treatment==0,drop=TRUE)

shapiro.test(log(Hs.Pop0$NormalizedAmount))
levene.test(log(Hs.Pop0$NormalizedAmount),Hs.Pop0$Population)
# log-transformation necessary!
model <- aov(log(Hs.Pop0$NormalizedAmount) ~ Hs.Pop0$Population*Hs.Pop0$Temperature)
summary(model)
significances <- TukeyHSD(model)[[3]][,4]

significancesTrue <- significances<0.05
names(significancesTrue) <- c("28F-28D",
                              "28N-28D",
                              "28S-28D",
                              "32D-28D",
                              "32F-28D",
                              "32N-28D",
                              "32S-28D",
                              "28N-28F",
                              "28S-28F",
                              "32D-28F",
                              "32F-28F",
                              "32N-28F",
                              "32S-28F",
                              "28S-28N",
                              "32D-28N",
                              "32F-28N",
                              "32N-28N",
                              "32S-28N",
                              "32D-28S",
                              "32F-28S",
                              "32N-28S",
                              "32S-28S",
                              "32F-32D",
                              "32N-32D",
                              "32S-32D",
                              "32N-32F",
                              "32S-32F",
                              "32S-32N")
library("multcompView")
Comparisons <- c("28N","28D","28F","28S","32N","32D","32F","32S")
Letters <- multcompLetters(significancesTrue)$Letters[match(c("28N","28D","28F","28S","32N","32D","32F","32S"),names(multcompLetters(significancesTrue)$Letters))]

# Calculating the Means and SEs

d28 <- d[d$Temperature==28,]
d32 <- d[d$Temperature==32,]

d28.Means <- as.matrix(tapply(as.numeric(as.vector(log(d28$NormalizedAmount))),list(as.factor(as.vector(d28$Population)),as.vector(d28$Treatment)),mean))
d28.Means <- as.matrix(rbind(d28.Means[3,c(1,2,4,3)],d28.Means[1,c(1,2,4,3)],d28.Means[2,c(1,2,4,3)],d28.Means[4,c(1,2,4,3)]))
rownames(d28.Means) <- c("Norway","Denmark","France","Spain")
#Back-transformation
d28.Means2 <- d28.Means
d28.Means <- exp(d28.Means)

Meanslist28[[l]] <- d28.Means

library(plotrix)

d28.SEs <- tapply(as.numeric(as.vector(log(d28$NormalizedAmount))),list(as.factor(as.vector(d28$Population)),as.vector(d28$Treatment)),std.error)
d28.SEs <- as.matrix(rbind(d28.SEs[3,c(1,2,4,3)],d28.SEs[1,c(1,2,4,3)],d28.SEs[2,c(1,2,4,3)],d28.SEs[4,c(1,2,4,3)]))
rownames(d28.SEs) <- c("Norway","Denmark","France","Spain")
#Back-transformation

d28.UpperSEs <- exp(d28.Means2+d28.SEs)
d28.LowerSEs <- exp(d28.Means2-d28.SEs)

SElist28upper[[l]] <- d28.UpperSEs
SElist28lower[[l]] <- d28.LowerSEs

d32.Means <- as.matrix(tapply(as.numeric(as.vector(log(d32$NormalizedAmount))),list(as.factor(as.vector(d32$Population)),as.vector(d32$Treatment)),mean))
d32.Means <- as.matrix(rbind(d32.Means[3,c(1,2,4,3)],d32.Means[1,c(1,2,4,3)],d32.Means[2,c(1,2,4,3)],d32.Means[4,c(1,2,4,3)]))
rownames(d32.Means) <- c("Norway","Denmark","France","Spain")
#Back-transformation
d32.Means2 <- d32.Means
d32.Means <- exp(d32.Means)

Meanslist32[[l]] <- d32.Means

library(plotrix)

d32.SEs <- tapply(as.numeric(as.vector(log(d32$NormalizedAmount))),list(as.factor(as.vector(d32$Population)),as.vector(d32$Treatment)),std.error)
d32.SEs <- as.matrix(rbind(d32.SEs[3,c(1,2,4,3)],d32.SEs[1,c(1,2,4,3)],d32.SEs[2,c(1,2,4,3)],d32.SEs[4,c(1,2,4,3)]))
rownames(d32.SEs) <- c("Norway","Denmark","France","Spain")
#Back-transformation

d32.UpperSEs <- exp(d32.Means2+d32.SEs)
d32.LowerSEs <- exp(d32.Means2-d32.SEs)

SElist32upper[[l]] <- d32.UpperSEs
SElist32lower[[l]] <- d32.LowerSEs

significancelist28[[l]] <-  Letters[1:4]
significancelist32[[l]] <-  Letters[5:8]

names(Meanslist28) <- HSPs
names(SElist28upper) <- HSPs
names(SElist28lower) <- HSPs
names(significancelist28) <- HSPs
names(Meanslist32) <- HSPs
names(SElist32upper) <- HSPs
names(SElist32lower) <- HSPs
names(significancelist32) <- HSPs

AbsMeanslist28 <- Meanslist28
AbsSElist28upper <- SElist28upper
AbsSElist28lower <- SElist28lower
Abssignificancelist28 <- significancelist28

AbsMeanslist32 <- Meanslist32
AbsSElist32upper <- SElist32upper
AbsSElist32lower <- SElist32lower
Abssignificancelist32 <- significancelist32

error.bar <- function(x, y, upper, lower=upper, length=0.05,...){
        if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper))
        stop("vectors must be same length")
        arrows(x,upper, x, lower, angle=90, code=3, length=length, ...)
        }

error.bar2 <- function(x, y, upper, lower=upper, length=0.05,...){
        if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper))
        stop("vectors must be same length")
        arrows(x,y+upper, x, y-lower, angle=90, code=3, length=length, ...)
        }

######################################################
############# Plotting ###############################
######################################################

cnorway <- "#fdfdfd"
cdenmark <- "#808080"
cfrance <- "#dfdfdf"
cspain <- "#202020"

######################################################
############# Plotting ###############################
######################################################

########## Plot for Control levels
png(filename="/home/alj/Documents/writing/2012HSR/2012HeatShockResponse/Audioslides/images/Controls_Comparisons.png",width=60,height=65,units='mm',res=100,pointsize=10)
par(xpd=NA,mar=c(1,0,2,0),oma=c(3,6.5,0,0),mgp=c(4,2,1),font=1,ps=10,mfrow=c(2,1),bg=NA)

# 28°C stress absolute control values
Means28 <- cbind(AbsMeanslist28$HSP70Compare[,1],AbsMeanslist28$HSP90Compare[,1],AbsMeanslist28$sHSPCompare[,1])
SEs28upper <- cbind(AbsSElist28upper$HSP70Compare[,1],AbsSElist28upper$HSP90Compare[,1],AbsSElist28upper$sHSPCompare[,1])
SEs28lower <- cbind(AbsSElist28lower$HSP70Compare[,1],AbsSElist28lower$HSP90Compare[,1],AbsSElist28lower$sHSPCompare[,1])
significance28 <- c(Abssignificancelist28$HSP70Compare,Abssignificancelist28$HSP90Compare,Abssignificancelist28$sHSPCompare)

barx <- barplot(Means28[,3], beside=TRUE,col=c(rgb(51,102,0,maxColorValue=255),rgb(255,221,17,maxColorValue=255),rgb(102,51,153,maxColorValue=255),rgb(51,221,238,maxColorValue=255)),border="white", ylim=c(0.001,10),axis.lty=1,lwd=1,cex.main=1,cex.lab=1,cex.axis=1,las=1,cex.names=1,cex.main=1.2,log="y",axes=FALSE,main="",names.arg="",xaxt="n")
axis(2, at=c(0.001,0.1,10),labels=as.character(c(0.001,0.1,10)),las=1)

lines(x=c(5.5,5.5),y=c(0.001,10000000),lty=2)
lines(x=c(10.5,10.5),y=c(0.001,10000000),lty=2)
error.bar(barx,Means28[,3],upper=SEs28upper[,3],lower=SEs28lower[,3],lwd=1)

distances <- Means28[,3]+3

text(barx,distances,significance28[9:12],cex=1)

# 32°C stress absolute control values
Means32 <- cbind(AbsMeanslist32$HSP70Compare[,1],AbsMeanslist32$HSP90Compare[,1],AbsMeanslist32$sHSPCompare[,1])
SEs32upper <- cbind(AbsSElist32upper$HSP70Compare[,1],AbsSElist32upper$HSP90Compare[,1],AbsSElist32upper$sHSPCompare[,1])
SEs32lower <- cbind(AbsSElist32lower$HSP70Compare[,1],AbsSElist32lower$HSP90Compare[,1],AbsSElist32lower$sHSPCompare[,1])
significance32 <- c(Abssignificancelist32$HSP70Compare,Abssignificancelist32$HSP90Compare,Abssignificancelist32$sHSPCompare)

barx <- barplot(Means32[,3], beside=TRUE,col=c(rgb(51,102,0,maxColorValue=255),rgb(255,221,17,maxColorValue=255),rgb(102,51,153,maxColorValue=255),rgb(51,221,238,maxColorValue=255)),border="white", ylim=c(0.001,10),axis.lty=1,xaxt="n",lwd=1,cex.main=1,cex.lab=1,cex.axis=1,las=1,cex.names=1,cex.main=1.2,log="y",axes=FALSE,main="")
axis(2, at=c(0.001,0.1,10),labels=as.character(c(0.001,0.1,10)),las=1)

error.bar(barx,Means32[,3],upper=SEs32upper[,3],lower=SEs32lower[,3],lwd=1)

distances <- Means32[,3]+3

text(barx,distances,significance32[9:12],cex=1)

dev.off()
dev.off(dev.prev())


model_penman <- function (evapoTranspirationPriestlyTaylor = 449.367,
         hslope = 0.584,
         VPDair = 2.19,
         psychrometricConstant = 0.66,
         Alpha = 1.5,
         lambdaV = 2.454,
         rhoDensityAir = 1.225,
         specificHeatCapacityAir = 0.00101,
         conductance = 598.685){
    #'- Name: Penman -Version: 1.0, -Time step: 1
    #'- Description:
    #'            * Title: Penman Model
    #'            * Author: Pierre Martre
    #'            * Reference: Modelling energy balance in the wheat crop model SiriusQuality2:
    #'            Evapotranspiration and canopy and soil temperature calculations
    #'            * Institution: INRA/LEPSE Montpellier
    #'            * Abstract: This method is used when wind and vapor pressure daily data are available
    #'
    #'- inputs:
    #'            * name: evapoTranspirationPriestlyTaylor
    #'                          ** description : evapoTranspiration of Priestly Taylor
    #'                          ** variablecategory : rate
    #'                          ** datatype : DOUBLE
    #'                          ** default : 449.367
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** unit : g m-2 d-1
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : variable
    #'            * name: hslope
    #'                          ** description : the slope of saturated vapor pressure temperature curve at a given temperature
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.584
    #'                          ** min : 0
    #'                          ** max : 1000
    #'                          ** unit : hPa °C-1
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : variable
    #'            * name: VPDair
    #'                          ** description :  vapour pressure density
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** default : 2.19
    #'                          ** min : 0
    #'                          ** max : 1000
    #'                          ** unit : hPa
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : variable
    #'            * name: psychrometricConstant
    #'                          ** description : psychrometric constant
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.66
    #'                          ** min : 0
    #'                          ** max : 1
    #'                          ** unit :
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : parameter
    #'            * name: Alpha
    #'                          ** description : Priestley-Taylor evapotranspiration proportionality constant
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 1.5
    #'                          ** min : 0
    #'                          ** max : 100
    #'                          ** unit :
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : parameter
    #'            * name: lambdaV
    #'                          ** description : latent heat of vaporization of water
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 2.454
    #'                          ** min : 0
    #'                          ** max : 10
    #'                          ** unit :
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : parameter
    #'            * name: rhoDensityAir
    #'                          ** description : Density of air
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 1.225
    #'                          ** unit :
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : parameter
    #'            * name: specificHeatCapacityAir
    #'                          ** description : Specific heat capacity of dry air
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.00101
    #'                          ** min : 0
    #'                          ** max : 1
    #'                          ** unit :
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : parameter
    #'            * name: conductance
    #'                          ** description : conductance
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** default : 598.685
    #'                          ** unit : m d-1
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    #'                          ** inputtype : variable
    #'- outputs:
    #'            * name: evapoTranspirationPenman
    #'                          ** description :  evapoTranspiration of Penman Monteith
    #'                          ** variablecategory : rate
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 5000
    #'                          ** unit : g m-2 d-1
    #'                          ** uri : http://www1.clermont.inra.fr/siriusquality/?page_id=547
    evapoTranspirationPenman <- evapoTranspirationPriestlyTaylor / Alpha + (1000.0 * (rhoDensityAir * specificHeatCapacityAir * VPDair * conductance / (lambdaV * (hslope + psychrometricConstant))))
    return (list('evapoTranspirationPenman' = evapoTranspirationPenman))
}


# script for cv mortality
# extract the data from the information
# save the datasets after combining the data.

library("tidyverse")
library("survival")
library("IPDfromKM")
library("metaRMST")
library("broom")
library("survminer")

# get the data 1 trial at a time and then format it to extract information.

# leader
# liraglutide arm -

li <- read.table("F:/GLP1_agonists/data/leader/cvmort_liraglutide.txt")

summary(li)

# convert V2 to survival -

li$V2 <- with(li, ifelse(V2 == -0.0479, 0, V2))

li$V2 <- 100 - li$V2

li$V2 <- with(li, ifelse(V2 > 100, 100, V2))

summary(li)

# now to extract information

nrisk_l <- c(4668, 4641, 4599, 4558, 4505, 4445, 4382, 4322, 1723, 484)

trisk_l <- c(0,6, 12, 18, 24, 32, 36, 42, 48, 54)

leader_l <- preprocess(dat = li,
                             trisk = trisk_l,
                             nrisk = nrisk_l,
                             maxy = 100)

leader_ipd_li <- getIPD(prep = leader_l,
                             armID = 1)

plot(leader_ipd_li)

cv_mort_li <- leader_ipd_li$IPD

# control arm

control <-
read.table("F:/GLP1_agonists/data/leader/cvmort_control.txt")

summary(control)

# convert V2 to survival -

control$V2 <- 100 - control$V2

summary(control)

# now to extract information

nrisk_c <- c(4672, 4648, 4601, 4479, 4407, 4338, 4267, 1709, 465)

trisk_c <- c(0,6, 12, 18, 24, 32, 36, 42, 48, 54)

leader_c <- preprocess(dat = control,
                       trisk = trisk_c,
                       nrisk = nrisk_c,
                       maxy = 100)

leader_ipd_c <- getIPD(prep = leader_c,
                        armID = 0)

plot(leader_ipd_c)

cvmort_control <- leader_ipd_c$IPD

# combine data and then plot

df_leader_cvmort <- rbind(cv_mort_li, cvmort_control)

cvmort_leader_s <-
  survfit(Surv(time, status) ~ treat, data = df_leader_cvmort)

ggsurvplot(cvmort_leader_s,
           fun = "event",
           ylim = c(0,0.20),
           xlim = c(0,54),
           break.x.y = 6,
           break.y.by = 0.05,
           censor.size = 0,
           palette = c("gray","blue2"))

# time already in months.

write_csv(df_leader_cvmort,
  'F:\\GLP1_agonists\\data\\pooled_data\\cvmort_leader.csv'
)

# sustain 6

sema <- read.table("F:/GLP1_agonists/data/sustain6/cvmort_semaglutide.txt")

summary(sema)

# convert V2 to survival -

sema$V2 <- 100 - sema$V2

summary(sema)

# now to extract information

nrisk_s <- c(1648, 1634, 1627, 1617, 1607, 1589, 1579)

trisk_s <- c(0,16, 32, 48, 64, 80, 96)

sustain6_s <- preprocess(dat = sema,
                       trisk = trisk_s,
                       nrisk = nrisk_s,
                       maxy = 100)

sustain6_ipd_sema <- getIPD(prep = sustain6_s,
                        armID = 1)

plot(sustain6_ipd_sema)

cv_mort_sema <- sustain6_ipd_sema$IPD

# now to get control arm data

control <-
read.table("F:/GLP1_agonists/data/sustain6/cvmort_control.txt")

summary(control)

# convert V2 to survival -

control$V2 <- 100 - control$V2

summary(control)

# now to extract information

nrisk_c <- c(1649, 1637, 1623, 1617, 1600, 1584, 1566)

trisk_c <- c(0,16, 32, 48, 64, 80, 96)

sustain6_c <- preprocess(dat = control,
                         trisk = trisk_c,
                         nrisk = nrisk_c,
                         maxy = 100)

sustain6_ipd_control <- getIPD(prep = sustain6_c,
                            armID = 0)

plot(sustain6_ipd_control)

cv_mort_control <- sustain6_ipd_control$IPD

# combine the dataset and then plot again

cvmort_sustain6 <- rbind(cv_mort_sema, cv_mort_control)

surv_sustain6 <- survfit(Surv(time, status) ~ treat,
                         data = cvmort_sustain6)

# plot graph

ggsurvplot(surv_sustain6,
           data = cvmort_sustain6,
           fun = "event",
           ylim = c(0,0.05),
           break.y.by = 0.01,
           xim = c(0, 104),
           break.x.by = 8,
           palette = c("gray","blue2"),
           censor.size = 0)

# now to convert weeks to months
# save with time in months

cvmort_sustain6$time <- cvmort_sustain6$time/4

# save dataaset

write_csv(cvmort_sustain6,
  'F:\\GLP1_agonists\\data\\pooled_data\\cvmort_sustain6.csv')

# EXCSEL

exe <-
read.table("F:/GLP1_agonists/data/excsel/cvmort_exenatide.txt")

summary(exe)

# convert V2 to survival -

exe$V2 <- 100 - exe$V2

summary(exe)

# now to extract information

nrisk_e <- c(7356, 7234, 6433, 4095, 2698, 892)

trisk_e <- c(0,1,2,3,4,5)

excsel_exe <- preprocess(dat = exe,
                         trisk = trisk_e,
                         nrisk = nrisk_e,
                         maxy = 100)

excsel_ipd_exe <- getIPD(prep = excsel_exe,
                            armID = 1)

plot(excsel_ipd_exe)

cv_mort_exe <- excsel_ipd_exe$IPD

# control arm of EXCSEL

control <-
  read.table("F:/GLP1_agonists/data/excsel/cvmort_control.txt")

summary(control)

# convert V2 to survival -

control$V2 <- 100 - control$V2

summary(control)

# now to extract information

nrisk_c <- c(7396, 7278, 6470, 4091, 2666, 907)

trisk_c <- c(0,1,2,3,4,5)

excsel_c <- preprocess(dat = control,
                         trisk = trisk_c,
                         nrisk = nrisk_c,
                         maxy = 100)

excsel_ipd_c <- getIPD(prep = excsel_c,
                         armID = 0)

plot(excsel_ipd_c)

cv_mort_control <- excsel_ipd_c$IPD

# combine dataset and then plot

cvmort_excsel <- rbind(cv_mort_exe, cv_mort_control)

cvmort_excsel_s <- survfit(Surv(time, status) ~ treat,
                           data = cvmort_excsel)

ggsurvplot(cvmort_excsel_s,
           data = cvmort_excsel,
           xlim = c(0,5),
            ylim = c(0,0.18),
            break.y.by = 0.03,
           censor.size = 0,
          fun = "event",
          palette = c("blue","red"),
          linetype = c(2,1))

# convert time to months
# save dataset

cvmort_excsel$time <- cvmort_excsel$time*12

write_csv(cvmort_excsel,
  'F:\\GLP1_agonists\\data\\pooled_data\\cvmort_excsel.csv'
)

# Harmony Outcomes

albi <-
  read.table("F:/GLP1_agonists/data/Harmony/cvmort_albiglutide.txt")

summary(albi)

# convert V2 to survival -

albi$V2 <- 100 - albi$V2

summary(albi)

# now to extract information

nrisk_a <- c(4731, 4681, 4611, 4379, 3274, 2234, 1121)

trisk_a <- c(0, 4, 8, 12, 16, 20, 24 )

harmony_a <- preprocess(dat = albi,
                         trisk = trisk_a,
                         nrisk = nrisk_a,
                         maxy = 100)

harmony_ipd_a <- getIPD(prep = harmony_a,
                         armID = 1)

plot(harmony_ipd_a)

cv_mort_albi <- harmony_ipd_a$IPD

# control arm in Harmony Outcomes

control <-
read.table("F:/GLP1_agonists/data/Harmony/cvmort_control.txt")

summary(control)

# convert V2 to survival -

control$V2 <- 100 - control$V2

summary(control)

# now to extract information

nrisk_c <- c(4732, 4662, 4580, 4373, 3245, 2261, 1121)

trisk_c <- c(0, 4, 8, 12, 16, 20, 24 )

harmony_c <- preprocess(dat = control,
                        trisk = trisk_c,
                        nrisk = nrisk_c,
                        maxy = 100)

harmony_ipd_c <- getIPD(prep = harmony_c,
                        armID = 0)

plot(harmony_ipd_c)

cv_mort_harmony_c <- harmony_ipd_c$IPD

# combine dataasets

cvmort_harmony <- rbind(cv_mort_albi, cv_mort_harmony_c)

cvmort_hs <- survfit(Surv(time, status) ~ treat,
                     data = cvmort_harmony)

ggsurvplot(
  cvmort_hs,
  data = cvmort_harmony,
  fun = "event",
  xlim = c(0,28),
  ylim = c(0, 0.18),
  break.y.by = 0.02,
  break.x.by = 4,
  censor.size = 0,
  palette = c("blue2","red")
)

# convert time to months from weeks

cvmort_harmony$time <- cvmort_harmony$time*4

write_csv(
  cvmort_harmony,
  'F:\\GLP1_agonists\\data\\pooled_data\\cvmort_harmony.csv'
)

# REWIND

dula <-
read.table("F:/GLP1_agonists/data/rewind/cvmort_dulaglutide.txt")

summary(dula)

dula$V1 <- with(dula, ifelse(V1 < 0, 0 , V1))

dula$V2 <- with(dula, ifelse(V2 < 0, 0, V2))

# convert V2 to survival -

dula$V2 <- 100 - dula$V2

summary(dula)

# now to extract information

nrisk_d <- c(4949, 4866, 4773, 4663, 4556, 3887, 807)

trisk_d <- c(0, 1, 2, 3, 4, 5, 6)

rewind_d <- preprocess(dat = dula,
                        trisk = trisk_d,
                        nrisk = nrisk_d,
                        maxy = 100)

rewind_ipd_d <- getIPD(prep = rewind_d,
                        armID = 1)

plot(rewind_ipd_d)

cvmort_rewind_d <- rewind_ipd_d$IPD

# control arm of rewind

control <-

read.table(
  "F:/GLP1_agonists/data/rewind/cvmort_control.txt"
)

summary(control)

control$V1 <- with(control, ifelse(V1 < 0, 0 , V1))

# convert V2 to survival -

control$V2 <- 100 - control$V2

summary(control)

# now to extract information

nrisk_c <- c(4952, 4854, 4748, 4617, 4499, 3813, 802)

trisk_c <- c(0, 1, 2, 3, 4, 5, 6)

rewind_c <- preprocess(dat = control,
                       trisk = trisk_c,
                       nrisk = nrisk_c,
                       maxy = 100)

rewind_ipd_c <- getIPD(prep = rewind_c,
                       armID = 0)

plot(rewind_ipd_c)

cvmort_rewind_c <- rewind_ipd_c$IPD

# combine dataset

cvmort_rewind <- rbind(cvmort_rewind_d, cvmort_rewind_c)

# create survobject and plot

cvmort_rewind_s <- survfit(Surv(time, status) ~ treat,
                           data = cvmort_rewind)

plot(cvmort_rewind_s)

ggsurvplot(cvmort_rewind_s,
           data = cvmort_rewind,
           fun = "event",
           ylim = c(0, 0.18),
           censor.size = 0,
           break.y.by = 0.03)

# convert years to months

cvmort_rewind$time <- cvmort_rewind*12

write_csv(
  cvmort_rewind,
  'F:\\GLP1_agonists\\data\\pooled_data\\cvmort_rewind.csv'
)

# PIONEER 6

psema <-
  read.table(
    "F:/GLP1_agonists/data/pioneer6/cvmort_semaglutide.txt")

summary(psema)

psema$V1 <- with(psema, ifelse(V1 < 0, 0, V1))

psema$V2 <- with(psema, ifelse(V2 < 0, 0, V2))

# convert V2 to survival -

psema$V2 <- 100 - psema$V2

summary(psema)

# now to extract information

pioneer6_sema <- preprocess(dat = psema,
                            totalpts = 1591,
                         maxy = 100)

pioneer6_ipd_sema <- getIPD(prep = pioneer6_sema,
                         armID = 1)

plot(pioneer6_ipd_sema)

cvmort_pioneer6_sema <- pioneer6_ipd_sema$IPD

# control arm for pioneer6

p_control <-
  read.table(
    "F:/GLP1_agonists/data/pioneer6/cvmort_control.txt")

summary(p_control)

p_control$V1 <- with(p_control, ifelse(V1 < 0, 0, V1))

# convert V2 to survival -

p_control$V2 <- 100 - p_control$V2

summary(p_control)

# now to extract information

pioneer6_control <- preprocess(dat = p_control,
                            totalpts = 1592,
                            maxy = 100)

pioneer6_ipd_control <- getIPD(prep = pioneer6_control,
                            armID = 0)

cvmort_pioneer6_control <- pioneer6_ipd_control$IPD

cvmort_pioneer6 <- rbind(cvmort_pioneer6_sema, cvmort_pioneer6_control)

# plot graph

cvmort_pioneer6_s <- survfit(Surv(time, status) ~ treat,
                             data = cvmort_pioneer6)

ggsurvplot(cvmort_pioneer6_s,
           data = cvmort_pioneer6,
           xlim = c(0, 83),
           ylim = c(0, 0.1),
           break.x.by = 9,
           break.y.by = 0.01,
           censor.size = 0,
           palette = c("gray","blue2"),
          fun = "event")

# convert weeks to months
# save combined dataset

cvmort_pioneer6$time <- cvmort_pioneer6$time/4

write_csv(cvmort_pioneer6,
          'F:\\GLP1_agonists\\data\\pooled_data\\cvmort_pioneer6.csv')


#' add
#'
#' Add two matrices: \code{ret = alpha*x + beta*y}.
#'
#' @param transx,transy Should x/y be transposed?
#' @param alpha,beta Scalars.
#' @param x,y Input data.
#' @param ret Either \code{NULL} or an already allocated fml matrix of the same
#' class and type as \code{x}.
#' @return Returns the matrix sum.
#'
#' @rdname linalg-add
#' @name add
#'
#' @useDynLib fmlr R_linalg_add
#'
#' @export
linalg_add = function(transx=FALSE, transy=FALSE, alpha=1, beta=1, x, y, ret=NULL)
{
  check_is_mat(x)
  check_is_mat(y)

  transx = as.logical(transx)
  transy = as.logical(transy)

  alpha = as.double(alpha)
  beta = as.double(beta)

  invisiret = check_inputs(ret, x, y)

  if (is.null(ret))
    ret = setret(x)

  .Call(R_linalg_add, get_backend(x), x$get_type(), transx, transy, alpha, beta, x$data_ptr(), y$data_ptr(), ret$data_ptr())

  if (invisiret)
    invisible(ret)
  else
    ret
}

#' matmult
#'
#' Multiply two matrices: \code{ret = alpha*x*y}.
#'
#' @param transx,transy Should x/y be transposed?
#' @param alpha Scalar.
#' @param x,y Input data.
#' @param ret Either \code{NULL} or an already allocated fml matrix of the same
#' class and type as \code{x}.
#' @return Returns the matrix product.
#'
#' @rdname linalg-matmult
#' @name matmult
#'
#' @useDynLib fmlr R_linalg_matmult
#'
#' @export
linalg_matmult = function(transx=FALSE, transy=FALSE, alpha=1, x, y, ret=NULL)
{
  if (!is_mat(x) && !is_vec(x))
    stop("argument 'x' must be a matrix or vector type")
  if (!is_mat(y) && !is_vec(y))
    stop("argument 'y' must be a matrix or vector type")

  transx = as.logical(transx)
  transy = as.logical(transy)

  alpha = as.double(alpha)

  invisiret = check_inputs(ret, x, y, check_class=FALSE)

  if (is.null(ret))
  {
    vec = is_vec(x) || is_vec(y)
    ret = setret(x, vec=vec)
  }

  .Call(R_linalg_matmult, get_backend(x), x$get_type(), transx, transy, alpha, x$get_class(), x$data_ptr(), y$get_class(), y$data_ptr(), ret$data_ptr())

  if (invisiret)
    invisible(ret)
  else
    ret
}

#' @useDynLib fmlr R_linalg_crossprod
linalg_crossprods = function(x, ret, alpha, xpose)
{
  check_is_mat(x)

  xpose = as.logical(xpose)
  alpha = as.double(alpha)

  invisiret = check_inputs(ret, x)

  if (is.null(ret))
    ret = setret(x)

  .Call(R_linalg_crossprod, get_backend(x), x$get_type(), xpose, alpha, x$data_ptr(), ret$data_ptr())

  if (invisiret)
    invisible(ret)
  else
    ret
}

#' crossprod
#'
#' Compute crossproducts.
#'
#' @param alpha Number to scale the crossproduct by.
#' @param x Input data.
#' @param ret Either \code{NULL} or an already allocated fml matrix of the same
#' class and type as \code{x}.
#' @return Returns the crossproduct.
#'
#' @rdname linalg-crossprod
#' @name crossprod
NULL

#' @rdname linalg-crossprod
#' @export
linalg_crossprod = function(alpha=1, x, ret=NULL)
{
  linalg_crossprods(x, ret, alpha, xpose=FALSE)
}

#' @rdname linalg-crossprod
#' @export
linalg_tcrossprod = function(alpha=1, x, ret=NULL)
{
  linalg_crossprods(x, ret, alpha, xpose=TRUE)
}

#' xpose
#'
#' Matrix transpose.
#'
#' @param x Input data.
#' @param ret Either \code{NULL} or an already allocated fml matrix of the same
#' class and type as \code{x}.
#' @return Returns the xpose.
#'
#' @rdname linalg-xpose
#' @name xpose
#' @useDynLib fmlr R_linalg_xpose
#'
#' @export
linalg_xpose = function(x, ret=NULL)
{
  check_is_mat(x)
  invisiret = check_inputs(ret, x)

  if (is.null(ret))
    ret = setret(x)

  .Call(R_linalg_xpose, get_backend(x), x$get_type(), x$data_ptr(), ret$data_ptr())

  if (invisiret)
    invisible(ret)
  else
    ret
}

#' lu
#'
#' LU factorization. The factorization occurs in-place.
#'
#' @param x Input data, overwritten by its LU factorization.
#' @return Returns \code{NULL}.
#'
#' @rdname linalg-lu
#' @name lu
#' @useDynLib fmlr R_linalg_lu
#'
#' @export
linalg_lu = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_lu, get_backend(x), x$get_type(), x$data_ptr())
  invisible(NULL)
}

#' det
#'
#' Determinant
#'
#' @param x Input data, overwritten by its LU factorization.
#'
#' @return Returns a list containing the modulus and the sign.
#'
#' @rdname linalg-det
#' @name det
#' @useDynLib fmlr R_linalg_det
#'
#' @export
linalg_det = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_det, get_backend(x), x$get_type(), x$data_ptr())
}

#' trace
#'
#' Matrix trace, i.e. theh sum of the diagonal elements.
#'
#' @param x Input data.
#' @return Returns the trace.
#'
#' @rdname linalg-trace
#' @name trace
#' @useDynLib fmlr R_linalg_trace
#'
#' @export
linalg_trace = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_trace, get_backend(x), x$get_type(), x$data_ptr())
}

#' svd
#'
#' Computes the singular value decomposition.
#'
#' @details
#' You will need to initialize the return objects \code{s} and/or \code{u} and
#' \code{vt}.
#' manually. See the example.
#'
#' @param x Input data. The input values are overwritten.
#' @param s Singular values.
#' @param u,vt The left/right singular vectors. Should both be \code{NULL} or
#' matrices of the same backend and fundamental type as \code{x}.
#'
#' @examples
#' suppressMessages(library(fmlr))
#' x = cpumat(3, 2)
#' x$fill_linspace(1, 6)
#'
#' s = cpuvec()
#' linalg_svd(x, s)
#' s$info()
#' s$print()
#'
#' @rdname linalg-svd
#' @name svd
#' @useDynLib fmlr R_linalg_svd
#'
#' @export
linalg_svd = function(x, s, u=NULL, vt=NULL)
{
  check_is_mat(x)
  check_is_vec(s)

  check_type_consistency(x, s)
  if (!is.null(u) && !is.null(vt))
    check_inputs(x, u, vt)
  else if (!is.null(u) || !is.null(vt))
    stop("must pass neither u and vt or both u and vt")

  if (is.null(u))
    .Call(R_linalg_svd, get_backend(x), x$get_type(), x$data_ptr(), s$data_ptr(), NULL, NULL)
  else
    .Call(R_linalg_svd, get_backend(x), x$get_type(), x$data_ptr(), s$data_ptr(), u$data_ptr(), vt$data_ptr())

  invisible(NULL)
}

#' eigen
#'
#' Computes the eigenvalues and/or eigenvectors
#'
#' @details
#' You will need to initialize the return objects \code{values} and/or
#' \code{vectors}.
#' manually. See the example.
#'
#' @param x Input data. The input values are overwritten.
#' @param values The eigenvalues.
#' @param vectors The eigenvectors.
#'
#' @rdname linalg-eigen
#' @name eigen
#' @useDynLib fmlr R_linalg_eigen_sym
#'
#' @export
linalg_eigen_sym = function(x, values, vectors=NULL)
{
  check_is_mat(x)
  check_is_vec(values)
  check_type_consistency(x, values)
  if (!is.null(vectors))
    check_inputs(x, vectors)

  if (is.null(vectors))
    .Call(R_linalg_eigen_sym, get_backend(x), x$get_type(), x$data_ptr(), values$data_ptr(), NULL)
  else
    .Call(R_linalg_eigen_sym, get_backend(x), x$get_type(), x$data_ptr(), values$data_ptr(), vectors$data_ptr())

  invisible(NULL)
}

#' invert
#'
#' Invert a matrix.
#'
#' @param x Input data, overwritten by the inverse.
#' @return Returns \code{NULL}.
#'
#' @rdname linalg-invert
#' @name invert
#' @useDynLib fmlr R_linalg_invert
#'
#' @export
linalg_invert = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_invert, get_backend(x), x$get_type(), x$data_ptr())
  invisible(NULL)
}

#' solve
#'
#' Solve a system of equations.
#'
#' @param x Input data. The input values are overwritten.
#' @param y The RHS, overwritten by the solution.
#'
#' @rdname linalg-solve
#' @name solve
#' @useDynLib fmlr R_linalg_solve
#'
#' @export
linalg_solve = function(x, y)
{
  check_is_mat(x)
  check_type_consistency(x, y)

  if (is_vec(y))
  {
    if (is_mpimat(x))
      stop("can not mix vector with mpimat")

    class = CLASS_VEC
  }
  else
  {
    check_class_consistency(x, y)
    class = CLASS_MAT
  }

  .Call(R_linalg_solve, get_backend(x), x$get_type(), x$data_ptr(), class, y$data_ptr())
  invisible(NULL)
}

#' qr
#'
#' Computes the compact QR factorization.
#'
#' @param x Input data. The input values are overwritten.
#' @param qraux Auxilliary data for the compact QR.
#'
#' @rdname linalg-qr
#' @name qr
#' @useDynLib fmlr R_linalg_qr
#'
#' @export
linalg_qr = function(x, qraux)
{
  check_is_mat(x)
  check_is_vec(qraux)
  check_type_consistency(x, qraux)

  .Call(R_linalg_qr, get_backend(x), x$get_type(), x$data_ptr(), qraux$data_ptr())
  invisible(NULL)
}

#' qr_Q
#'
#' Computes the Q matrix from the compact QR factorization.
#'
#' @param QR The compact QR factorization. The return from \code{qr()}.
#' @param qraux Auxilliary data for the compact QR.
#' @param Q The output Q matrix.
#' @param work A workspace vector.
#'
#' @rdname linalg-qr-Q
#' @name qr_Q
#' @useDynLib fmlr R_linalg_qr_Q
#'
#' @export
linalg_qr_Q = function(QR, qraux, Q, work)
{
  check_inputs(QR, Q)
  check_is_vec(qraux)
  check_is_vec(work)
  check_type_consistency(QR, qraux, work)

  .Call(R_linalg_qr_Q, get_backend(QR), QR$get_type(), QR$data_ptr(), qraux$data_ptr(), Q$data_ptr(), work$data_ptr())
  invisible(NULL)
}

#' qr_R
#'
#' Computes the R matrix from the compact QR factorization.
#'
#' @param QR The compact QR factorization. The return from \code{qr()}.
#' @param R The output R matrix.
#'
#' @rdname linalg-qr-R
#' @name qr_R
#' @useDynLib fmlr R_linalg_qr_R
#'
#' @export
linalg_qr_R = function(QR, R)
{
  check_inputs(QR, R)
  .Call(R_linalg_qr_R, get_backend(QR), QR$get_type(), QR$data_ptr(), R$data_ptr())
  invisible(NULL)
}

#' lq
#'
#' Computes the compact LQ factorization.
#'
#' @param x Input data. The input values are overwritten.
#' @param lqaux Auxilliary data for the compact LQ.
#'
#' @rdname linalg-lq
#' @name lq
#' @useDynLib fmlr R_linalg_lq
#'
#' @export
linalg_lq = function(x, lqaux)
{
  check_is_mat(x)
  check_is_vec(lqaux)
  check_type_consistency(x, lqaux)

  .Call(R_linalg_lq, get_backend(x), x$get_type(), x$data_ptr(), lqaux$data_ptr())
  invisible(NULL)
}

#' lq_L
#'
#' Computes the L matrix from the compact LQ factorization.
#'
#' @param LQ The compact LQ factorization. The return from \code{lq()}.
#' @param L The output L matrix.
#'
#' @rdname linalg-qr-R
#' @name lq_L
#' @useDynLib fmlr R_linalg_lq_L
#'
#' @export
linalg_lq_L = function(LQ, L)
{
  check_inputs(LQ, L)
  .Call(R_linalg_lq_L, get_backend(LQ), LQ$get_type(), LQ$data_ptr(), L$data_ptr())
  invisible(NULL)
}

#' lq_Q
#'
#' Computes the Q matrix from the compact LQ factorization.
#'
#' @param LQ The compact LQ factorization. The return from \code{lq()}.
#' @param lqaux Auxilliary data for the compact LQ.
#' @param Q The output Q matrix.
#' @param work A workspace vector.
#'
#' @rdname linalg-lq-Q
#' @name lq_Q
#' @useDynLib fmlr R_linalg_lq_Q
#'
#' @export
linalg_lq_Q = function(LQ, lqaux, Q, work)
{
  check_inputs(LQ, Q)
  check_is_vec(lqaux)
  check_is_vec(work)
  check_type_consistency(LQ, lqaux, work)

  .Call(R_linalg_lq_Q, get_backend(LQ), LQ$get_type(), LQ$data_ptr(), lqaux$data_ptr(), Q$data_ptr(), work$data_ptr())
  invisible(NULL)
}

#' qrsvd
#'
#' QR/LQ-based SVD. Useful for very tall/skinny or short/wide data.
#'
#' @param x Input data. The input values are overwritten.
#' @param s Singular values.
#' @param u,vt The left/right singular vectors. Should both be \code{NULL} or
#' matrices of the same backend and fundamental type as \code{x}.
#'
#' @rdname linalg-qrsvd
#' @name qrsvd
#' @useDynLib fmlr R_linalg_qrsvd
#'
#' @export
linalg_qrsvd = function(x, s, u=NULL, vt=NULL)
{
  check_is_mat(x)
  check_is_vec(s)

  check_type_consistency(x, s)
  if (!is.null(u) && !is.null(vt))
    check_inputs(x, u, vt)
  else if (!is.null(u) || !is.null(vt))
    stop("must pass neither u and vt or both u and vt")

  if (is.null(u))
    .Call(R_linalg_qrsvd, get_backend(x), x$get_type(), x$data_ptr(), s$data_ptr(), NULL, NULL)
  else
    .Call(R_linalg_qrsvd, get_backend(x), x$get_type(), x$data_ptr(), s$data_ptr(), u$data_ptr(), vt$data_ptr())

  invisible(NULL)
}

#' cpsvd
#'
#' "Crossproducts" SVD.
#'
#' @details
#' Computes the approximate SVD via the eigenvalue decomposition of
#' \code{crossprod(x)} if the input is tall/skinny and \code{tcrossprod(x)}
#' otherwise.
#'
#' @param x Input data. The input values are overwritten.
#' @param s Singular values.
#' @param u,vt The left/right singular vectors. Should both be \code{NULL} or
#' matrices of the same backend and fundamental type as \code{x}.
#'
#' @rdname linalg-cpsvd
#' @name cpsvd
#' @useDynLib fmlr R_linalg_cpsvd
#'
#' @export
linalg_cpsvd = function(x, s, u=NULL, vt=NULL)
{
  check_is_mat(x)
  check_is_vec(s)

  check_type_consistency(x, s)
  if (!is.null(u) && !is.null(vt))
    check_inputs(x, u, vt)
  else if (!is.null(u) || !is.null(vt))
    stop("must pass neither u and vt or both u and vt")

  if (is.null(u))
    .Call(R_linalg_cpsvd, get_backend(x), x$get_type(), x$data_ptr(), s$data_ptr(), NULL, NULL)
  else
    .Call(R_linalg_cpsvd, get_backend(x), x$get_type(), x$data_ptr(), s$data_ptr(), u$data_ptr(), vt$data_ptr())

  invisible(NULL)
}

#' chol
#'
#' Compute the lower-triangular Cholesky factor.
#'
#' @param x Input data, overwritten by the inverse.
#' @return Returns \code{NULL}.
#'
#' @rdname linalg-chol
#' @name chol
#' @useDynLib fmlr R_linalg_chol
#'
#' @export
linalg_chol = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_chol, get_backend(x), x$get_type(), x$data_ptr())
  invisible(NULL)
}

#' norms
#'
#' Norms.
#'
#' @param x Input data. The data is un-modified except for \code{norm_2()}.
#'
#' @return The requested norm.
#'
#' @rdname linalg-norm
#' @name norm
#'
#' @useDynLib fmlr R_linalg_norm
NULL

#' @rdname linalg-norm
#' @export
linalg_norm_1 = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_norm, get_backend(x), x$get_type(), x$data_ptr(), "1")
}

#' @rdname linalg-norm
#' @export
linalg_norm_I = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_norm, get_backend(x), x$get_type(), x$data_ptr(), "I")
}

#' @rdname linalg-norm
#' @export
linalg_norm_F = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_norm, get_backend(x), x$get_type(), x$data_ptr(), "F")
}

#' @rdname linalg-norm
#' @export
linalg_norm_M = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_norm, get_backend(x), x$get_type(), x$data_ptr(), "M")
}

#' @rdname linalg-norm
#' @export
linalg_norm_2 = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_norm, get_backend(x), x$get_type(), x$data_ptr(), "2")
}

#' Condition Number
#'
#' Condition numbers.
#'
#' @param x Input data. The data is modified in each case.
#'
#' @return The requested condition number.
#'
#' @rdname linalg-cond
#' @name cond
#'
#' @useDynLib fmlr R_linalg_cond
NULL

#' @rdname linalg-cond
#' @export
linalg_cond_1 = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_cond, get_backend(x), x$get_type(), x$data_ptr(), "1")
}

#' @rdname linalg-cond
#' @export
linalg_cond_I = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_cond, get_backend(x), x$get_type(), x$data_ptr(), "I")
}

#' @rdname linalg-cond
#' @export
linalg_cond_2 = function(x)
{
  check_is_mat(x)
  .Call(R_linalg_cond, get_backend(x), x$get_type(), x$data_ptr(), "2")
}

#' dot
#'
#' Compute vector dot product i.e. \code{sum(x*y)}.
#'
#' @param x,y Input data.
#' class and type as \code{x}.
#' @return Returns the dot product.
#'
#' @rdname linalg-dot
#' @name dot
#'
#' @useDynLib fmlr R_linalg_dot
#'
#' @export
linalg_dot = function(x, y=NULL)
{
  check_is_vec(x)

  if (!is.null(y))
  {
    check_is_vec(y)
    check_backend_consistency(x, y)
    .Call(R_linalg_dot, get_backend(x), x$get_type(), x$data_ptr(), y$data_ptr())
  }
  else
    .Call(R_linalg_dot, get_backend(x), x$get_type(), x$data_ptr(), NULL)
}

#' trinv
#'
#' Invert a triangular matrix.
#'
#' @param upper Is the matrix upper triangular? Otherwise only the lower
#' triangle will be referenced.
#' @param unit_diag Is the matrix unit diagonal?
#' @param x Input data, overwritten by the inverse.
#' @return Returns \code{NULL}.
#'
#' @rdname linalg-trinv
#' @name trinv
#' @useDynLib fmlr R_linalg_trinv
#'
#' @export
linalg_trinv = function(upper, unit_diag, x)
{
  check_is_mat(x)

  upper = as.logical(upper)
  unit_diag = as.logical(unit_diag)

  .Call(R_linalg_trinv, get_backend(x), x$get_type(), upper, unit_diag, x$data_ptr())
  invisible(NULL)
}

#' rsvd
#'
#' SVD approximation via random projections.
#'
#' @param seed Seed for the random generator.
#' @param k The number of components to estimate. Integer > 0.
#' @param q Exponent (see paper if you really care). Values of 1 or 2 are good.
#' @param x Input data. The input values are overwritten.
#' @param s Singular values.
#' @param u,vt The left/right singular vectors. Should both be \code{NULL} or
#' matrices of the same backend and fundamental type as \code{x}.
#'
#' @references Halko, Nathan, Per-Gunnar Martinsson, and Joel A. Tropp. "Finding
#' structure with randomness: Probabilistic algorithms for constructing
#' approximate matrix decompositions." SIAM review 53, no. 2 (2011): 217-288.
#'
#' @rdname linalg-rsvd
#' @name rsvd
#' @useDynLib fmlr R_linalg_rsvd
#'
#' @export
linalg_rsvd = function(seed, k, q, x, s, u=NULL, vt=NULL)
{
  seed = as.integer(seed)
  k = as.integer(k)
  q = as.integer(q)

  check_is_mat(x)
  check_is_vec(s)

  check_type_consistency(x, s)
  if (!is.null(u) && !is.null(vt))
    check_inputs(x, u, vt)
  else if (!is.null(u) || !is.null(vt))
    stop("must pass neither u and vt or both u and vt")

  if (is.null(u))
    .Call(R_linalg_rsvd, get_backend(x), x$get_type(), seed, k, q, x$data_ptr(), s$data_ptr(), NULL, NULL)
  else
    .Call(R_linalg_rsvd, get_backend(x), x$get_type(), seed, k, q, x$data_ptr(), s$data_ptr(), u$data_ptr(), vt$data_ptr())

  invisible(NULL)
}


 C02AMJ Example Program Results

  Roots of cubic equation             Error estimates
                                    (machine-dependent)

  z =  -2.0000E+00 +3.0000E+00*i          1.3E-15
  z =   1.0000E+00 -2.0000E+00*i          2.2E-15
  z =   3.0000E+00 -4.0000E+00*i          2.1E-15


# Get command line args with file names for processing
args <- commandArgs(TRUE)

# MBE PG functions
source("/ufrc/barbazuk/lboat/T.lamottei_T.crocifolius/Complete_data_set/align_reads_for_samcompare/scripts/emp_bayesian/Subroutines_model2_experimental.R")
source("/ufrc/barbazuk/lboat/T.lamottei_T.crocifolius/Complete_data_set/align_reads_for_samcompare/scripts/emp_bayesian/AI_poissongamma_functions.R")

# Prepare output file
fileout = args[2]
headers_out = "commonID,q4_mean_theta,q4_q025,q4_q975,q5_mean_theta,q5_q025,q5_q975,q6_mean_theta,q6_q025,q6_q975"
cat(headers_out,file=fileout,append=FALSE,sep="\n")

# Make Connection to input
con = file(args[1],"r")
newline<-readLines(con,n=1) # Go to header line
headers_in=strsplit(newline,split=",")[[1]]

mydata=rep(NA,length(headers_in))
names(mydata)=headers_in
m=1

while(length(newline) != 0 ){
    # Move past fusions that are not flag_analyze
    flaganalyze=0
    while(flaganalyze==0){
        newline<-readLines(con,n=1)
        if(length(newline)==0){break}
        mydata<-as.vector(strsplit(newline,split=",")[[1]])
        names(mydata)=headers_in
        flaganalyze=as.numeric(mydata["flag_analyze"])
    }
    if(length(newline)==0){break}

    print(paste("------------Analyzing",mydata['line'],mydata['mating_status'],mydata['fusion_id'], "--------------"));
    m=m+1
    X_RNA <- as.numeric(mydata[c("LINE_TOTAL_1","LINE_TOTAL_2","LINE_TOTAL_3","LINE_TOTAL_4","LINE_TOTAL_5")])
    X_RNA <- X_RNA[!is.na(X_RNA)]
    Y_RNA <- as.numeric(mydata[c("TESTER_TOTAL_1","TESTER_TOTAL_2","TESTER_TOTAL_3","TESTER_TOTAL_4","TESTER_TOTAL_5")])
    Y_RNA <- Y_RNA[!is.na(Y_RNA)]
    n_i <- X_RNA + Y_RNA

    # Create storage vectors for Quantiles and posterior means for theta (proportion of male reads) under different models
    means=q_025=q_975=rep(NA,3)
    names(means)=names(q_025)=names(q_975)=c("PG_4","PG_5","PG_6")

    #Poisson Gamma models q = .4
    tem_PG=gibbs_poissongamma(nsim=1000,nburnin=1000,lag=10,x=X_RNA,y=Y_RNA,both=c(0,0,0),a_mu=1/2,b_mu=1/2,a_alpha=1/2,b_alpha=1/2,a_beta=1/2,b_beta=1/2,
    q_=.4,#<-------As before but with q=q_sim
    abundance=FALSE)

    thetas=tem_PG$alphas/(1+tem_PG$alphas)
    q_025["PG_4"]= quantile(thetas,c(.025),na.rm=TRUE)
    q_975["PG_4"]= quantile(thetas,c(.975),na.rm=TRUE)
    means["PG_4"]= mean(thetas)

    #Poisson Gamma models q = .5
    tem_PG=gibbs_poissongamma(nsim=1000,nburnin=1000,lag=10,x=X_RNA,y=Y_RNA,both=c(0,0,0),a_mu=1/2,b_mu=1/2,a_alpha=1/2,b_alpha=1/2,a_beta=1/2,b_beta=1/2,
    q_=.5,#<-------As before but with q=q_sim
    abundance=FALSE)

    thetas=tem_PG$alphas/(1+tem_PG$alphas)
    q_025["PG_5"]= quantile(thetas,c(.025),na.rm=TRUE)
    q_975["PG_5"]= quantile(thetas,c(.975),na.rm=TRUE)
    means["PG_5"]= mean(thetas)

    #Poisson Gamma models q = .6
    tem_PG=gibbs_poissongamma(nsim=1000,nburnin=1000,lag=10,x=X_RNA,y=Y_RNA,both=c(0,0,0),a_mu=1/2,b_mu=1/2,a_alpha=1/2,b_alpha=1/2,a_beta=1/2,b_beta=1/2,
    q_=.6,#<-------As before but with q=q_sim
    abundance=FALSE)

    thetas=tem_PG$alphas/(1+tem_PG$alphas)
    q_025["PG_6"]= quantile(thetas,c(.025),na.rm=TRUE)
    q_975["PG_6"]= quantile(thetas,c(.975),na.rm=TRUE)
    means["PG_6"]= mean(thetas)

    # Create output and write to table
    SNPout = paste(mydata["commonID"],paste(round(c(means["PG_4"],q_025["PG_4"],q_975["PG_4"]),3),collapse=","),paste(round(c(means["PG_5"],q_025["PG_5"],q_975["PG_5"]),3),collapse=","),paste(round(c(means["PG_6"],q_025["PG_6"],q_975["PG_6"]),3),collapse=","),sep=",")
    cat(SNPout,file=fileout,append=TRUE,sep="\n")
}


model_snowdensity <- function (ps_t1 = 0.0,
         Sdepth_t1 = 0.0,
         Sdry_t1 = 0.0,
         Swet_t1 = 0.0){
    #'- Name: SnowDensity -Version: 1.0, -Time step: 1
    #'- Description:
    #'            * Title: Density of snow cover calculation
    #'            * Author: STICS
    #'            * Reference: doi:http://dx.doi.org/10.1016/j.agrformet.2014.05.002
    #'            * Institution: INRA
    #'            * Abstract: density of snow cover
    #'- inputs:
    #'            * name: ps_t1
    #'                          ** description : density of snow cover in previous day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 100.0
    #'                          ** unit : kg/m**3
    #'                          ** uri :
    #'            * name: Sdepth_t1
    #'                          ** description : snow cover depth Calculation in previous day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : m
    #'                          ** uri :
    #'            * name: Sdry_t1
    #'                          ** description : water in solid state in the snow cover in previous day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'            * name: Swet_t1
    #'                          ** description : water in liquid state in the snow cover
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 100.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'- outputs:
    #'            * name: ps
    #'                          ** description : density of snow cover
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : kg/m**3
    #'                          ** uri :
    ps <- 0.0
    if (abs(Sdepth_t1) > 0.0)
    {
        if (abs(Sdry_t1 + Swet_t1) > 0.0)
        {
            ps <- (Sdry_t1 + Swet_t1) / Sdepth_t1
        }
        else
        {
            ps <- ps_t1
        }
    }
    return (list('ps' = ps))
}


#'@title calcSpeedUnitConversion
#'
#'@description Convert speed in knots to m/s.
#'
#'@param shipSpeed Ship speed (vector of numericals, knots)
#'
#'@return speed (vector of numericals, m/s)
#'
#'@examples
#'calcSpeedUnitConversion(seq(10,15,1))
#'
#'@export

calcSpeedUnitConversion<- function(shipSpeed){

  speed<- shipSpeed*0.5144

  return(speed)
}


# This is a special version of K-dO rq modified to compute the LR process
# Note that the sol array is now p+3 by J and the third row contains the
# value of the objective function at the tau specified in row one.
#
#     This software is in the public domain  and may be freely
#     used and redistributed for non-commercial purposes.  No guarantees
#     are offered or implied.  comments, bug reports, etc are welcome
#     and should be sent to roger@ysidro.econ.uiuc.edu or to
#
#        roger koenker
#        department of economics
#        university of illinois
#        champaign, illinois, 61820
#
#
    z <- .Fortran("rqbr", as.integer(n), as.integer(p), as.integer(n +
        5), as.integer(p + 3), as.integer(p + 4), as.double(x),
        as.double(y), as.double(tau), as.double(tol), flag = as.integer(1),
        coef = double(p), resid = double(n), integer(n), double((n +
            5) * (p + 4)), double(n), as.integer(nsol), as.integer(ndsol),
        sol = double((p + 3) * nsol), dsol = double(n * ndsol),
        lsol = as.integer(0), h = integer(p * nsol), qn = as.double(qn),
        cutoff = as.double(cutoff), ci = double(4 * p), tnmat = double(4 *
            p), as.double(big), as.logical(lci1))

# If I can get this to work and not crash
# then should just be a matter of porting the wrapper into a SKlearn style interface
# for br and fn. ppro is harder because it is more of an r source port.

# Also important to use 'conquer' package as that's reputed to be better than BR/FN
# And updated preprocessing when available

Cf2py intent(in) m
Cf2py intent(in) nn
Cf2py intent(in) m5
Cf2py intent(in) n3
Cf2py intent(in) n4
Cf2py intent(in) a
Cf2py intent(in) b
Cf2py intent(in) t
Cf2py intent(in) toler
Cf2py intent(out) ift
Cf2py intent(out) x
Cf2py intent(out) e
Cf2py intent(out) s
Cf2py intent(out) wa
Cf2py intent(out) wb
Cf2py intent(out) nsol
Cf2py intent(out) ndsol
Cf2py intent(out) sol
Cf2py intent(out) dsol
Cf2py intent(out) lsol
Cf2py intent(out) h
Cf2py intent(out) qn
Cf2py intent(out) cutoff
Cf2py intent(out) ci
Cf2py intent(out) tnmat
Cf2py intent(out) big
Cf2py intent(out) lci1

subroutine rqbr(m,nn,m5,n3,n4,a,b,t,toler,ift,x,e,s,wa,wb,nsol,ndsol,sol,dsol,lsol,h,qn,cutoff,ci,tnmat,big,lci1)
#
#     m = number of observations
#     n = number of parameters
#     m5 = m+5
#     n3 = n+3
#     n4 = n+4
#     a is the x matrix
#     b is the y vector
#     t, the desired quantile
#     toler, smallest detectable |x-y|/x machine precision to the 2/3
#     ift exit code:
#     		0-ok
#    		else dimensions inconsistent see below
#     x the parameter estimate betahat
#     e is the residual vector
#     s is an integer work array
#     wa is a real work array
#     wb is another real work array
#     nsol is an estimated (row) dimension of the primal solution array say 3*m; minimum value = 2
#     ndsol is an estimated (row) dimension of the dual solution array say 3*m; minimum value = 2
#     sol is the primal solution array
#     dsol is the dual solution arry
#     lsol is the actual dimension of the solution arrays
#     h is the matrix of basic observations indices
#     qn is the vector of residuals variances from the projection of each column of the x matrix on the remaining columns
#     cutoff, the critical point for N(0,1)
#     ci is the matrix of confidence intervals
#     tnmat is the matrix of the JGPK rank test statistics
#     big, large positive finite floating-point number
#     utilization:  if you just want a solution at a single quantile you
#     neednt bother with sol, nsol, etc, if you want all the solutions
#     then set theta to something <0 and sol and dsol will return all the
#     estimated quantile solutions.
#     the algorithm  is a slightly modified version of algorithm as 229
#     described in koenker and dorey, computing regression quantiles,
#     applied statistics, pp. 383-393.
#
integer i,j,k,kl,kount,kr,l,lsol,m,m1,m2,m3,m4,m5,ift
integer n,n1,n2,n3,nsol,ndsol,out,s(m),h(nn,nsol)
integer nn,n4,idxcf
logical stage,test,init,iend,lup
logical lci1,lci2,skip
double precision a1,aux,b1,big,d,dif,pivot,smax,t,t0,t1,tnt,dk
double precision min,max,toler,zero,half,one,two
double precision b(m),sol(n3,nsol),a(m,nn),x(nn),wa(m5,n4),wb(m)
double precision sum,e(m),dsol(m,ndsol)
double precision qn(nn),cutoff,ci(4,nn),tnmat(4,nn),tnew,told,tn
parameter( zero = 0.d0)
parameter( one = 1.d0)
parameter( two = 2.d0)
#
#  check dimension parameters
#
n=nn
ift = 0
wa(m+2,nn+1) = one
if (m5!=m+5)
  ift = 3
if (n3!=n+3)
  ift = 4
if (n4!=n+4)
  ift = 5
if (m<=zero||n<=zero)
  ift = 6
if (ift<=two) {
#
#  initialization
#
  half = one/two
  iend = .true.
  lci2 = .false.
  lup = .true.
  skip = .false.
  idxcf = 0
  tnew = zero
  tn = zero
  m1 = m+1
  n1 = n+1
  n2 = n+2
  m2 = m+2
  m3 = m+3
  m4 = m+4
  do j = 1,n{
    x(j) = zero
    }
  do i = 1,m
    e(i) = zero
  if (t<zero||t>one) {
    t0 = one/(two*float(m))
    t1 = one-t0
    t = t0
    iend = .false.
    lci1 = .false.
    }
  repeat { #0
    do i = 1,m {
      k = 1
      do j = 1,nn
        if (k<=nn){
          if(j==idxcf)
            skip = .true.
          else
            skip = .false.
          if(!skip){
            wa(i,k) = a(i,j)
            k = k+1
            }
          }
      wa(i,n4) = n+i
      wa(i,n2) = b(i)
      if (idxcf != 0)
        wa(i,n3) = tnew*a(i,idxcf)
      else
        wa(i,n3) = zero
      wa(i,n1) = wa(i,n2)-wa(i,n3)
      if (wa(i,n1)<zero)
        do j = 1,n4
          wa(i,j) = -wa(i,j)
      }
    do j = 1,n {
      wa(m4,j) = j
      wa(m2,j) = zero
      wa(m3,j) = zero
      do i = 1,m {
        aux = sign(one,wa(m4,j))*wa(i,j)
        wa(m2,j) = wa(m2,j)+aux*(one-sign(one,wa(i,n4)))
        wa(m3,j) = wa(m3,j)+aux*sign(one,wa(i,n4))
        }
      wa(m3,j) = two*wa(m3,j)
      }
    dif = zero
    init = .false.
    if(!lci2){
#compute the columns means
      do k = 1,n {
        wa(m5,k) = zero
        do i = 1,m{
          wa(m5,k) = wa(m5,k)+a(i,k)
          }
        wa(m5,k) = wa(m5,k)/float(m)
        }
      }
    lsol = 1
    kount = 0
    repeat { #1
#
# compute new marginal costs
#
      do j = 1,n{
        wa(m1,j) = wa(m2,j)+wa(m3,j)*t
        }
      if (!init) {
#
# stage 1
#
# determine the vector to enter the basis
#
        stage = .true.
        kr = 1
        kl = 1
        go to 30
        }
      repeat { #2
#
# stage 2
#
        stage = .false.
        repeat { #3
#
# determine the vector to enter the basis
#
          max = -big
          do j = kr,n {
            d = wa(m1,j)
            if (d<zero) {
              if (d>(-two))
                next 1
              d = -d-two
              }
            if (d>max) {
              max = d
              in = j
              }
            }
          if (max<=toler)
            break 2
          if (wa(m1,in)<=zero) {
            do i = 1,m4
              wa(i,in) = -wa(i,in)
            wa(m1,in) = wa(m1,in)-two
            wa(m2,in) = wa(m2,in)-two
            }
          repeat { #4
#
# determine the vector to leave the basis
#
            k = 0
            do i = kl,m {
              d = wa(i,in)
              if (d>toler) {
                k = k+1
                wb(k) = wa(i,n1)/d
                s(k) = i
                test = .true.
                }
              }
            repeat { #5
              if (k<=0)
                test = .false.
              else {
                min = big
                do i = 1,k
                  if (wb(i)<min) {
                    j = i
                    min = wb(i)
                    out = s(i)
                    }
                wb(j) = wb(k)
                s(j) = s(k)
                k = k-1
                }
#
# check for linear dependence in stage 1
#
              if (!test&&stage)
                break 1
              if (!test)
                break 5
              pivot = wa(out,in)
              if (wa(m1,in)-pivot-pivot<=toler){
                go to 10
                }
              do j = kr,n3 {
                d = wa(out,j)
                wa(m1,j) = wa(m1,j)-d-d
                wa(m2,j) = wa(m2,j)-d-d
                wa(out,j) = -d
                }
              wa(out,n4) = -wa(out,n4)
              } #5
            do i = 1,m4 {
              d = wa(i,kr)
              wa(i,kr) = wa(i,in)
              wa(i,in) = d
              }
            kr = kr+1
            go to 20
#
# pivot on wa(out,in)
#
            10  do j = kr,n3
              if (j!=in)
                wa(out,j) = wa(out,j)/pivot
            do i = 1,m3
              if (i!=out) {
                d = wa(i,in)
                do j = kr,n3
                  if (j!=in)
                    wa(i,j) = wa(i,j)-d*wa(out,j)
                }
            do i = 1,m3
              if (i!=out)
                wa(i,in) = -wa(i,in)/pivot
            wa(out,in) = one/pivot
            d = wa(out,n4)
            wa(out,n4) = wa(m4,in)
            wa(m4,in) = d
            kount = kount+1
            if (!stage)
              break 1
#
# interchange rows in stage 1
#
            kl = kl+1
            do j = kr,n4 {
              d = wa(out,j)
              wa(out,j) = wa(kount,j)
              wa(kount,j) = d
              }
            20  if (kount+kr==n1)
              break 2
            30  max = -one
            do j = kr,n
              if (abs(wa(m4,j))<=n) {
                d = abs(wa(m1,j))
                if (d>max) {
                  max = d
                  in = j
                  }
                }
            if (wa(m1,in)<zero)
              do i = 1,m4
                wa(i,in) = -wa(i,in)
            } #4
          } #3
        } #2
      if (kr==1) {
        do j = 1,n {
          d = abs(wa(m1,j))
          if (d<=toler||two-d<=toler){
            ift = 1
            wa(m2,nn+1) = zero
            go to 80
            }
          }
        }
      80 kount = 0
      sum = zero
      if (!lci2){
        do i = 1,kl-1 {
          k = wa(i,n4)*sign(one,wa(i,n4))
          x(k) = wa(i,n1)*sign(one,wa(i,n4))
          }
        }
      do i = 1,n {
        kd = abs(wa(m4,i))-n
        dsol(kd,lsol) = one+wa(m1,i)/two
        if (wa(m4,i)<zero)
          dsol(kd,lsol) = one-dsol(kd,lsol)
        if (!lci2){
          sum = sum + x(i)*wa(m5,i)
          sol(i+3,lsol) = x(i)
          h(i,lsol) = kd
          }
        }
      do i = kl,m {
        kd = abs(wa(i,n4))-n
        if (wa(i,n4)<zero)
          dsol(kd,lsol) = zero
        if (wa(i,n4)>zero)
          dsol(kd,lsol) = one
        }
      if (!lci2){
        sol(1,lsol) = smax
        sol(2,lsol) = sum
        sum = zero
        do j=kl,m{
          d = wa(j,n1)*sign(one,wa(j,n4))
          sum = sum + d*(smax + half*(sign(one,d) - one))
	 }
        sol(3,lsol) = sum
        do i=1,m
          dsol(i,lsol+1) = dsol(i,lsol)
        }
      if (lci2){
# compute next theta
        a1 = zero
        do i = 1,m {
          a1 = a1+a(i,idxcf)*(dsol(i,lsol)+t-one)
          }
        tn = a1/sqrt(qn(idxcf)*t*(one-t))
        if (abs(tn)<cutoff){
          if (lup)
            smax = big
          else
            smax = -big
          do i =1,kl-1 {
            k = wa(i,n4)*sign(one,wa(i,n4))
            sol(k,1) = wa(i,n2)*sign(one,wa(i,n4))
            sol(k,2) = wa(i,n3)*sign(one,wa(i,n4))/tnew
            }
          do i = kl,m {
            a1 = zero
            b1 = zero
            k = wa(i,n4)*sign(one,wa(i,n4))-n
            dk = wa(i,n4)*sign(one,wa(i,n4))
            l = 1
            do j = 1,n{
              if (j==idxcf)
                l = l+1
              a1 = a1 + a(k,l)*sol(j,1)
              b1 = b1 + a(k,l)*sol(j,2)
              l = l+1
              }
            tnt = (b(k)-a1)/(a(k,idxcf)-b1)
            if (lup){
              if (tnt>tnew)
                if (tnt<smax){
                  smax = tnt
                  out = i
                  }
              }
            else {
              if (tnt<tnew)
                if (tnt>smax){
                  smax = tnt
                  out = i
                  }
              }
            }
          if (lup){
            told = tnew
            tnew = smax + toler
            ci(3,idxcf) = told - toler
            tnmat(3,idxcf) = tn
            if (!(tnew < big-toler)){
              ci(3,idxcf) = big
              ci(4,idxcf) = big
              tnmat(3,idxcf) = tn
              tnmat(4,idxcf) = tn
              lup = .false.
              go to 70
              }
            }
          else{
            told = tnew
            tnew = smax - toler
            ci(2,idxcf) = told + toler
            tnmat(2,idxcf) = tn
            if (!(tnew > -big+toler)){
              ci(2,idxcf) = -big
              ci(1,idxcf) = -big
              tnmat(2,idxcf) = tn
              tnmat(1,idxcf) = tn
              lup = .true.
              go to 60
              }
            }
#update the new marginal cost
          do i = 1,m{
            wa(i,n3) = wa(i,n3)/told*tnew
            wa(i,n1) = wa(i,n2) - wa(i,n3)
            }
          do j = kr,n3{
            d = wa(out,j)
            wa(m1,j) = wa(m1,j) -d -d
            wa(m2,j) = wa(m2,j) -d -d
            wa(out,j) = -d
            }
          wa(out,n4) = -wa(out,n4)
          init = .true.
          }
        else{
          if (lup){
            ci(4,idxcf) = tnew - toler
            tnmat(4,idxcf) = tn
            lup = .false.
            go to 70
            }
          else{
            ci(1,idxcf) = tnew + toler
            tnmat(1,idxcf) = tn
            lup = .true.
            go to 60
            }
          }
        }
      if ((iend)&&(!lci2))
        go to 40
      if (!lci2){
        init = .true.
        lsol = lsol+1
        do i = 1,m
          s(i) = zero
        do j = 1,n
          x(j) = zero
#
#  compute next t
#
        smax = two
        do j = 1,n {
          b1 = wa(m3,j)
          a1 = (-two-wa(m2,j))/b1
          b1 = -wa(m2,j)/b1
          if (a1>=t)
            if (a1<smax) {
              smax = a1
              dif = (b1-a1)/two
              }
          if (b1>t)
            if (b1<smax) {
              smax = b1
              dif = (b1-a1)/two
              }
          }
        tnt = smax+toler*(one+abs(dif))
        if (tnt>=t1+toler)
          iend = .true.
        t = tnt
        if (iend)
          t = t1
        }
      } #1
    wa(m2,nn+1) = two
    ift = 2
    go to 50
    40  if (lsol>2) {
      sol(1,1) = zero
      #sol(2,1) = zero
      sol(3,1) = zero
      sol(1,lsol) = one
      #sol(2,lsol) = zero
      sol(3,lsol) = zero
      do i = 1,m {
        dsol(i,1) = one
        dsol(i,lsol) = zero
        dsol(i,lsol+1) = zero
        }
      }
    l = kl-1
    do i = 1,l
      if (wa(i,n1)<zero)
        do j = kr,n4
          wa(i,j) = -wa(i,j)
    50  sum = zero
    if(!lci2){
      do i = kl,m {
        k = wa(i,n4)*sign(one,wa(i,n4))
        d = wa(i,n1)*sign(one,wa(i,n4))
        sum = sum+d*sign(one,d)*(half+sign(one,d)*(t-half))
        k = k-n
        e(k) = d
        }
      wa(m2,n2) = kount
      wa(m1,n2) = n1-kr
      wa(m1,n1) = sum
      }
    if (wa(m2,nn+1)==two)
      break 1
    if (!lci1)
      break 1
    if (!lci2){
      lci2 = .true.
      n = nn-1
      n1 = n+1
      n2 = n+2
      n3 = n+3
      n4 = n+4
    60 idxcf = idxcf+1
      if (idxcf>nn){
        break 1
	}
    70  if (lup){
        tnew = x(idxcf)+toler
        told = tnew
        ci(3,idxcf) = x(idxcf)
        tnmat(3,idxcf) = zero
        }
      else{
        tnew = x(idxcf)-toler
        told = tnew
        ci(2,idxcf) = x(idxcf)
        tnmat(2,idxcf) = zero
        }
      }
    } #0
  # restore the original value of dual when ci is true
  do i=1,m
    dsol(i,lsol) = dsol(i,lsol+1)
  }
return
end


# Latent class models with one (loglinear independence) to three classes
data(election)
f <- cbind(MORALG,CARESG,KNOWG,LEADG,DISHONG,INTELG,
           MORALB,CARESB,KNOWB,LEADB,DISHONB,INTELB)~1
nes1 <- poLCA(f,election,nclass=1) # log-likelihood: -18647.31
nes2 <- poLCA(f,election,nclass=2) # log-likelihood: -17344.92
nes3 <- poLCA(f,election,nclass=3) # log-likelihood: -16714.66
# Three-class model with a single covariate (party)
f2a <- cbind(MORALG,CARESG,KNOWG,LEADG,DISHONG,INTELG,
             MORALB,CARESB,KNOWB,LEADB,DISHONB,INTELB)~PARTY
nes2a <- poLCA(f2a,election,nclass=3,nrep=5) # log-likelihood: -16222.32
pidmat <- cbind(1,c(1:7))
exb <- exp(pidmat %*% nes2a$coeff)
matplot(c(1:7),(cbind(1,exb)/(1+rowSums(exb))),ylim=c(0,1),type="l",
        main="Party ID as a predictor of candidate affinity class",
        xlab="Party ID: strong Democratic (1) to strong Republican (7)",
        ylab="Probability of latent class membership",lwd=2,col=1)
text(5.9,0.35,"Other")
text(5.4,0.7,"Bush affinity")
text(1.8,0.6,"Gore affinity")


#R version 3.3.2

i <- 1

# O(maxN)
while (i <= 1000000000) {
    if (i %% 2 == 0 && i %% 3 == 0 && i %% 4 == 0 && i %% 5 == 0 && i %% 6 == 0 && i %% 7 == 0 && i %% 8 == 0 &&
                            i %% 9 == 0 && i %% 10 == 0 && i %% 11 == 0 && i %% 12 == 0 &&
                            i %% 13 == 0 && i %% 14 == 0 && i %% 15 == 0 && i %% 16 == 0 &&
                            i %% 17 == 0 && i %% 18 == 0 && i %% 19 == 0 && i %% 20 == 0) {
        print(i)
        break
    }
    i <- i + 1
}

i <- 2*3*5*7*11*13*17*19

# O(n / (f(k))
while (i <= 1000000000) {
    if (i %% 4 == 0 && i %% 6 == 0 && i %% 8 == 0 &&
                            i %% 9 == 0 && i %% 10 == 0 && i %% 12 == 0 &&
                            i %% 14 == 0 && i %% 15 == 0 && i %% 16 == 0 &&
                            i %% 18 == 0 && i %% 20 == 0) {
        print(i)
        break
    }
    i <- 2*3*5*7*11*13*17*19
}