net.maizegenetics.stats.linearmodels.PartitionedLinearModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tassel6 Show documentation
Show all versions of tassel6 Show documentation
TASSEL 6 is a software package to evaluate traits association. Feature Tables are at the heart of the package where, a feature is a range of positions or a single position. Row in the that table are taxon.
package net.maizegenetics.stats.linearmodels;
import java.util.ArrayList;
import java.util.List;
import net.maizegenetics.matrixalgebra.Matrix.DoubleMatrix;
import net.maizegenetics.matrixalgebra.Matrix.DoubleMatrixFactory;
import net.maizegenetics.stats.linearmodels.ModelEffect;
import net.maizegenetics.stats.linearmodels.SweepFastLinearModel;
public class PartitionedLinearModel {
// ArrayList modelEffectList; //the model effects in the first partition
SweepFastLinearModel lm = null; //the linear model representing the first partition
ArrayList baseModel;
DoubleMatrix G1; //the inverse for the first partition
DoubleMatrix[][] x2tx1matrices;
DoubleMatrix X1Ty;
double modelss;
double errorss;
double modeldf;
double errordf;
double[] y;
public PartitionedLinearModel(ArrayList baseModel, SweepFastLinearModel lm) {
this.lm = lm;
this.baseModel = baseModel;
init();
}
public PartitionedLinearModel(List baseModel, SweepFastLinearModel lm) {
this.lm = lm;
if (baseModel instanceof ArrayList>)
this.baseModel = (ArrayList) baseModel;
else
baseModel = new ArrayList<>(baseModel);
init();
}
private void init() {
y = lm.y;
G1 = lm.getInverseOfXtX();
x2tx1matrices = new DoubleMatrix[1][baseModel.size()];
int nx1 = baseModel.size();
DoubleMatrix[][] x1tymatrices = new DoubleMatrix[nx1][1];
for (int i = 0; i < nx1; i++) {
x1tymatrices[i][0] = baseModel.get(i).getXty(y);
}
X1Ty = DoubleMatrixFactory.DEFAULT.compose(x1tymatrices);
}
public SweepFastLinearModel getLinearModel() {
return lm;
}
public void testNewModelEffect(ModelEffect me) {
int nx1 = baseModel.size();
for (int i = 0; i < nx1; i++) {
x2tx1matrices[0][i] = ModelEffectUtils.getXtY(me, baseModel.get(i));
}
//from Searle. 1987. Linear Models for Unbalanced Data. p.264
//for the added term, ssmodel = y'M1X2BX2'M1y, where
//B = inverse(X2'M1X2)
//X2'M1X2 = X2'X2 - X2'X1G1X1'X2
//use A = X2'X1G1 and X2'M1X2 = X2'X2 - AX1'X2
//X2'M1y = X2'y - X2'X1G1X1'y = X2Ty - AX1Ty
DoubleMatrix X2TX1 = DoubleMatrixFactory.DEFAULT.compose(x2tx1matrices);
DoubleMatrix X2TX2 = me.getXtX();
DoubleMatrix A = X2TX1.mult(G1);
DoubleMatrix X2TM1X2 = X2TX2.minus(A.tcrossproduct(X2TX1));
double[] ssdf = lm.getResidualSSdf();
DoubleMatrix X2Ty = me.getXty(y);
DoubleMatrix X2TM1y = X2Ty.minus(A.mult(X1Ty));
int[] rank = new int[] { 0 };
DoubleMatrix B = X2TM1X2.generalizedInverseWithRank(rank);
modelss = X2TM1y.crossproduct(B).mult(X2TM1y).get(0, 0);
errorss = ssdf[0] - modelss;
modeldf = rank[0];
errordf = ssdf[1] - modeldf;
}
public double testNewModelEffect(double[] covariate) {
//from Searle. 1987. Linear Models for Unbalanced Data. p.264
//for the added term, ssmodel = y'M1X2BX2'M1y, where
//B = inverse(X2'M1X2)
//X2'M1X2 = X2'X2 - X2'X1G1X1'X2
//use A = X2'X1G1 and X2'X1G1X1'X2 = AX1'X2
//X2'M1y = X2'y - X2'X1G1X1'y = X2Ty - AX1Ty
int nx1 = baseModel.size();
for (int i = 0; i < nx1; i++) {
x2tx1matrices[0][i] = baseModel.get(i).getXty(covariate).transpose();
}
DoubleMatrix X2TX1 = DoubleMatrixFactory.DEFAULT.compose(x2tx1matrices);
DoubleMatrix A = X2TX1.mult(G1);
double ax1ty = A.mult(X1Ty).get(0, 0);
double ax1tx2 = A.tcrossproduct(X2TX1).get(0, 0);
double x2tx2 = 0;
double x2ty = 0;
int count = 0;
for (double d : covariate) {
x2tx2 += d * d;
x2ty += d * y[count++];
}
double x2tm1x2 = x2tx2 - ax1tx2;
double x2tm1y = x2ty - ax1ty;
if (x2tm1x2 < 1e-12) {
return 0;
}
return x2tm1y * x2tm1y / x2tm1x2;
}
//only appropriate for a covariate which has one df
public void setModelSS(double modelss) {
this.modelss = modelss;
double[] ssdf = lm.getResidualSSdf();
errorss = ssdf[0] - modelss;
modeldf = 1;
errordf = ssdf[1] - modeldf;
}
public double getModelSS() {
return modelss;
}
public double getModeldf() {
return modeldf;
}
public double getErrorSS() {
return errorss;
}
public double getErrordf() {
return errordf;
}
public double getF() {
return modelss / errorss / modeldf * errordf;
}
public double getp() {
double p = 1;
if (modeldf == 0)
return 1;
try {
p = LinearModelUtils.Ftest(getF(), modeldf, errordf);
} catch (Exception e) {
// System.err.println("error calculating p");
}
return p;
}
public double[] getFp() {
double F = modelss / errorss / modeldf * errordf;
double p = Double.NaN;
if (modeldf > 0) {
try {
p = LinearModelUtils.Ftest(getF(), modeldf, errordf);
} catch (Exception e) {
// System.err.println("error calculating p");
}
}
return new double[] { F, p };
}
}