예제 #1
0
        public void Test02_4x3Matrix()
        {
            double[][] x = new double[4][] {
                new double[] { 1, 1, 1 },
                new double[] { 1, 2, 4 },
                new double[] { 1, 3, 9 },
                new double[] { 1, 4, 16 }
            };

            double[][] expectedU = new double[][]
            {
                new double[] { 0.06694942772363194830335878, -0.6496907508990609956156238, 0.7234775064393449793067184 },
                new double[] { 0.2274012268163765838895085, -0.6075911990028880215461633, -0.3593349648122762034053743 },
                new double[] { 0.4855667535109152389501883, -0.2675906812177502659847019, -0.4925648741133399561928825 },
                new double[] { 0.8414460078072479134853980, 0.3703108024563522710687606, 0.3237877785361537209441937 }
            };

            double[] expectedSingularValues = new double[] { 19.62136402366775701042283, 1.712069874450694805376275, 0.2662528792614848629364699 };

            double[][] expectedV = new double[][]
            {
                new double[] { 0.08263255367478247093846163, -0.6743660675845837168765756, 0.7337589985572162375998953 },
                new double[] { 0.2723682291746780408033352, -0.6929635293730795997776881, -0.6675455749947378000917574 },
                new double[] { 0.9586383096921561352973747, 0.2550136346341303246410893, 0.1264145456079166187153824 }
            };


            IMatrix X = MatrixMath.ToMatrix(x);

            MatrixMath.SingularValueDecomposition decomp =
                MatrixMath.GetSingularValueDecomposition(X);



            for (int i = 0; i < 3; i++)
            {
                Assert.AreEqual(expectedSingularValues[i], decomp.Diagonal[i], accuracy, "SingularValue_" + i.ToString());
            }


            // Test the U Matrix
            for (int i = 0; i < expectedU.Length; i++)
            {
                for (int j = 0; j < expectedU[0].Length; j++)
                {
                    Assert.AreEqual(Math.Abs(expectedU[i][j]), Math.Abs(decomp.U[i][j]), accuracy, string.Format("U[{0}][{1}]", i, j));
                }
            }


            // Test the V Matrix
            for (int i = 0; i < expectedV.Length; i++)
            {
                for (int j = 0; j < expectedV[0].Length; j++)
                {
                    Assert.AreEqual(Math.Abs(expectedV[i][j]), Math.Abs(decomp.V[i][j]), accuracy, string.Format("V[{0}][{1}]", i, j));
                }
            }
        }
예제 #2
0
        public void Test01_3x3Matrix()
        {
            double[][] x = new double[][]
            {
                new double[] { 1, 1, 1 },
                new double[] { 1, 2, 4 },
                new double[] { 1, 3, 9 }
            };

            double[][] expectedU = new double[][]
            {
                new double[] { 0.1323855611751141383983336, -0.8014095371363918468296921, 0.5832810788798007027395599 },
                new double[] { 0.4263811717635121943505712, -0.4851883520178218054139224, -0.7634077281713910856496549 },
                new double[] { 0.8948034195050466074658404, 0.3497642303796436079288927, 0.2774740052491605347063156 }
            };

            double[] expectedSingularValues = new double[] { 10.64956309214167630396485, 1.250703401814404251343328, 0.1501564090663296496197768 };

            double[][] expectedV = new double[][]
            {
                new double[] { 0.1364910597615280451679478, -0.7490454230919167919488232, 0.6483063664273445542029725 },
                new double[] { 0.3445735878052170177361156, -0.5776697728534024470814668, -0.7399774835213155452612752 },
                new double[] { 0.9287837386562145112758128, 0.3243895616023268212207566, 0.1792545093748964368092940 }
            };

            IMatrix X = MatrixMath.ToMatrix(x);

            MatrixMath.SingularValueDecomposition decomp =
                MatrixMath.GetSingularValueDecomposition(X);


            // Test singular values
            for (int i = 0; i < 3; i++)
            {
                Assert.AreEqual(expectedSingularValues[i], decomp.Diagonal[i], accuracy, "SingularValue_" + i.ToString());
            }


            // Test the U Matrix
            for (int i = 0; i < expectedU.Length; i++)
            {
                for (int j = 0; j < expectedU[0].Length; j++)
                {
                    Assert.AreEqual(expectedU[i][j], decomp.U[i][j], accuracy, string.Format("U[{0}][{1}]", i, j));
                }
            }


            // Test the V Matrix
            for (int i = 0; i < expectedV.Length; i++)
            {
                for (int j = 0; j < expectedV[0].Length; j++)
                {
                    Assert.AreEqual(expectedV[i][j], decomp.V[i][j], accuracy, string.Format("V[{0}][{1}]", i, j));
                }
            }
        }
예제 #3
0
        public void Test03_3x4Matrix()
        {
            double[][] x = new double[3][] {
                new double[] { 1, 1, 1, 1 },
                new double[] { 1, 2, 4, 8 },
                new double[] { 1, 3, 9, 27 }
            };

            double[][] expectedU = new double[][]
            {
                new double[] { 0.04734386493551604995477145, -0.6298036597816627273392776, 0.7753102015184575401987200 },
                new double[] { 0.3019315922550259026382404, -0.7308495124910898427130366, -0.6121244184721608492599749 },
                new double[] { 0.9521532818046222520788651, 0.2630709794279101755469104, 0.1555563811983541387310737 }
            };

            double[] expectedSingularValues = new double[] { 30.06856910125475242387046, 2.167597107698223914976808, 0.4274049388650818475368850, 0 };

            double[][] expectedV = new double[][]
            {
                new double[] { 0.04328203096770760439694849, -0.5063589487856289461733263, 0.7457615372696186799476553 },
                new double[] { 0.1166555975127217050621376, -0.6007988024412046764051820, 0.04148409753120615124080518 },
                new double[] { 0.3267348618124714344785811, -0.5469479963247332138954797, -0.6391597680419712306939267 },
                new double[] { 0.9368897840411354775696647, 0.2889451561910784800441657, 0.1832855425226170318735145 }
            };


            IMatrix X = MatrixMath.ToMatrix(x);

            MatrixMath.SingularValueDecomposition decomp =
                MatrixMath.GetSingularValueDecomposition(X);


            double[] calculatedSingularValues = decomp.Diagonal;
            for (int i = 0; i < 4; i++)
            {
                Assert.AreEqual(expectedSingularValues[i], calculatedSingularValues[i], accuracy, "SingularValue_" + i.ToString());
            }

            // Test the U Matrix
            for (int i = 0; i < expectedU.Length; i++)
            {
                for (int j = 0; j < expectedU[0].Length; j++)
                {
                    Assert.AreEqual(Math.Abs(expectedU[i][j]), Math.Abs(decomp.U[i][j]), accuracy, string.Format("U[{0}][{1}]", i, j));
                }
            }


            // Test the V Matrix
            for (int i = 0; i < expectedV.Length; i++)
            {
                for (int j = 0; j < expectedV[0].Length; j++)
                {
                    Assert.AreEqual(Math.Abs(expectedV[i][j]), Math.Abs(decomp.V[i][j]), accuracy, string.Format("V[{0}][{1}]", i, j));
                }
            }
        }
예제 #4
0
        public static void CalculateXLeverageFromPreprocessed(
            IROMatrix <double> xScores,
            int numberOfFactors,
            IMatrix <double> leverage)
        {
            var subscores = new MatrixMath.LeftSpineJaggedArrayMatrix <double>(xScores.RowCount, numberOfFactors);

            MatrixMath.Submatrix(xScores, subscores);

            var decompose = new MatrixMath.SingularValueDecomposition(subscores);

            for (int i = 0; i < xScores.RowCount; i++)
            {
                leverage[i, 0] = decompose.HatDiagonal[i];
            }
        }
예제 #5
0
        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];
            }
        }
예제 #6
0
        public static void ExecuteAnalysis(
            IROMatrix <double> X,           // matrix of spectra (a spectra is a row of this matrix)
            IROMatrix <double> Y,           // matrix of concentrations (a mixture is a row of this matrix)
            ref int numFactors,
            out IROMatrix <double> xLoads,  // out: the loads of the X matrix
            out IROMatrix <double> xScores, // matrix of weighting values
            out IROVector <double> V        // vector of cross products
            )
        {
            var matrixX = new MatrixMath.LeftSpineJaggedArrayMatrix <double>(X.RowCount, X.ColumnCount);

            MatrixMath.Copy(X, matrixX);
            var decompose = new MatrixMath.SingularValueDecomposition(matrixX);

            numFactors = Math.Min(numFactors, matrixX.ColumnCount);
            numFactors = Math.Min(numFactors, matrixX.RowCount);

            xLoads  = JaggedArrayMath.ToTransposedROMatrix(decompose.V, Y.RowCount, X.ColumnCount);
            xScores = JaggedArrayMath.ToMatrix(decompose.U, Y.RowCount, Y.RowCount);
            V       = VectorMath.ToROVector(decompose.Diagonal, numFactors);
        }
예제 #7
0
        } // end partial-least-squares-predict

        public static void CalculateXLeverageFromPreprocessed(
            IROMatrix matrixX,
            IROMatrix W,      // weighting matrix
            int numFactors,   // number of factors to use for prediction
            IMatrix leverage, // Matrix of predicted y-values, must be same number of rows as spectra
            int leverageColumn
            )
        {
            // get the score matrix
            MatrixMath.BEMatrix weights = new MatrixMath.BEMatrix(numFactors, W.Columns);
            MatrixMath.Submatrix(W, weights, 0, 0);
            MatrixMath.BEMatrix scoresMatrix = new MatrixMath.BEMatrix(matrixX.Rows, weights.Rows);
            MatrixMath.MultiplySecondTransposed(matrixX, weights, scoresMatrix);

            MatrixMath.SingularValueDecomposition decomposition = MatrixMath.GetSingularValueDecomposition(scoresMatrix);


            for (int i = 0; i < matrixX.Rows; i++)
            {
                leverage[i, leverageColumn] = decomposition.HatDiagonal[i];
            }
        }
예제 #8
0
        /// <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.</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
            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);
        }
예제 #9
0
        public DynamicParameterEstimation Calculate(IROVector x, IROVector y, int numX, int numY, int backgroundOrder)
        {
            _numX = numX;
            _numY = numY;
            _backgroundOrderPlus1 = 1 + Math.Max(-1, backgroundOrder);

            // where to start the calculation (index of first y point that can be used)
            int start        = Math.Max(_numX - 1, _numY);
            int numberOfData = 0;

            if (numX > 0)
            {
                numberOfData = Math.Min(x.Length, y.Length) - start;
            }
            else
            {
                numberOfData = y.Length - start;
            }

            int numberOfParameter = _numX + _numY + _backgroundOrderPlus1;



            MatrixMath.BEMatrix u = new MatrixMath.BEMatrix(numberOfData, numberOfParameter);

            // Fill the matrix
            for (int i = 0; i < numberOfData; i++)
            {
                int yIdx = i + start;
                // x
                for (int j = 0; j < _numX; j++)
                {
                    u[i, j] = x[yIdx - j];
                }
                // y
                for (int j = 0; j < _numY; j++)
                {
                    u[i, j + _numX] = y[yIdx - 1 - j];
                }
                // polynomial background component
                double background = 1;
                for (int j = 0; j < _backgroundOrderPlus1; j++)
                {
                    u[i, j + _numX + _numY] = background;
                    background *= yIdx;
                }
            }

            // Fill the y
            double[] scaledY = new double[numberOfData];
            for (int i = 0; i < numberOfData; i++)
            {
                scaledY[i] = y[i + start];
            }


            _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

            _parameter = new double[numberOfParameter];
            _decomposition.Backsubstitution(scaledY, _parameter);

            return(this);
        }