All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.maizegenetics.stats.linearmodels.SweepFastNestedModel Maven / Gradle / Ivy

package net.maizegenetics.stats.linearmodels;

import java.util.ArrayList;

import net.maizegenetics.matrixalgebra.Matrix.DoubleMatrix;

public class SweepFastNestedModel {
	double markerSS;
	double markerdf;
	double errorSS;
	double errordf;
	double taxaSS;
	double taxadf;
	double modelcfmSS;
	double modelcfmdf;
	double[] beta;
	DoubleMatrix G; //the inverse of X'X
	
	/**
	 * The constructor for this class. It will calculate the SS and df for marker after all other effects in the model except taxa nested in marker.
	 * Taxa in marker will then be added to the model and its SS and df calculated. Error SS and df will be the final residual.
	 * @param marker	the ModelEffect for the marker being tested
	 * @param taxaInMarker	the ModelEffect for taxa nested in marker
	 * @param otherEffects	any other effects in the model. The mean is always the first of these.
	 * @param data	the dependent variable
	 */
	public SweepFastNestedModel(ArrayList modelEffects, double[] data) {
		
		//order to add effects is other, marker, taxaInMarker
		int numberOfEffects = modelEffects.size();
		
		DoubleMatrix[][] xtx = new DoubleMatrix[numberOfEffects][numberOfEffects];
		DoubleMatrix[] xty = new DoubleMatrix[numberOfEffects];
		double yty;
		int[] dimX = new int[numberOfEffects];
		
		for (int i = 0; i < numberOfEffects; i++) {
			xtx[i][i] = modelEffects.get(i).getXtX();
			dimX[i] = xtx[i][i].numberOfColumns();
			xty[i] = modelEffects.get(i).getXty(data);
			for (int j = i + 1; j < numberOfEffects; j++) {
				xtx[i][j] = ModelEffectUtils.getXtY(modelEffects.get(i), modelEffects.get(j));
			}
		}
		
		
		yty = 0;
		int nobs = data.length;
		for (int i = 0; i < nobs; i++) {
			yty += data[i] * data[i];
		}
		
		SweepFast sf = new SweepFast(xtx, xty, yty);

		//assume that the first effect is the mean
		sf.revg2sweep(0);
		double residualAfterMean = sf.getResidualSS();
		sf.setDminFromA();
		
		//now sweep the rest of the other effects up to marker
		double dfother = 0;
		int col = 1;
		for (int i = 1; i < numberOfEffects - 2; i++) {
			for (int j = 0; j < dimX[i]; j++) if (sf.revg2sweep(col++)) dfother++;
		}
		
		double residualAfterOther = sf.getResidualSS();
		
		//sweep marker
		markerdf = 0;
		for (int i = 0; i < dimX[numberOfEffects - 2]; i++) {
			if (sf.revg2sweep(col++)) markerdf++;
		}
		double residualAfterMarker = sf.getResidualSS();
		
		//sweep taxa in marker
		taxadf = 0;
		for (int i = 0; i < dimX[numberOfEffects - 1]; i++) {
			if (sf.revg2sweep(col++)) taxadf++;
		}
		
		//calculate SS and df needed for output
		markerSS = residualAfterOther - residualAfterMarker;
		taxaSS = residualAfterMarker - sf.getResidualSS();
		modelcfmSS = residualAfterMean - residualAfterMarker;
		modelcfmdf = dfother + markerdf;
		errordf = data.length - 1 - modelcfmdf;
		errorSS = residualAfterMarker;
		
		beta = sf.getBeta();
		G = sf.getXTXpart();
	}
	
	public double[] getMarkerSSdf() {
		return new double[]{markerSS, markerdf};
	}
	
	public double[] getErrorSSdf() {
		return new double[] {errorSS, errordf};
	}
	
	public double[] getTaxaInMarkerSSdf() {
		return new double[] {taxaSS, taxadf};
	}
	
	public double[] getModelcfmSSdf() {
		return new double[] {modelcfmSS, modelcfmdf};
	}
	
	public double[] getBeta() {
		return beta;
	}
	
	public DoubleMatrix getInverseOfXtX() { return G; }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy