Exemple #1
0
    /// <summary>
    /// Processes the spectra in matrix xMatrix for prediction.
    /// </summary>
    /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
    /// <param name="xMean">Not used.</param>
    /// <param name="xScale">Not used.</param>
    /// <param name="regionstart">Starting index of the region to process.</param>
    /// <param name="regionend">End index of the region to process.</param>
    public void ProcessForPrediction(IMatrix xMatrix, IROVector xMean, IROVector xScale, int regionstart, int regionend)
    {
      int regionlength = regionend - regionstart;

      for(int n=0;n<xMatrix.Rows;n++)
      {
        // 1.) Get the mean response of a spectrum
        double mean = 0;
        for(int i=regionstart;i<regionend;i++)
          mean += xMatrix[n,i];
        mean /= regionlength;

        // 2.) Subtract mean response
        for(int i=regionstart;i<regionend;i++)
          xMatrix[n,i] -= mean;

        // 3.) Get the standard deviation
        double dev = 0;
        for(int i=regionstart;i<regionend;i++)
          dev += xMatrix[n,i]*xMatrix[n,i];
        dev = Math.Sqrt(dev/(regionlength-1));

        // 4. Divide by standard deviation
        for(int i=regionstart;i<regionend;i++)
          xMatrix[n,i] /= dev;
      }
    }
Exemple #2
0
 /// <summary>
 /// Copies elements of a source vector to a destination vector.
 /// </summary>
 /// <param name="src">The source vector.</param>
 /// <param name="srcstart">First element of the source vector to copy.</param>
 /// <param name="dest">The destination vector.</param>
 /// <param name="deststart">First element of the destination vector to copy to.</param>
 /// <param name="count">Number of elements to copy.</param>
 public static void Copy(IROVector src, int srcstart, IVector dest, int deststart, int count)
 {
     for (int i = 0; i < count; i++)
     {
         dest[i + deststart] = src[i + srcstart];
     }
 }
    /// <summary>
    /// Constructor. Takes an read only vector and evaluates the spaces between
    /// the vector elements.
    /// </summary>
    /// <param name="vec">The vector.</param>
    public VectorSpacingEvaluator(IROVector vec)
    {
      int lower = vec.LowerBound;
      int upper = vec.UpperBound;

      _numtotalsteps = upper-lower;
      for(int i=lower;i<upper;i++)
      {
        double step = vec[i+1]-vec[i];
        
        if(!double.IsNaN(step))
        {
          _numvalidsteps++;

          if(step>_stepmax)
            _stepmax = step;
          if(step<_stepmin)
            _stepmin = step;

          _sumsteps += step;
        }
      }

      // if all steps are valid, we calculate sumsteps from the boundaries
      // to enhance the accuracy.
      if(_numvalidsteps>0 && _numtotalsteps == _numvalidsteps)
        _sumsteps = vec[upper] - vec[lower];
    }
		/// <summary>
		/// Constructor of a bivariate linear spline. The vectors and the data matrix are not cloned, so make sure that they don't change during usage of this instance.
		/// </summary>
		/// <param name="x">Vector of x values corresponding to the rows of the data matrix. Must be strongly increasing or decreasing.</param>
		/// <param name="y">Vector of y values corresponding to the columns of the data matrix. Must be strongly increasing or decreasing.</param>
		/// <param name="datamatrix"></param>
		public BivariateLinearSpline(IROVector x, IROVector y, IROMatrix datamatrix)
		{
			_x = x;
			_y = y;
			_vmatrix = datamatrix;

			// check the arguments
			if (_x.Length < 2)
				throw new ArgumentException("x.Length is less or equal 1 (you can use univariate interpolation instead)");
			if (_y.Length < 2)
				throw new ArgumentException("y.Length is less or equal 1 (you can use univariate interpolation instead)");
			if (_x.Length != _vmatrix.Rows)
				throw new ArgumentException("Length of vector x is not equal to datamatrix.Rows");
			if (_y.Length != _vmatrix.Columns)
				throw new ArgumentException("Length of vector y is not equal to datamatrix.Columns");

			if (!VectorMath.IsStrictlyIncreasingOrDecreasing(_x, out _isXDecreasing))
				throw new ArgumentException("Vector x is not strictly increasing or decreasing");

			if (!VectorMath.IsStrictlyIncreasingOrDecreasing(_y, out _isYDecreasing))
				throw new ArgumentException("Vector y is not strictly increasing or decreasing");

			_lastIX = 0;
			_lastIY = 0;
		}
Exemple #5
0
 /// <summary>
 /// Processes the spectra in matrix xMatrix for prediction.
 /// </summary>
 /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
 /// <param name="xMean">Not used.</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 ProcessForPrediction(IMatrix xMatrix, IROVector xMean, IROVector xScale, int[] regions)
 {
   for(int i=0;i<=regions.Length;i++)
   {
     ProcessForPrediction(xMatrix,xMean,xScale,RegionStart(i,regions),RegionEnd(i,regions,xMatrix.Columns));
   }
 }
        /// <summary>
        /// Constructor. Takes an read only vector and evaluates the spaces between
        /// the vector elements.
        /// </summary>
        /// <param name="vec">The vector.</param>
        public VectorSpacingEvaluator(IROVector vec)
        {
            int lower = vec.LowerBound;
            int upper = vec.UpperBound;

            _numtotalsteps = upper - lower;
            for (int i = lower; i < upper; i++)
            {
                double step = vec[i + 1] - vec[i];

                if (!double.IsNaN(step))
                {
                    _numvalidsteps++;

                    if (step > _stepmax)
                    {
                        _stepmax = step;
                    }
                    if (step < _stepmin)
                    {
                        _stepmin = step;
                    }

                    _sumsteps += step;
                }
            }

            // if all steps are valid, we calculate sumsteps from the boundaries
            // to enhance the accuracy.
            if (_numvalidsteps > 0 && _numtotalsteps == _numvalidsteps)
            {
                _sumsteps = vec[upper] - vec[lower];
            }
        }
Exemple #7
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);
            }
        }
		/// <summary>
		/// Constructor. Takes an read only vector and evaluates the spaces between
		/// the vector elements.
		/// </summary>
		/// <param name="vec">The vector.</param>
		public VectorSpacingEvaluator(IROVector vec)
		{
			_numtotalsteps = vec.Length - 1;
			for (int i = 0; i < _numtotalsteps; i++)
			{
				double step = vec[i + 1] - vec[i];

				if (!double.IsNaN(step))
				{
					_numvalidsteps++;

					if (step > _stepmax)
						_stepmax = step;
					if (step < _stepmin)
						_stepmin = step;

					_sumsteps += step;
				}
			}

			// if all steps are valid, we calculate sumsteps from the boundaries
			// to enhance the accuracy.
			if (_numvalidsteps > 0 && _numtotalsteps == _numvalidsteps)
				_sumsteps = vec[_numtotalsteps] - vec[0];
		}
Exemple #9
0
        /// <summary>
        /// Extrapolates y-values until the end of the vector by using linear prediction.
        /// </summary>
        /// <param name="yTraining">Input vector of y values used to calculated the prediction coefficients.
        /// <param name="yPredValues">Input/output vector of y values to extrapolate.
        /// The fields beginning from 0 to <c>len-1</c> must contain valid values used for initialization of the extrapolation.
        /// At the end of the procedure, the upper end (<c>len</c> .. <c>yPredValues.Count-1</c> contain the
        /// extrapolated data.</param>
        /// </param>
        /// <param name="len">Number of valid input data points for extrapolation (not for the training data!).</param>
        /// <param name="yOrder">Number of history samples used for prediction. Must be greater or equal to 1.</param>
        public static DynamicParameterEstimation Extrapolate(IROVector yTraining, IVector yPredValues, int len, int yOrder)
        {
            if (yOrder < 1)
            {
                throw new ArgumentException("yOrder must be at least 1");
            }
            if (yOrder >= (yTraining.Length - yOrder))
            {
                throw new ArgumentException("Not enough data points for this degree (yOrder must be less than yTraining.Length/2).");
            }

            DynamicParameterEstimation est = new DynamicParameterEstimation();

            est.Calculate(null, yTraining, 0, yOrder, 0);

            // now calculate the extrapolation data

            for (int i = len; i < yPredValues.Length; i++)
            {
                double sum = 0;
                for (int j = 0; j < yOrder; j++)
                {
                    sum += yPredValues[i - j - 1] * est._parameter[j];
                }
                yPredValues[i] = sum;
            }
            return(est);
        }
Exemple #10
0
        public static void GetPredictionScoreMatrix(
            IROMatrix xLoads,
            IROMatrix yLoads,
            IROMatrix xScores,
            IROVector crossProduct,
            int numberOfFactors,
            IMatrix predictionScores)
        {
            int numX = xLoads.Columns;
            int numY = yLoads.Columns;
            int numM = yLoads.Rows;

            MatrixMath.BEMatrix UtY = new MatrixMath.BEMatrix(xScores.Columns, yLoads.Columns);
            MatrixMath.MultiplyFirstTransposed(xScores, yLoads, UtY);

            MatrixMath.ZeroMatrix(predictionScores);

            for (int nf = 0; nf < numberOfFactors; nf++)
            {
                double scale = 1 / crossProduct[nf];
                for (int cn = 0; cn < numY; cn++)
                {
                    for (int k = 0; k < numX; k++)
                    {
                        predictionScores[k, cn] += scale * xLoads[nf, k] * UtY[nf, cn];
                    }
                }
            }
        }
Exemple #11
0
        public static void GetSpectralResiduals(
            IROMatrix matrixX,
            IROMatrix xLoads,
            IROMatrix yLoads,
            IROMatrix xScores,
            IROVector crossProduct,
            int numberOfFactors,
            IMatrix spectralResiduals)
        {
            int numX = xLoads.Columns;
            int numY = yLoads.Columns;
            int numM = yLoads.Rows;

            MatrixMath.BEMatrix reconstructedSpectra = new MatrixMath.BEMatrix(matrixX.Rows, matrixX.Columns);
            MatrixMath.ZeroMatrix(reconstructedSpectra);

            for (int nf = 0; nf < numberOfFactors; nf++)
            {
                double scale = crossProduct[nf];
                for (int m = 0; m < numM; m++)
                {
                    for (int k = 0; k < numX; k++)
                    {
                        reconstructedSpectra[m, k] += scale * xScores[m, nf] * xLoads[nf, k];
                    }
                }
            }
            for (int m = 0; m < numM; m++)
            {
                spectralResiduals[m, 0] = MatrixMath.SumOfSquaredDifferences(
                    MatrixMath.ToROSubMatrix(matrixX, m, 0, 1, matrixX.Columns),
                    MatrixMath.ToROSubMatrix(reconstructedSpectra, m, 0, 1, matrixX.Columns));
            }
        }
		public static void SetContentFromMatrix(DataTable destinationTable, IROMatrix matrix, string columnBaseName, IROVector rowHeaderColumn, string rowHeaderColumnName, IROVector colHeaderColumn, string colHeaderColumnName)
		{
			var c = new MatrixToDataTableConverter(matrix, destinationTable);
			c.ColumnBaseName = columnBaseName;
			c.AddMatrixColumnHeaderData(rowHeaderColumn, rowHeaderColumnName);
			c.AddMatrixColumnHeaderData(colHeaderColumn, colHeaderColumnName);
			c.Execute();
		}
Exemple #13
0
        /// <summary>
        /// Copies the source vector to the destination vector. Both vectors must have the same length.
        /// </summary>
        /// <param name="src">The source vector.</param>
        /// <param name="dest">The destination vector.</param>
        public static void Copy(IROVector src, IVector dest)
        {
            if (src.Length != dest.Length)
            {
                throw new ArgumentException("src and destination vector have unequal length!");
            }

            Copy(src, src.LowerBound, dest, dest.LowerBound, src.Length);
        }
Exemple #14
0
        private DoubleVector Pivot(IROVector B)
        {
            DoubleVector ret = new DoubleVector(B.Length);

            for (int i = 0; i < pivots.Length; i++)
            {
                ret.data[i] = B[pivots[i]];
            }
            return(ret);
        }
Exemple #15
0
        /// <summary>
        /// Resizes the vector to the same boundaries as the provided vector and copies the elements from it.
        /// </summary>
        /// <param name="a">The vector to copy the data from.</param>
        public void CopyFrom(IROVector a)
        {
            Resize(a.LowerBound, a.UpperBound);
            int lo = a.LowerBound;

            for (int i = 0; i < data.Length; ++i)
            {
                data[i] = a[i + lo];
            }
        }
Exemple #16
0
        /// <summary>
        /// This applies the set-up filter to an array of numbers. The left and right side is special treated by
        /// applying Savitzky-Golay with appropriate adjusted left and right number of points.
        /// </summary>
        /// <param name="array">The array of numbers to filter.</param>
        /// <param name="result">The resulting array. Must not be identical to the input array!</param>
        public void Apply(IROVector array, IVector result)
        {
            int filterPoints = _middle.Length;
            int sidePoints   = (filterPoints - 1) / 2;

            if (object.ReferenceEquals(array, result))
            {
                throw new ArgumentException("Argument array and result must not be identical!");
            }

            if (array.Length < filterPoints)
            {
                throw new ArgumentException("Input array must have same or greater length than the filter!");
            }

            // left side
            for (int n = 0; n < sidePoints; n++)
            {
                double[] filter = _left[n];
                double   sum    = 0;
                for (int i = 0; i < filterPoints; i++)
                {
                    sum += array[i] * filter[i];
                }
                result[n] = sum;
            }

            // middle
            int middleend = array.Length - filterPoints;

            for (int n = 0; n <= middleend; n++)
            {
                double sum = 0;
                for (int i = 0; i < filterPoints; i++)
                {
                    sum += array[n + i] * _middle[i];
                }
                result[n + sidePoints] = sum;
            }

            // right side
            int arrayOffset  = array.Length - filterPoints;
            int resultOffset = array.Length - 1;

            for (int n = 0; n < sidePoints; n++)
            {
                double[] filter = _right[n];
                double   sum    = 0;
                for (int i = 0; i < filterPoints; i++)
                {
                    sum += array[arrayOffset + i] * filter[i];
                }
                result[resultOffset - n] = sum;
            }
        }
Exemple #17
0
 /// <summary>
 /// Processes the spectra in matrix xMatrix for prediction.
 /// </summary>
 /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
 /// <param name="xMean">Must be supplied, and will be subtracted from all spectra (if option set).</param>
 /// <param name="xScale">Must be supplied, and will be multiplied to all spectra (if option set).</param>
 /// <param name="regions">Vector of spectal regions. Each element is the index of the start of a new region.</param>
 public override void ProcessForPrediction(IMatrix xMatrix, IROVector xMean, IROVector xScale, int[] regions)
 {
   if(_ensembleMean)
   {
     MatrixMath.SubtractRow(xMatrix, xMean,xMatrix);
   }
   if(_ensembleScale)
   {
     MatrixMath.MultiplyRow(xMatrix,xScale,xMatrix);
   }
 }
Exemple #18
0
    /// <summary>
    /// Processes the spectra in matrix xMatrix for prediction.
    /// </summary>
    /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
    /// <param name="xMean">Not used.</param>
    /// <param name="xScale">Not used.</param>
    /// <param name="regionstart">Starting index of the region.</param>
    /// <param name="regionend">End index of the region (one behind the last region element).</param>
    public void Process(IMatrix xMatrix, IROVector xMean, IROVector xScale, int regionstart, int regionend)
    {
      int regionlength = regionend-regionstart;
      int currentorder = Math.Min(_order,regionlength);

      switch(currentorder)
      {
        case 0: // Detrending of order 0 - subtract mean
          for(int n=0;n<xMatrix.Rows;n++)
          {
            // 1.) Get the mean response of a spectrum
            double mean = 0;
            for(int i=regionstart;i<regionend;i++)
              mean += xMatrix[n,i];
            mean /= regionlength;

            for(int i=regionstart;i<regionend;i++)
              xMatrix[n,i] -= mean;
          }
          break;
        case 1: // Detrending of order 1 - subtract linear regression line
          for(int n=0;n<xMatrix.Rows;n++)
          {
            QuickLinearRegression regression = new QuickLinearRegression();
            for(int i=regionstart;i<regionend;i++)
              regression.Add(i,xMatrix[n,i]);

            double a0 = regression.GetA0();
            double a1 = regression.GetA1();

            for(int i=regionstart;i<regionend;i++)
              xMatrix[n,i] -= (a1*i+a0);
          }
          break;
        case 2: // Detrending of order 2 - subtract quadratic regression line
          for(int n=0;n<xMatrix.Rows;n++)
          {
            QuickQuadraticRegression regression = new QuickQuadraticRegression();
            for(int i=regionstart;i<regionend;i++)
              regression.Add(i,xMatrix[n,i]);

            double a0 = regression.GetA0();
            double a1 = regression.GetA1();
            double a2 = regression.GetA2();

            for(int i=regionstart;i<regionend;i++)
              xMatrix[n,i] -= (((a2*i)+a1)*i+a0);
          }
          break;

        default:
          throw new NotImplementedException(string.Format("Detrending of order {0} is not implemented yet",_order));
      }
    }
Exemple #19
0
        public static void Interpolation(WorksheetController ctrl)
        {
            if (ctrl.SelectedDataColumns.Count == 0)
            {
                return;
            }

            object paramobject = new InterpolationParameters();

            if (!Current.Gui.ShowDialog(ref paramobject, "Interpolation"))
            {
                return;
            }

            InterpolationParameters parameters = (InterpolationParameters)paramobject;


            Altaxo.Data.DataColumn yCol = ctrl.Doc.DataColumns[ctrl.SelectedDataColumns[0]];
            Altaxo.Data.DataColumn xCol = ctrl.Doc.DataColumns.FindXColumnOf(yCol);

            if (!(yCol is INumericColumn))
            {
                Current.Gui.ErrorMessageBox("The selected column is not numeric!");
                return;
            }
            if (!(xCol is INumericColumn))
            {
                Current.Gui.ErrorMessageBox("The x-column of the selected column is not numeric!");
                return;
            }

            int       rows = Math.Min(xCol.Count, yCol.Count);
            IROVector yVec = DataColumnWrapper.ToROVector((INumericColumn)yCol, rows);
            IROVector xVec = DataColumnWrapper.ToROVector((INumericColumn)xCol, rows);

            parameters.InterpolationInstance.Interpolate(xVec, yVec);

            DoubleColumn xRes = new DoubleColumn();
            DoubleColumn yRes = new DoubleColumn();

            for (int i = 0; i < parameters.NumberOfPoints; i++)
            {
                double r = i / (double)(parameters.NumberOfPoints - 1);
                double x = parameters.XOrg * (1 - r) + parameters.XEnd * (r);
                double y = ((IInterpolationFunction)parameters.InterpolationInstance).GetYOfX(x);
                xRes[i] = x;
                yRes[i] = y;
            }

            int newgroup = ctrl.DataTable.DataColumns.GetUnusedColumnGroupNumber();

            ctrl.DataTable.DataColumns.Add(xRes, xCol.Name + ".I", ColumnKind.X, newgroup);
            ctrl.DataTable.DataColumns.Add(yRes, yCol.Name + ".I", ColumnKind.V, newgroup);
        }
        ///// <summary>
        ///// Returns the sum of the elements in the vector.
        ///// </summary>
        ///// <param name="xarray">The vector.</param>
        ///// <returns>The sum of all elements in xarray.</returns>
        public static double Sum(this IROVector xarray)
        {
            double sum = 0;

            for (int i = 0; i < xarray.Length; i++)
            {
                sum += xarray[i];
            }

            return(sum);
        }
Exemple #21
0
    /// <summary>
    /// Processes the spectra in matrix xMatrix for prediction.
    /// </summary>
    /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
    /// <param name="xMean">Not used.</param>
    /// <param name="xScale">Not used.</param>
    /// <param name="regionstart">Starting index of the region to process.</param>
    /// <param name="regionend">End index of the region to process.</param>
    public void ProcessForPrediction(IMatrix xMatrix, IROVector xMean, IROVector xScale, int regionstart, int regionend)
    {
      int regionlength = regionend - regionstart;

      IVector helpervector = VectorMath.ToVector(new double[regionlength]);
      for(int n=0;n<xMatrix.Rows;n++)
      {
        IVector vector = MatrixMath.RowToVector(xMatrix,n,regionstart,regionlength);
        _filter.Apply(vector,helpervector);
        VectorMath.Copy(helpervector,vector);
      }
    }
Exemple #22
0
        /// <summary>
        /// Returns the maximum of the elements in xarray.
        /// </summary>
        /// <param name="xarray">The array to search for maximum element.</param>
        /// <returns>Maximum element of xarray. Returns NaN if the array is empty.</returns>
        public static double Max(IROVector xarray)
        {
            double max = xarray.Length == 0 ? double.NaN : xarray[xarray.LowerBound];

            int last = xarray.UpperBound;

            for (int i = xarray.LowerBound + 1; i <= last; i++)
            {
                max = Math.Max(max, xarray[i]);
            }
            return(max);
        }
        void WriteVector(string name, IROVector col, int numberOfData)
        {
            _writer.WriteStartElement(name);

            for (int i = 0; i < numberOfData; i++)
            {
                _writer.WriteElementString("e", System.Xml.XmlConvert.ToString(col[i]));
            }


            _writer.WriteEndElement(); // name
        }
Exemple #24
0
            public void Append(IROVector <T> vector)
            {
                if (_length + vector.Length >= _arr.Length)
                {
                    Redim((int)(32 + 1.3 * (_length + vector.Length)));
                }

                for (int i = 0; i < vector.Length; i++)
                {
                    _arr[i + _length] = vector[i];
                }
                _length += vector.Length;
            }
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution vector, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception>
        public DoubleVector Solve(IROVector B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Length != order)
                {
                    throw new System.ArgumentException("The length of B must be the same as the order of the matrix.");
                }
#if MANAGED
                // Copy right hand side.
                DoubleVector X = new DoubleVector(B);
                // Solve L*Y = B;
                for (int i = 0; i < order; i++)
                {
                    double sum = B[i];
                    for (int k = i - 1; k >= 0; k--)
                    {
                        sum -= l.data[i][k] * X.data[k];
                    }
                    X.data[i] = sum / l.data[i][i];
                }
                // Solve L'*X = Y;
                for (int i = order - 1; i >= 0; i--)
                {
                    double sum = X.data[i];
                    for (int k = i + 1; k < order; k++)
                    {
                        sum -= l.data[k][i] * X.data[k];
                    }
                    X.data[i] = sum / l.data[i][i];
                }

                return(X);
#else
                double[] rhs = DoubleMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length);
                DoubleVector ret = new DoubleVector(order, B.Length);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Exemple #26
0
            public void Append(IROVector a)
            {
                if (_length + a.Length >= _arr.Length)
                {
                    Redim((int)(32 + 1.3 * (_length + a.Length)));
                }


                for (int i = 0; i < a.Length; i++)
                {
                    _arr[i + _length] = a[i + a.LowerBound];
                }
                _length += a.Length;
            }
Exemple #27
0
        /// <summary>
        /// Processes the spectra in matrix xMatrix according to the set-up options for prediction.
        /// Since it is prediction, the xMean and xScale vectors must be supplied here!
        /// </summary>
        /// <param name="xMatrix">The matrix of spectra. Each spectrum is a row of the matrix.</param>
        /// <param name="xMean">Vector of spectral mean, must be supplied here.</param>
        /// <param name="xScale">Vector of inverse spectral variance, must be supplied here.</param>
        public void ProcessForPrediction(IMatrix xMatrix, IROVector xMean, IROVector xScale)
        {
            GetPreprocessingMethod().ProcessForPrediction(xMatrix, xMean, xScale, _regions);

            if (UseDetrending)
            {
                new DetrendingCorrection(_detrendingOrder).ProcessForPrediction(xMatrix, xMean, xScale, _regions);
            }

            if (EnsembleMeanAfterProcessing || EnsembleScale)
            {
                new EnsembleMeanAndScaleCorrection(EnsembleMeanAfterProcessing, EnsembleScale).ProcessForPrediction(xMatrix, xMean, xScale, _regions);
            }
        }
		private static int FindIndex(IROVector v, bool isDecreasing, int lastIdx, double x)
		{
			if (isDecreasing) // strictly decreasing
			{
				if (x > v[lastIdx])
				{
					if (lastIdx == 0)
						return -1;
					if (x <= v[lastIdx - 1])
						return lastIdx - 1;
					return BinarySearchForIndex(v, isDecreasing, x);
				}
				else if (x < v[lastIdx + 1])
				{
					if (lastIdx + 2 <= v.Length)
						return -1;
					if (x >= v[lastIdx + 2])
						return lastIdx + 1;
					return BinarySearchForIndex(v, isDecreasing, x);
				}
				else
				{
					return lastIdx;
				}
			}
			else // strictly increasing
			{
				if (x < v[lastIdx])
				{
					if (lastIdx == 0)
						return -1;
					if (x >= v[lastIdx - 1])
						return lastIdx - 1;
					return BinarySearchForIndex(v, isDecreasing, x);
				}
				else if (x > v[lastIdx + 1])
				{
					if (lastIdx + 2 >= v.Length)
						return -1;
					if (x <= v[lastIdx + 2])
						return lastIdx + 1;
					return BinarySearchForIndex(v, isDecreasing, x);
				}
				else
				{
					return lastIdx;
				}
			}
		}
            /// <summary>
            /// Constructor, takes a double array for wrapping.
            /// </summary>
            /// <param name="x"></param>
            /// <param name="start">Start index of the section to wrap.</param>
            /// <param name="len">Length of the section to wrap.</param>
            public ROVectorSectionWrapper(IROVector x, int start, int len)
            {
                if (start >= x.Length)
                {
                    throw new ArgumentException("Start of the section is beyond length of the vector");
                }
                if (start + len > x.Length)
                {
                    throw new ArgumentException("End of the section is beyond length of the vector");
                }

                _x      = x;
                _start  = start;
                _length = len;
            }
Exemple #30
0
        /// <summary>
        /// Returns the sum of squared differences of the elements of xarray and yarray.
        /// </summary>
        /// <param name="xarray">The first array.</param>
        /// <param name="yarray">The other array.</param>
        /// <returns>The sum of squared differences all elements of xarray and yarray.</returns>
        public static double SumOfSquaredDifferences(IROVector xarray, IROVector yarray)
        {
            if (xarray.Length != yarray.Length)
            {
                throw new ArgumentException("Length of xarray is unequal length of yarray");
            }

            double sum = 0;

            for (int i = 0; i < xarray.Length; i++)
            {
                sum += Square(xarray[i] - yarray[i]);
            }

            return(sum);
        }
Exemple #31
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution vector, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="SingularMatrixException">A is singular.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception>
        public DoubleVector Solve(IROVector B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (singular)
            {
                throw new SingularMatrixException();
            }
            else
            {
                if (B.Length != order)
                {
                    throw new System.ArgumentException("The length of B must be the same as the order of the matrix.");
                }
#if MANAGED
                // Copy right hand side with pivoting
                DoubleVector X = Pivot(B);

                // Solve L*Y = B(piv,:)
                for (int k = 0; k < order; k++)
                {
                    for (int i = k + 1; i < order; i++)
                    {
                        X[i] -= X[k] * factor[i][k];
                    }
                }
                // Solve U*X = Y;
                for (int k = order - 1; k >= 0; k--)
                {
                    X[k] /= factor[k][k];
                    for (int i = 0; i < k; i++)
                    {
                        X[i] -= X[k] * factor[i][k];
                    }
                }
                return(X);
#else
                double[] rhs = DoubleMatrix.ToLinearArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, 1, factor, order, pivots, rhs, rhs.Length);
                return(new DoubleVector(rhs));
#endif
            }
        }
Exemple #32
0
		public static double Nrd0(IROVector x)
		{
			if (x.Length < 2) throw new ArgumentException("need at least 2 data points");

			double hi = Statistics.StandardDeviation(x);
			double lo = Math.Min(hi, Statistics.InterQuartileRange(x) / 1.34);  // qnorm(.75) - qnorm(.25) = 1.34898
			if (lo.IsNaN())
			{
				lo = hi;
				if (lo.IsNaN())
				{
					lo = Math.Abs(x[0]);
					if (lo.IsNaN())
						lo = 1;
				}
			}

			return 0.9 * lo * Math.Pow(x.Length, (-0.2));
		}
Exemple #33
0
    /// <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="regionstart">Starting index of the region to process.</param>
    /// <param name="regionend">End index of the region to process.</param>
    void ProcessForPrediction(IMatrix xMatrix, IROVector xMean, IROVector xScale, int regionstart, int regionend)
    {
      int regionlength = regionend - regionstart;

      for(int n=0;n<xMatrix.Rows;n++)
      {
        // 2.) Do linear regression of the current spectrum versus the mean spectrum
        QuickLinearRegression regression = new QuickLinearRegression();
        for(int i=regionstart;i<regionend;i++)
          regression.Add(xMean[i],xMatrix[n,i]);

        double intercept = regression.GetA0();
        double slope = regression.GetA1();

        // 3.) Subtract intercept and divide by slope
        for(int i=regionstart;i<regionend;i++)
          xMatrix[n,i] = (xMatrix[n,i]-intercept)/slope;
      }
    }
Exemple #34
0
 ///<summary>Constructor for <c>DoubleVector</c> to deep copy from a <see cref="IROVector" /></summary>
 ///<param name="src"><c>Vector</c> to deep copy into <c>DoubleVector</c>.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null passed as 'src' parameter.</exception>
 public DoubleVector(IROVector src)
 {
     if (src == null)
     {
         throw new ArgumentNullException("IROVector cannot be null");
     }
     if (src is DoubleVector)
     {
         data = (double[])(((DoubleVector)src).data.Clone());
     }
     else
     {
         data = new double[src.Length];
         for (int i = 0; i < src.Length; ++i)
         {
             data[i] = src[i];
         }
     }
 }
Exemple #35
0
        /// <summary>
        /// Trys to identify spectral regions by supplying the spectral x values.
        /// A end_of_region is recognized when the gap between two x-values is ten times higher
        /// than the previous gap, or if the sign of the gap value changes.
        /// This method fails if a spectral region contains only a single point (since no gap value can be obtained then).
        /// (But in this case almost all spectral correction methods also fails).
        /// </summary>
        /// <param name="xvalues">The vector of x values for the spectra (wavelength, frequencies...).</param>
        /// <returns>The array of regions. Each element in the array is the starting index of a new region into the vector xvalues.</returns>
        public static int[] IdentifyRegions(IROVector xvalues)
        {
            System.Collections.ArrayList list = new System.Collections.ArrayList();

            int len = xvalues.Length;

            for (int i = 0; i < len - 2; i++)
            {
                double gap     = Math.Abs(xvalues[i + 1] - xvalues[i]);
                double nextgap = Math.Abs(xvalues[i + 2] - xvalues[i + 1]);
                if (gap != 0 && (Math.Sign(gap) == -Math.Sign(nextgap) || Math.Abs(nextgap) > 10 * Math.Abs(gap)))
                {
                    list.Add(i + 2);
                    i++;
                }
            }

            return((int[])list.ToArray(typeof(int)));
        }
Exemple #36
0
		/// <summary>
		/// Constructs an Akima bivariate spline.
		/// </summary>
		/// <param name="x">ARRAY OF DIMENSION LX STORING THE X COORDINATES OF INPUT GRID POINTS (IN ASCENDING ORDER)</param>
		/// <param name="y">ARRAY OF DIMENSION LY STORING THE Y COORDINATES OF INPUT GRID POINTS (IN ASCENDING ORDER)</param>
		/// <param name="z">DOUBLY-DIMENSIONED ARRAY OF DIMENSION (LX,LY) STORING THE VALUES OF THE FUNCTION (Z VALUES) AT INPUT GRID POINTS</param>
		/// <param name="copyDataLocally">If true, the data where cloned before stored here in this instance. If false, the data
		/// are stored directly. Make sure then, that the data are not changed outside.</param>
		public BivariateAkimaSpline(IROVector x, IROVector y, IROMatrix z, bool copyDataLocally)
		{
			if (copyDataLocally)
			{
				_myX = VectorMath.ToVector(new double[x.Length]);
				VectorMath.Copy(x, (IVector)_myX);

				_myY = VectorMath.ToVector(new double[y.Length]);
				VectorMath.Copy(y, (IVector)_myY);

				_myZ = new MatrixMath.BEMatrix(_myZ.Rows, _myZ.Columns);
				MatrixMath.Copy(z, (IMatrix)_myZ);
			}
			else
			{
				_myX = x;
				_myY = y;
				_myZ = z;
			}
		}
Exemple #37
0
        /// <summary>
        /// Constructs an Akima bivariate spline.
        /// </summary>
        /// <param name="x">ARRAY OF DIMENSION LX STORING THE X COORDINATES OF INPUT GRID POINTS (IN ASCENDING ORDER)</param>
        /// <param name="y">ARRAY OF DIMENSION LY STORING THE Y COORDINATES OF INPUT GRID POINTS (IN ASCENDING ORDER)</param>
        /// <param name="z">DOUBLY-DIMENSIONED ARRAY OF DIMENSION (LX,LY) STORING THE VALUES OF THE FUNCTION (Z VALUES) AT INPUT GRID POINTS</param>
        /// <param name="copyDataLocally">If true, the data where cloned before stored here in this instance. If false, the data
        /// are stored directly. Make sure then, that the data are not changed outside.</param>
        public BivariateAkimaSpline(IROVector x, IROVector y, IROMatrix z, bool copyDataLocally)
        {
            if (copyDataLocally)
            {
                _myX = VectorMath.ToVector(new double[x.Length]);
                VectorMath.Copy(x, (IVector)_myX);

                _myY = VectorMath.ToVector(new double[y.Length]);
                VectorMath.Copy(y, (IVector)_myY);

                _myZ = new MatrixMath.BEMatrix(_myZ.Rows, _myZ.Columns);
                MatrixMath.Copy(z, (IMatrix)_myZ);
            }
            else
            {
                _myX = x;
                _myY = y;
                _myZ = z;
            }
        }
Exemple #38
0
    /// <summary>
    /// Copies the source vector to the destination vector. Both vectors must have the same length.
    /// </summary>
    /// <param name="src">The source vector.</param>
    /// <param name="dest">The destination vector.</param>
    public static void Copy(IROVector src, IVector dest)
    {
      if(src.Length!=dest.Length)
        throw new ArgumentException("src and destination vector have unequal length!");

      Copy(src,src.LowerBound,dest,dest.LowerBound,src.Length);
    }
Exemple #39
0
 /// <summary>
 /// Copies elements of a source vector to a destination vector.
 /// </summary>
 /// <param name="src">The source vector.</param>
 /// <param name="srcstart">First element of the source vector to copy.</param>
 /// <param name="dest">The destination vector.</param>
 /// <param name="deststart">First element of the destination vector to copy to.</param>
 /// <param name="count">Number of elements to copy.</param>
 public static void Copy(IROVector src, int srcstart, IVector dest, int deststart, int count)
 {
   for(int i=0;i<count;i++)
     dest[i+deststart] = src[i+srcstart];
 }
Exemple #40
0
      public void Append(IROVector a)
      {
        if(_length+a.Length>=_arr.Length)
          Redim((int)(32+1.3*(_length+a.Length)));


        for(int i=0;i<a.Length;i++)
          _arr[i+_length] = a[i+a.LowerBound];
        _length += a.Length;
      }
Exemple #41
0
 /// <summary>
 /// Wraps a section of a original vector <c>x</c> into a new vector.
 /// </summary>
 /// <param name="x">Original vector.</param>
 /// <param name="start">Index of the start of the section to wrap.</param>
 /// <param name="len">Length (=number of elements) of the section to wrap.</param>
 /// <returns>A IROVector that contains the section from <c>start</c> to <c>start+len-1</c> of the original vector.</returns>
 public static IROVector ToROVector(IROVector x, int start, int len)
 {
   return new ROVectorSectionWrapper(x, start, len);
 }
Exemple #42
0
		/// <summary>
		/// Execute an analysis and stores the result in the provided table.
		/// </summary>
		/// <param name="matrixX">The matrix of spectra (horizontal oriented), centered and preprocessed.</param>
		/// <param name="matrixY">The matrix of concentrations, centered.</param>
		/// <param name="plsOptions">Information how to perform the analysis.</param>
		/// <param name="plsContent">A structure to store information about the results of the analysis.</param>
		/// <param name="table">The table where to store the results to.</param>
		/// <param name="press">On return, gives a vector holding the PRESS values of the analysis.</param>
		public virtual void ExecuteAnalysis(
			IMatrix matrixX,
			IMatrix matrixY,
			MultivariateAnalysisOptions plsOptions,
			MultivariateContentMemento plsContent,
			DataTable table,
			out IROVector press
			)
		{
			int numFactors = Math.Min(matrixX.Columns, plsOptions.MaxNumberOfFactors);
			MultivariateRegression regress = this.CreateNewRegressionObject();
			regress.AnalyzeFromPreprocessed(matrixX, matrixY, numFactors);
			plsContent.NumberOfFactors = regress.NumberOfFactors;
			plsContent.CrossValidationType = plsOptions.CrossPRESSCalculation;
			press = regress.GetPRESSFromPreprocessed(matrixX);

			Import(regress.CalibrationModel, table);
		}
Exemple #43
0
		public virtual void StorePreprocessedData(
			IROVector meanX, IROVector scaleX,
			IROVector meanY, IROVector scaleY,
			DataTable table)
		{
			// Store X-Mean and X-Scale
			Altaxo.Data.DoubleColumn colXMean = new Altaxo.Data.DoubleColumn();
			Altaxo.Data.DoubleColumn colXScale = new Altaxo.Data.DoubleColumn();

			for (int i = 0; i < meanX.Length; i++)
			{
				colXMean[i] = meanX[i];
				colXScale[i] = scaleX[i];
			}

			table.DataColumns.Add(colXMean, _XMean_ColumnName, Altaxo.Data.ColumnKind.V, 0);
			table.DataColumns.Add(colXScale, _XScale_ColumnName, Altaxo.Data.ColumnKind.V, 0);

			// store the y-mean and y-scale
			Altaxo.Data.DoubleColumn colYMean = new Altaxo.Data.DoubleColumn();
			Altaxo.Data.DoubleColumn colYScale = new Altaxo.Data.DoubleColumn();

			for (int i = 0; i < meanY.Length; i++)
			{
				colYMean[i] = meanY[i];
				colYScale[i] = 1;
			}

			table.DataColumns.Add(colYMean, _YMean_ColumnName, Altaxo.Data.ColumnKind.V, 1);
			table.DataColumns.Add(colYScale, _YScale_ColumnName, Altaxo.Data.ColumnKind.V, 1);
		}
Exemple #44
0
		/// <summary>
		/// Resizes the vector to the same boundaries as the provided vector and copies the elements from it.
		/// </summary>
		/// <param name="a">The vector to copy the data from.</param>
		public void CopyFrom(IROVector a)
		{
			if (object.ReferenceEquals(this, a))
				return;

			Resize(a.Length);
			for (int i = 0; i < data.Length; ++i)
				data[i] = a[i];
		}
Exemple #45
0
    /// <summary>
    /// Returns the sum of squared differences of the elements of xarray and yarray.
    /// </summary>
    /// <param name="xarray">The first array.</param>
    /// <param name="yarray">The other array.</param>
    /// <returns>The sum of squared differences all elements of xarray and yarray.</returns>
    public static double SumOfSquaredDifferences(IROVector xarray, IROVector yarray)
    {
      if(xarray.Length!=yarray.Length)
        throw new ArgumentException("Length of xarray is unequal length of yarray");

      double sum = 0;
      for(int i=0;i<xarray.Length;i++)
        sum += Square(xarray[i]-yarray[i]);

      return sum;
    }
Exemple #46
0
		/// <summary>
		/// This maps the indices of a master x column to the indices of a column to map.
		/// </summary>
		/// <param name="xmaster">The master column containing x-values, for instance the spectral wavelength of the PLS calibration model.</param>
		/// <param name="xtomap">The column to map containing x-values, for instance the spectral wavelength of an unknown spectra to predict.</param>
		/// <param name="failureMessage">In case of a mapping error, contains detailed information about the error.</param>
		/// <returns>The indices of the mapping column that matches those of the master column. Contains as many indices as items in xmaster. In case of mapping error, returns null.</returns>
		public static Altaxo.Collections.AscendingIntegerCollection MapSpectralX(IROVector xmaster, IROVector xtomap, out string failureMessage)
		{
			failureMessage = null;
			int mastercount = xmaster.Length;

			int mapcount = xtomap.Length;

			if (mapcount < mastercount)
			{
				failureMessage = string.Format("More items to map ({0} than available ({1}", mastercount, mapcount);
				return null;
			}

			Altaxo.Collections.AscendingIntegerCollection result = new Altaxo.Collections.AscendingIntegerCollection();
			// return an empty collection if there is nothing to map
			if (mastercount == 0)
				return result;

			// there is only one item to map - we can not check this - return a 1:1 map
			if (mastercount == 1)
			{
				result.Add(0);
				return result;
			}

			// presumtion here (checked before): mastercount>=2, mapcount>=1

			double distanceback, distancecurrent, distanceforward;
			int i, j;
			for (i = 0, j = 0; i < mastercount && j < mapcount; j++)
			{
				distanceback = j == 0 ? double.MaxValue : Math.Abs(xtomap[j - 1] - xmaster[i]);
				distancecurrent = Math.Abs(xtomap[j] - xmaster[i]);
				distanceforward = (j + 1) >= mapcount ? double.MaxValue : Math.Abs(xtomap[j + 1] - xmaster[i]);

				if (distanceback < distancecurrent)
				{
					failureMessage = string.Format("Mapping error - distance of master[{0}] to current map[{1}] is greater than to previous map[{2}]", i, j, j - 1);
					return null;
				}
				else if (distanceforward < distancecurrent)
					continue;
				else
				{
					result.Add(j);
					i++;
				}
			}

			if (i != mastercount)
			{
				failureMessage = string.Format("Mapping error- no mapping found for current master[{0}]", i - 1);
				return null;
			}

			return result;
		}
Exemple #47
0
		public static void Interpolation(Altaxo.Data.DataColumn xCol, Altaxo.Data.DataColumn yCol,
			Calc.Interpolation.IInterpolationFunction interpolInstance, IROVector samplePoints,
			Altaxo.Data.DataColumn xRes, Altaxo.Data.DataColumn yRes)
		{
			int rows = Math.Min(xCol.Count, yCol.Count);
			IROVector yVec = DataColumnWrapper.ToROVector((INumericColumn)yCol, rows);
			IROVector xVec = DataColumnWrapper.ToROVector((INumericColumn)xCol, rows);

			interpolInstance.Interpolate(xVec, yVec);

			using (var suspendToken_xRes = xRes.SuspendGetToken())
			{
				using (var suspendToken_yRes = yRes.SuspendGetToken())
				{
					for (int i = 0; i < samplePoints.Length; i++)
					{
						//double r = i / (double)(parameters.NumberOfPoints - 1);
						//double x = parameters.XOrg * (1 - r) + parameters.XEnd * (r);
						double x = samplePoints[i];
						double y = interpolInstance.GetYOfX(x);
						xRes[i] = x;
						yRes[i] = y;
					}
					suspendToken_yRes.Resume();
				}
				suspendToken_xRes.Resume();
			}
		}
Exemple #48
0
		/// <summary>
		/// Get the matrix of x and y values (raw data).
		/// </summary>
		/// <param name="srctable">The table where the data come from.</param>
		/// <param name="selectedColumns">The selected columns.</param>
		/// <param name="selectedRows">The selected rows.</param>
		/// <param name="selectedPropertyColumns">The selected property column(s).</param>
		/// <param name="bHorizontalOrientedSpectrum">True if a spectrum is a single row, False if a spectrum is a single column.</param>
		/// <param name="matrixX">On return, gives the matrix of spectra (each spectra is a row in the matrix).</param>
		/// <param name="matrixY">On return, gives the matrix of y-values (each measurement is a row in the matrix).</param>
		/// <param name="plsContent">Holds information about the analysis results.</param>
		/// <param name="xOfX">On return, this is the vector of values corresponding to each spectral bin, i.e. wavelength values, frequencies etc.</param>
		/// <returns></returns>
		public static string GetXYMatrices(
			Altaxo.Data.DataTable srctable,
			IAscendingIntegerCollection selectedColumns,
			IAscendingIntegerCollection selectedRows,
			IAscendingIntegerCollection selectedPropertyColumns,
			bool bHorizontalOrientedSpectrum,
			MultivariateContentMemento plsContent,
			out IMatrix matrixX,
			out IMatrix matrixY,
			out IROVector xOfX
			)
		{
			matrixX = null;
			matrixY = null;
			xOfX = null;
			plsContent.SpectrumIsRow = bHorizontalOrientedSpectrum;

			Altaxo.Data.DataColumn xColumnOfX = null;
			Altaxo.Data.DataColumn labelColumnOfX = new Altaxo.Data.DoubleColumn();

			Altaxo.Data.DataColumnCollection concentration = bHorizontalOrientedSpectrum ? srctable.DataColumns : srctable.PropertyColumns;

			// we presume for now that the spectrum is horizontally,
			// if not we exchange the collections later

			AscendingIntegerCollection numericDataCols = new AscendingIntegerCollection();
			AscendingIntegerCollection numericDataRows = new AscendingIntegerCollection();
			AscendingIntegerCollection concentrationIndices = new AscendingIntegerCollection();

			AscendingIntegerCollection spectralIndices = bHorizontalOrientedSpectrum ? numericDataCols : numericDataRows;
			AscendingIntegerCollection measurementIndices = bHorizontalOrientedSpectrum ? numericDataRows : numericDataCols;

			plsContent.ConcentrationIndices = concentrationIndices;
			plsContent.MeasurementIndices = measurementIndices;
			plsContent.SpectralIndices = spectralIndices;
			plsContent.SpectrumIsRow = bHorizontalOrientedSpectrum;
			plsContent.OriginalDataTableName = srctable.Name;

			bool bUseSelectedColumns = (null != selectedColumns && 0 != selectedColumns.Count);
			// this is the number of columns (for now), but it can be less than this in case
			// not all columns are numeric
			int prenumcols = bUseSelectedColumns ? selectedColumns.Count : srctable.DataColumns.ColumnCount;
			// check for the number of numeric columns
			int numcols = 0;
			for (int i = 0; i < prenumcols; i++)
			{
				int idx = bUseSelectedColumns ? selectedColumns[i] : i;
				if (srctable[idx] is Altaxo.Data.INumericColumn)
				{
					numericDataCols.Add(idx);
					numcols++;
				}
			}

			// check the number of rows
			bool bUseSelectedRows = (null != selectedRows && 0 != selectedRows.Count);
			int numrows;
			if (bUseSelectedRows)
			{
				numrows = selectedRows.Count;
				numericDataRows.Add(selectedRows);
			}
			else
			{
				numrows = 0;
				for (int i = 0; i < numcols; i++)
				{
					int idx = bUseSelectedColumns ? selectedColumns[i] : i;
					numrows = Math.Max(numrows, srctable[idx].Count);
				}
				numericDataRows.Add(ContiguousIntegerRange.FromStartAndCount(0, numrows));
			}

			if (bHorizontalOrientedSpectrum)
			{
				if (numcols < 2)
					return "At least two numeric columns are neccessary to do Partial Least Squares (PLS) analysis!";

				// check that the selected columns are in exactly two groups
				// the group which has more columns is then considered to have
				// the spectrum, the other group is the y-values
				int group0 = -1;
				int group1 = -1;
				int groupcount0 = 0;
				int groupcount1 = 0;

				for (int i = 0; i < numcols; i++)
				{
					int grp = srctable.DataColumns.GetColumnGroup(numericDataCols[i]);

					if (group0 < 0)
					{
						group0 = grp;
						groupcount0 = 1;
					}
					else if (group0 == grp)
					{
						groupcount0++;
					}
					else if (group1 < 0)
					{
						group1 = grp;
						groupcount1 = 1;
					}
					else if (group1 == grp)
					{
						groupcount1++;
					}
					else
					{
						return "The columns you selected must be members of two groups (y-values and spectrum), but actually there are more than two groups!";
					}
				} // end for all columns

				if (groupcount1 <= 0)
					return "The columns you selected must be members of two groups (y-values and spectrum), but actually only one group was detected!";

				if (groupcount1 < groupcount0)
				{
					int hlp;
					hlp = groupcount1;
					groupcount1 = groupcount0;
					groupcount0 = hlp;

					hlp = group1;
					group1 = group0;
					group0 = hlp;
				}

				// group0 is now the group of y-values (concentrations)
				// group1 is now the group of x-values (spectra)

				// we delete group0 from numericDataCols and add it to concentrationIndices

				for (int i = numcols - 1; i >= 0; i--)
				{
					int index = numericDataCols[i];
					if (group0 == srctable.DataColumns.GetColumnGroup(index))
					{
						numericDataCols.Remove(index);
						concentrationIndices.Add(index);
					}
				}

				// fill the corresponding X-Column of the spectra
				xColumnOfX = Altaxo.Data.DataColumn.CreateColumnOfSelectedRows(
					srctable.PropertyColumns.FindXColumnOfGroup(group1),
					spectralIndices);
			}
			else // vertically oriented spectrum -> one spectrum is one data column
			{
				// we have to exchange measurementIndices and

				// if PLS on columns, than we should have property columns selected
				// that designates the y-values
				// so count all property columns

				bool bUseSelectedPropCols = (null != selectedPropertyColumns && 0 != selectedPropertyColumns.Count);
				// this is the number of property columns (for now), but it can be less than this in case
				// not all columns are numeric
				int prenumpropcols = bUseSelectedPropCols ? selectedPropertyColumns.Count : srctable.PropCols.ColumnCount;
				// check for the number of numeric property columns
				for (int i = 0; i < prenumpropcols; i++)
				{
					int idx = bUseSelectedPropCols ? selectedPropertyColumns[i] : i;
					if (srctable.PropCols[idx] is Altaxo.Data.INumericColumn)
					{
						concentrationIndices.Add(idx);
					}
				}

				if (concentrationIndices.Count < 1)
					return "At least one numeric property column must exist to hold the y-values!";

				// fill the corresponding X-Column of the spectra
				xColumnOfX = Altaxo.Data.DataColumn.CreateColumnOfSelectedRows(
					srctable.DataColumns.FindXColumnOf(srctable[measurementIndices[0]]), spectralIndices);
			} // else vertically oriented spectrum

			IVector xOfXRW = VectorMath.CreateExtensibleVector(xColumnOfX.Count);
			xOfX = xOfXRW;
			if (xColumnOfX is INumericColumn)
			{
				for (int i = 0; i < xOfX.Length; i++)
					xOfXRW[i] = ((INumericColumn)xColumnOfX)[i];
			}
			else
			{
				for (int i = 0; i < xOfX.Length; i++)
					xOfXRW[i] = spectralIndices[i];
			}

			// now fill the matrix

			// fill in the y-values
			matrixY = new MatrixMath.BEMatrix(measurementIndices.Count, concentrationIndices.Count);
			for (int i = 0; i < concentrationIndices.Count; i++)
			{
				Altaxo.Data.INumericColumn col = concentration[concentrationIndices[i]] as Altaxo.Data.INumericColumn;
				for (int j = 0; j < measurementIndices.Count; j++)
				{
					matrixY[j, i] = col[measurementIndices[j]];
				}
			} // end fill in yvalues

			matrixX = new MatrixMath.BEMatrix(measurementIndices.Count, spectralIndices.Count);
			if (bHorizontalOrientedSpectrum)
			{
				for (int i = 0; i < spectralIndices.Count; i++)
				{
					labelColumnOfX[i] = spectralIndices[i];
					Altaxo.Data.INumericColumn col = srctable[spectralIndices[i]] as Altaxo.Data.INumericColumn;
					for (int j = 0; j < measurementIndices.Count; j++)
					{
						matrixX[j, i] = col[measurementIndices[j]];
					}
				} // end fill in x-values
			}
			else // vertical oriented spectrum
			{
				for (int i = 0; i < spectralIndices.Count; i++)
				{
					labelColumnOfX[i] = spectralIndices[i];
				}
				for (int i = 0; i < measurementIndices.Count; i++)
				{
					Altaxo.Data.INumericColumn col = srctable[measurementIndices[i]] as Altaxo.Data.INumericColumn;
					for (int j = 0; j < spectralIndices.Count; j++)
					{
						matrixX[i, j] = col[spectralIndices[j]];
					}
				} // end fill in x-values
			}

			return null;
		}
Exemple #49
0
		/// <summary>
		///
		/// </summary>
		/// <param name="mcalib"></param>
		/// <param name="groupingStrategy"></param>
		/// <param name="preprocessOptions"></param>
		/// <param name="xOfX"></param>
		/// <param name="matrixX">Matrix of horizontal spectra, centered and preprocessed.</param>
		/// <param name="matrixY">Matrix of concentrations, centered.</param>
		/// <param name="numberOfFactors"></param>
		/// <param name="predictedY"></param>
		/// <param name="spectralResiduals"></param>
		public virtual void CalculateCrossPredictedY(
			IMultivariateCalibrationModel mcalib,
			ICrossValidationGroupingStrategy groupingStrategy,
			SpectralPreprocessingOptions preprocessOptions,
			IROVector xOfX,
			IMatrix matrixX,
			IMatrix matrixY,
			int numberOfFactors,
			IMatrix predictedY,
			IMatrix spectralResiduals)
		{
			MultivariateRegression.GetCrossYPredicted(xOfX,
				matrixX, matrixY, numberOfFactors, groupingStrategy, preprocessOptions,
				this.CreateNewRegressionObject(),
				predictedY);
		}
Exemple #50
0
		/// <summary>
		/// Calculate the cross PRESS values and stores the results in the provided table.
		/// </summary>
		/// <param name="xOfX">Vector of spectral wavelengths. Necessary to divide the spectras in different regions.</param>
		/// <param name="matrixX">Matrix of spectra (horizontal oriented).</param>
		/// <param name="matrixY">Matrix of concentrations.</param>
		/// <param name="plsOptions">Analysis options.</param>
		/// <param name="plsContent">Information about this analysis.</param>
		/// <param name="table">Table to store the results.</param>
		public virtual void CalculateCrossPRESS(
			IROVector xOfX,
			IMatrix matrixX,
			IMatrix matrixY,
			MultivariateAnalysisOptions plsOptions,
			MultivariateContentMemento plsContent,
			DataTable table
			)
		{
			IROVector crossPRESSMatrix;

			Altaxo.Data.DoubleColumn crosspresscol = new Altaxo.Data.DoubleColumn();

			double meanNumberOfExcludedSpectra = 0;
			if (plsOptions.CrossPRESSCalculation != CrossPRESSCalculationType.None)
			{
				// now a cross validation - this can take a long time for bigger matrices

				MultivariateRegression.GetCrossPRESS(
					xOfX, matrixX, matrixY, plsOptions.MaxNumberOfFactors, GetGroupingStrategy(plsOptions),
					plsContent.SpectralPreprocessing,
					this.CreateNewRegressionObject(),
					out crossPRESSMatrix);

				VectorMath.Copy(crossPRESSMatrix, DataColumnWrapper.ToVector(crosspresscol, crossPRESSMatrix.Length));

				table.DataColumns.Add(crosspresscol, GetCrossPRESSValue_ColumnName(), Altaxo.Data.ColumnKind.V, 4);

				plsContent.MeanNumberOfMeasurementsInCrossPRESSCalculation = plsContent.NumberOfMeasurements - meanNumberOfExcludedSpectra;
			}
			else
			{
				table.DataColumns.Add(crosspresscol, GetCrossPRESSValue_ColumnName(), Altaxo.Data.ColumnKind.V, 4);
			}
		}
Exemple #51
0
    /// <summary>
    /// Adds (elementwise) two vectors a and b and stores the result in c. All vectors must have the same length.
    /// </summary>
    /// <param name="a">First summand.</param>
    /// <param name="b">Second summand.</param>
    /// <param name="c">The resulting vector.</param>
    public static void Add(IROVector a, IROVector b, IVector c)
    {
      if(a.Length != b.Length)
        throw new ArgumentException("Length of vectors a and b unequal");
      if(c.Length != b.Length)
        throw new ArgumentException("Length of vectors a and c unequal");
      if(a.LowerBound != b.LowerBound || a.LowerBound != c.LowerBound)
        throw new ArgumentException("Vectors a, b, and c have not the same LowerBound property");

      int end = c.UpperBound;
      for(int i=c.LowerBound;i<=end;i++)
        c[i]=a[i]+b[i];
    }
Exemple #52
0
		public virtual void StoreXOfX(IROVector xOfX, DataTable table)
		{
			DoubleColumn xColOfX = new DoubleColumn();
			VectorMath.Copy(xOfX, DataColumnWrapper.ToVector(xColOfX, xOfX.Length));
			table.DataColumns.Add(xColOfX, _XOfX_ColumnName, Altaxo.Data.ColumnKind.X, 0);
		}
Exemple #53
0
    /// <summary>
    /// Returns the maximum of the elements in xarray.
    /// </summary>
    /// <param name="xarray">The array to search for maximum element.</param>
    /// <returns>Maximum element of xarray. Returns NaN if the array is empty.</returns>
    public static double Max(IROVector xarray)
    {
      double max = xarray.Length==0 ? double.NaN : xarray[xarray.LowerBound];

      int last = xarray.UpperBound;
      for(int i=xarray.LowerBound+1;i<=last;i++)
      {
        max = Math.Max(max,xarray[i]);
      }
      return max;
    }
		public void SetErrorVariance(IROVector dyy, double errvar)
		{
			dy.CopyFrom(dyy);
			var = errvar;
		}
Exemple #55
0
		///<summary>Constructor for <c>DoubleVector</c> to deep copy from a <see cref="IROVector" /></summary>
		///<param name="src"><c>Vector</c> to deep copy into <c>DoubleVector</c>.</param>
		///<exception cref="ArgumentNullException">Exception thrown if null passed as 'src' parameter.</exception>
		public DoubleVector(IROVector src)
		{
			if (src == null)
			{
				throw new ArgumentNullException("IROVector cannot be null");
			}
			if (src is DoubleVector)
			{
				data = (double[])(((DoubleVector)src).data.Clone());
			}
			else
			{
				data = new double[src.Length];
				for (int i = 0; i < src.Length; ++i)
				{
					data[i] = src[i];
				}
			}
		}
Exemple #56
0
		public virtual void StorePRESSData(
			IROVector PRESS,
			DataTable table)
		{
			StoreNumberOfFactors(PRESS.Length, table);

			Altaxo.Data.DoubleColumn presscol = new Altaxo.Data.DoubleColumn();
			for (int i = 0; i < PRESS.Length; i++)
				presscol[i] = PRESS[i];
			table.DataColumns.Add(presscol, GetPRESSValue_ColumnName(), Altaxo.Data.ColumnKind.V, 4);
		}
 /// <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 virtual void ProcessForPrediction(IMatrix xMatrix, IROVector xMean, IROVector xScale, int[] regions)
 {
 }
Exemple #58
0
 /// <summary>
 /// Constructor, takes a double array for wrapping.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="start">Start index of the section to wrap.</param>
 /// <param name="len">Length of the section to wrap.</param>
 public ROVectorSectionWrapper(IROVector x, int start, int len)
 {
   if(start>=x.Length)
     throw new ArgumentException("Start of the section is beyond length of the vector");
  if (start+len>=x.Length)
     throw new ArgumentException("End of the section is beyond length of the vector");
  
   _x = x;
   _start = start;
   _length = len;
 }
		//----------------------------------------------------------------------------//
		//
		// int MpCrossValidatedSpline (const Vector &X,
		//                             const Vector &F,
		//                             Vector &DF,
		//             Vector &Y, Vector &C1, Vector &C2, Vector &C3,
		//             double& var, Vector &SE, Vector &WK)
		//
		//  Arguments:
		//
		//              X   Vector of length n containing the abscissae of the
		//        n data points (x[i],f[i]).
		//        x must be ordered so that x[i] < x[i+1].
		//
		//    F   Vector of length n containing the ordinates
		//        of the n data points (x[i],f[i]).
		//
		//             DF   Vector df[i] is the relative standard
		//        deviation of the error associated with data point i.
		//                  Each df[i] must be positive. The values in df are
		//        scaled by the subroutine so that their mean square
		//        value is 1, and unscaled again on normal exit.
		//                  The mean square value of the df[i] is returned in
		//        wk[6] on normal exit.
		//                  If the absolute standard deviations are known,
		//                  these should be provided in df and the error
		//                  variance parameter var (see below) should then be
		//                  set to 1.
		//                  If the relative standard deviations are unknown,
		//                  set each df[i]=1.
		//
		//     Y,C1,C2,C3   Spline coefficient arrays of length n. (output)
		//        The value of the spline approximation at t is
		//
		//                    s(t) = ((c3[i]*d+c2[i])*d+c1[i])*d+y[i]
		//
		//                  where x[i] <= t < x[i+1] and d = t-x[i].
		//
		//        That means
		//       y[i]  contains the function value y(x[i])
		//       c1[i] contains the 1st derivative y'(x[i])
		//       c2[i] contains the 2nd derivative y''(x[i])
		//        of the smoothing spline.
		//
		//            var   Error variance. (input/output)
		//                  If var is negative (i.e. unknown) then
		//                  the smoothing parameter is determined
		//                  by minimizing the generalized cross validation
		//                  and an estimate of the error variance is returned in var.
		//                  If var is non-negative (i.e. known) then the
		//                  smoothing parameter is determined to minimize
		//                  an estimate, which depends on var, of the true
		//                  mean square error, and var is unchanged.
		//                  In particular, if var is zero, then an
		//                  interpolating natural cubic spline is calculated.
		//                  var should be set to 1 if absolute standard
		//                  deviations have been provided in df (see above).
		//
		//            SE    Vector se of length n returning Bayesian standard
		//                  error estimates of the fitted spline values in y.
		//                  If a NullVector is passed to the subroutine
		//        then no standard error estimates are computed.
		//
		//            WK    Work vector of length 7*(n+2)+1, arbitrary offset.
		//                  On normal exit the first 7 values of wk are assigned
		//                  as follows:
		//
		//                  ( here we arbitrarily start numbering from 0)
		//
		//                  wk[0] = smoothing parameter = rho/(rho+1)
		//                      If w[1]=0 (rho=0) an interpolating natural
		//          cubic spline has been calculated.
		//                          If wk[1]=1 (rho=infinite) a least squares
		//                           regression line has been calculated.
		//                  wk[1] = estimate of the number of degrees of
		//                          freedom of the residual sum of squares
		//                          which reduces to the usual value of n-2
		//                when a least squares regression line
		//                is calculated.
		//                  wk[2] = generalized cross validation
		//                  wk[3] = mean square residual
		//                  wk[4] = estimate of the true mean square error
		//                          at the data points
		//                  wk[5] = estimate of the error variance
		//                          wk[6] coincides with the output value of
		//          var if var is negative on input. It is
		//                calculated with the unscaled values of the
		//          df[i] to facilitate comparisons with a
		//          priori variance estimates.
		//                  wk[6] = mean square value of the df[i]
		//
		//                  wk[2],wk[3],wk[4] are calculated with the df[i]
		//                  scaled to have mean square value 1. The unscaled
		//        values of wk[2],wk[3],wk[4] may be calculated by
		//        dividing by wk[6].
		//
		//  Return value:
		//        = 0  if no errors occured.
		//                  = 1  if number of data points n is less than 3.
		//                  = 2  if input abscissae are not ordered x[i] < x[i+1].
		//                  = 3  if standard deviation df[i] not positive for some i.
		//

		public override int Interpolate(IROVector x, IROVector y)
		{
			// check input parameters

			if (!MatchingIndexRange(x, y))
				throw new ArgumentException("index range mismatch of vectors");

			// here we must use a copy of the original vectors

			// Empty data vectors - free auxilliary storage
			if (x.Length == 0)
			{
				xstore.Clear();
				ystore.Clear();
				y0.Clear();
				y1.Clear();
				y2.Clear();
				y3.Clear();
				se.Clear();
				wkr.Clear();
				wkt.Clear();
				wku.Clear();
				wkv.Clear();
				return 0;
			}

			xstore.CopyFrom(x);
			ystore.CopyFrom(y);

			// link original data vectors into base class
			base.x = xstore;
			base.y = ystore;

			var n = x.Length;

			// Resize the auxilliary vectors. Note, that there is no reallocation if the
			// vector already has the appropriate dimension.
			y0.Resize(n);
			y1.Resize(n);
			y2.Resize(n);
			y3.Resize(n);
			// se.Resize(lo,hi); // currently zero
			wkr.Resize(3 * (n + 2));
			wkt.Resize(2 * (n + 2));
			wku.Resize(1 * (n + 2));
			wkv.Resize(1 * (n + 2));
			if (calculateErrorEstimates)
				se.Resize(n);

			// set derivatives for a single point
			if (x.Length == 1)
			{
				y0[0] = y[0];
				y1[0] = y2[0] = y3[0] = 0.0;
				return 0;
			}

			// set derivatives for a line
			if (x.Length == 2)
			{
				y0[0] = y[0];
				y0[n - 1] = y[n - 1];
				y1[0] = y1[n - 1] = (y[n - 1] - y[0]) / (x[n - 1] - x[0]);
				y2[0] = y2[n - 1] =
					y3[0] = y3[n - 1] = 0.0;
				return 0;
			}

			// set standard deviation of the points to 1 if dy is not set or has
			// the wrong length
			if (dy.Store() == null || dy.Length != xstore.Length)
			{
				dy.Resize(n);
				for (int k = 0; k < n; ++k)
					dy[k] = 1;
			}

			// adjust pointers to vectors so that indexing starts from 1
			double[] xx = xstore.Store();
			double[] f = ystore.Store();

			double[] yy = y0.Store(); // coefficients calculated
			double[] c1 = y1.Store();
			double[] c2 = y2.Store();
			double[] c3 = y3.Store();
			double[] df = dy.Store();

			// index starts from 0
			double[] wwr = wkr.Store();
			double[] wwt = wkt.Store();
			double[] wwu = wku.Store();
			double[] wwv = wkv.Store();

			// set ss to (double*)0 if a NullVector is given
			double[] ss = null;
			if (se.Length > 0) ss = se.Store();

			return cubgcv(xx, f, df, n, yy, c1, c2, c3, ss, wwr, wwt, wwu, wwv);
		}
    ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
    ///<param name="B">RHS side of the system.</param>
    ///<returns>the solution vector, X.</returns>  
    ///<exception cref="ArgumentNullException">B is null.</exception>
    ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
    ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception>
    public DoubleVector Solve (IROVector B) 
    {
      if ( B == null ) 
      {
        throw new System.ArgumentNullException("B cannot be null.");
      }
      Compute();
      if ( !ispd ) 
      {
        throw new NotPositiveDefiniteException();
      } 
      else 
      {
        if ( B.Length != order ) 
        {
          throw new System.ArgumentException("The length of B must be the same as the order of the matrix." );
        }
#if MANAGED
        // Copy right hand side.
        DoubleVector X = new DoubleVector(B);
        // Solve L*Y = B;
        for (int i = 0; i < order; i++) 
        {
          double sum = B[i];
          for (int k = i-1; k >= 0; k--) 
          {
            sum -= l.data[i][k] * X.data[k];
          }
          X.data[i] = sum / l.data[i][i];
        }
        // Solve L'*X = Y;
        for (int i =order-1; i >= 0; i--) 
        {
          double sum = X.data[i];
          for (int k = i+1; k < order; k++) 
          {
            sum -= l.data[k][i] * X.data[k];
          }
          X.data[i] = sum / l.data[i][i];
        }

        return X;
#else
                double[] rhs = DoubleMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower,order,1,l.data,order,rhs,B.Length);
                DoubleVector ret = new DoubleVector(order,B.Length);
                ret.data = rhs;
                return ret;
#endif
      }
    }