Ejemplo n.º 1
0
        /**
         * <p>
         * Creates a pivot matrix that exchanges the rows in a matrix:
         * <br>
         * A' = P*A<br>
         * </p>
         * <p>
         * For example, if element 0 in 'pivots' is 2 then the first row in A' will be the 3rd row in A.
         * </p>
         *
         * @param ret If null then a new matrix is declared otherwise the results are written to it.  Is modified.
         * @param pivots Specifies the new order of rows in a matrix.
         * @param numPivots How many elements in pivots are being used.
         * @param transposed If the transpose of the matrix is returned.
         * @return A pivot matrix.
         */
        public static CMatrixRMaj pivotMatrix(CMatrixRMaj ret, int[] pivots, int numPivots, bool transposed)
        {
            if (ret == null)
            {
                ret = new CMatrixRMaj(numPivots, numPivots);
            }
            else
            {
                if (ret.numCols != numPivots || ret.numRows != numPivots)
                {
                    throw new ArgumentException("Unexpected matrix dimension");
                }
                CommonOps_CDRM.fill(ret, 0, 0);
            }

            if (transposed)
            {
                for (int i = 0; i < numPivots; i++)
                {
                    ret.set(pivots[i], i, 1, 0);
                }
            }
            else
            {
                for (int i = 0; i < numPivots; i++)
                {
                    ret.set(i, pivots[i], 1, 0);
                }
            }

            return(ret);
        }
Ejemplo n.º 2
0
        /**
         * Computes the householder vector used in QR decomposition.
         *
         * u = x / max(x)
         * u(0) = u(0) + |u|
         * u = u / u(0)
         *
         * @param x Input vector.  Unmodified.
         * @return The found householder reflector vector
         */
        public static CMatrixRMaj householderVector(CMatrixRMaj x)
        {
            CMatrixRMaj u = (CMatrixRMaj)x.copy();

            float max = CommonOps_CDRM.elementMaxAbs(u);

            CommonOps_CDRM.elementDivide(u, max, 0, u);

            float       nx = NormOps_CDRM.normF(u);
            Complex_F32 c  = new Complex_F32();

            u.get(0, 0, c);

            float realTau, imagTau;

            if (c.getMagnitude() == 0)
            {
                realTau = nx;
                imagTau = 0;
            }
            else
            {
                realTau = c.real / c.getMagnitude() * nx;
                imagTau = c.imaginary / c.getMagnitude() * nx;
            }

            u.set(0, 0, c.real + realTau, c.imaginary + imagTau);
            CommonOps_CDRM.elementDivide(u, u.getReal(0, 0), u.getImag(0, 0), u);

            return(u);
        }
Ejemplo n.º 3
0
        /**
         * <p>
         * Creates a reflector from the provided vector and gamma.<br>
         * <br>
         * Q = I - &gamma; u u<sup>H</sup><br>
         * </p>
         *
         * @param u A vector.  Not modified.
         * @param gamma To produce a reflector gamma needs to be equal to 2/||u||.
         * @return An orthogonal reflector.
         */
        public static CMatrixRMaj createReflector(CMatrixRMaj u, float gamma)
        {
            if (!MatrixFeatures_CDRM.isVector(u))
            {
                throw new ArgumentException("u must be a vector");
            }

            CMatrixRMaj Q = CommonOps_CDRM.identity(u.getNumElements());

            CommonOps_CDRM.multAddTransB(-gamma, 0, u, u, Q);

            return(Q);
        }
Ejemplo n.º 4
0
        /**
         * <p>
         * Creates a reflector from the provided vector.<br>
         * <br>
         * Q = I - &gamma; u u<sup>T</sup><br>
         * &gamma; = 2/||u||<sup>2</sup>
         * </p>
         *
         * @param u A vector. Not modified.
         * @return An orthogonal reflector.
         */
        public static CMatrixRMaj createReflector(CMatrixRMaj u)
        {
            if (!MatrixFeatures_CDRM.isVector(u))
            {
                throw new ArgumentException("u must be a vector");
            }

            float norm  = NormOps_CDRM.normF(u);
            float gamma = -2.0f / (norm * norm);

            CMatrixRMaj Q = CommonOps_CDRM.identity(u.getNumElements());

            CommonOps_CDRM.multAddTransB(gamma, 0, u, u, Q);

            return(Q);
        }
Ejemplo n.º 5
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 CMatrixRMaj hermitianPosDef(int width, IMersenneTwister rand)
        {
            // This is not formally proven to work.  It just seems to work.
            CMatrixRMaj a = RandomMatrices_CDRM.rectangle(width, 1, rand);
            CMatrixRMaj b = new CMatrixRMaj(1, width);
            CMatrixRMaj c = new CMatrixRMaj(width, width);

            CommonOps_CDRM.transposeConjugate(a, b);
            CommonOps_CDRM.mult(a, b, c);

            for (int i = 0; i < width; i++)
            {
                c.data[2 * (i * width + i)] += 1;
            }

            return(c);
        }
Ejemplo n.º 6
0
        /**
         * Q = I - gamma*u*u<sup>H</sup>
         */
        public static CMatrixRMaj householder(CMatrixRMaj u, float gamma)
        {
            int N = u.getDataLength() / 2;
            // u*u^H
            CMatrixRMaj uut = new CMatrixRMaj(N, N);

            VectorVectorMult_CDRM.outerProdH(u, u, uut);
            // foo = -gamma*u*u^H
            CommonOps_CDRM.elementMultiply(uut, -gamma, 0, uut);

            // I + foo
            for (int i = 0; i < N; i++)
            {
                int index = (i * uut.numCols + i) * 2;
                uut.data[index] = 1 + uut.data[index];
            }

            return(uut);
        }
Ejemplo n.º 7
0
        /**
         * <p>
         * Unitary matrices have the following properties:<br><br>
         * Q*Q<sup>H</sup> = I
         * </p>
         * <p>
         * This is the complex equivalent of orthogonal matrix.
         * </p>
         * @param Q The matrix being tested. Not modified.
         * @param tol Tolerance.
         * @return True if it passes the test.
         */
        public static bool isUnitary(CMatrixRMaj Q, float tol)
        {
            if (Q.numRows < Q.numCols)
            {
                throw new ArgumentException("The number of rows must be more than or equal to the number of columns");
            }

            Complex_F32 prod = new Complex_F32();

            CMatrixRMaj[] u = CommonOps_CDRM.columnsToVector(Q, null);

            for (int i = 0; i < u.Length; i++)
            {
                CMatrixRMaj a = u[i];

                VectorVectorMult_CDRM.innerProdH(a, a, prod);

                if (Math.Abs(prod.real - 1) > tol)
                {
                    return(false);
                }
                if (Math.Abs(prod.imaginary) > tol)
                {
                    return(false);
                }

                for (int j = i + 1; j < u.Length; j++)
                {
                    VectorVectorMult_CDRM.innerProdH(a, u[j], prod);

                    if (!(prod.getMagnitude2() <= tol * tol))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 8
0
        /**
         * <p>
         * Computes the Frobenius matrix norm:<br>
         * <br>
         * normF = Sqrt{  &sum;<sub>i=1:m</sub> &sum;<sub>j=1:n</sub> { a<sub>ij</sub><sup>2</sup>}   }
         * </p>
         * <p>
         * This is equivalent to the element wise p=2 norm.
         * </p>
         *
         * @param a The matrix whose norm is computed.  Not modified.
         * @return The norm's value.
         */
        public static float normF(CMatrixRMaj a)
        {
            float total = 0;

            float scale = CommonOps_CDRM.elementMaxAbs(a);

            if (scale == 0.0f)
            {
                return(0.0f);
            }

            int size = a.getDataLength();

            for (int i = 0; i < size; i += 2)
            {
                float real = a.data[i] / scale;
                float imag = a.data[i + 1] / scale;

                total += real * real + imag * imag;
            }

            return(scale * (float)Math.Sqrt(total));
        }