/// <summary>
        /// Linear algebraic matrix-matrix multiplication; <tt>C = alpha * A x B + beta*C</tt>.
        /// </summary>
        /// <param name="b">
        /// The econd source matrix.
        /// </param>
        /// <param name="c">
        /// The matrix where results are to be stored. Set this parameter to <tt>null</tt> to indicate that a new result matrix shall be constructed.
        /// </param>
        /// <param name="alpha">
        /// The alpha.
        /// </param>
        /// <param name="beta">
        /// The beta.
        /// </param>
        /// <param name="transposeA">
        /// Whether A must be transposed.
        /// </param>
        /// <param name="transposeB">
        /// Whether B must be transposed.
        /// </param>
        /// <returns>
        /// C (for convenience only).
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// If <tt>B.rows() != A.columns()</tt>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If <tt>C.rows() != A.rows() || C.columns() != B.columns()</tt>.
        /// </exception>
        /// <exception cref="ArithmeticException">
        /// If <tt>A == C || B == C</tt>.
        /// </exception>
        public override DoubleMatrix2D ZMult(DoubleMatrix2D b, DoubleMatrix2D c, double alpha, double beta, bool transposeA, bool transposeB)
        {
            // overriden for performance only
            if (transposeA)
            {
                return(ViewDice().ZMult(b, c, alpha, beta, false, transposeB));
            }
            if (b is SparseDoubleMatrix2D)
            {
                // exploit quick sparse mult
                // A*B = (B' * A')'
                if (c == null)
                {
                    return(b.ZMult(this, null, alpha, beta, !transposeB, true).ViewDice());
                }

                b.ZMult(this, c.ViewDice(), alpha, beta, !transposeB, true);
                return(c);
            }

            if (transposeB)
            {
                return(ZMult(b.ViewDice(), c, alpha, beta, false, false));
            }

            int m = Rows;
            int n = Columns;
            int p = b.Columns;

            if (c == null)
            {
                c = new DenseDoubleMatrix2D(m, p);
            }
            if (!(c is DenseDoubleMatrix2D))
            {
                return(base.ZMult(b, c, alpha, beta, false, false));
            }
            if (b.Rows != n)
            {
                throw new ArgumentOutOfRangeException("b", "Matrix2D inner dimensions must agree:" + this + ", " + b);
            }
            if (c.Rows != m || c.Columns != p)
            {
                throw new ArgumentException("Incompatible result matrix: " + this + ", " + b + ", " + c);
            }
            if (this == c || b == c)
            {
                throw new ArgumentException("Matrices must not be identical");
            }

            var bb = (DenseDoubleMatrix2D)b;
            var cc = (DenseDoubleMatrix2D)c;

            double[] aElems = Elements;
            double[] bElems = bb.Elements;
            double[] cElems = cc.Elements;
            if (aElems == null || bElems == null || cElems == null)
            {
                throw new ApplicationException();
            }

            int cA = ColumnStride;
            int cB = bb.ColumnStride;
            int cC = cc.ColumnStride;

            int rA = RowStride;
            int rB = bb.RowStride;
            int rC = cc.RowStride;

            /*
             * A is blocked to hide memory latency
             *      xxxxxxx B
             *      xxxxxxx
             *      xxxxxxx
             * A
             * xxx     xxxxxxx C
             * xxx     xxxxxxx
             * ---     -------
             * xxx     xxxxxxx
             * xxx     xxxxxxx
             * ---     -------
             * xxx     xxxxxxx
             */
            const int BLOCK_SIZE = 30000;
            int       m_optimal  = (BLOCK_SIZE - n) / (n + 1);

            if (m_optimal <= 0)
            {
                m_optimal = 1;
            }
            int blocks = m / m_optimal;
            int rr     = 0;

            if (m % m_optimal != 0)
            {
                blocks++;
            }
            for (; --blocks >= 0;)
            {
                int jB     = bb.Index(0, 0);
                int indexA = Index(rr, 0);
                int jC     = cc.Index(rr, 0);
                rr += m_optimal;
                if (blocks == 0)
                {
                    m_optimal += m - rr;
                }

                for (int j = p; --j >= 0;)
                {
                    int iA = indexA;
                    int iC = jC;
                    for (int i = m_optimal; --i >= 0;)
                    {
                        int    kA = iA;
                        int    kB = jB;
                        double s  = 0;

                        /*
                         * // not unrolled:
                         * for (int k = n; --k >= 0;) {
                         *  //s += getQuick(i,k) * B.getQuick(k,j);
                         *  s += AElems[kA] * BElems[kB];
                         *  kB += rB;
                         *  kA += cA;
                         * }
                         */

                        // loop unrolled
                        kA -= cA;
                        kB -= rB;

                        for (int k = n % 4; --k >= 0;)
                        {
                            s += aElems[kA += cA] * bElems[kB += rB];
                        }
                        for (int k = n / 4; --k >= 0;)
                        {
                            s += (aElems[kA += cA] * bElems[kB += rB]) +
                                 (aElems[kA += cA] * bElems[kB += rB]) +
                                 (aElems[kA += cA] * bElems[kB += rB]) +
                                 (aElems[kA += cA] * bElems[kB += rB]);
                        }

                        cElems[iC] = (alpha * s) + (beta * cElems[iC]);
                        iA        += rA;
                        iC        += rC;
                    }

                    jB += cB;
                    jC += cC;
                }
            }

            return(c);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// A square matrix <i>A</i> is <i>orthogonal</i> if <i>A*transpose(A) = I</i>.
 /// <summary>
 /// <exception cref="ArgumentException">if <i>!isSquare(A)</i>. </exception>
 public Boolean IsOrthogonal(DoubleMatrix2D A)
 {
     CheckSquare(A);
     return(Equals(A.ZMult(A, null, 1, 0, false, true), Cern.Colt.Matrix.DoubleFactory2D.Dense.Identity(A.Rows)));
 }
 /// <summary>
 /// Encode a vector in the space spanned by columns of U.
 /// </summary>
 /// <param name="d">
 /// The vector d.
 /// </param>
 /// <returns>
 /// U'd
 /// </returns>
 public DoubleMatrix1D Encode(DoubleMatrix1D d)
 {
     return(_u.ZMult(d.Size < _m ? DoubleFactory1D.Sparse.AppendColumns(d, DoubleFactory1D.Sparse.Make(_m - d.Size)) : d, null, 1, 0, true));
 }
Ejemplo n.º 4
0
 public void Dgemv(Boolean transposeA, double alpha, DoubleMatrix2D A, DoubleMatrix1D x, double beta, DoubleMatrix1D y)
 {
     A.ZMult(x, y, alpha, beta, transposeA);
 }
Ejemplo n.º 5
0
 public void Dgemm(Boolean transposeA, Boolean transposeB, double alpha, DoubleMatrix2D A, DoubleMatrix2D B, double beta, DoubleMatrix2D C)
 {
     A.ZMult(B, C, alpha, beta, transposeA, transposeB);
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Linear algebraic matrix-matrix multiplication; <i>C = A x B</i>.
 /// </summary>
 /// <param name="a">
 /// The first source matrix.
 /// </param>
 /// <param name="b">
 /// The second source matrix.
 /// </param>
 /// <returns>
 /// <i>C</i>; a new matrix holding the results, with <i>C.Rows=A.Rows, C.Columns==B.Columns</i>.
 /// </returns>
 /// <exception cref="ArgumentException">
 /// If <i>B.Rows != A.Columns</i>.
 /// </exception>
 public static DoubleMatrix2D Mult(DoubleMatrix2D a, DoubleMatrix2D b)
 {
     return(a.ZMult(b, null));
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Linear algebraic matrix-vector multiplication; <i>z = A * y</i>.
 /// </summary>
 /// <param name="a">
 /// The matrix A.
 /// </param>
 /// <param name="y">
 /// The vector y.
 /// </param>
 /// <returns>
 /// <i>z</i>; a new vector with <i>z.Size==A.Rows</i>.
 /// </returns>
 public static DoubleMatrix1D Mult(DoubleMatrix2D a, DoubleMatrix1D y)
 {
     return(a.ZMult(y, null));
 }