/// <summary>
        /// Creates an analyis from preprocessed spectra and preprocessed concentrations.
        /// </summary>
        /// <param name="matrixX">The spectral matrix (each spectrum is a row in the matrix). They must at least be centered.</param>
        /// <param name="matrixY">The matrix of concentrations (each experiment is a row in the matrix). They must at least be centered.</param>
        /// <param name="maxFactors">Maximum number of factors for analysis.</param>
        /// <returns>A regression object, which holds all the loads and weights neccessary for further calculations.</returns>
        protected override void AnalyzeFromPreprocessedWithoutReset(IROMatrix matrixX, IROMatrix matrixY, int maxFactors)
        {
            int     numberOfFactors = _calib.NumberOfFactors = Math.Min(matrixX.Columns, maxFactors);
            IMatrix helperY         = new MatrixMath.BEMatrix(matrixY.Rows, 1);

            _PRESS = null;

            for (int i = 0; i < matrixY.Columns; i++)
            {
                MatrixMath.Submatrix(matrixY, helperY, 0, i);

                PLS2Regression r = PLS2Regression.CreateFromPreprocessed(matrixX, helperY, maxFactors);

                IPLS2CalibrationModel cal = r.CalibrationModel;
                _calib.NumberOfFactors = Math.Min(_calib.NumberOfFactors, cal.NumberOfFactors);
                _calib.XLoads[i]       = cal.XLoads;
                _calib.YLoads[i]       = cal.YLoads;
                _calib.XWeights[i]     = cal.XWeights;
                _calib.CrossProduct[i] = cal.CrossProduct;

                if (_PRESS == null)
                {
                    _PRESS = VectorMath.CreateExtensibleVector(r.PRESS.Length);
                }
                VectorMath.Add(_PRESS, r.PRESS, _PRESS);
            }
        }
Exemple #2
0
        public static void CalculatePRESS(
            IROMatrix <double> yLoads,
            IROMatrix <double> xScores,
            int numberOfFactors,
            out IROVector <double> press)
        {
            int numMeasurements = yLoads.RowCount;

            IExtensibleVector <double> PRESS = VectorMath.CreateExtensibleVector <double>(numberOfFactors + 1);
            var UtY        = new MatrixMath.LeftSpineJaggedArrayMatrix <double>(yLoads.RowCount, yLoads.ColumnCount);
            var predictedY = new MatrixMath.LeftSpineJaggedArrayMatrix <double>(yLoads.RowCount, yLoads.ColumnCount);

            press = PRESS;

            MatrixMath.MultiplyFirstTransposed(xScores, yLoads, UtY);

            // now calculate PRESS by predicting the y
            // using yp = U (w*(1/w)) U' y
            // of course w*1/w is the identity matrix, but we use only the first factors, so using a cutted identity matrix
            // we precalculate the last term U'y = UtY
            // and multiplying with one row of U in every factor step, summing up the predictedY
            PRESS[0] = MatrixMath.SumOfSquares(yLoads);
            for (int nf = 0; nf < numberOfFactors; nf++)
            {
                for (int cn = 0; cn < yLoads.ColumnCount; cn++)
                {
                    for (int k = 0; k < yLoads.RowCount; k++)
                    {
                        predictedY[k, cn] += xScores[k, nf] * UtY[nf, cn];
                    }
                }
                PRESS[nf + 1] = MatrixMath.SumOfSquaredDifferences(yLoads, predictedY);
            }
        }
        public CrossValidationResult(int numberOfPoints, int numberOfY, int numberOfFactors, bool multipleSpectralResiduals)
        {
            _predictedY       = new IMatrix[numberOfFactors + 1];
            _spectralResidual = new IMatrix[numberOfFactors + 1];
            _crossPRESS       = VectorMath.CreateExtensibleVector(numberOfFactors + 1);

            for (int i = 0; i <= numberOfFactors; i++)
            {
                _predictedY[i]       = new MatrixMath.BEMatrix(numberOfPoints, numberOfY);
                _spectralResidual[i] = new MatrixMath.BEMatrix(numberOfPoints, multipleSpectralResiduals ? numberOfY : 1);
            }
        }
        /// <summary>
        /// Processes the spectra in matrix xMatrix.
        /// </summary>
        /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
        /// <param name="xMean">Output: On return, contains the ensemble mean of the spectra.</param>
        /// <param name="xScale">Not used.</param>
        /// <param name="regions">Vector of spectal regions. Each element is the index of the start of a new region.</param>
        public override void Process(IMatrix xMatrix, IVector xMean, IVector xScale, int[] regions)
        {
            // note: we have a light deviation here to the literature:
            // we repeat the multiple scattering correction until the xMean vector is self consistent,
            // in detail: after each MSC correction, we calculate the new xMean and compare with the xMean
            // of the step before. We repeat until the deviation of the xMean to the xMean_before is
            // reasonable small.
            // The reason for this deviation is that we don't want to store two separate xMean vectors: one used
            // for MSC (the x in linear regression) and another to center the MSC corrected spectra

            IVector xMeanBefore = null;
            double  threshold   = 1E-14 * MatrixMath.SumOfSquares(xMatrix) / xMatrix.Rows;

            for (int cycle = 0; cycle < 50; cycle++)
            {
                // 1.) Get the mean spectrum
                // we want to have the mean of each matrix column, but not center the matrix now, since this
                // is done later on
                int cols = xMatrix.Columns;
                int rows = xMatrix.Rows;
                for (int n = 0; n < cols; n++)
                {
                    double sum = 0;
                    for (int i = 0; i < rows; i++)
                    {
                        sum += xMatrix[i, n];
                    }
                    xMean[n] = sum / rows;
                }

                // 2.) Process the spectras
                ProcessForPrediction(xMatrix, xMean, xScale, regions);

                // 3. Compare the xMean with the xMean_before
                if (xMeanBefore == null)
                {
                    xMeanBefore = VectorMath.CreateExtensibleVector(xMean.Length);
                    VectorMath.Copy(xMean, xMeanBefore);
                }
                else
                {
                    double sumdiffsquare = VectorMath.SumOfSquaredDifferences(xMean, xMeanBefore);
                    if (sumdiffsquare < threshold)
                    {
                        break;
                    }
                    else
                    {
                        VectorMath.Copy(xMean, xMeanBefore);
                    }
                }
            }
        }
        /// <summary>
        /// Creates an analyis from preprocessed spectra and preprocessed concentrations.
        /// </summary>
        /// <param name="matrixX">The spectral matrix (each spectrum is a row in the matrix). They must at least be centered.</param>
        /// <param name="matrixY">The matrix of concentrations (each experiment is a row in the matrix). They must at least be centered.</param>
        /// <param name="maxFactors">Maximum number of factors for analysis.</param>
        /// <returns>A regression object, which holds all the loads and weights neccessary for further calculations.</returns>
        protected override void AnalyzeFromPreprocessedWithoutReset(IROMatrix matrixX, IROMatrix matrixY, int maxFactors)
        {
            int numberOfFactors = _calib.NumberOfFactors = Math.Min(matrixX.Columns, maxFactors);

            MatrixMath.BEMatrix _xLoads = new MatrixMath.BEMatrix(0, 0);
            MatrixMath.BEMatrix _yLoads = new MatrixMath.BEMatrix(0, 0);
            MatrixMath.BEMatrix _W      = new MatrixMath.BEMatrix(0, 0);
            MatrixMath.REMatrix _V      = new MatrixMath.REMatrix(0, 0);
            _PRESS = VectorMath.CreateExtensibleVector(0);

            ExecuteAnalysis(matrixX, matrixY, ref numberOfFactors, _xLoads, _yLoads, _W, _V, _PRESS);
            _calib.NumberOfFactors = Math.Min(_calib.NumberOfFactors, numberOfFactors);
            _calib.XLoads          = _xLoads;
            _calib.YLoads          = _yLoads;
            _calib.XWeights        = _W;
            _calib.CrossProduct    = _V;
        }
Exemple #6
0
        /// <summary>
        /// Creates an analyis from preprocessed spectra and preprocessed concentrations.
        /// </summary>
        /// <param name="matrixX">The spectral matrix (each spectrum is a row in the matrix). They must at least be centered.</param>
        /// <param name="matrixY">The matrix of concentrations (each experiment is a row in the matrix). They must at least be centered.</param>
        /// <param name="maxFactors">Maximum number of factors for analysis.</param>
        /// <returns>A regression object, which holds all the loads and weights neccessary for further calculations.</returns>
        protected override void AnalyzeFromPreprocessedWithoutReset(IROMatrix <double> matrixX, IROMatrix <double> matrixY, int maxFactors)
        {
            int numberOfFactors = _calib.NumberOfFactors = Math.Min(matrixX.ColumnCount, maxFactors);

            var _xLoads = new MatrixMath.LeftSpineJaggedArrayMatrix <double>(0, 0);
            var _yLoads = new MatrixMath.LeftSpineJaggedArrayMatrix <double>(0, 0);
            var _W      = new MatrixMath.LeftSpineJaggedArrayMatrix <double>(0, 0);
            var _V      = new MatrixMath.TopSpineJaggedArrayMatrix <double>(0, 0);

            _PRESS = VectorMath.CreateExtensibleVector <double>(0);

            ExecuteAnalysis(matrixX, matrixY, ref numberOfFactors, _xLoads, _yLoads, _W, _V, _PRESS);
            _calib.NumberOfFactors = Math.Min(_calib.NumberOfFactors, numberOfFactors);
            _calib.XLoads          = _xLoads;
            _calib.YLoads          = _yLoads;
            _calib.XWeights        = _W;
            _calib.CrossProduct    = _V;
        }
Exemple #7
0
        public static void CalculatePRESS(
            IROMatrix matrixX,
            IROMatrix xLoads,
            IROMatrix yLoads,
            IROMatrix xScores,
            IROVector crossProduct,
            int numberOfFactors,
            out IROVector PRESS)
        {
            IMatrix predictedY = new JaggedArrayMatrix(yLoads.Rows, yLoads.Columns);
            IVector press      = VectorMath.CreateExtensibleVector(numberOfFactors + 1);

            PRESS = press;

            press[0] = MatrixMath.SumOfSquares(yLoads);
            for (int nf = 0; nf < numberOfFactors; nf++)
            {
                Predict(matrixX, xLoads, yLoads, xScores, crossProduct, nf, predictedY, null);
                press[nf + 1] = MatrixMath.SumOfSquaredDifferences(yLoads, predictedY);
            }
        }
Exemple #8
0
        public static void CalculatePRESS(
            IROMatrix <double> matrixX,
            IROMatrix <double> xLoads,
            IROMatrix <double> yLoads,
            IROMatrix <double> xScores,
            IReadOnlyList <double> crossProduct,
            int numberOfFactors,
            out IROVector <double> PRESS)
        {
            IMatrix <double> predictedY = new JaggedArrayMatrix(yLoads.RowCount, yLoads.ColumnCount);
            var press = VectorMath.CreateExtensibleVector <double>(numberOfFactors + 1);

            PRESS = press;

            press[0] = MatrixMath.SumOfSquares(yLoads);
            for (int nf = 0; nf < numberOfFactors; nf++)
            {
                Predict(matrixX, xLoads, yLoads, xScores, crossProduct, nf, predictedY, null);
                press[nf + 1] = MatrixMath.SumOfSquaredDifferences(yLoads, predictedY);
            }
        }