public CacheEntry(Key key, QrFactorization qrFactorization) { Key = key; QrFactorization = qrFactorization; MatrixCrossproduct = ImmutableMatrix.OfMatrix(ComputeMatrixCrossproduct(key.Matrix, qrFactorization.IndependentColumnIndexes)); MatrixCrossproductInverse = ImmutableMatrix.OfMatrix(MatrixCrossproduct.Inverse()); }
public IList <LinearFitResult> Fit(double[] observations) { if (observations.Length != DesignMatrix.RowCount) { throw new ArgumentException("Wrong number of rows"); // Not L10N } var coefficients = QrFactorization.Solve(observations); var fittedValues = new double[observations.Length]; var residuals = new double[observations.Length]; for (int iRow = 0; iRow < observations.Length; iRow++) { var designRow = Enumerable.Range(0, DesignMatrix.ColumnCount).Select(index => DesignMatrix[iRow, index]).ToArray(); fittedValues[iRow] = DotProduct(designRow, coefficients); residuals[iRow] = observations[iRow] - fittedValues[iRow]; } double rss = DotProduct(residuals, residuals); int degreesOfFreedom = observations.Length - QrFactorization.NumberIndependentColumns; double resVar = rss / degreesOfFreedom; double sigma = Math.Sqrt(resVar); var covarianceUnscaled = MatrixCrossproductInverse; var scaledCovariance = covarianceUnscaled.Multiply(sigma * sigma); var indepColIndexes = QrFactorization.IndependentColumnIndexes.ToArray(); var result = new List <LinearFitResult>(); foreach (var contrastRow in ContrastValues.EnumerateRows()) { double standardError = 0; for (int iRow = 0; iRow < indepColIndexes.Length; iRow++) { for (int iCol = 0; iCol < indepColIndexes.Length; iCol++) { standardError += contrastRow[indepColIndexes[iRow]] * scaledCovariance[iRow, iCol] * contrastRow[indepColIndexes[iCol]]; } } standardError = Math.Sqrt(standardError); double foldChange = DotProduct(coefficients, contrastRow); double tValue = foldChange / standardError; double pValue; if (0 != degreesOfFreedom) { var studentT = new StudentT(0, 1.0, degreesOfFreedom); pValue = (1 - studentT.CumulativeDistribution(Math.Abs(tValue))) * 2; } else { pValue = 1; } result.Add(new LinearFitResult(foldChange) .SetDegreesOfFreedom(degreesOfFreedom) .SetTValue(tValue) .SetStandardError(standardError) .SetPValue(pValue)); } return(result); }