Exemplo n.º 1
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);
            }
        }
Exemplo n.º 2
0
        /**
         * This method computes the eigen vector with the largest eigen value by using the
         * direct power method. This technique is the easiest to implement, but the slowest to converge.
         * Works only if all the eigenvalues are real.
         *
         * @param A The matrix. Not modified.
         * @return If it converged or not.
         */
        public bool computeDirect(FMatrixRMaj A)
        {
            initPower(A);

            bool converged = false;

            for (int i = 0; i < maxIterations && !converged; i++)
            {
//            q0.print();

                CommonOps_FDRM.mult(A, q0, q1);
                float s = NormOps_FDRM.normPInf(q1);
                CommonOps_FDRM.divide(q1, s, q2);

                converged = checkConverged(A);
            }

            return(converged);
        }
Exemplo n.º 3
0
        public void setup(FMatrixRMaj A)
        {
            if (A.numRows != A.numCols)
            {
                throw new InvalidOperationException("Must be square");
            }

            if (N != A.numRows)
            {
                N = A.numRows;

                this.A = (FMatrixRMaj)A.copy();
                u      = new FMatrixRMaj(A.numRows, 1);

                _temp        = new FMatrixRMaj(A.numRows, 1);
                numStepsFind = new int[A.numRows];
            }
            else
            {
                this.A.set(A);
                UtilEjml.memset(numStepsFind, 0, numStepsFind.Length);
            }

            // zero all the off numbers that should be zero for a hessenberg matrix
            for (int i = 2; i < N; i++)
            {
                for (int j = 0; j < i - 1; j++)
                {
                    this.A.set(i, j, 0);
                }
            }

            eigenvalues = new Complex_F32[A.numRows];
            for (int i = 0; i < eigenvalues.Length; i++)
            {
                eigenvalues[i] = new Complex_F32();
            }

            numEigen        = 0;
            lastExceptional = 0;
            numExceptional  = 0;
            steps           = 0;
        }
Exemplo n.º 4
0
        private void initPower(FMatrixRMaj A)
        {
            if (A.numRows != A.numCols)
            {
                throw new ArgumentException("A must be a square matrix.");
            }

            if (seed != null)
            {
                q0.set(seed);
            }
            else
            {
                for (int i = 0; i < A.numRows; i++)
                {
                    q0.data[i] = 1;
                }
            }
        }
Exemplo n.º 5
0
        /**
         * <p>
         * Performs a rank one update on matrix A using vectors u and w.  The results are stored in A.<br>
         * <br>
         * A = A + &gamma; u w<sup>T</sup><br>
         * </p>
         * <p>
         * This is called a rank1 update because the matrix u w<sup>T</sup> has a rank of 1.
         * </p>
         *
         * @param gamma A scalar.
         * @param A A m by m matrix. Modified.
         * @param u A vector with m elements.  Not modified.
         */
        public static void rank1Update(float gamma,
                                       FMatrixRMaj A,
                                       FMatrixRMaj u,
                                       FMatrixRMaj w)
        {
            int n = u.getNumElements();

            int matrixIndex = 0;

            for (int i = 0; i < n; i++)
            {
                float elementU = u.data[i];

                for (int j = 0; j < n; j++)
                {
                    A.data[matrixIndex++] += gamma * elementU * w.data[j];
                }
            }
        }
Exemplo n.º 6
0
        /**
         * Performs a variety of tests to see if the provided matrix is a valid
         * covariance matrix.
         *
         * @return  0 = is valid 1 = failed positive diagonal, 2 = failed on symmetry, 2 = failed on positive definite
         */
        public static int isValid(FMatrixRMaj cov)
        {
            if (!MatrixFeatures_FDRM.isDiagonalPositive(cov))
            {
                return(1);
            }

            if (!MatrixFeatures_FDRM.isSymmetric(cov, TOL))
            {
                return(2);
            }

            if (!MatrixFeatures_FDRM.isPositiveSemidefinite(cov))
            {
                return(3);
            }

            return(0);
        }
Exemplo n.º 7
0
        /**
         * Creates a random matrix where all elements are zero but diagonal elements.  Diagonal elements
         * randomly drawn from a uniform distribution from min to max, inclusive.
         *
         * @param numRows Number of rows in the returned matrix..
         * @param numCols Number of columns in the returned matrix.
         * @param min Minimum value of a diagonal element.
         * @param max Maximum value of a diagonal element.
         * @param rand Random number generator.
         * @return A random diagonal matrix.
         */
        public static FMatrixRMaj diagonal(int numRows, int numCols, float min, float max, IMersenneTwister rand)
        {
            if (max < min)
            {
                throw new ArgumentException("The max must be >= the min");
            }

            FMatrixRMaj ret = new FMatrixRMaj(numRows, numCols);

            int N = Math.Min(numRows, numCols);

            float r = max - min;

            for (int i = 0; i < N; i++)
            {
                ret.set(i, i, rand.NextFloat() * r + min);
            }

            return(ret);
        }
        /**
         * Extracts the tridiagonal matrix found in the decomposition.
         *
         * @param T If not null then the results will be stored here.  Otherwise a new matrix will be created.
         * @return The extracted T matrix.
         */
        public FMatrixRMaj getT(FMatrixRMaj T)
        {
            T = UtilDecompositons_FDRM.checkZeros(T, N, N);

            T.data[0] = QT.data[0];
            T.data[1] = QT.data[1];


            for (int i = 1; i < N - 1; i++)
            {
                T.set(i, i, QT.get(i, i));
                T.set(i, i + 1, QT.get(i, i + 1));
                T.set(i, i - 1, QT.get(i - 1, i));
            }

            T.data[(N - 1) * N + N - 1] = QT.data[(N - 1) * N + N - 1];
            T.data[(N - 1) * N + N - 2] = QT.data[(N - 2) * N + N - 1];

            return(T);
        }
Exemplo n.º 9
0
        /**
         * Creates a random symmetric positive definite matrix.
         *
         * @param width The width of the square matrix it returns.
         * @param rand Random number generator used to make the matrix.
         * @return The random symmetric  positive definite matrix.
         */
        public static FMatrixRMaj symmetricPosDef(int width, IMersenneTwister rand)
        {
            // This is not formally proven to work.  It just seems to work.
            FMatrixRMaj a = new FMatrixRMaj(width, 1);
            FMatrixRMaj b = new FMatrixRMaj(width, width);

            for (int i = 0; i < width; i++)
            {
                a.set(i, 0, rand.NextFloat());
            }

            CommonOps_FDRM.multTransB(a, a, b);

            for (int i = 0; i < width; i++)
            {
                b.add(i, i, 1);
            }

            return(b);
        }
Exemplo n.º 10
0
        /**
         * Performs QR decomposition on A
         *
         * @param A not modified.
         */
        public override bool setA(FMatrixRMaj A)
        {
            if (A.numRows > maxRows || A.numCols > maxCols)
            {
                setMaxSize(A.numRows, A.numCols);
            }

            _setA(A);
            if (!decomposer.decompose(A))
            {
                return(false);
            }

            Q.reshape(numRows, numRows, false);
            R.reshape(numRows, numCols, false);
            decomposer.getQ(Q, false);
            decomposer.getR(R, false);

            return(true);
        }
        /**
         * Sets the size of the matrix being decomposed, declares new memory if needed,
         * and sets all helper functions to their initial value.
         */
        public void reset(int N)
        {
            this.N = N;

            this.diag = null;
            this.off  = null;

            if (splits.Length < N)
            {
                splits = new int[N];
            }

            numSplits = 0;

            x1 = 0;
            x2 = N - 1;

            steps = numExceptional = lastExceptional = 0;

            this.Q = null;
        }
Exemplo n.º 12
0
        /**
         * Sets the provided square matrix to be a random symmetric matrix whose values are selected from an uniform distribution
         * from min to max, inclusive.
         *
         * @param A The matrix that is to be modified.  Must be square.  Modified.
         * @param min Minimum value an element can have.
         * @param max Maximum value an element can have.
         * @param rand Random number generator.
         */
        public static void symmetric(FMatrixRMaj A, float min, float max, IMersenneTwister rand)
        {
            if (A.numRows != A.numCols)
            {
                throw new ArgumentException("A must be a square matrix");
            }

            float range = max - min;

            int length = A.numRows;

            for (int i = 0; i < length; i++)
            {
                for (int j = i; j < length; j++)
                {
                    float val = rand.NextFloat() * range + min;
                    A.set(i, j, val);
                    A.set(j, i, val);
                }
            }
        }
Exemplo n.º 13
0
        public static FMatrixRMaj convert(FMatrixSparseTriplet src, FMatrixRMaj dst)
        {
            if (dst == null)
            {
                dst = new FMatrixRMaj(src.numRows, src.numCols);
            }
            else
            {
                dst.reshape(src.numRows, src.numCols);
                dst.zero();
            }

            for (int i = 0; i < src.nz_length; i++)
            {
                FMatrixSparseTriplet.Element e = src.nz_data[i];

                dst.unsafe_set(e.row, e.col, e.value);
            }

            return(dst);
        }
Exemplo n.º 14
0
        public override bool setA(FMatrixRMaj A)
        {
            if (A.numRows != A.numCols)
            {
                throw new ArgumentException("Matrix must be square");
            }

            _setA(A);

            if (decomposer.decompose(A))
            {
                n  = A.numCols;
                vv = decomposer._getVV();
                t  = decomposer.getT().data;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 15
0
        /**
         * Creates a copy of a matrix but swaps the rows as specified by the order array.
         *
         * @param order Specifies which row in the dest corresponds to a row in the src. Not modified.
         * @param src The original matrix. Not modified.
         * @param dst A Matrix that is a row swapped copy of src. Modified.
         */
        public static FMatrixRMaj copyChangeRow(int[] order, FMatrixRMaj src, FMatrixRMaj dst)
        {
            if (dst == null)
            {
                dst = new FMatrixRMaj(src.numRows, src.numCols);
            }
            else if (src.numRows != dst.numRows || src.numCols != dst.numCols)
            {
                throw new ArgumentException("src and dst must have the same dimensions.");
            }

            for (int i = 0; i < src.numRows; i++)
            {
                int indexDst = i * src.numCols;
                int indexSrc = order[i] * src.numCols;

                Array.Copy(src.data, indexSrc, dst.data, indexDst, src.numCols);
            }

            return(dst);
        }
Exemplo n.º 16
0
        /**
         * Computes the eigenvalue of the provided tridiagonal matrix.  Note that only the upper portion
         * needs to be tridiagonal.  The bottom diagonal is assumed to be the same as the top.
         *
         * @param sideLength Number of rows and columns in the input matrix.
         * @param diag Diagonal elements from tridiagonal matrix. Modified.
         * @param off Off diagonal elements from tridiagonal matrix. Modified.
         * @return true if it succeeds and false if it fails.
         */
        public bool process(int sideLength,
                            float[] diag,
                            float[] off,
                            float[] eigenvalues)
        {
            if (diag != null)
            {
                helper.init(diag, off, sideLength);
            }
            if (Q == null)
            {
                Q = CommonOps_FDRM.identity(helper.N);
            }
            helper.setQ(Q);

            this.followingScript = true;
            this.eigenvalues     = eigenvalues;
            this.fastEigenvalues = false;

            return(_process());
        }
        public static void inv2(FMatrixRMaj mat, FMatrixRMaj inv, float scale)
        {
            float[] data = mat.data;

            float a11 = data[0] * scale;
            float a12 = data[1] * scale;
            float a21 = data[2] * scale;
            float a22 = data[3] * scale;

            float m11 = a22;
            float m12 = -(a21);
            float m21 = -(a12);
            float m22 = a11;

            float det = (a11 * m11 + a12 * m12) / scale;

            data    = inv.data;
            data[0] = m11 / det;
            data[1] = m21 / det;
            data[2] = m12 / det;
            data[3] = m22 / det;
        }
Exemplo n.º 18
0
        public override void solve(FMatrixRMaj b, FMatrixRMaj x)
        {
            if (b.numCols != x.numCols || b.numRows != numRows || x.numRows != this.numCols)
            {
                throw new ArgumentException("Unexpected matrix size");
            }

            int numCols = b.numCols;

            float[] dataB = b.data;
            float[] dataX = x.data;

            float[] vv = decomp._getVV();

//        for( int j = 0; j < numCols; j++ ) {
//            for( int i = 0; i < this.numCols; i++ ) vv[i] = dataB[i*numCols+j];
//            decomp._solveVectorInternal(vv);
//            for( int i = 0; i < this.numCols; i++ ) dataX[i*numCols+j] = vv[i];
//        }
            for (int j = 0; j < numCols; j++)
            {
                int index = j;
                for (int i = 0; i < this.numCols; i++, index += numCols)
                {
                    vv[i] = dataB[index];
                }
                decomp._solveVectorInternal(vv);
                index = j;
                for (int i = 0; i < this.numCols; i++, index += numCols)
                {
                    dataX[index] = vv[i];
                }
            }

            if (doImprove)
            {
                improveSol(b, x);
            }
        }
Exemplo n.º 19
0
        /**
         * Sets the matrix 'inv' equal to the inverse of the matrix that was decomposed.
         *
         * @param inv Where the value of the inverse will be stored.  Modified.
         */
        public override void invert(FMatrixRMaj inv)
        {
            if (inv.numRows != n || inv.numCols != n)
            {
                throw new InvalidOperationException("Unexpected matrix dimension");
            }
            if (inv.data == t)
            {
                throw new ArgumentException("Passing in the same matrix that was decomposed.");
            }

            float[] a = inv.data;

            if (decomposer.isLower())
            {
                setToInverseL(a);
            }
            else
            {
                throw new InvalidOperationException("Implement");
            }
        }
Exemplo n.º 20
0
        public override /**/ double quality()
        {
            return(SpecializedOps_FDRM.qualityTriangular(R));
        }

        /**
         * Solves for X using the QR decomposition.
         *
         * @param B A matrix that is n by m.  Not modified.
         * @param X An n by m matrix where the solution is written to.  Modified.
         */
        public override void solve(FMatrixRMaj B, FMatrixRMaj X)
        {
            if (X.numRows != numCols)
            {
                throw new ArgumentException("Unexpected dimensions for X");
            }
            else if (B.numRows != numRows || B.numCols != X.numCols)
            {
                throw new ArgumentException("Unexpected dimensions for B");
            }

            int BnumCols = B.numCols;

            Y.reshape(numRows, 1, false);
            Z.reshape(numRows, 1, false);

            // solve each column one by one
            for (int colB = 0; colB < BnumCols; colB++)
            {
                // make a copy of this column in the vector
                for (int i = 0; i < numRows; i++)
                {
                    Y.data[i] = B.get(i, colB);
                }

                // Solve Qa=b
                // a = Q'b
                CommonOps_FDRM.multTransA(Q, Y, Z);

                // solve for Rx = b using the standard upper triangular solver
                TriangularSolver_FDRM.solveU(R.data, Z.data, numCols);

                // save the results
                for (int i = 0; i < numCols; i++)
                {
                    X.set(i, colB, Z.data[i]);
                }
            }
        }
        /**
         * An orthogonal matrix that has the following property: T = Q<sup>T</sup>AQ
         *
         * @param Q If not null then the results will be stored here.  Otherwise a new matrix will be created.
         * @return The extracted Q matrix.
         */
        public FMatrixRMaj getQ(FMatrixRMaj Q)
        {
            Q = UtilDecompositons_FDRM.checkIdentity(Q, N, N);

            for (int i = 0; i < N; i++)
            {
                w[i] = 0;
            }

            for (int j = N - 2; j >= 0; j--)
            {
                w[j + 1] = 1;
                for (int i = j + 2; i < N; i++)
                {
                    w[i] = QT.get(j, i);
                }
                QrHelperFunctions_FDRM.rank1UpdateMultR(Q, w, gammas[j + 1], j + 1, j + 1, N, b);
//            Q.print();
            }

            return(Q);
        }
Exemplo n.º 22
0
        /**
         * Computes the most dominant eigen vector of A using an inverted shifted matrix.
         * The inverted shifted matrix is defined as <b>B = (A - &alpha;I)<sup>-1</sup></b> and
         * can converge faster if &alpha; is chosen wisely.
         *
         * @param A An invertible square matrix matrix.
         * @param alpha Shifting factor.
         * @return If it converged or not.
         */
        public bool computeShiftInvert(FMatrixRMaj A, float alpha)
        {
            initPower(A);

            LinearSolverDense <FMatrixRMaj> solver = LinearSolverFactory_FDRM.linear(A.numCols);

            SpecializedOps_FDRM.addIdentity(A, B, -alpha);
            solver.setA(B);

            bool converged = false;

            for (int i = 0; i < maxIterations && !converged; i++)
            {
                solver.solve(q0, q1);
                float s = NormOps_FDRM.normPInf(q1);
                CommonOps_FDRM.divide(q1, s, q2);

                converged = checkConverged(A);
            }

            return(converged);
        }
Exemplo n.º 23
0
        /**
         * <p>
         * Induced matrix p = infinity norm.<br>
         * <br>
         * ||A||<sub>&#8734;</sub> = max(i=1 to m; sum(j=1 to n; |a<sub>ij</sub>|))
         * </p>
         *
         * @param A A matrix.
         * @return the norm.
         */
        public static float inducedPInf(FMatrixRMaj A)
        {
            float max = 0;

            int m = A.numRows;
            int n = A.numCols;

            for (int i = 0; i < m; i++)
            {
                float total = 0;
                for (int j = 0; j < n; j++)
                {
                    total += Math.Abs(A.get(i, j));
                }
                if (total > max)
                {
                    max = total;
                }
            }

            return(max);
        }
Exemplo n.º 24
0
        /**
         * Creates a new SimpleMatrix which is a copy of the Matrix.
         *
         * @param orig The original matrix whose value is copied.  Not modified.
         */
        public SimpleMatrix(Matrix orig)
        {
            Matrix mat;

            if (orig is DMatrixRBlock)
            {
                DMatrixRMaj a = new DMatrixRMaj(orig.getNumRows(), orig.getNumCols());
                ConvertDMatrixStruct.convert((DMatrixRBlock)orig, a);
                mat = a;
            }
            else if (orig is FMatrixRBlock)
            {
                FMatrixRMaj a = new FMatrixRMaj(orig.getNumRows(), orig.getNumCols());
                ConvertFMatrixStruct.convert((FMatrixRBlock)orig, a);
                mat = a;
            }
            else
            {
                mat = orig.copy();
            }
            setMatrix((T)mat);
        }
Exemplo n.º 25
0
        public override /**/ double quality()
        {
            return(decomp.quality());
        }

        public override void invert(FMatrixRMaj A_inv)
        {
            float[]     vv = decomp._getVV();
            FMatrixRMaj LU = decomp.getLU();

            if (A_inv.numCols != LU.numCols || A_inv.numRows != LU.numRows)
            {
                throw new ArgumentException("Unexpected matrix dimension");
            }

            int n = A.numCols;

            float[] dataInv = A_inv.data;

            for (int j = 0; j < n; j++)
            {
                // don't need to change inv into an identity matrix before hand
                for (int i = 0; i < n; i++)
                {
                    vv[i] = i == j ? 1 : 0;
                }
                decomp._solveVectorInternal(vv);
//            for( int i = 0; i < n; i++ ) dataInv[i* n +j] = vv[i];
                int index = j;
                for (int i = 0; i < n; i++, index += n)
                {
                    dataInv[index] = vv[i];
                }
            }
        }

        /**
         * This attempts to improve upon the solution generated by account
         * for numerical imprecisions.  See numerical recipes for more information.  It
         * is assumed that solve has already been run on 'b' and 'x' at least once.
         *
         * @param b A matrix. Not modified.
         * @param x A matrix. Modified.
         */
        public void improveSol(FMatrixRMaj b, FMatrixRMaj x)
        {
            if (b.numCols != x.numCols)
            {
                throw new ArgumentException("bad shapes");
            }

            float[] dataA = A.data;
            float[] dataB = b.data;
            float[] dataX = x.data;

            int nc = b.numCols;
            int n  = b.numCols;

            float[] vv = decomp._getVV();

//        BigDecimal sdp = new BigDecimal(0);
            for (int k = 0; k < nc; k++)
            {
                for (int i = 0; i < n; i++)
                {
                    // *NOTE* in the book this is a long float.  extra precision might be required
                    float sdp = -dataB[i * nc + k];
//                BigDecimal sdp = new BigDecimal(-dataB[ i * nc + k]);
                    for (int j = 0; j < n; j++)
                    {
                        sdp += dataA[i * n + j] * dataX[j * nc + k];
//                    sdp = sdp.add( BigDecimal.valueOf(dataA[i* n +j] * dataX[ j * nc + k]));
                    }
                    vv[i] = sdp;
//                vv[i] = sdp.floatValue();
                }
                decomp._solveVectorInternal(vv);
                for (int i = 0; i < n; i++)
                {
                    dataX[i * nc + k] -= vv[i];
                }
            }
        }
        /**
         * <p>
         * Performs this operation:<br>
         * <br>
         * c = c - a<sup>T</sup>a <br>
         * where c is a submatrix.
         * </p>
         *
         * Only the upper triangle is updated.
         *
         * @param a A matrix.
         * @param c A matrix.
         * @param startIndexC start of the submatrix in c.
         */
        public static void symmRankTranA_sub(FMatrixRMaj a, FMatrixRMaj c,
                                             int startIndexC)
        {
            // TODO update so that it doesn't modify/read parts that it shouldn't
            float[] dataA = a.data;
            float[] dataC = c.data;

//        for( int i = 0; i < a.numCols; i++ ) {
//            for( int k = 0; k < a.numRows; k++ ) {
//                float valA = dataA[k*a.numCols+i];
//
//                for( int j = i; j < a.numCols; j++ ) {
//                    dataC[startIndexC+i*c.numCols+j] -= valA * dataA[k*a.numCols+j];
//                }
//            }
//        }

            int strideC = c.numCols + 1;

            for (int i = 0; i < a.numCols; i++)
            {
                int indexA = i;
                int endR   = a.numCols;

                for (int k = 0; k < a.numRows; k++, indexA += a.numCols, endR += a.numCols)
                {
                    int   indexC = startIndexC;
                    float valA   = dataA[indexA];
                    int   indexR = indexA;

                    while (indexR < endR)
                    {
                        dataC[indexC++] -= valA * dataA[indexR++];
                    }
                }
                startIndexC += strideC;
            }
        }
Exemplo n.º 27
0
        /**
         * Test for convergence by seeing if the element with the largest change
         * is smaller than the tolerance.  In some test cases it alternated between
         * the + and - values of the eigen vector.  When this happens it seems to have "converged"
         * to a non-dominant eigen vector.    At least in the case I looked at.  I haven't devoted
         * a lot of time into this issue...
         */
        private bool checkConverged(FMatrixRMaj A)
        {
            float worst  = 0;
            float worst2 = 0;

            for (int j = 0; j < A.numRows; j++)
            {
                float val = Math.Abs(q2.data[j] - q0.data[j]);
                if (val > worst)
                {
                    worst = val;
                }
                val = Math.Abs(q2.data[j] + q0.data[j]);
                if (val > worst2)
                {
                    worst2 = val;
                }
            }

            // swap vectors
            FMatrixRMaj temp = q0;

            q0 = q2;
            q2 = temp;

            if (worst < tol)
            {
                return(true);
            }
            else if (worst2 < tol)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        private void solveWithLU(float real, int index, FMatrixRMaj r)
        {
            FMatrixRMaj A = new FMatrixRMaj(index, index);

            CommonOps_FDRM.extract(_implicit.A, 0, index, 0, index, A, 0, 0);

            for (int i = 0; i < index; i++)
            {
                A.add(i, i, -real);
            }

            r.reshape(index, 1, false);

            SpecializedOps_FDRM.subvector(_implicit.A, 0, index, index, false, 0, r);
            CommonOps_FDRM.changeSign(r);

            // TODO this must be very inefficient
            if (!solver.setA(A))
            {
                throw new InvalidOperationException("Solve failed");
            }
            solver.solve(r, r);
        }
Exemplo n.º 29
0
 /**
  * An unsafe but faster version of {@link #normP} that calls routines which are faster
  * but more prone to overflow/underflow problems.
  *
  * @param A Vector or matrix whose norm is to be computed.
  * @param p The p value of the p-norm.
  * @return The computed norm.
  */
 public static float fastNormP(FMatrixRMaj A, float p)
 {
     if (p == 1)
     {
         return(normP1(A));
     }
     else if (p == 2)
     {
         return(fastNormP2(A));
     }
     else if (float.IsInfinity(p))
     {
         return(normPInf(A));
     }
     if (MatrixFeatures_FDRM.isVector(A))
     {
         return(fastElementP(A, p));
     }
     else
     {
         throw new ArgumentException("Doesn't support induced norms yet.");
     }
 }
        /**
         * If needed declares and sets up internal data structures.
         *
         * @param A Matrix being decomposed.
         */
        public void init(FMatrixRMaj A)
        {
            if (A.numRows != A.numCols)
            {
                throw new ArgumentException("Must be square");
            }

            if (A.numCols != N)
            {
                N = A.numCols;
                QT.reshape(N, N, false);

                if (w.Length < N)
                {
                    w      = new float[N];
                    gammas = new float[N];
                    b      = new float[N];
                }
            }

            // just copy the top right triangle
            QT.set(A);
        }