/**
         * Computes a basis (the principal components) from the most dominant eigenvectors.
         *
         * @param numComponents Number of vectors it will use to describe the data.  Typically much
         * smaller than the number of elements in the input vector.
         */
        public void computeBasis(int numComponents)
        {
            if (numComponents > A.getNumCols())
            {
                throw new ArgumentException("More components requested that the data's length.");
            }
            if (sampleIndex != A.getNumRows())
            {
                throw new ArgumentException("Not all the data has been added");
            }
            if (numComponents > sampleIndex)
            {
                throw new ArgumentException("More data needed to compute the desired number of components");
            }

            this.numComponents = numComponents;

            // compute the mean of all the samples
            for (int i = 0; i < A.getNumRows(); i++)
            {
                for (int j = 0; j < mean.Length; j++)
                {
                    mean[j] += A.get(i, j);
                }
            }
            for (int j = 0; j < mean.Length; j++)
            {
                mean[j] /= A.getNumRows();
            }

            // subtract the mean from the original data
            for (int i = 0; i < A.getNumRows(); i++)
            {
                for (int j = 0; j < mean.Length; j++)
                {
                    A.set(i, j, A.get(i, j) - mean[j]);
                }
            }

            // Compute SVD and save time by not computing U
            SingularValueDecomposition <DMatrixRMaj> svd =
                DecompositionFactory_DDRM.svd(A.numRows, A.numCols, false, true, false);

            if (!svd.decompose(A))
            {
                throw new InvalidOperationException("SVD failed");
            }

            V_t = svd.getV(null, true);
            DMatrixRMaj W = svd.getW(null);

            // Singular values are in an arbitrary order initially
            SingularOps_DDRM.descendingOrder(null, false, W, V_t, true);

            // strip off unneeded components and find the basis
            V_t.reshape(numComponents, mean.Length, true);
        }
예제 #2
0
        public SimpleSVD(Matrix mat, bool compact)
        {
            this.mat  = mat;
            this.is64 = mat is DMatrixRMaj;
            if (is64)
            {
                DMatrixRMaj m = (DMatrixRMaj)mat;
                svd = (SingularValueDecomposition <T>)DecompositionFactory_DDRM.svd(m.numRows, m.numCols, true, true, compact);
            }
            else
            {
                FMatrixRMaj m = (FMatrixRMaj)mat;
                svd = (SingularValueDecomposition <T>)DecompositionFactory_FDRM.svd(m.numRows, m.numCols, true, true, compact);
            }

            if (!svd.decompose((T)mat))
            {
                throw new InvalidOperationException("Decomposition failed");
            }
            U = SimpleMatrix <T> .wrap(svd.getU(null, false));

            W = SimpleMatrix <T> .wrap(svd.getW(null));

            V = SimpleMatrix <T> .wrap(svd.getV(null, false));

            // order singular values from largest to smallest
            if (is64)
            {
                var um = U.getMatrix() as DMatrixRMaj;
                var wm = W.getMatrix() as DMatrixRMaj;
                var vm = V.getMatrix() as DMatrixRMaj;
                SingularOps_DDRM.descendingOrder(um, false, wm, vm, false);
                tol = SingularOps_DDRM.singularThreshold((SingularValueDecomposition_F64 <DMatrixRMaj>)svd);
            }
            else
            {
                var um = U.getMatrix() as FMatrixRMaj;
                var wm = W.getMatrix() as FMatrixRMaj;
                var vm = V.getMatrix() as FMatrixRMaj;
                SingularOps_FDRM.descendingOrder(um, false, wm, vm, false);
                tol = SingularOps_FDRM.singularThreshold((SingularValueDecomposition_F32 <FMatrixRMaj>)svd);
            }
        }