public static void CalculateXLeverageFromPreprocessed( IROMatrix xScores, int numberOfFactors, IMatrix leverage) { IMatrix subscores = new MatrixMath.BEMatrix(xScores.Rows,numberOfFactors); MatrixMath.Submatrix(xScores,subscores); MatrixMath.SingularValueDecomposition decompose = new MatrixMath.SingularValueDecomposition(subscores); for(int i=0;i<xScores.Rows;i++) leverage[i,0] = decompose.HatDiagonal[i]; }
/// <summary> /// Fits a data set linear to a given x base. /// </summary> /// <param name="xbase">The matrix of x values of the data set. Dimensions: numberOfData x numberOfParameters. The matrix is changed during calculation!</param> /// <param name="yarr">The array of y values of the data set.</param> /// <param name="stddev">The array of y standard deviations of the data set. Can be null if the standard deviation is unkown.</param> /// <param name="numberOfData">The number of data points (may be smaller than the array sizes of the data arrays).</param> /// <param name="numberOfParameter">The number of parameters to fit == size of the function base.</param> /// <param name="threshold">A treshold value (usually 1E-5) used to chop the unimportant singular values away.</param> public LinearFitBySvd Calculate( IROMatrix xbase, // NumberOfData, NumberOfParameters double[] yarr, double[] stddev, int numberOfData, int numberOfParameter, double threshold) { _numberOfParameter = numberOfParameter; _numberOfFreeParameter = numberOfParameter; _numberOfData = numberOfData; _parameter = new double[numberOfParameter]; _residual = new double[numberOfData]; _predicted = new double[numberOfData]; _reducedPredictionVariance = new double[numberOfData]; double[] scaledY = new double[numberOfData]; // Calculated some useful values _yMean = Mean(yarr,0,_numberOfData); _yCorrectedSumOfSquares = CorrectedSumOfSquares(yarr,_yMean,0,_numberOfData); MatrixMath.BEMatrix u = new MatrixMath.BEMatrix(numberOfData,numberOfParameter); // Fill the function base matrix (rows: numberOfData, columns: numberOfParameter) // and scale also y if (null == stddev) { for (int i = 0; i < numberOfData; i++) { for (int j = 0; j < numberOfParameter; j++) u[i, j] = xbase[i, j]; scaledY[i] = yarr[i]; } } else { for (int i = 0; i < numberOfData; i++) { double scale = 1 / stddev[i]; for (int j = 0; j < numberOfParameter; j++) u[i, j] = scale * xbase[i, j]; scaledY[i] = scale * yarr[i]; } } _decomposition = MatrixMath.GetSingularValueDecomposition(u); // set singular values < thresholdLevel to zero // ChopSingularValues makes only sense if all columns of the x matrix have the same variance //decomposition.ChopSingularValues(1E-5); // recalculate the parameters with the chopped singular values _decomposition.Backsubstitution(scaledY,_parameter); _chiSquare = 0; for(int i=0;i<numberOfData;i++) { double ypredicted=0; for(int j=0;j<numberOfParameter;j++) ypredicted += _parameter[j]*xbase[i,j]; double deviation = yarr[i]-ypredicted; _predicted[i] = ypredicted; _residual[i] = deviation; _chiSquare += deviation*deviation; } _covarianceMatrix = _decomposition.GetCovariances(); //calculate the reduced prediction variance x'(X'X)^(-1)x for(int i=0;i<numberOfData;i++) { double total = 0; for(int j=0;j<numberOfParameter;j++) { double sum=0; for(int k=0;k<numberOfParameter;k++) sum += _covarianceMatrix[j][k]*u[i,k]; total += u[i,j]*sum; } _reducedPredictionVariance[i] = total; } return this; }
public static void ExecuteAnalysis( IROMatrix X, // matrix of spectra (a spectra is a row of this matrix) IROMatrix Y, // matrix of concentrations (a mixture is a row of this matrix) ref int numFactors, out IROMatrix xLoads, // out: the loads of the X matrix out IROMatrix xScores, // matrix of weighting values out IROVector V // vector of cross products ) { IMatrix matrixX = new MatrixMath.BEMatrix(X.Rows,X.Columns); MatrixMath.Copy(X,matrixX); MatrixMath.SingularValueDecomposition decompose = new MatrixMath.SingularValueDecomposition(matrixX); numFactors = Math.Min(numFactors,matrixX.Columns); numFactors = Math.Min(numFactors,matrixX.Rows); xLoads = JaggedArrayMath.ToTransposedROMatrix(decompose.V,Y.Rows,X.Columns); xScores = JaggedArrayMath.ToMatrix(decompose.U,Y.Rows,Y.Rows); V = VectorMath.ToROVector(decompose.Diagonal,numFactors); }