public void Transform_SimpleExample_ReturnsExpectedOutput()
        {
            var m = new Matrix(new[]
            {
                new [] { 2d, 4d},
                new [] { 1d, 3d},
                new [] { 0d, 0d},
                new [] { 0d, 0d}
            });

            var svd = new SingularValueDecomposition();

            var t = svd.Transform(m);
        }
        private double regress(double[][] inputs, double[] outputs, out double[,] designMatrix, bool robust)
        {
            if (inputs.Length != outputs.Length)
            {
                throw new ArgumentException("Number of input and output samples does not match", "outputs");
            }

            int rows = inputs.Length;    // number of instance points
            int cols = inputs[0].Length; // dimension of each point

            NumberOfInputs = cols;

            ISolverMatrixDecomposition <double> solver;


            // Create the problem's design matrix. If we
            //  have to add an intercept term, add a new
            //  extra column at the end and fill with 1s.

            if (!addIntercept)
            {
                // Just copy values over
                designMatrix = new double[rows, cols];
                for (int i = 0; i < inputs.Length; i++)
                {
                    for (int j = 0; j < inputs[i].Length; j++)
                    {
                        designMatrix[i, j] = inputs[i][j];
                    }
                }
            }
            else
            {
                // Add an intercept term
                designMatrix = new double[rows, cols + 1];
                for (int i = 0; i < inputs.Length; i++)
                {
                    for (int j = 0; j < inputs[i].Length; j++)
                    {
                        designMatrix[i, j] = inputs[i][j];
                    }
                    designMatrix[i, cols] = 1;
                }
            }

            // Check if we have an overdetermined or underdetermined
            //  system to select an appropriate matrix solver method.

            if (robust || cols >= rows)
            {
                // We have more variables than equations, an
                // underdetermined system. Solve using a SVD:
                solver = new SingularValueDecomposition(designMatrix,
                                                        computeLeftSingularVectors: true,
                                                        computeRightSingularVectors: true,
                                                        autoTranspose: true);
            }
            else
            {
                // We have more equations than variables, an
                // overdetermined system. Solve using the QR:
                solver = new QrDecomposition(designMatrix);
            }


            // Solve V*C = B to find C (the coefficients)
            coefficients = solver.Solve(outputs);
            if (addIntercept)
            {
                intercept = coefficients[coefficients.Length - 1];
            }

            // Calculate Sum-Of-Squares error
            double error = 0.0;
            double e;

            for (int i = 0; i < outputs.Length; i++)
            {
                e      = outputs[i] - Compute(inputs[i]);
                error += e * e;
            }

            return(error);
        }
示例#3
0
        public static double[,] PseudoInverse(this double[,] m)
        {
            SingularValueDecomposition svd = new SingularValueDecomposition(m);

            return(svd.Solve(Matrix.Diagonal(m.GetLength(0), m.GetLength(1), 1.0)));
        }
示例#4
0
        /// <summary>
        ///   Parallel (symmetric) iterative algorithm.
        /// </summary>
        ///
        /// <returns>
        ///   Returns a matrix in which each row contains
        ///   the mixing coefficients for each component.
        /// </returns>
        ///
        private double[,] parallel(double[,] X, int components, double[,] winit)
        {
            // References:
            // - Hyvärinen, A (1999). Fast and Robust Fixed-Point
            //   Algorithms for Independent Component Analysis.

            // There are two ways to apply the fixed-unit algorithm to compute the whole
            // ICA iteration. The second approach is to perform orthogonalization at once
            // using an Eigendecomposition [Hyvärinen]. The Eigendecomposition can in turn
            // be converted to a more stable singular value decomposition and be used to
            // create a projection basis in the same way as in Principal Component Analysis.

            int n = X.GetLength(0);
            int m = X.GetLength(1);

            // Algorithm initialization
            double[,] W0 = winit;
            double[,] W  = winit;
            double[,] K  = new double[components, components];

            bool   stop       = false;
            int    iterations = 0;
            double lastChange = 1;


            do // until convergence
            {
                // [Hyvärinen, 1997]'s paper suggests the use of the Eigendecomposition
                //   to orthogonalize W (after equation 10). However, [E, D] = eig(W'W)
                //   can be replaced by [U, S] = svd(W), which is more stable and avoids
                //   computing W'W. Since the singular values are already the square roots
                //   of the eigenvalues of W'W, the computation of E'*D^(-1/2)*E' reduces
                //   to U*S^(-1)*U'.

                // Perform simultaneous decorrelation of all components at once
                var svd = new SingularValueDecomposition(W,
                                                         computeLeftSingularVectors: true,
                                                         computeRightSingularVectors: false,
                                                         autoTranspose: true);

                double[] S = svd.Diagonal;
                double[,] U = svd.LeftSingularVectors;

                // Form orthogonal projection basis K
                for (int i = 0; i < components; i++)
                {
                    for (int j = 0; j < components; j++)
                    {
                        double s = 0;
                        for (int k = 0; k < S.Length; k++)
                        {
                            if (S[k] != 0.0)
                            {
                                s += U[i, k] * U[j, k] / S[k];
                            }
                        }
                        K[i, j] = s;
                    }
                }

                // Orthogonalize
                W = K.Multiply(W);


                // Gets the maximum parameter absolute change
                double delta = getMaximumAbsoluteChange(W0, W);

                // Check for convergence
                if (delta < tolerance * lastChange || iterations >= maxIterations)
                {
                    stop = true;
                }
                else
                {
                    // Advance to the next iteration
                    W0         = W; W = new double[components, m];
                    lastChange = delta;
                    iterations++;


                    // For each component (in parallel)
                    global::Accord.Threading.Tasks.Parallel.For(0, components, i =>
                    {
                        double[] wx    = new double[n];
                        double[] dgwx  = new double[n];
                        double[] gwx   = new double[n];
                        double[] means = new double[m];

                        // Compute wx = w*x
                        for (int j = 0; j < wx.Length; j++)
                        {
                            double s = 0;
                            for (int k = 0; k < m; k++)
                            {
                                s += W0[i, k] * X[j, k];
                            }
                            wx[j] = s;
                        }

                        // Compute g(wx) and g'(wx)
                        contrast.Evaluate(wx, gwx, dgwx);

                        // Compute E{ x*g(w*x) }
                        for (int j = 0; j < means.Length; j++)
                        {
                            for (int k = 0; k < gwx.Length; k++)
                            {
                                means[j] += X[k, j] * gwx[k];
                            }
                            means[j] /= n;
                        }

                        // Compute E{ g'(w*x) }
                        double mean = Statistics.Tools.Mean(dgwx);


                        // Compute next update for w according
                        //  to Hyvärinen paper's equation (20).

                        // w+ = E{ xg(w*x)} - E{ g'(w*x)}*w
                        for (int j = 0; j < means.Length; j++)
                        {
                            W[i, j] = means[j] - mean * W0[i, j];
                        }

                        // The normalization to w* will be performed
                        //  in the beginning of the next iteration.
                    });
                }
            } while (!stop);

            // Return the component basis matrix
            return(W); // vectors stored as rows.
        }
示例#5
0
        /// <summary>
        ///   Performs the regression using the input vectors and output
        ///   vectors, returning the sum of squared errors of the fit.
        /// </summary>
        ///
        /// <param name="inputs">The input vectors to be used in the regression.</param>
        /// <param name="outputs">The output values for each input vector.</param>
        /// <returns>The Sum-Of-Squares error of the regression.</returns>
        ///
        public virtual double Regress(double[][] inputs, double[][] outputs)
        {
            if (inputs.Length != outputs.Length)
            {
                throw new ArgumentException("Number of input and output samples does not match", "outputs");
            }

            int cols = inputs[0].Length;      // inputs
            int rows = inputs.Length;         // points

            if (insertConstant)
            {
                cols++;
            }

            for (int c = 0; c < coefficients.GetLength(1); c++)
            {
                double[] B = new double[cols];
                double[,] V = new double[cols, cols];


                // Compute V and B matrices
                for (int i = 0; i < cols; i++)
                {
                    // Least Squares Matrix
                    for (int j = 0; j < cols; j++)
                    {
                        for (int k = 0; k < rows; k++)
                        {
                            if (insertConstant)
                            {
                                double a = (i == cols - 1) ? 1 : inputs[k][i];
                                double b = (j == cols - 1) ? 1 : inputs[k][j];

                                V[i, j] += a * b;
                            }
                            else
                            {
                                V[i, j] += inputs[k][i] * inputs[k][j];
                            }
                        }
                    }

                    // Function to minimize
                    for (int k = 0; k < rows; k++)
                    {
                        if (insertConstant && (i == cols - 1))
                        {
                            B[i] += outputs[k][c];
                        }
                        else
                        {
                            B[i] += inputs[k][i] * outputs[k][c];
                        }
                    }
                }


                // Solve V*C = B to find C (the coefficients)
                double[] coef = new SingularValueDecomposition(V).Solve(B);

                if (insertConstant)
                {
                    intercepts[c] = coef[coef.Length - 1];
                    for (int i = 0; i < cols - 1; i++)
                    {
                        coefficients[i, c] = coef[i];
                    }
                }
                else
                {
                    for (int i = 0; i < cols; i++)
                    {
                        coefficients[i, c] = coef[i];
                    }
                }
            }


            // Calculate Sum-Of-Squares error
            double error = 0.0, e;

            for (int i = 0; i < outputs.Length; i++)
            {
                double[] y = Compute(inputs[i]);

                for (int c = 0; c < y.Length; c++)
                {
                    e      = outputs[i][c] - y[c];
                    error += e * e;
                }
            }

            return(error);
        }
示例#6
0
        // decompositions
        #region svd
        protected double[] svd(double[,] m)
        {
            var svd = new SingularValueDecomposition(m, false, false, true);

            return(svd.Diagonal);
        }
示例#7
0
    /// <summary>
    /// Calculates the pseudo inverse of the matrix <c>input</c> by means of singular value decomposition.
    /// A relative value of <c>100*DBL_EPSILON</c> is used to chop the singular values before calculation.
    /// </summary>
    /// <param name="input">Input matrix</param>
    /// <param name="rank">Returns the rank of the input matrix.</param>
    /// <returns>The pseudo inverse of matrix <c>input</c>.</returns>
    public static IMatrix PseudoInverse(IROMatrix input, out int rank)
    {
      MatrixMath.BEMatrix ma = new BEMatrix(input.Rows,input.Columns);
      MatrixMath.Copy(input,ma);
      SingularValueDecomposition svd =  new SingularValueDecomposition(ma);
      
      
      double[][] B = GetMatrixArray(input.Columns,input.Rows);


      /* compute the pseudoinverse in B */
      double[] s = svd.Diagonal;
      int m = input.Rows;
      int n = input.Columns;
      int minmn = Math.Min(m,n);

      double[][] v = svd.V;
      double[][] u = svd.U;
      double thresh = (DoubleConstants.DBL_EPSILON*100) * s[0];
      for(rank=0; rank<minmn && s[rank]>thresh; rank++)
      {
        double one_over_denom=1.0/s[rank];

        for(int j=0; j<m; j++)
          for(int i=0; i<n; i++)
            B[i][j]+=v[i][rank]*u[j][rank]*one_over_denom;
      }

      return new JaggedArrayMatrix(B);
    }
 public static double SquareMahalanobis(double[] x, double[] y, SingularValueDecomposition svd)
 {
     return(new SquareMahalanobis(svd).Distance(x, y));
 }
        public void SingularValueDecompositionConstructorTest1()
        {
            // This test catches the bug in SingularValueDecomposition in the line
            //   for (int j = k + 1; j < nu; j++)
            // where it should be
            //   for (int j = k + 1; j < n; j++)


            // Test for m-x-n matrices where m < n. The available SVD
            // routine was not meant to be used in this case.

            double[,] value = new double[, ]
            {
                { 1, 2 },
                { 3, 4 },
                { 5, 6 },
                { 7, 8 }
            }.Transpose();  // value is 2x4, having less rows than columns.

            var target = new SingularValueDecomposition(value, true, true, false);

            double[,] actual = target.LeftSingularVectors.Dot(
                target.DiagonalMatrix).Dot(target.RightSingularVectors.Transpose());

            // Checking the decomposition
            Assert.IsTrue(Matrix.IsEqual(actual, value, 1e-2));
            Assert.IsTrue(Matrix.IsEqual(target.Reverse(), value, 1e-2));

            // Checking values
            double[,] U =
            {
                { -0.641423027995072, -0.767187395072177 },
                { -0.767187395072177,  0.641423027995072 },
            };

            // U should be equal
            Assert.IsTrue(Matrix.IsEqual(target.LeftSingularVectors, U, 0.001));


            double[,] V = // economy svd
            {
                { -0.152483233310201,  0.822647472225661, },
                { -0.349918371807964,  0.421375287684580, },
                { -0.547353510305727, 0.0201031031435023, },
                { -0.744788648803490, -0.381169081397574, },
            };

            var matrix = target.RightSingularVectors.Submatrix(0, 3, 0, 1);

            // V can be different, but for the economy SVD it is often equal
            Assert.IsTrue(
                Matrix.IsEqual(matrix, V, 0.0001));

            double[,] S =
            {
                { 14.2690954992615, 0.000000000000000 },
                {  0.0000000000000, 0.626828232417543 },
            };

            // The diagonal values should be equal
            Assert.IsTrue(Matrix.IsEqual(target.Diagonal.First(2),
                                         Matrix.Diagonal(S), 0.001));
        }
示例#10
0
        /// <summary>
        ///   Reverts a set of projected data into it's original form. Complete reverse
        ///   transformation is not always possible and is not even guaranteed to exist.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This method works using a closed-form MDS approach as suggested by
        ///   Kwok and Tsang. It is currently a direct implementation of the algorithm
        ///   without any kind of optimization.
        /// </para>
        /// <para>
        ///   Reference:
        ///   - http://cmp.felk.cvut.cz/cmp/software/stprtool/manual/kernels/preimage/list/rbfpreimg3.html
        /// </para>
        /// </remarks>
        ///
        /// <param name="data">The kpca-transformed data.</param>
        /// <param name="neighbors">The number of nearest neighbors to use while constructing the pre-image.</param>
        ///
        public double[,] Revert(double[,] data, int neighbors)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (sourceCentered == null)
            {
                throw new InvalidOperationException("The analysis must have been computed first.");
            }

            if (neighbors < 2)
            {
                throw new ArgumentOutOfRangeException("neighbors", "At least two neighbors are necessary.");
            }

            // Verify if the current kernel supports
            // distance calculation in feature space.
            var distance = kernel as IReverseDistance;

            if (distance == null)
            {
                throw new NotSupportedException(
                          "Current kernel does not support distance calculation in feature space.");
            }


            int rows = data.GetLength(0);


            var result = Result;

            double[,] reversion = new double[rows, sourceCentered.GetLength(1)];

            // number of neighbors cannot exceed the number of training vectors.
            int nn = System.Math.Min(neighbors, sourceCentered.GetLength(0));


            // For each point to be reversed
            for (int p = 0; p < rows; p++)
            {
                // 1. Get the point in feature space
                double[] y = data.GetRow(p);

                // 2. Select nn nearest neighbors of the feature space
                double[,] X = sourceCentered;
                double[] d2  = new double[Result.GetLength(0)];
                int[]    inx = new int[Result.GetLength(0)];

                // 2.1 Calculate distances
                for (int i = 0; i < X.GetLength(0); i++)
                {
                    inx[i] = i;
                    d2[i]  = distance.ReverseDistance(y, result.GetRow(i).Submatrix(y.Length));

                    if (Double.IsNaN(d2[i]))
                    {
                        d2[i] = Double.PositiveInfinity;
                    }
                }

                // 2.2 Order them
                Array.Sort(d2, inx);

                // 2.3 Select nn neighbors

                int def = 0;
                for (int i = 0; i < d2.Length && i < nn; i++, def++)
                {
                    if (Double.IsInfinity(d2[i]))
                    {
                        break;
                    }
                }

                inx = inx.Submatrix(def);
                X   = X.Submatrix(inx).Transpose(); // X is in input space
                d2  = d2.Submatrix(def);            // distances in input space


                // 3. Perform SVD
                //    [U,L,V] = svd(X*H);

                // TODO: If X has more columns than rows, the SV decomposition should be
                //  computed on the transpose of X and the left and right vectors should
                //  be swapped. This should be fixed after more unit tests are elaborated.
                SingularValueDecomposition svd = new SingularValueDecomposition(X,
                                                                                computeLeftSingularVectors: true, computeRightSingularVectors: true,
                                                                                autoTranspose: false);

                double[,] U = svd.LeftSingularVectors;
                double[,] L = Matrix.Diagonal(def, svd.Diagonal);
                double[,] V = svd.RightSingularVectors;


                // 4. Compute projections
                //    Z = L*V';
                double[,] Z = L.Multiply(V.Transpose());


                // 5. Calculate distances
                //    d02 = sum(Z.^2)';
                double[] d02 = Matrix.Sum(Matrix.ElementwisePower(Z, 2));


                // 6. Get the pre-image using z = -0.5*inv(Z')*(d2-d02)
                double[,] inv = Matrix.PseudoInverse(Z.Transpose());

                double[] w = (-0.5).Multiply(inv).Multiply(d2.Subtract(d02));
                double[] z = w.Submatrix(U.GetLength(1));


                // 8. Project the pre-image on the original basis
                //    using x = U*z + sum(X,2)/nn;
                double[] x = (U.Multiply(z)).Add(Matrix.Sum(X.Transpose()).Multiply(1.0 / nn));


                // 9. Store the computed pre-image.
                for (int i = 0; i < reversion.GetLength(1); i++)
                {
                    reversion[p, i] = x[i];
                }
            }



            // if the data has been standardized or centered,
            //  we need to revert those operations as well
            if (this.Method == AnalysisMethod.Standardize)
            {
                // multiply by standard deviation and add the mean
                for (int i = 0; i < reversion.GetLength(0); i++)
                {
                    for (int j = 0; j < reversion.GetLength(1); j++)
                    {
                        reversion[i, j] = (reversion[i, j] * StandardDeviations[j]) + Means[j];
                    }
                }
            }
            else if (this.Method == AnalysisMethod.Center)
            {
                // only add the mean
                for (int i = 0; i < reversion.GetLength(0); i++)
                {
                    for (int j = 0; j < reversion.GetLength(1); j++)
                    {
                        reversion[i, j] = reversion[i, j] + Means[j];
                    }
                }
            }


            return(reversion);
        }
示例#11
0
        /// <summary>
        ///   Reverts a set of projected data into it's original form. Complete reverse
        ///   transformation is not always possible and is not even guaranteed to exist.
        /// </summary>
        /// <remarks>
        ///   This method works using a closed-form MDS approach as suggested by
        ///   Kwok and Tsang. It is currently a direct implementation of the algorithm
        ///   without any kind of optimization.
        ///
        ///   Reference:
        ///   - http://cmp.felk.cvut.cz/cmp/software/stprtool/manual/kernels/preimage/list/rbfpreimg3.html
        /// </remarks>
        /// <param name="data">The kpca-transformed data.</param>
        /// <param name="neighbors">The number of nearest neighbors to use while constructing the pre-image.</param>
        public double[,] Revert(double[,] data, int neighbors)
        {
            int rows = data.GetLength(0);
            int cols = data.GetLength(1);

            double[,] reversion = new double[rows, sourceCentered.GetLength(1)];

            // number of neighbors cannot exceed the number of training vectors.
            int nn = System.Math.Min(neighbors, sourceCentered.GetLength(0));


            // For each point to be reversed
            for (int p = 0; p < rows; p++)
            {
                // 1. Get the point in feature space
                double[] y = data.GetRow(p);

                // 2. Select nn nearest neighbors of the feature space
                double[,] X = sourceCentered;
                double[] d2  = new double[Result.GetLength(0)];
                int[]    inx = new int[Result.GetLength(0)];

                // 2.1 Calculate distances
                for (int i = 0; i < X.GetLength(0); i++)
                {
                    inx[i] = i;
                    d2[i]  = kernel.Distance(y, Result.GetRow(i).Submatrix(y.Length));
                }

                // 2.2 Order them
                Array.Sort(d2, inx);

                // 2.3 Select nn neighbors
                inx = inx.Submatrix(nn);
                X   = X.Submatrix(inx).Transpose(); // X is in input space
                d2  = d2.Submatrix(nn);             // distances in input space


                // 3. Create centering matrix
                // H = eye(nn, nn) - 1 / nn * ones(nn, nn);
                double[,] H = Matrix.Identity(nn).Subtract(Matrix.Create(nn, 1.0 / nn));


                // 4. Perform SVD
                //    [U,L,V] = svd(X*H);
                SingularValueDecomposition svd = new SingularValueDecomposition(X.Multiply(H));
                double[,] U = svd.LeftSingularVectors;
                double[,] L = Matrix.Diagonal(nn, svd.Diagonal);
                double[,] V = svd.RightSingularVectors;


                // 5. Compute projections
                //    Z = L*V';
                double[,] Z = L.Multiply(V.Transpose());


                // 6. Calculate distances
                //    d02 = sum(Z.^2)';
                double[] d02 = Matrix.Sum(Matrix.DotPow(Z, 2));


                // 7. Get the pre-image using z = -0.5*inv(Z')*(d2-d02)
                double[,] inv = Matrix.PseudoInverse(Z.Transpose());
                double[] z = (-0.5).Multiply(inv).Multiply(d2.Subtract(d02));


                // 8. Project the pre-image on the original basis
                //    using x = U*z + sum(X,2)/nn;
                double[] x = (U.Multiply(z)).Add(Matrix.Sum(X.Transpose()).Multiply(1.0 / nn));


                // 9. Store the computed pre-image.
                for (int i = 0; i < reversion.GetLength(1); i++)
                {
                    reversion[p, i] = x[i];
                }
            }



            // if the data has been standardized or centered,
            //  we need to revert those operations as well
            if (this.Method == AnalysisMethod.Correlation)
            {
                // multiply by standard deviation and add the mean
                for (int i = 0; i < reversion.GetLength(0); i++)
                {
                    for (int j = 0; j < reversion.GetLength(1); j++)
                    {
                        reversion[i, j] = (reversion[i, j] * StandardDeviations[j]) + Means[j];
                    }
                }
            }
            else
            {
                // only add the mean
                for (int i = 0; i < reversion.GetLength(0); i++)
                {
                    for (int j = 0; j < reversion.GetLength(1); j++)
                    {
                        reversion[i, j] = reversion[i, j] + Means[j];
                    }
                }
            }


            return(reversion);
        }
示例#12
0
        public void PC()
        {
            Random rng = new Random(1);
            double s   = 1.0 / Math.Sqrt(2.0);

            MultivariateSample MS = new MultivariateSample(2);
            RectangularMatrix  R  = new RectangularMatrix(1000, 2);

            for (int i = 0; i < 1000; i++)
            {
                double r1 = 2.0 * rng.NextDouble() - 1.0;
                double r2 = 2.0 * rng.NextDouble() - 1.0;
                double x  = r1 * 4.0 * s - r2 * 9.0 * s;
                double y  = r1 * 4.0 * s + r2 * 9.0 * s;
                R[i, 0] = x; R[i, 1] = y;
                MS.Add(x, y);
            }

            Console.WriteLine("x {0} {1}", MS.Column(0).Mean, MS.Column(0).Variance);
            Console.WriteLine("y {0} {1}", MS.Column(1).Mean, MS.Column(1).Variance);

            Console.WriteLine("SVD");

            SingularValueDecomposition SVD = R.SingularValueDecomposition();

            for (int i = 0; i < SVD.Dimension; i++)
            {
                Console.WriteLine("{0} {1}", i, SVD.SingularValue(i));
                ColumnVector v = SVD.RightSingularVector(i);
                Console.WriteLine("  {0} {1}", v[0], v[1]);
            }

            Console.WriteLine("PCA");

            PrincipalComponentAnalysis PCA = MS.PrincipalComponentAnalysis();

            Console.WriteLine("Dimension = {0} Count = {1}", PCA.Dimension, PCA.Count);
            for (int i = 0; i < PCA.Dimension; i++)
            {
                PrincipalComponent PC = PCA.Component(i);
                Console.WriteLine("  {0} {1} {2} {3}", PC.Index, PC.Weight, PC.VarianceFraction, PC.CumulativeVarianceFraction);
                RowVector v = PC.NormalizedVector();
                Console.WriteLine("  {0} {1}", v[0], v[1]);
            }

            // reconstruct
            SquareMatrix U  = SVD.LeftTransformMatrix();
            SquareMatrix V  = SVD.RightTransformMatrix();
            double       x1 = U[0, 0] * SVD.SingularValue(0) * V[0, 0] + U[0, 1] * SVD.SingularValue(1) * V[0, 1];

            Console.WriteLine("x1 = {0} {1}", x1, R[0, 0]);
            double y1 = U[0, 0] * SVD.SingularValue(0) * V[1, 0] + U[0, 1] * SVD.SingularValue(1) * V[1, 1];

            Console.WriteLine("y1 = {0} {1}", y1, R[0, 1]);
            double x100 = U[100, 0] * SVD.SingularValue(0) * V[0, 0] + U[100, 1] * SVD.SingularValue(1) * V[0, 1];

            Console.WriteLine("x100 = {0} {1}", x100, R[100, 0]);
            double y100 = U[100, 0] * SVD.SingularValue(0) * V[1, 0] + U[100, 1] * SVD.SingularValue(1) * V[1, 1];

            Console.WriteLine("y100 = {0} {1}", y100, R[100, 1]);

            ColumnVector d1 = U[0, 0] * SVD.SingularValue(0) * SVD.RightSingularVector(0) +
                              U[0, 1] * SVD.SingularValue(1) * SVD.RightSingularVector(1);

            Console.WriteLine("d1 = ({0} {1})", d1[0], d1[1]);
            ColumnVector d100 = U[100, 0] * SVD.SingularValue(0) * SVD.RightSingularVector(0) +
                                U[100, 1] * SVD.SingularValue(1) * SVD.RightSingularVector(1);

            Console.WriteLine("d100 = ({0} {1})", d100[0], d100[1]);

            Console.WriteLine("compare");
            MultivariateSample     RS  = PCA.TransformedSample();
            IEnumerator <double[]> RSE = RS.GetEnumerator();

            RSE.MoveNext();
            double[] dv1 = RSE.Current;
            Console.WriteLine("{0} {1}", dv1[0], dv1[1]);
            Console.WriteLine("{0} {1}", U[0, 0], U[0, 1]);
            RSE.Dispose();
        }
示例#13
0
        public void AllTests()
        {
            Matrix A, B, C, Z, O, I, R, S, X, SUB, M, T, SQ, DEF, SOL;
            double tmp;

            double[]   columnwise = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 };
            double[]   rowwise = { 1.0, 4.0, 7.0, 10.0, 2.0, 5.0, 8.0, 11.0, 3.0, 6.0, 9.0, 12.0 };
            double[][] avals = { new double[] { 1.0, 4.0, 7.0, 10.0 }, new double[] { 2.0, 5.0, 8.0, 11.0 }, new double[] { 3.0, 6.0, 9.0, 12.0 } };
            double[][] rankdef = avals;
            double[][] tvals = { new double[] { 1.0, 2.0, 3.0 }, new double[] { 4.0, 5.0, 6.0 }, new double[] { 7.0, 8.0, 9.0 }, new double[] { 10.0, 11.0, 12.0 } };
            double[][] subavals = { new double[] { 5.0, 8.0, 11.0 }, new double[] { 6.0, 9.0, 12.0 } };
            double[][] pvals = { new double[] { 25, -5, 10 }, new double[] { -5, 17, 10 }, new double[] { 10, 10, 62 } };
            double[][] ivals = { new double[] { 1.0, 0.0, 0.0, 0.0 }, new double[] { 0.0, 1.0, 0.0, 0.0 }, new double[] { 0.0, 0.0, 1.0, 0.0 } };
            double[][] evals = { new double[] { 0.0, 1.0, 0.0, 0.0 }, new double[] { 1.0, 0.0, 2e-7, 0.0 }, new double[] { 0.0, -2e-7, 0.0, 1.0 }, new double[] { 0.0, 0.0, 1.0, 0.0 } };
            double[][] square = { new double[] { 166.0, 188.0, 210.0 }, new double[] { 188.0, 214.0, 240.0 }, new double[] { 210.0, 240.0, 270.0 } };
            double[][] sqSolution = { new double[] { 13.0 }, new double[] { 15.0 } };
            double[][] condmat = { new double[] { 1.0, 3.0 }, new double[] { 7.0, 9.0 } };
            int        rows = 3, cols = 4;
            int        invalidld = 5;                  /* should trigger bad shape for construction with val */
            int        validld = 3;                    /* leading dimension of intended test Matrices */
            int        nonconformld = 4;               /* leading dimension which is valid, but nonconforming */
            int        ib = 1, ie = 2, jb = 1, je = 3; /* index ranges for sub Matrix */

            int[]  rowindexset       = new int[] { 1, 2 };
            int[]  badrowindexset    = new int[] { 1, 3 };
            int[]  columnindexset    = new int[] { 1, 2, 3 };
            int[]  badcolumnindexset = new int[] { 1, 2, 4 };
            double columnsummax      = 33.0;
            double rowsummax         = 30.0;
            double sumofdiagonals    = 15;
            double sumofsquares      = 650;

            #region Testing constructors and constructor-like methods

            // Constructors and constructor-like methods:
            // double[], int
            // double[,]
            // int, int
            // int, int, double
            // int, int, double[,]
            // Create(double[,])
            // Random(int,int)
            // Identity(int)

            try
            {
                // check that exception is thrown in packed constructor with invalid length
                A = new Matrix(columnwise, invalidld);
                Assert.Fail("Catch invalid length in packed constructor: exception not thrown for invalid input");
            }
            catch (ArgumentException) { }

            A           = new Matrix(columnwise, validld);
            B           = new Matrix(avals);
            tmp         = B[0, 0];
            avals[0][0] = 0.0;
            C           = B - A;
            avals[0][0] = tmp;
            B           = Matrix.Create(avals);
            tmp         = B[0, 0];
            avals[0][0] = 0.0;
            Assert.AreEqual((tmp - B[0, 0]), 0.0, "Create");

            avals[0][0] = columnwise[0];
            I           = new Matrix(ivals);
            NumericAssert.AreAlmostEqual(I, Matrix.Identity(3, 4), "Identity");

            #endregion

            #region Testing access methods

            // Access Methods:
            // getColumnDimension()
            // getRowDimension()
            // getArray()
            // getArrayCopy()
            // getColumnPackedCopy()
            // getRowPackedCopy()
            // get(int,int)
            // GetMatrix(int,int,int,int)
            // GetMatrix(int,int,int[])
            // GetMatrix(int[],int,int)
            // GetMatrix(int[],int[])
            // set(int,int,double)
            // SetMatrix(int,int,int,int,Matrix)
            // SetMatrix(int,int,int[],Matrix)
            // SetMatrix(int[],int,int,Matrix)
            // SetMatrix(int[],int[],Matrix)

            // Various get methods
            B = new Matrix(avals);
            Assert.AreEqual(B.RowCount, rows, "getRowDimension");
            Assert.AreEqual(B.ColumnCount, cols, "getColumnDimension");

            B = new Matrix(avals);
            double[][] barray = (Matrix)B;
            Assert.AreSame(barray, avals, "getArray");

            barray = B.Clone();
            Assert.AreNotSame(barray, avals, "getArrayCopy");
            NumericAssert.AreAlmostEqual(new Matrix(barray), B, "getArrayCopy II");

            //            double[] bpacked = B.ColumnPackedCopy;
            //            try
            //            {
            //                check(bpacked, columnwise);
            //                try_success("getColumnPackedCopy... ", "");
            //            }
            //            catch (System.SystemException e)
            //            {
            //                errorCount = try_failure(errorCount, "getColumnPackedCopy... ", "data not successfully (deep) copied by columns");
            //                System.Console.Out.WriteLine(e.Message);
            //            }
            //            bpacked = B.RowPackedCopy;
            //            try
            //            {
            //                check(bpacked, rowwise);
            //                try_success("getRowPackedCopy... ", "");
            //            }
            //            catch (System.SystemException e)
            //            {
            //                errorCount = try_failure(errorCount, "getRowPackedCopy... ", "data not successfully (deep) copied by rows");
            //                System.Console.Out.WriteLine(e.Message);
            //            }

            try
            {
                tmp = B[B.RowCount, B.ColumnCount - 1];
                Assert.Fail("get(int,int): OutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                tmp = B[B.RowCount - 1, B.ColumnCount];
                Assert.Fail("get(int,int): OutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }
            Assert.AreEqual(B[B.RowCount - 1, B.ColumnCount - 1], avals[B.RowCount - 1][B.ColumnCount - 1], "get(int,int)");

            SUB = new Matrix(subavals);
            try
            {
                M = B.GetMatrix(ib, ie + B.RowCount + 1, jb, je);
                Assert.Fail("GetMatrix(int,int,int,int): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                M = B.GetMatrix(ib, ie, jb, je + B.ColumnCount + 1);
                Assert.Fail("GetMatrix(int,int,int,int): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            M = B.GetMatrix(ib, ie, jb, je);
            NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int,int,int,int)");

            try
            {
                M = B.GetMatrix(ib, ie, badcolumnindexset);
                Assert.Fail("GetMatrix(int,int,int[]): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                M = B.GetMatrix(ib, ie + B.RowCount + 1, columnindexset);
                Assert.Fail("GetMatrix(int,int,int[]): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            M = B.GetMatrix(ib, ie, columnindexset);
            NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int,int,int[])");

            try
            {
                M = B.GetMatrix(badrowindexset, jb, je);
                Assert.Fail("GetMatrix(int[],int,int): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                M = B.GetMatrix(rowindexset, jb, je + B.ColumnCount + 1);
                Assert.Fail("GetMatrix(int[],int,int): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            M = B.GetMatrix(rowindexset, jb, je);
            NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int[],int,int)");

            try
            {
                M = B.GetMatrix(badrowindexset, columnindexset);
                Assert.Fail("GetMatrix(int[],int[]): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                M = B.GetMatrix(rowindexset, badcolumnindexset);
                Assert.Fail("GetMatrix(int[],int[]): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            M = B.GetMatrix(rowindexset, columnindexset);
            NumericAssert.AreAlmostEqual(SUB, M, "GetMatrix(int[],int[])");

            // Various set methods:
            try
            {
                B[B.RowCount, B.ColumnCount - 1] = 0.0;
                Assert.Fail("set(int,int,double): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                B[B.RowCount - 1, B.ColumnCount] = 0.0;
                Assert.Fail("set(int,int,double): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            B[ib, jb] = 0.0;
            tmp       = B[ib, jb];
            NumericAssert.AreAlmostEqual(tmp, 0.0, "set(int,int,double)");

            M = new Matrix(2, 3, 0.0);
            try
            {
                B.SetMatrix(ib, ie + B.RowCount + 1, jb, je, M);
                Assert.Fail("SetMatrix(int,int,int,int,Matrix): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                B.SetMatrix(ib, ie, jb, je + B.ColumnCount + 1, M);
                Assert.Fail("SetMatrix(int,int,int,int,Matrix): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            B.SetMatrix(ib, ie, jb, je, M);
            NumericAssert.AreAlmostEqual(M - B.GetMatrix(ib, ie, jb, je), M, "SetMatrix(int,int,int,int,Matrix)");
            B.SetMatrix(ib, ie, jb, je, SUB);
            try
            {
                B.SetMatrix(ib, ie + B.RowCount + 1, columnindexset, M);
                Assert.Fail("SetMatrix(int,int,int[],Matrix): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                B.SetMatrix(ib, ie, badcolumnindexset, M);
                Assert.Fail("SetMatrix(int,int,int[],Matrix): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            B.SetMatrix(ib, ie, columnindexset, M);
            NumericAssert.AreAlmostEqual(M - B.GetMatrix(ib, ie, columnindexset), M, "SetMatrix(int,int,int[],Matrix)");
            B.SetMatrix(ib, ie, jb, je, SUB);
            try
            {
                B.SetMatrix(rowindexset, jb, je + B.ColumnCount + 1, M);
                Assert.Fail("SetMatrix(int[],int,int,Matrix): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                B.SetMatrix(badrowindexset, jb, je, M);
                Assert.Fail("SetMatrix(int[],int,int,Matrix): IndexOutOfBoundsException expected but not thrown II");
            }
            catch (IndexOutOfRangeException) { }

            B.SetMatrix(rowindexset, jb, je, M);
            NumericAssert.AreAlmostEqual(M - B.GetMatrix(rowindexset, jb, je), M, "SetMatrix(int[],int,int,Matrix)");

            B.SetMatrix(ib, ie, jb, je, SUB);
            try
            {
                B.SetMatrix(rowindexset, badcolumnindexset, M);
                Assert.Fail("SetMatrix(int[],int[],Matrix): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }
            try
            {
                B.SetMatrix(badrowindexset, columnindexset, M);
                Assert.Fail("SetMatrix(int[],int[],Matrix): IndexOutOfBoundsException expected but not thrown");
            }
            catch (IndexOutOfRangeException) { }

            B.SetMatrix(rowindexset, columnindexset, M);
            NumericAssert.AreAlmostEqual(M - B.GetMatrix(rowindexset, columnindexset), M, "SetMatrix(int[],int[],Matrix)");

            #endregion

            #region Testing array-like methods

            // Array-like methods:
            // Subtract
            // SubtractEquals
            // Add
            // AddEquals
            // ArrayLeftDivide
            // ArrayLeftDivideEquals
            // ArrayRightDivide
            // ArrayRightDivideEquals
            // arrayTimes
            // ArrayMultiplyEquals
            // uminus

            S = new Matrix(columnwise, nonconformld);
            R = Matrix.Random(A.RowCount, A.ColumnCount);
            A = R;
            try
            {
                S = A - S;
                Assert.Fail("Subtract conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }
            Assert.AreEqual((A - R).Norm1(), 0.0, "Subtract: difference of identical Matrices is nonzero,\nSubsequent use of Subtract should be suspect");

            A = R.Clone();
            A.Subtract(R);
            Z = new Matrix(A.RowCount, A.ColumnCount);
            try
            {
                A.Subtract(S);
                Assert.Fail("SubtractEquals conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }
            Assert.AreEqual((A - Z).Norm1(), 0.0, "SubtractEquals: difference of identical Matrices is nonzero,\nSubsequent use of Subtract should be suspect");

            A = R.Clone();
            B = Matrix.Random(A.RowCount, A.ColumnCount);
            C = A - B;
            try
            {
                S = A + S;
                Assert.Fail("Add conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }
            NumericAssert.AreAlmostEqual(C + B, A, "Add");

            C = A - B;
            C.Add(B);
            try
            {
                A.Add(S);
                Assert.Fail("AddEquals conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }
            NumericAssert.AreAlmostEqual(C, A, "AddEquals");

            A = ((Matrix)R.Clone());
            A.UnaryMinus();
            NumericAssert.AreAlmostEqual(A + R, Z, "UnaryMinus");

            A = (Matrix)R.Clone();
            O = new Matrix(A.RowCount, A.ColumnCount, 1.0);
            try
            {
                Matrix.ArrayDivide(A, S);
                Assert.Fail("ArrayRightDivide conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }

            C = Matrix.ArrayDivide(A, R);
            NumericAssert.AreAlmostEqual(C, O, "ArrayRightDivide");
            try
            {
                A.ArrayDivide(S);
                Assert.Fail("ArrayRightDivideEquals conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }

            A.ArrayDivide(R);
            NumericAssert.AreAlmostEqual(A, O, "ArrayRightDivideEquals");

            A = (Matrix)R.Clone();
            B = Matrix.Random(A.RowCount, A.ColumnCount);
            try
            {
                S = Matrix.ArrayMultiply(A, S);
                Assert.Fail("arrayTimes conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }

            C = Matrix.ArrayMultiply(A, B);
            C.ArrayDivide(B);
            NumericAssert.AreAlmostEqual(C, A, "arrayTimes");
            try
            {
                A.ArrayMultiply(S);
                Assert.Fail("ArrayMultiplyEquals conformance check: nonconformance not raised");
            }
            catch (ArgumentException) { }

            A.ArrayMultiply(B);
            A.ArrayDivide(B);
            NumericAssert.AreAlmostEqual(A, R, "ArrayMultiplyEquals");

            #endregion

            #region Testing linear algebra methods

            // LA methods:
            // Transpose
            // Multiply
            // Condition
            // Rank
            // Determinant
            // trace
            // Norm1
            // norm2
            // normF
            // normInf
            // Solve
            // solveTranspose
            // Inverse
            // chol
            // Eigen
            // lu
            // qr
            // svd

            A = new Matrix(columnwise, 3);
            T = new Matrix(tvals);
            T = Matrix.Transpose(A);
            NumericAssert.AreAlmostEqual(Matrix.Transpose(A), T, "Transpose");
            NumericAssert.AreAlmostEqual(A.Norm1(), columnsummax, "Norm1");
            NumericAssert.AreAlmostEqual(A.NormInf(), rowsummax, "NormInf");
            NumericAssert.AreAlmostEqual(A.NormF(), Math.Sqrt(sumofsquares), "NormF");
            NumericAssert.AreAlmostEqual(A.Trace(), sumofdiagonals, "Trace");
            NumericAssert.AreAlmostEqual(A.GetMatrix(0, A.RowCount - 1, 0, A.RowCount - 1).Determinant(), 0.0, "Determinant");

            SQ = new Matrix(square);
            NumericAssert.AreAlmostEqual(A * Matrix.Transpose(A), SQ, "Multiply(Matrix)");
            NumericAssert.AreAlmostEqual(0.0 * A, Z, "Multiply(double)");

            A = new Matrix(columnwise, 4);
            QRDecomposition QR = A.QRDecomposition;
            R = QR.R;
            NumericAssert.AreAlmostEqual(A, QR.Q * R, "QRDecomposition");

            SingularValueDecomposition SVD = A.SingularValueDecomposition;
            NumericAssert.AreAlmostEqual(A, SVD.LeftSingularVectors * (SVD.S * Matrix.Transpose(SVD.RightSingularVectors)), "SingularValueDecomposition");

            DEF = new Matrix(rankdef);
            NumericAssert.AreAlmostEqual(DEF.Rank(), Math.Min(DEF.RowCount, DEF.ColumnCount) - 1, "Rank");

            B   = new Matrix(condmat);
            SVD = B.SingularValueDecomposition;
            double[] singularvalues = SVD.SingularValues;
            NumericAssert.AreAlmostEqual(B.Condition(), singularvalues[0] / singularvalues[Math.Min(B.RowCount, B.ColumnCount) - 1], "Condition");

            int n = A.ColumnCount;
            A       = A.GetMatrix(0, n - 1, 0, n - 1);
            A[0, 0] = 0.0;
            LUDecomposition LU = A.LUDecomposition;
            NumericAssert.AreAlmostEqual(A.GetMatrix(LU.Pivot, 0, n - 1), LU.L * LU.U, "LUDecomposition");

            X = A.Inverse();
            NumericAssert.AreAlmostEqual(A * X, Matrix.Identity(3, 3), "Inverse");

            O   = new Matrix(SUB.RowCount, 1, 1.0);
            SOL = new Matrix(sqSolution);
            SQ  = SUB.GetMatrix(0, SUB.RowCount - 1, 0, SUB.RowCount - 1);
            NumericAssert.AreAlmostEqual(SQ.Solve(SOL), O, "Solve");

            A = new Matrix(pvals);
            CholeskyDecomposition Chol = A.CholeskyDecomposition;
            Matrix L = Chol.TriangularFactor;
            NumericAssert.AreAlmostEqual(A, L * Matrix.Transpose(L), "CholeskyDecomposition");

            X = Chol.Solve(Matrix.Identity(3, 3));
            NumericAssert.AreAlmostEqual(A * X, Matrix.Identity(3, 3), "CholeskyDecomposition Solve");

            EigenvalueDecomposition Eig = A.EigenvalueDecomposition;
            Matrix D = Eig.BlockDiagonal;
            Matrix V = Eig.EigenVectors;
            NumericAssert.AreAlmostEqual(A * V, V * D, "EigenvalueDecomposition (symmetric)");

            A   = new Matrix(evals);
            Eig = A.EigenvalueDecomposition;
            D   = Eig.BlockDiagonal;
            V   = Eig.EigenVectors;
            NumericAssert.AreAlmostEqual(A * V, V * D, "EigenvalueDecomposition (nonsymmetric)");

            #endregion
        }
示例#14
0
        /// <summary>
        ///   Parallel (symmetric) iterative algorithm.
        /// </summary>
        /// <returns>
        ///   Returns a matrix in which each row contains
        ///   the mixing coefficients for each component.
        /// </returns>
        private double[,] parallel(double[,] X, int components, double[,] winit)
        {
            int n = X.GetLength(0);
            int m = X.GetLength(1);

            // Algorithm initialization
            double[,] W0 = winit;
            double[,] W = winit;
            double[,] K = new double[components, components];

            bool stop = false;
            int iterations = 0;


            do // until convergence
            {

                // Perform simultaneous decorrelation of all components at once
                var svd = new SingularValueDecomposition(W, true, false, true);
                var S = svd.Diagonal;
                var U = svd.LeftSingularVectors;

                // Normalize
                for (int i = 0; i < components; i++)
                {
                    for (int j = 0; j < components; j++)
                    {
                        double s = 0;
                        for (int k = 0; k < components; k++)
                            if (S[k] != 0.0)
                                s += U[i, k] * U[j, k] / S[k];
                        K[i, j] = s;
                    }
                }

                // Decorrelate
                W = K.Multiply(W);


                // Gets the maximum absolute change in the parameters
                double delta = Matrix.Max(Matrix.Abs(Matrix.Abs(Matrix.Diagonal(W0.Multiply(W.Transpose()))).Subtract(1.0)));

                // Check for convergence
                if (delta < tolerance || iterations >= maxIterations)
                {
                    stop = true;
                }
                else
                {
                    // Advance to the next iteration
                    W0 = W; W = new double[components,m];
                    iterations++;


#if DEBUG           // For each component (in parallel)
                    for (int i = 0; i < components; i++)
#else
                    GABIZ.Base.Parallel.For(0, components, i =>
#endif
                    {
                        double[] wx = new double[n];
                        double[] dgwx = new double[n];
                        double[] gwx = new double[n];
                        double[] means = new double[m];

                        // Compute wx = w*x
                        for (int j = 0; j < n; j++)
                        {
                            double s = 0;
                            for (int k = 0; k < m; k++)
                                s += W0[i, k] * X[j, k];
                            wx[j] = s;
                        }

                        // Compute g(wx) and g'(wx)
                        contrast.Evaluate(wx, gwx, dgwx);

                        // Compute E{ x*g(w*x) }
                        for (int j = 0; j < m; j++)
                        {
                            for (int k = 0; k < n; k++)
                                means[j] += X[k, j] * gwx[k];
                            means[j] /= n;
                        }

                        // Compute E{ g'(w*x) }
                        double mean = GABIZ.Base.Statistics.Tools.Mean(dgwx);


                        // Compute next update for w
                        for (int j = 0; j < m; j++)
                            W[i, j] = means[j] - W0[i, j] * mean;
                    }
#if !DEBUG
);
#endif
                }

            } while (!stop);

            // Return the component basis matrix
            return W; // vectors stored as rows.
        }
示例#15
0
        protected static void svd(double[,] m, out double[,] U)
        {
            var svd = new SingularValueDecomposition(m, true, false, true);

            U = svd.LeftSingularVectors;
        }
示例#16
0
        /// <summary>
        /// Perform the Singular Value Decomposition and identify the rank of the embedding subspace
        /// Characteristic of projection: the proportion of variance captured in the subspace
        /// </summary>
        public void Decompose()
        {
            //transformation of the embedded matrix
            var XT = _xCom.Transpose();
            //embedding (trajectory) matrix helper var
            var X = _xCom;

            //S matrix calculation
            double[,] S = _xCom.Dot(XT);

            /*Single Value Decomposition
             * For an m-by-n matrix A with m >= n, the singular value decomposition is
             *
             *                      an m-by-n orthogonal matrix U,
             *                      an n-by-n diagonal matrix S,
             *                  and an n-by-n orthogonal matrix V
             *                 so that A = U * S * V'.
             *
             * The singular values, sigma[k] = S[k,k], are ordered so that sigma[0] >= sigma[1] >= ... >= sigma[n-1].
             */
            var svd = new SingularValueDecomposition(S);

            //summary of the SVD calculation
            //left eigenvector
            double[,] U = svd.LeftSingularVectors;
            double[] s = svd.Diagonal.Sqrt();
            //right eigenvector
            double[,] V = svd.RightSingularVectors;
            int d = svd.Rank;

            //helper variable to calculate characteristics of projection
            double[][] Ys = new double[d][];
            double[][] Zs = new double[d][];
            var        Vs = new double[d][];

            //SVD trajectory matrix written as Xs = X1 + X2 + X3 + ... + Xd
            _Xs = new Dictionary <int, double[, ]>();

            //calculation of the eigen-triple of the SVD
            for (int i = 0; i < d; i++)
            {
                //
                Zs[i] = V.GetColumn(i).Multiply(s[i]);

                //
                Vs[i] = XT.Dot(U.GetColumn(i).Divide(s[i]));

                //
                Ys[i] = U.GetColumn(i).Multiply(s[i]);

                //vector of Ys[i] to matrix d x 1
                var y = Ys[i].ToMatrix(asColumnVector: true);
                //vector of Vs[i] to matrix 1 x n
                var v = Vs[i].ToMatrix(asColumnVector: false);

                //matrix multiplication
                var x = y.Dot(v);
                _Xs.Add(i, x);
            }

            //calculate contributions
            _sContributions = getControbutions(X, s);

            int r                = _sContributions.Length;
            var firstRValues     = s.Take(r).ToArray();
            var _rCharacteristic = Math.Round(firstRValues.Multiply(firstRValues).Sum() / s.Multiply(s).Sum(), 4);

            //
            var orthonormalBase = new double[r][];

            foreach (var ind in Enumerable.Range(0, r))
            {
                orthonormalBase[ind] = U.GetColumn(ind);
            }
            //set final value of the orthonormal matrix
            _orthonormalBase = orthonormalBase;
        }
示例#17
0
        private static void decompose(NormalOptions options, double[,] cov, out CholeskyDecomposition chol, out SingularValueDecomposition svd)
        {
            svd  = null;
            chol = null;

            if (options == null)
            {
                // We don't have options. Just attempt a standard fitting. If
                // the matrix is not positive semi-definite, throw an exception.

                chol = new CholeskyDecomposition(cov);

                if (!chol.IsPositiveDefinite)
                {
                    throw new NonPositiveDefiniteMatrixException("Covariance matrix is not positive "
                                                                 + "definite. Try specifying a regularization constant in the fitting options "
                                                                 + "(there is an example in the Multivariate Normal Distribution documentation).");
                }

                return;
            }
            else
            {
                // We have options. In this case, we will either be using the SVD
                // or we can add a regularization constant until the covariance
                // matrix becomes positive semi-definite.

                if (options.Robust)
                {
                    // No need to apply a regularization constant in this case
                    svd = new SingularValueDecomposition(cov, true, true, true);
                }
                else
                {
                    // Apply a regularization constant until covariance becomes positive
                    chol = new CholeskyDecomposition(cov);

                    // Check if need to add a regularization constant
                    double regularization = options.Regularization;

                    if (regularization > 0)
                    {
                        int dimension = cov.Rows();

                        while (!chol.IsPositiveDefinite)
                        {
                            for (int i = 0; i < dimension; i++)
                            {
                                for (int j = 0; j < dimension; j++)
                                {
                                    if (Double.IsNaN(cov[i, j]) || Double.IsInfinity(cov[i, j]))
                                    {
                                        cov[i, j] = 0.0;
                                    }
                                }

                                cov[i, i] += regularization;
                            }

                            chol = new CholeskyDecomposition(cov, false, true);
                        }
                    }

                    if (!chol.IsPositiveDefinite)
                    {
                        throw new NonPositiveDefiniteMatrixException("Covariance matrix is not positive "
                                                                     + "definite. Try specifying a regularization constant in the fitting options "
                                                                     + "(there is an example in the Multivariate Normal Distribution documentation).");
                    }
                }
            }
        }
        /// <summary>
        ///   Fits the underlying distribution to a given set of observations.
        /// </summary>
        ///
        /// <param name="observations">The array of observations to fit the model against. The array
        ///   elements can be either of type double (for univariate data) or
        ///   type double[] (for multivariate data).</param>
        /// <param name="weights">The weight vector containing the weight for each of the samples.</param>
        /// <param name="options">Optional arguments which may be used during fitting, such
        ///   as regularization constants and additional parameters.</param>
        ///
        /// <example>
        ///   Please see <see cref="MultivariateNormalDistribution"/>.
        /// </example>
        ///
        public void Fit(double[][] observations, double[] weights, NormalOptions options)
        {
            double[] means;
            double[,] cov;


            if (weights != null)
            {
#if DEBUG
                for (int i = 0; i < weights.Length; i++)
                {
                    if (Double.IsNaN(weights[i]) || Double.IsInfinity(weights[i]))
                    {
                        throw new ArgumentException("Invalid numbers in the weight vector.", "weights");
                    }
                }
#endif
                // Compute weighted mean vector
                means = Measures.WeightedMean(observations, weights);

                // Compute weighted covariance matrix
                if (options != null && options.Diagonal)
                {
                    cov = Matrix.Diagonal(Measures.WeightedVariance(observations, weights, means));
                }
                else
                {
                    cov = Measures.WeightedCovariance(observations, weights, means);
                }
            }
            else
            {
                // Compute mean vector
                means = Measures.Mean(observations);

                // Compute covariance matrix
                if (options != null && options.Diagonal)
                {
                    cov = Matrix.Diagonal(Measures.Variance(observations, means));
                }
                cov = Measures.Covariance(observations, means);
            }


            CholeskyDecomposition      chol = null;
            SingularValueDecomposition svd  = null;

            if (options == null)
            {
                // We don't have further options. Just attempt a standard
                // fitting. If the matrix is not positive semi-definite,
                // throw an exception.

                chol = new CholeskyDecomposition(cov,
                                                 robust: false, lowerTriangular: true);

                if (!chol.PositiveDefinite)
                {
                    throw new NonPositiveDefiniteMatrixException("Covariance matrix is not positive "
                                                                 + "definite. Try specifying a regularization constant in the fitting options "
                                                                 + "(there is an example in the Multivariate Normal Distribution documentation).");
                }

                // Become the newly fitted distribution.
                initialize(means, cov, chol, svd: null);

                return;
            }

            // We have options. In this case, we will either be using the SVD
            // or we can add a regularization constant until the covariance
            // matrix becomes positive semi-definite.

            if (options.Robust)
            {
                svd = new SingularValueDecomposition(cov, true, true, true);

                // No need to apply a regularization constant in this case
                // Become the newly fitted distribution.
                initialize(means, cov, null, svd);

                return;
            }


            chol = new CholeskyDecomposition(cov,
                                             robust: false, lowerTriangular: true);

            // Check if need to add a regularization constant
            double regularization = options.Regularization;

            if (regularization > 0)
            {
                int dimension = observations[0].Length;

                while (!chol.PositiveDefinite)
                {
                    for (int i = 0; i < dimension; i++)
                    {
                        for (int j = 0; j < dimension; j++)
                        {
                            if (Double.IsNaN(cov[i, j]) || Double.IsInfinity(cov[i, j]))
                            {
                                cov[i, j] = 0.0;
                            }
                        }

                        cov[i, i] += regularization;
                    }

                    chol = new CholeskyDecomposition(cov, false, true);
                }
            }

            if (!chol.PositiveDefinite)
            {
                throw new NonPositiveDefiniteMatrixException("Covariance matrix is not positive "
                                                             + "definite. Try specifying a regularization constant in the fitting options "
                                                             + "(there is an example in the Multivariate Normal Distribution documentation).");
            }

            // Become the newly fitted distribution.
            initialize(means, cov, chol, svd: null);
        }
        public virtual void Compute()
        {
            if (!onlyCovarianceMatrixAvailable)
            {
                int rows;

                if (this.array != null)
                {
                    rows = array.Length;

                    // Center and standardize the source matrix
                    double[][] matrix = Adjust(array, Overwrite);

                    // Perform the Singular Value Decomposition (SVD) of the matrix
                    var svd = new JaggedSingularValueDecomposition(matrix,
                                                                   computeLeftSingularVectors: true,
                                                                   computeRightSingularVectors: true,
                                                                   autoTranspose: true,
                                                                   inPlace: true);

                    SingularValues = svd.Diagonal;

                    //  The principal components of 'Source' are the eigenvectors of Cov(Source). Thus if we
                    //  calculate the SVD of 'matrix' (which is Source standardized), the columns of matrix V
                    //  (right side of SVD) will be the principal components of Source.

                    // The right singular vectors contains the principal components of the data matrix
                    ComponentVectors = svd.RightSingularVectors.Transpose();
                }
                else
                {
                    rows = source.GetLength(0);

                    // Center and standardize the source matrix
#pragma warning disable 612, 618
                    double[,] matrix = Adjust(source, Overwrite);
#pragma warning restore 612, 618

                    // Perform the Singular Value Decomposition (SVD) of the matrix
                    var svd = new SingularValueDecomposition(matrix,
                                                             computeLeftSingularVectors: true,
                                                             computeRightSingularVectors: true,
                                                             autoTranspose: true,
                                                             inPlace: true);

                    SingularValues = svd.Diagonal;

                    //  The principal components of 'Source' are the eigenvectors of Cov(Source). Thus if we
                    //  calculate the SVD of 'matrix' (which is Source standardized), the columns of matrix V
                    //  (right side of SVD) will be the principal components of Source.

                    // The right singular vectors contains the principal components of the data matrix
                    ComponentVectors = svd.RightSingularVectors.ToArray().Transpose();

                    // The left singular vectors contains the factor scores for the principal components
                }

                // Eigenvalues are the square of the singular values
                Eigenvalues = new double[SingularValues.Length];
                for (int i = 0; i < SingularValues.Length; i++)
                {
                    Eigenvalues[i] = SingularValues[i] * SingularValues[i] / (rows - 1);
                }
            }
            else
            {
                // We only have the covariance matrix. Compute the Eigenvalue decomposition
                var evd = new EigenvalueDecomposition(covarianceMatrix,
                                                      assumeSymmetric: true,
                                                      sort: true);

                // Gets the Eigenvalues and corresponding Eigenvectors
                Eigenvalues = evd.RealEigenvalues;
                var eigenvectors = evd.Eigenvectors.ToJagged();
                SingularValues   = Eigenvalues.Sqrt();
                ComponentVectors = eigenvectors.Transpose();
            }

            if (Whiten)
            {
                ComponentVectors = ComponentVectors.Transpose().Divide(Eigenvalues, dimension: 0).Transpose();
            }

            CreateComponents();

            if (!onlyCovarianceMatrixAvailable)
            {
                if (array != null)
                {
                    result = Transform(array).ToMatrix();
                }
                else if (source != null)
                {
                    result = Transform(source.ToJagged()).ToMatrix();
                }
            }
        }
        public ArgumentsValue Function(MatrixValue M)
        {
            var svd = new SingularValueDecomposition(M);

            return(new ArgumentsValue(svd.S, svd.GetU(), svd.GetV()));
        }
示例#21
0
        private void computeMagCalButton_Click(object sender, EventArgs e)
        {
            int i, j;

            calStatusText.Text = "Computing Calibration...";

            // Construct D matrix
            // D = [x.^2, y.^2, z.^2, x.*y, x.*z, y.*z, x, y, z, ones(N,1)];
            for (i = 0; i < SAMPLES; i++)
            {
                // x^2 term
                D.SetElement(i, 0, loggedData[i, 0] * loggedData[i, 0]);

                // y^2 term
                D.SetElement(i, 1, loggedData[i, 1] * loggedData[i, 1]);

                // z^2 term
                D.SetElement(i, 2, loggedData[i, 2] * loggedData[i, 2]);

                // x*y term
                D.SetElement(i, 3, loggedData[i, 0] * loggedData[i, 1]);

                // x*z term
                D.SetElement(i, 4, loggedData[i, 0] * loggedData[i, 2]);

                // y*z term
                D.SetElement(i, 5, loggedData[i, 1] * loggedData[i, 2]);

                // x term
                D.SetElement(i, 6, loggedData[i, 0]);

                // y term
                D.SetElement(i, 7, loggedData[i, 1]);

                // z term
                D.SetElement(i, 8, loggedData[i, 2]);

                // Constant term
                D.SetElement(i, 9, 1);
            }

            // QR=triu(qr(D))
            QRDecomposition QR = new QRDecomposition(D);
            // [U,S,V] = svd(D)
            SingularValueDecomposition SVD = new SingularValueDecomposition(QR.R);
            GeneralMatrix V = SVD.GetV();

            GeneralMatrix A = new GeneralMatrix(3, 3);

            double[] p = new double[V.RowDimension];

            for (i = 0; i < V.RowDimension; i++)
            {
                p[i] = V.GetElement(i, V.ColumnDimension - 1);
            }

            /*
             * A = [p(1) p(4)/2 p(5)/2;
             * p(4)/2 p(2) p(6)/2;
             * p(5)/2 p(6)/2 p(3)];
             */

            if (p[0] < 0)
            {
                for (i = 0; i < V.RowDimension; i++)
                {
                    p[i] = -p[i];
                }
            }

            A.SetElement(0, 0, p[0]);
            A.SetElement(0, 1, p[3] / 2);
            A.SetElement(1, 2, p[4] / 2);

            A.SetElement(1, 0, p[3] / 2);
            A.SetElement(1, 1, p[1]);
            A.SetElement(1, 2, p[5] / 2);

            A.SetElement(2, 0, p[4] / 2);
            A.SetElement(2, 1, p[5] / 2);
            A.SetElement(2, 2, p[2]);

            CholeskyDecomposition Chol = new CholeskyDecomposition(A);
            GeneralMatrix         Ut   = Chol.GetL();
            GeneralMatrix         U    = Ut.Transpose();

            double[]      bvect = { p[6] / 2, p[7] / 2, p[8] / 2 };
            double        d     = p[9];
            GeneralMatrix b     = new GeneralMatrix(bvect, 3);

            GeneralMatrix v = Ut.Solve(b);

            double vnorm_sqrd = v.GetElement(0, 0) * v.GetElement(0, 0) + v.GetElement(1, 0) * v.GetElement(1, 0) + v.GetElement(2, 0) * v.GetElement(2, 0);
            double s          = 1 / Math.Sqrt(vnorm_sqrd - d);

            GeneralMatrix c = U.Solve(v);

            for (i = 0; i < 3; i++)
            {
                c.SetElement(i, 0, -c.GetElement(i, 0));
            }

            U = U.Multiply(s);

            for (i = 0; i < 3; i++)
            {
                for (j = 0; j < 3; j++)
                {
                    calMat[i, j] = U.GetElement(i, j);
                }
            }

            for (i = 0; i < 3; i++)
            {
                bias[i] = c.GetElement(i, 0);
            }

            magAlignment00.Text = calMat[0, 0].ToString();
            magAlignment01.Text = calMat[0, 1].ToString();
            magAlignment02.Text = calMat[0, 2].ToString();

            magAlignment10.Text = calMat[1, 0].ToString();
            magAlignment11.Text = calMat[1, 1].ToString();
            magAlignment12.Text = calMat[1, 2].ToString();

            magAlignment20.Text = calMat[2, 0].ToString();
            magAlignment21.Text = calMat[2, 1].ToString();
            magAlignment22.Text = calMat[2, 2].ToString();

            biasX.Text = bias[0].ToString();
            biasY.Text = bias[1].ToString();
            biasZ.Text = bias[2].ToString();

            calStatusText.Text               = "Done";
            flashCommitButton.Enabled        = true;
            magAlignmentCommitButton.Enabled = true;
        }
示例#22
0
 public SingularValueDecompositionWrapper(SingularValueDecomposition svd)
 {
     _svd = svd;
 }