Determines the eigenvalues and eigenvectors of a real square matrix.

In the mathematical discipline of linear algebra, eigendecomposition or sometimes spectral decomposition is the factorization of a matrix into a canonical form, whereby the matrix is represented in terms of its eigenvalues and eigenvectors.

If A is symmetric, then A = V * D * V' and A = V * V' where the eigenvalue matrix D is diagonal and the eigenvector matrix V is orthogonal. If A is not symmetric, the eigenvalue matrix D is block diagonal with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The columns of V represent the eigenvectors in the sense that A * V = V * D. The matrix V may be badly conditioned, or even singular, so the validity of the equation A = V * D * inverse(V) depends upon the condition of V.

Inheritance: ICloneable
Beispiel #1
0
        public void LearnAlgorithm(List <byte[]> imageList)
        {
            byte[] array        = new byte[imageList[1].Length];
            byte[] avarageImage = new byte[imageList[1].Length];

            //Calculate avarage face
            for (int i = 0; i < imageList.Count(); i++)
            {
                array = imageList[i];
                for (int j = 0; j < array.Length; j++)
                {
                    avarageImage[j] = (byte)(avarageImage[j] + array[j]);
                }
            }

            for (int j = 0; j < array.Length; j++)
            {
                avarageImage[j] = (byte)(avarageImage[j] / imageList.Count());
            }

            //Make matrix of images

            Double[,] T = new Double[imageList.Count(), avarageImage.Length];

            for (int i = 0; i < imageList.Count(); i++)
            {
                array = imageList[i];
                for (int j = 0; j < avarageImage.Length; j++)
                {
                    T[i, j] = array[j] - avarageImage[j];
                }
            }

            //Making mathematical things

            Double[,] TT = T.Transpose();
            Double[,] C  = Accord.Math.Matrix.Multiply(T, TT);
            EigenvalueDecomposition dec2 = new Accord.Math.Decompositions.EigenvalueDecomposition(C);

            Double[,] V = dec2.Eigenvectors;
            Double[,] E = Accord.Math.Matrix.Multiply(TT, V);;  //EE actually is eigenvectors matrix
            E           = E.Transpose();
            pca         = new PrincipalComponentAnalysis(E);
            pca.Compute();
            R = pca.Transform(T);
        }
        public void InverseTestNaN()
        {
            int n = 5;

            var I = Matrix.Identity(n);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    double[,] value = Matrix.Magic(n);

                    value[i, j] = double.NaN;

                    var target = new EigenvalueDecomposition(value);
                }
            }
        }
Beispiel #3
0
    public void SetToRotations(RotationIndex[] rotationIndices)
    {
        if (rotationIndices.Length == 1)
        {
            SetToRotation(rotationIndices[0].index);
            return;
        }
        var matrixM = Accord.Math.Matrix.Zeros(4, 4);

        double weightSum = 0;

        foreach (RotationIndex rotIdx in rotationIndices)
        {
            Quaternion currRot = GetRotation(rotIdx.index).normalized;

            double[] q = { currRot.x, currRot.y, currRot.z, currRot.w };
            if (currRot.x < 0)
            {
                q.Multiply(-1);
            }
            double currWeight = rotIdx.weight;

            matrixM = (q.Outer(q)).Multiply(currWeight).Add(matrixM);

            weightSum += currWeight;
        }

        matrixM.Divide(weightSum);
        var eigDec = new Accord.Math.Decompositions.EigenvalueDecomposition(matrixM, false, true);

        double[] outQuat = eigDec.Eigenvectors.GetColumn(0);

        Quaternion newRot = new Quaternion((float)outQuat[0], (float)outQuat[1], (float)outQuat[2], (float)outQuat[3]);

        this.transform.localRotation = newRot;
        //this.transform.localRotation = GetRotation(index);
        foreach (KNNBone child in this.children)
        {
            child.SetToRotations(rotationIndices);
        }
    }
        public EllipsoidQuadraticForm(double A, double B, double C, double D, double E, double F, double G, double H, double I, double J)
        {
            var doubleUtils = new DoubleUtils(1e-12);
            if (doubleUtils.Sign(A) < 0) {
                A = -A;
                B = -B;
                C = -C;
                D = -D;
                E = -E;
                F = -F;
                G = -G;
                H = -H;
                I = -I;
                J = -J;
            }
            Requires.Positive(doubleUtils.Sign(A), "A");
            Requires.Positive(doubleUtils.Sign(B), "B");
            Requires.Positive(doubleUtils.Sign(C), "C");
            Requires.Positive(doubleUtils.Sign(A * B - D * D), "A * B - D * D");
            Requires.Positive(doubleUtils.Sign(A * C - E * E), "A * C - E * E");
            Requires.Positive(doubleUtils.Sign(B * C - F * F), "B * C - F * F");
            _coefficients = new[] { A, B, C, D, E, F, G, H, I, J };
            QuadraticFrom = new[,] {
                { A, D, E },
                { D, B, F },
                { E, F, C }
            };
            Offset = new[] { G, H, I, };

            var b = QuadraticFrom.Inverse().Multiply(Offset.Multiply(-1));
            var eigenDecomposition = new EigenvalueDecomposition(QuadraticFrom);
            var axisNumerator = b.ElementwiseMultiply(QuadraticFrom.Multiply(b)).Sum() - J;
            var xradius = System.Math.Sqrt(axisNumerator / eigenDecomposition.RealEigenvalues[0]);
            var yradius = System.Math.Sqrt(axisNumerator / eigenDecomposition.RealEigenvalues[1]);
            var zradius = System.Math.Sqrt(axisNumerator / eigenDecomposition.RealEigenvalues[2]);
            var rotation = eigenDecomposition.Eigenvectors;
            EllipsoidParametricForm = new EllipsoidParametricForm(xradius, yradius, zradius, new Point3D(b[0], b[1], b[2]), rotation);

            var sqrt = rotation.Multiply(eigenDecomposition.DiagonalMatrix.Sqrt().Multiply(rotation.Inverse()));
            AffineTransform = sqrt.Multiply(1.0 / System.Math.Sqrt(axisNumerator));
        }
        public void EigenvalueDecompositionConstructorTest()
        {
            // Symmetric test
            double[,] A =
            {
                { 4, 2 },
                { 2, 4 }
            };

            var target = new EigenvalueDecomposition(A);

            var D = target.DiagonalMatrix;
            var Q = target.Eigenvectors;

            double[,] expectedD =
            { 
                { 2, 0 },
                { 0, 6 }
            };

            double[,] expectedQ = 
            {
               {  0.7071, 0.7071 },
               { -0.7071, 0.7071 }
            };


            Assert.IsTrue(Matrix.IsEqual(expectedD, D, 0.00001));
            Assert.IsTrue(Matrix.IsEqual(expectedQ, Q, 0.0001));


            // Decomposition identity
            var actualA = Matrix.Multiply(Matrix.Multiply(Q, D), Q.Inverse());


            Assert.IsTrue(Matrix.IsEqual(expectedD, D, 0.00001));
            Assert.IsTrue(Matrix.IsEqual(A, actualA, 0.0001));
            Assert.IsTrue(Matrix.IsEqual(A, target.Reverse(), 0.0001));
        }
 /// <summary>Eigenvalue decomposition.</summary>
 protected static double[] eig(double[,] a, out double[,] V, out double[] im)
 {
     var eig = new EigenvalueDecomposition(a);
     V = eig.Eigenvectors;
     im = eig.ImaginaryEigenvalues;
     return eig.RealEigenvalues;
 }
        public void EigenvalueDecompositionConstructorTest2()
        {
            // Asymmetric test
            double[,] A =
            {
                {  5, 2, 1 },
                {  1, 4, 1 },
                { -1, 2, 3 }
            };

            EigenvalueDecomposition target = new EigenvalueDecomposition(A);
            var D = target.DiagonalMatrix;
            var Q = target.Eigenvectors;

            double[,] expectedD =
            { 
                { 6, 0, 0 },
                { 0, 4, 0 },
                { 0, 0, 2 }
            };

            // Decomposition identity
            var actualA = Q.Multiply(D).Multiply(Q.Inverse());

            Assert.IsTrue(Matrix.IsEqual(expectedD, D, 0.00001));
            Assert.IsTrue(Matrix.IsEqual(A, actualA, 0.0001));

        }
 /// <summary>
 ///   Creates a new object that is a copy of the current instance.
 /// </summary>
 /// <returns>
 ///   A new object that is a copy of this instance.
 /// </returns>
 public object Clone()
 {
     var clone = new EigenvalueDecomposition();
     clone.d = (Double[])d.Clone();
     clone.e = (Double[])e.Clone();
     clone.H = (Double[,])H.Clone();
     clone.n = n;
     clone.ort = (Double[])ort;
     clone.symmetric = symmetric;
     clone.V = (Double[,])V.Clone();
     return clone;
 }
Beispiel #9
0
        static void Main(string[] args)
        {
            Console.WriteLine("Please take a look at the source for examples!");
            Console.ReadKey();

            #region 1. Declaring matrices

            // 1.1 Using standard .NET declaration
            double[,] A = 
            {
                {1, 2, 3},
                {6, 2, 0},
                {0, 0, 1}
            };

            double[,] B = 
            {
                {2, 0, 0},
                {0, 2, 0},
                {0, 0, 2}
            };

            {
                // 1.2 Using Accord extension methods
                double[,] Bi = Matrix.Identity(3).Multiply(2);
                double[,] Bj = Matrix.Diagonal(3, 2.0); // both are equal to B

                // 1.2 Using Accord extension methods with implicit typing
                var I = Matrix.Identity(3);
            }
            #endregion



            #region 2. Matrix Operations
            {
                // 2.1 Addition
                var C = A.Add(B);

                // 2.2 Subtraction
                var D = A.Subtract(B);

                // 2.3 Multiplication
                {
                    // 2.3.1 By a scalar
                    var halfM = A.Multiply(0.5);

                    // 2.3.2 By a vector
                    double[] m = A.Multiply(new double[] { 1, 2, 3 });

                    // 2.3.3 By a matrix
                    var M = A.Multiply(B);

                    // 2.4 Transposing
                    var At = A.Transpose();
                }
            }


            // 2.5 Elementwise operations

            // 2.5.1 Elementwise multiplication
            A.ElementwiseMultiply(B); // A.*B

            // 2.5.1 Elementwise division
            A.ElementwiseDivide(B); // A./B

            #endregion



            #region 3. Matrix characteristics
            {
                // 3.1 Calculating the determinant
                double det = A.Determinant();

                // 3.2 Calculating the trace
                double tr = A.Trace();

                // 3.3 Computing the sum vector
                {
                    double[] sumVector = A.Sum();

                    // 3.3.1 Computing the total sum of elements
                    double sum = sumVector.Sum();

                    // 3.3.2 Computing the sum along the rows
                    sumVector = A.Sum(0); // Equivalent to Octave's sum(A, 1)

                    // 3.3.2 Computing the sum along the columns
                    sumVector = A.Sum(1); // Equivalent to Octave's sum(A, 2)
                }
            }
            #endregion



            #region 4. Linear Algebra
            {
                // 4.1 Computing the inverse
                var invA = A.Inverse();

                // 4.2 Computing the pseudo-inverse
                var pinvA = A.PseudoInverse();

                // 4.3 Solving a linear system (Ax = B)
                var x = A.Solve(B);
            }
            #endregion



            #region 5. Special operators
            {
                // 5.1 Finding the indices of elements
                double[] v = { 5, 2, 2, 7, 1, 0 };
                int[] idx = v.Find(e => e > 2); // finding the index of every element in v higher than 2.

                // 5.2 Selecting elements by index
                double[] u = v.Submatrix(idx); // u is { 5, 7 }

                // 5.3 Converting between different matrix representations
                double[][] jaggedA = A.ToArray(); // from multidimensional to jagged array

                // 5.4 Extracting a column or row from the matrix
                double[] a = A.GetColumn(0); // retrieves the first column
                double[] b = B.GetRow(1); // retrieves the second row

                // 5.5 Taking the absolute of a matrix
                var absA = A.Abs();

                // 5.6 Applying some function to every element
                var newv = v.Apply(e => e + 1);
            }
            #endregion



            #region 7. Vector operations
            {
                double[] u = { 1, 2, 3 };
                double[] v = { 4, 5, 6 };

                var w1 = u.InnerProduct(v);
                var w2 = u.OuterProduct(v);
                var w3 = u.CartesianProduct(v);


                double[] m = { 1, 2, 3, 4 };
                double[,] M = Matrix.Reshape(m, 2, 2);
            }
            #endregion


            #region Decompositions
            {
                // Singular value decomposition
                {
                    SingularValueDecomposition svd = new SingularValueDecomposition(A);
                    var U = svd.LeftSingularVectors;
                    var S = svd.Diagonal;
                    var V = svd.RightSingularVectors;
                }
                // or (please see documentation for details)
                {
                    SingularValueDecomposition svd = new SingularValueDecomposition(A.Transpose());
                    var U = svd.RightSingularVectors;
                    var S = svd.Diagonal;
                    var V = svd.LeftSingularVectors;
                }

                // Eigenvalue decomposition
                {
                    EigenvalueDecomposition eig = new EigenvalueDecomposition(A);
                    var V = eig.Eigenvectors;
                    var D = eig.DiagonalMatrix;
                }

                // QR decomposition
                {
                    QrDecomposition qr = new QrDecomposition(A);
                    var Q = qr.OrthogonalFactor;
                    var R = qr.UpperTriangularFactor;
                }

                // Cholesky decomposition
                {
                    CholeskyDecomposition chol = new CholeskyDecomposition(A);
                    var R = chol.LeftTriangularFactor;
                }

                // LU decomposition
                {
                    LuDecomposition lu = new LuDecomposition(A);
                    var L = lu.LowerTriangularFactor;
                    var U = lu.UpperTriangularFactor;
                }

            }
            #endregion

        }
        /// <summary>
        ///   Computes the Kernel Principal Component Analysis algorithm.
        /// </summary>
        /// 
        public void Compute(int components)
        {
            if (components < 0 || components > Source.GetLength(0))
            {
                throw new ArgumentException(
                    "The number of components must be between 0 and " +
                    "the number of rows in your source data matrix.");
            }

            int dimension = Source.GetLength(0);

            // If needed, center the source matrix
            sourceCentered = Adjust(Source, Overwrite);


            // Create the Gram (Kernel) Matrix
            this.kernelMatrix = new double[dimension, dimension];
            for (int i = 0; i < dimension; i++)
            {
                double[] row = sourceCentered.GetRow(i);
                for (int j = i; j < dimension; j++)
                {
                    double k = kernel.Function(row, sourceCentered.GetRow(j));
                    kernelMatrix[i, j] = k; // Kernel matrix is symmetric
                    kernelMatrix[j, i] = k;
                }
            }


            // Center the Gram (Kernel) Matrix if requested
            double[,] Kc = centerFeatureSpace ? centerKernel(kernelMatrix) : kernelMatrix;


            // Perform the Eigenvalue Decomposition (EVD) of the Kernel matrix
            EigenvalueDecomposition evd = new EigenvalueDecomposition(Kc, assumeSymmetric: true);

            // Gets the Eigenvalues and corresponding Eigenvectors
            double[] evals = evd.RealEigenvalues;
            double[,] eigs = evd.Eigenvectors;


            // Sort eigenvalues and vectors in descending order
            eigs = Matrix.Sort(evals, eigs, new GeneralComparer(ComparerDirection.Descending, true));


            // Eliminate unwanted components
            if (components != Source.GetLength(0))
            {
                eigs = eigs.Submatrix(null, 0, components - 1);
                evals = evals.Submatrix(0, components - 1);
            }

            if (threshold > 0)
            {
                // We will be discarding less important
                // eigenvectors to conserve memory.

                // Calculate component proportions
                double sum = 0.0; // total variance
                for (int i = 0; i < evals.Length; i++)
                    sum += Math.Abs(evals[i]);

                if (sum > 0)
                {
                    int keep = 0;

                    // Now we will detect how many components we have
                    //  have to keep in order to achieve the level of
                    //  explained variance specified by the threshold.

                    while (keep < components)
                    {
                        // Get the variance explained by the component
                        double explainedVariance = Math.Abs(evals[keep]);

                        // Check its proportion
                        double proportion = explainedVariance / sum;

                        // Now, if the component explains an
                        // enough proportion of the variance,
                        if (proportion > threshold)
                            keep++; // We can keep it.
                        else
                            break;  // Otherwise we can stop, since the
                        // components are ordered by variance.
                    }

                    if (keep != components)
                    {
                        if (keep > 0)
                        {
                            // Resize the vectors keeping only needed components
                            eigs = eigs.Submatrix(0, components - 1, 0, keep - 1);
                            evals = evals.Submatrix(0, keep - 1);
                        }
                        else
                        {
                            // No component will be kept.
                            eigs = new double[dimension, 0];
                            evals = new double[0];
                        }
                    }
                }
            }


            // Normalize eigenvectors
            if (centerFeatureSpace)
            {
                for (int j = 0; j < evals.Length; j++)
                {
                    double val = Math.Sqrt(Math.Abs(evals[j]));
                    for (int i = 0; i < eigs.GetLength(0); i++)
                        eigs[i, j] = eigs[i, j] / val;
                }
            }



            // Set analysis properties
            this.SingularValues = new double[evals.Length];
            this.Eigenvalues = evals;
            this.ComponentMatrix = eigs;


            // Project the original data into principal component space
            this.Result = Kc.Multiply(eigs);


            // Computes additional information about the analysis and creates the
            //  object-oriented structure to hold the principal components found.
            CreateComponents();
        }
        private double[][] getFeature(double[][] input, int K)
        {
            //var activationContext = Type.GetTypeFromProgID("matlab.application.single");
            //var matlab = (MLApp.MLApp)Activator.CreateInstance(activationContext);
            //matlab.Visible = 0;

            int i, j;

            int row = input[0].Length;
            int column = input.Length;
            double[][] X = new double[column][];

            for (i = 0; i < column; i++) {
            X[i] = input[i].Subtract(this.meanMatrix);
            }

               // matlab.PutWorkspaceData("X", "base", X.ToMatrix());
              //  MessageBox.Show(matlab.Execute("XTX=X'*X;"));
              //  MessageBox.Show(matlab.Execute("size(XTX)"));
             //   var t = matlab.GetVariable("XTX", "base");
            //    matlab.Quit();

            double[][] XT = X.Transpose();
            double[,] XTX = X.Multiply(XT).ToMatrix();
            var feature = new EigenvalueDecomposition(XTX);

            //EigenvalueDecomposition feature = XTX.eig();
            double[] d = feature.RealEigenvalues;

            //	assert d.length >= K : "number of eigenvalues is less than K";
            int[] indexes;
            d.StableSort(out indexes);
               indexes= indexes.Reverse().ToArray();
            indexes = indexes.Submatrix(0, K-1);

            double[][] eigenVectors = XT.Multiply(feature.Eigenvectors.ToArray());
            double[][] selectedEigenVectors = eigenVectors.Submatrix(0,
                eigenVectors.Length - 1, indexes);

            // normalize the eigenvectors
            row = selectedEigenVectors.Length;
            column = selectedEigenVectors[0].Length;
            for (i = 0; i < column; i++) {
            double temp = 0;
            for (j = 0; j < row; j++)
                temp += Math.Pow(selectedEigenVectors[j][ i], 2);
            temp = Math.Sqrt(temp);

            for (j = 0; j < row; j++) {
                selectedEigenVectors[j][ i]= selectedEigenVectors[j][ i] / temp;
            }
            }

            return selectedEigenVectors;
        }
        public Matrix KLTransform(Matrix matrix)
        {
            matrix = (Matrix)matrix.Transpose();

            int columnNumber = matrix.ColumnCount;

            Matrix mean = GetMean(matrix);

            //Don't print it becouse is a lot of values
          //  PrintMatrix(mean, null, " mean matrix"); - 

            float[,] oneD = new float[1, columnNumber];
            for (int i = 0; i < columnNumber; i++)
            {
                oneD[0, i] = 1;
            }

            //so called edinichna matrica
            Matrix onesMatrix = DenseMatrix.OfArray(oneD);

            // center the data
            Matrix xm = (DenseMatrix)matrix.Subtract(mean.Multiply(onesMatrix));
           // PrintMatrix(null, xm.ToArray(), "center the data");

            // Calculate covariance matrix

            DenseMatrix cov = (DenseMatrix)(xm.Multiply(xm.Transpose())).Multiply(1.0f / columnNumber);
          //  PrintMatrix(cov, null, "Calculate covariance matrix");
            PrintText(cov.ColumnCount.ToString() + " Calculate covariance  ColumnCount");
            PrintText(cov.RowCount.ToString() + " Calculate covariance  RowCount");

            //this is from another libraly accord .net 
            EigenvalueDecomposition v = new EigenvalueDecomposition(FromFloatMatrixToDouble(cov.ToArray()));

            double[,] eigVectors = v.Eigenvectors;
            double[,] eidDiagonal = v.DiagonalMatrix;

            Matrix eigVectorsTransposedMatrix = (DenseMatrix)DenseMatrix.OfArray(FromDoubleMatrixToFlaot(eigVectors)).Transpose();
            Matrix eidDiagonalMatrix = DenseMatrix.OfArray(FromDoubleMatrixToFlaot(eidDiagonal));

            int rowsCountDiagonals = eidDiagonal.GetLength(0);
            int maxLambdaIndex = 0;
            for (int i = 0; i < rowsCountDiagonals - 1; i++)
            {
                if (eidDiagonal[i, i] <= eidDiagonal[i + 1, i + 1])
                {
                    maxLambdaIndex = i + 1;
                }
            }

            double maxAlpha = eidDiagonal[maxLambdaIndex, maxLambdaIndex];

            double sumAlpha = 0;
            for (int i = 0; i < rowsCountDiagonals; i++)
            {
                sumAlpha += eidDiagonal[i, i];
            }

            CalculateAndPrintError(maxAlpha, sumAlpha);
           PrintText("Max lambda index " + maxLambdaIndex);

           // PrintMatrix(eidDiagonalMatrix, null, "Eign vals");

            // //PCA

            float[,] arr = new float[1, eigVectorsTransposedMatrix.ColumnCount];
            for (int i = 0; i < eigVectorsTransposedMatrix.ColumnCount; i++)
            {
                arr[0, i] = eigVectorsTransposedMatrix[maxLambdaIndex, i];
            }

            Matrix mainComponentMatrix = DenseMatrix.OfArray(arr);
          //  PrintMatrix(mainComponentMatrix, null, "Main Component");


            Matrix pca = (DenseMatrix)mainComponentMatrix.Multiply(xm);
          //  PrintMatrix(pca, null, "PCA");

            return pca;

        }
        public LDA(double[][] trainingSet, List<string> labels,int numOfComponents)
        {
            int n = trainingSet.Length; // sample size
            HashSet<String> tempSet = new HashSet<String>(labels);
            int c = tempSet.Count; // class size

            // process in PCA
            PCA pca = new PCA(trainingSet, labels, n - c);

            // classify
            double[][] meanTotal = new double[n - c][];
            for (int i = 0; i < n - c; i++)
            {
            meanTotal[i] = new double[1];
            }
            Dictionary<String, List<double[]>> dict = new Dictionary<String, List<double[]>>();
            List<projectedTrainingMatrix> pcaTrain = pca.getProjectedTrainingSet();
            for (int i = 0; i < pcaTrain.Count; i++) {
            String key = pcaTrain[i].label;
               meanTotal= meanTotal.Add(pcaTrain[i].matrix);
            if (!dict.ContainsKey(key)) {
                List<double[]> temp = new List<double[]>();

               temp.Add(pcaTrain[i].matrix.Transpose()[0]);
                dict.Add(key, temp);
            } else {
                List<double[]> temp = dict[key];
                temp.Add(pcaTrain[i].matrix.Transpose()[0]);
                dict[key]= temp;
            }
            }
            meanTotal.ToMatrix().Multiply((double) 1 / n);

            // calculate Sw, Sb
            double[][] Sw = new double[n - c][];
            double[][] Sb = new double[n - c][];
            for (int i = 0; i < n - c; i++)
            {
            Sw[i] = new double[n-c];
            Sb[i] = new double[n-c];
            }
            List<String> labelSet = dict.Keys.ToList();
            foreach(string label in labelSet)
               {
               List<double[]> tempMatrix = dict[label];
               double[][] matrixWithinThatClass = tempMatrix.ToArray();
               double[] meanOfCurrentClass = Accord.Statistics.Tools.Mean(matrixWithinThatClass);
            for (int i = 0; i < matrixWithinThatClass.Length; i++) {
                double[][] temp1 = matrixWithinThatClass[i].ToArray().Subtract(meanOfCurrentClass.ToArray());
                temp1 = temp1.Multiply(temp1.Transpose());
                Sw =Sw.Add(temp1);
            }

            double[][] temp = meanOfCurrentClass.ToArray().Subtract(meanTotal);
            temp = temp.Multiply(temp.Transpose()).ToMatrix().Multiply((double)matrixWithinThatClass.Length).ToArray();
            Sb=Sb.Add(temp);
            }

            // calculate the eigenvalues and vectors of Sw^-1 * Sb
            double [][] targetForEigen = Sw.Inverse().Multiply(Sb);
            var feature = new EigenvalueDecomposition(targetForEigen.ToMatrix());

            double[] d = feature.RealEigenvalues;
            int[] indexes;
            d.StableSort(out indexes);
            indexes = indexes.Reverse().ToArray();

            indexes = indexes.Submatrix(0, c - 1);

               //int[] indexes = getIndexesOfKEigenvalues(d, c - 1);

            double[][] eigenVectors = feature.Eigenvectors.ToArray();
            double[][] selectedEigenVectors = eigenVectors.Submatrix(0,	eigenVectors.Length - 1, indexes);

            this.W = pca.getW().Multiply(selectedEigenVectors);

            // Construct projectedTrainingMatrix
            this.projectedTrainingSet = new List<projectedTrainingMatrix>();
             for (int i = 0; i < trainingSet.Length; i++) {
            projectedTrainingMatrix ptm = new projectedTrainingMatrix(this.W.Transpose().Multiply(trainingSet[i].Subtract(pca.meanMatrix).ToArray()), labels[i]);
            this.projectedTrainingSet.Add(ptm);
            }
            this.meanMatrix= pca.meanMatrix;
            GC.Collect();
        }
Beispiel #14
0
        public void CalculateLambda2CriterionIrregularGrids(List <Vector3d> pointsToRegistrate, Dictionary <string, List <float> > scalarValues, List <string> scalarNames, List <Vector4> tetraPoints)
        {
            List <float> scalarValuesX = new List <float>();
            List <float> scalarValuesY = new List <float>();
            List <float> scalarValuesZ = new List <float>();

            //if (scalarNames.Count() <= 4)
            //{
            scalarValues.TryGetValue(scalarNames[0], out scalarValuesX);
            scalarValues.TryGetValue(scalarNames[1], out scalarValuesY);
            scalarValues.TryGetValue(scalarNames[2], out scalarValuesZ);
            //}
            //else
            //{
            //    scalarValues.TryGetValue(scalarNames[1], out scalarValuesX);
            //    scalarValues.TryGetValue(scalarNames[2], out scalarValuesY);
            //    scalarValues.TryGetValue(scalarNames[3], out scalarValuesZ);
            //}

            vtkDoubleArray lambda2Values     = new vtkDoubleArray();
            List <double>  lambda2ValuesList = new List <double>();

            // create vectorfield
            List <Vector3d> vectorField = new List <Vector3d>();

            for (int i = 0; i < scalarValuesX.Count(); i++)
            {
                Vector3d vec = new Vector3d(scalarValuesX[i], scalarValuesY[i], scalarValuesZ[i]);

                vectorField.Add(vec);
            }

            int count = 0;

            double[,] lambda2ValuesArray = new double[pointsToRegistrate.Count(), 2];
            for (int k = 0; k < tetraPoints.Count(); k++)
            {
                // first rows and than columns
                double[,] A         = new double[12, 12];
                double[,] rightSide = new double[12, 1];
                int i = 0, j = 0;
                int s = 0;

                if (k == 779834)
                {
                    Console.WriteLine("Test");
                }

                for (int g = 0; g < 12; g += 3, i++, s++)
                {
                    //1-3 columns of 4x3 Matrix
                    for (int l = 0; l < 3; l++)
                    {
                        for (int m = 0; m < 3; m++)
                        {
                            if (l == m)
                            {
                                // Warum tetraPoints[k]
                                A[g + l, m] = pointsToRegistrate[(int)tetraPoints[k][i]].X;
                            }
                            else
                            {
                                A[g + l, m] = 0;
                            }
                        }
                    }
                    for (int l = 0; l < 3; l++)
                    {
                        for (int m = 3; m < 6; m++)
                        {
                            if (l == (m - 3))
                            {
                                A[g + l, m] = pointsToRegistrate[(int)tetraPoints[k][i]].Y;
                            }
                            else
                            {
                                A[g + l, m] = 0;
                            }
                        }
                    }
                    for (int l = 0; l < 3; l++)
                    {
                        for (int m = 6; m < 9; m++)
                        {
                            if (l == (m - 6))
                            {
                                A[g + l, m] = pointsToRegistrate[(int)tetraPoints[k][i]].Z;
                            }
                            else
                            {
                                A[g + l, m] = 0;
                            }
                        }
                    }

                    for (int l = 0; l < 3; l++)
                    {
                        for (int m = 9; m < 12; m++)
                        {
                            if (l == (m - 9))
                            {
                                A[g + l, m] = 1;
                            }
                            else
                            {
                                A[g + l, m] = 0;
                            }
                        }
                    }

                    rightSide[g, 0]     = vectorField[(int)tetraPoints[k][s]].X;
                    rightSide[g + 1, 0] = vectorField[(int)tetraPoints[k][s]].Y;
                    rightSide[g + 2, 0] = vectorField[(int)tetraPoints[k][s]].Z;
                }

                //for (int l = 0; l < 12; l++)
                //{
                //    for (int m = 0; m < 12; m++)
                //    {
                //        Console.Write(A[l, m] + " ");
                //    }
                //    Console.WriteLine("");
                //}



                double[,] Vold = Accord.Math.Matrix.Solve(A, rightSide, leastSquares: true);
                // Solve matrix with matlab
                //LGS lgsObj = new LGS();
                //MWNumericArray mwV = (MWNumericArray)lgsObj.solveLGS((MWNumericArray)A, (MWNumericArray)rightSide);
                //double[,] V = new double[mwV.Dimensions[0], 1];
                //for (i = 1; i <= mwV.Dimensions[1]; i++)
                //{
                //    V[i, 0] = (double)mwV[1, i];
                //}

                double[,] jacobiMat = new double[3, 3];
                int n = 0;
                for (i = 0; i < 3; i++)
                {
                    for (j = 0; j < 3; j++)
                    {
                        // first increas rows and than columns
                        jacobiMat[j, i] = Vold[n, 0];
                        //jacobiMat[i, j] = Vold[n, 0];
                        n++;
                    }
                }

                if (jacobiMat[1, 1] == 0 && jacobiMat[0, 0] == 0 && jacobiMat[2, 2] == 0)
                {
                    //lambda2Values.InsertNextValue(0);
                    //lambda2ValuesList.Add(0);

                    count++;
                }
                //only if diagonal elements are not equal zero
                else
                {
                    MatrixOperations classObj = new MatrixOperations();

                    double[,] transposedJacobiMat = classObj.TransposeRowsAndColumns(jacobiMat);
                    // calculation of S und Omega
                    double[,] S        = classObj.DivideArrayByValue(classObj.AddArrays(jacobiMat, transposedJacobiMat), 2);
                    double[,] squaredS = classObj.MultiplyArrays(S, S);

                    double[,] Omega        = classObj.DivideArrayByValue(classObj.SubtractArrays(jacobiMat, transposedJacobiMat), 2);
                    double[,] squaredOmega = classObj.MultiplyArrays(Omega, Omega);

                    double[,] summation = classObj.AddArrays(squaredS, squaredOmega);

                    var    eigenvalueDecomposition = new Accord.Math.Decompositions.EigenvalueDecomposition(summation, false, true, true);
                    var    eigenVec   = eigenvalueDecomposition.Eigenvectors;
                    var    eigenValue = eigenvalueDecomposition.RealEigenvalues;
                    double lambda2    = eigenValue[1];

                    //int t = (int)lambda2Values.InsertNextValue(lambda2);

                    //lambda2ValuesList.Add(lambda2);

                    lambda2ValuesArray[(int)tetraPoints[k][0], 0] += lambda2;
                    lambda2ValuesArray[(int)tetraPoints[k][0], 1] += 1;


                    lambda2ValuesArray[(int)tetraPoints[k][1], 0] += lambda2;
                    lambda2ValuesArray[(int)tetraPoints[k][1], 1] += 1;

                    lambda2ValuesArray[(int)tetraPoints[k][2], 0] += lambda2;
                    lambda2ValuesArray[(int)tetraPoints[k][2], 1] += 1;

                    lambda2ValuesArray[(int)tetraPoints[k][3], 0] += lambda2;
                    lambda2ValuesArray[(int)tetraPoints[k][3], 1] += 1;

                    //if (k == 779834)
                    //    Console.WriteLine("Test");

                    //if (lambda2 < 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][0], 0] = lambda2;
                    //    lambda2ValuesArray[(int)tetraPoints[k][0], 1] += 1;
                    //}
                    ////else
                    ////{
                    ////    lambda2ValuesArray[(int)tetraPoints[k][0], 0] += lambda2;
                    ////    lambda2ValuesArray[(int)tetraPoints[k][0], 1] += 1;
                    ////}
                    //if (lambda2 < 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][1], 0] = lambda2;
                    //    lambda2ValuesArray[(int)tetraPoints[k][1], 1] += 1;

                    //}
                    ////else
                    ////{
                    ////    lambda2ValuesArray[(int)tetraPoints[k][1], 0] += lambda2;
                    ////    lambda2ValuesArray[(int)tetraPoints[k][1], 1] += 1;
                    ////}
                    //if (lambda2 < 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][2], 0] = lambda2;
                    //    lambda2ValuesArray[(int)tetraPoints[k][2], 1] += 1;

                    //}
                    ////else
                    ////{
                    ////    lambda2ValuesArray[(int)tetraPoints[k][2], 0] += lambda2;
                    ////    lambda2ValuesArray[(int)tetraPoints[k][2], 1] += 1;
                    ////}
                    //if (lambda2 < 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][3], 0] = lambda2;
                    //    lambda2ValuesArray[(int)tetraPoints[k][3], 1] += 1;

                    //}

                    // if (lambda2ValuesArray[(int)tetraPoints[k][0], 1] == 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][0], 0] = lambda2;
                    //}
                    // if (lambda2ValuesArray[(int)tetraPoints[k][1], 1] == 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][1], 0] = lambda2;
                    //}
                    // if (lambda2ValuesArray[(int)tetraPoints[k][2], 1] == 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][2], 0] = lambda2;
                    //}
                    // if (lambda2ValuesArray[(int)tetraPoints[k][3], 1] == 0)
                    //{
                    //    lambda2ValuesArray[(int)tetraPoints[k][3], 0] = lambda2;
                    //}
                }
            }
            for (int i = 0; i < pointsToRegistrate.Count(); i++)
            {
                if (lambda2ValuesArray[i, 1] > 1)
                {
                    double lambda2 = lambda2ValuesArray[i, 0] / lambda2ValuesArray[i, 1];
                    //if (lambda2 < 0)
                    //    Console.WriteLine("lambda2 ist " + lambda2);
                    lambda2ValuesList.Add(lambda2);
                    lambda2Values.InsertNextValue(lambda2);
                    count++;
                }
                else
                {
                    count++;
                    lambda2Values.InsertNextValue(lambda2ValuesArray[i, 0]);
                }
            }

            //WriteScalarDifferences(lambda2ValuesList, "..\\..\\..\\..\\..\\03Daten\\lambda2\\Tomo_lambda2regularGridsOwnEigen.txt");
            vtkDataArray dataArray;

            dataArray = lambda2Values;
            dataArray.SetName("lambda2");
            if (this.scalar_dataArray.ContainsKey("lambda2"))
            {
                this.scalar_dataArray["lambda2"] = lambda2Values;
            }

            else
            {
                this.scalar_dataArray.Add("lambda2", dataArray);
                this.arrayNames.Add("lambda2");
            }
        }
Beispiel #15
0
        public void CalculateLambdaCriterionRegularGrids(List <Vector3d> pointsToRegistrate, Dictionary <string, List <float> > scalarValues, List <string> scalarNames, int[] dimensions)
        {
            List <float> scalarValuesX = new List <float>();

            scalarValues.TryGetValue(scalarNames[0], out scalarValuesX);
            List <float> scalarValuesY = new List <float>();

            scalarValues.TryGetValue(scalarNames[1], out scalarValuesY);
            List <float> scalarValuesZ = new List <float>();

            scalarValues.TryGetValue(scalarNames[2], out scalarValuesZ);

            // create vectorfield
            List <Vector3d> vectorField = new List <Vector3d>();

            for (int i = 0; i < scalarValuesX.Count(); i++)
            {
                Vector3d vec = new Vector3d(scalarValuesX[i], scalarValuesY[i], scalarValuesZ[i]);

                vectorField.Add(vec);
            }

            vtkDoubleArray lambda2Values = new vtkDoubleArray();
            // lambda2Values.SetNumberOfValues(vectorField.Count());

            int sizeJacobimat = 3;

            // iterating over all points
            for (int k = 0; k < vectorField.Count(); k++)
            {
                if (k == 356003)
                {
                    Console.WriteLine("ID");
                }
                double[,] jacobiMat = new double[sizeJacobimat, sizeJacobimat];

                for (int j = 0, i = 0; j < sizeJacobimat; j++, i++)
                {
                    Vector3d vec = vectorField[k];

                    Vector3d gradVec = new Vector3d();
                    // first column of jacobi matrix
                    if (i == 0)
                    {
                        // forward difference
                        if (k == 0)
                        {
                            double hx = Math.Abs(pointsToRegistrate[k + 1].X - pointsToRegistrate[k].X);
                            gradVec = (vectorField[k + 1] - vec) / hx;
                        }
                        // backward difference
                        else if (k == vectorField.Count() - 1)
                        {
                            double hx = Math.Abs(pointsToRegistrate[k - 1].X - pointsToRegistrate[k].X);
                            gradVec = (vec - vectorField[k - 1]) / hx;
                        }
                        // central difference
                        else
                        {
                            double   hx = Math.Abs(pointsToRegistrate[k + 1].X - pointsToRegistrate[k].X);
                            Vector3d f  = vectorField[k + 1];
                            Vector3d b  = vectorField[k - 1];
                            gradVec = (f - b) / (2 * hx);
                        }
                    }
                    // second column of jacobi matrix
                    else if (i == 1)
                    {
                        // forward difference
                        if (k - dimensions[0] < 0)
                        {
                            double hy = Math.Abs(pointsToRegistrate[k + dimensions[0]].Y - pointsToRegistrate[k].Y);
                            gradVec = (vectorField[k + dimensions[0]] - vec) / hy;
                        }
                        // backward difference
                        else if (k + dimensions[0] > vectorField.Count() - 1)
                        {
                            double hy = Math.Abs(pointsToRegistrate[k - dimensions[0]].Y - pointsToRegistrate[k].Y);
                            gradVec = (vec - vectorField[k - dimensions[0]]) / hy;
                        }
                        // central difference
                        else
                        {
                            double   hy = Math.Abs(pointsToRegistrate[k + dimensions[0]].Y - pointsToRegistrate[k].Y);
                            Vector3d f  = vectorField[k + dimensions[0]];
                            Vector3d b  = vectorField[k - dimensions[0]];
                            gradVec = (f - b) / (2 * hy);
                        }
                    }
                    // third column of jacobi matrix
                    else if (i == 2)
                    {
                        // forward difference
                        if (k - (dimensions[0] * dimensions[1]) < 0)
                        {
                            double hz = Math.Abs(pointsToRegistrate[k + (dimensions[0] * dimensions[1])].Z - pointsToRegistrate[k].Z);
                            gradVec = (vectorField[k + (dimensions[0] * dimensions[1])] - vec) / hz;
                        }
                        // backward difference
                        else if (k + (dimensions[0] * dimensions[1]) > vectorField.Count() - 1)
                        {
                            double hz = Math.Abs(pointsToRegistrate[k - (dimensions[0] * dimensions[1])].Z - pointsToRegistrate[k].Z);
                            gradVec = (vec - vectorField[k - (dimensions[0] * dimensions[1])]) / hz;
                        }
                        // central difference
                        else
                        {
                            double   hz = Math.Abs(pointsToRegistrate[k + (dimensions[0] * dimensions[1])].Z - pointsToRegistrate[k].Z);
                            Vector3d f  = vectorField[k + (dimensions[0] * dimensions[1])];
                            Vector3d b  = vectorField[k - (dimensions[0] * dimensions[1])];
                            gradVec = (f - b) / (2 * hz);
                        }
                    }
                    // fill jacobi matrix
                    jacobiMat[0, j] = gradVec[0];
                    jacobiMat[1, j] = gradVec[1];
                    if (sizeJacobimat == 3)
                    {
                        jacobiMat[2, j] = gradVec[2];
                    }
                }
                // only if diagonal elements are not equal zero
                if (jacobiMat[1, 1] == 0 && jacobiMat[0, 0] == 0 && jacobiMat[2, 2] == 0)
                {
                    lambda2Values.InsertNextValue(0);
                }
                else
                {
                    MatrixOperations classObj = new MatrixOperations();

                    double[,] transposedJacobiMat = classObj.TransposeRowsAndColumns(jacobiMat);
                    // calculation of S und Omega
                    double[,] S        = classObj.DivideArrayByValue(classObj.AddArrays(jacobiMat, transposedJacobiMat), 2);
                    double[,] squaredS = classObj.MultiplyArrays(S, S);

                    double[,] Omega        = classObj.DivideArrayByValue(classObj.SubtractArrays(jacobiMat, transposedJacobiMat), 2);
                    double[,] squaredOmega = classObj.MultiplyArrays(Omega, Omega);

                    double[,] summation = classObj.AddArrays(squaredS, squaredOmega);

                    var    eigenvalueDecomposition = new Accord.Math.Decompositions.EigenvalueDecomposition(summation, false, false, true);
                    var    eigenVec   = eigenvalueDecomposition.Eigenvectors;
                    var    eigenValue = eigenvalueDecomposition.RealEigenvalues;
                    double lambda2    = eigenValue[1];


                    lambda2Values.InsertNextValue(lambda2);
                }
            }
            vtkDataArray dataArray;

            dataArray = lambda2Values;
            dataArray.SetName("lambda2");
            Console.WriteLine("All lambda2 were calculated!");
            if (this.scalar_dataArray.ContainsKey("lambda2"))
            {
                this.scalar_dataArray["lambda2"] = lambda2Values;
            }

            else
            {
                this.scalar_dataArray.Add("lambda2", dataArray);
                this.arrayNames.Add("lambda2");
            }
        }