public CacheEntry(Key key, QrFactorization qrFactorization)
 {
     Key = key;
     QrFactorization = qrFactorization;
     MatrixCrossproduct = ImmutableMatrix.OfMatrix(ComputeMatrixCrossproduct(key.Matrix, qrFactorization.IndependentColumnIndexes));
     MatrixCrossproductInverse = ImmutableMatrix.OfMatrix(MatrixCrossproduct.Inverse());
 }
Esempio n. 2
0
        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);
        }