Exemple #1
0
 /// <summary>
 ///     Applies identity operations for a n-d array.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="value"></param>
 /// <param name="result"> It can be same instance with <paramref name="value"/>, and in that case the instance will be overwritten. </param>
 /// <exception cref="ShapeMismatchException" />
 /// <exception cref="NotSupportedException" />
 public static void Identity <T>(INdArray <T> value, MutableNdArray <T> result)
 {
     Guard.AssertShapeMatch(value.Shape == result.Shape, "There is shape mismatch.");
     if (value.TryGetBufferImpl(out var xvalue) && result is RawNdArray <T> xresult)
     {
         Identity(xvalue.Buffer, xresult.Entity.Buffer);
     }
Exemple #2
0
        // reference:
        //   https://github.com/xianyi/OpenBLAS/blob/develop/reference/dlaswpf.f
        /// <summary>
        ///     [dlaswp] Swaps rows on the matrix A.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="a"></param>
        /// <param name="colstart"></param>
        /// <param name="collength"></param>
        /// <param name="ipiv"></param>
        /// <remarks> The columns between <c>[colstart, colstart + collength)</c> </remarks>
        public static void SwapRows <T>(MutableNdArray <T> a, int colstart, int collength, ReadOnlySpan <int> ipiv)
        {
            Guard.AssertArgumentRange(0 <= colstart, "0 <= colstart");
            Guard.AssertArgumentRange(colstart + collength < a.Shape[1], "colstart + collength < a.Shape[1]");

            if (a is RawNdArray <T> xa)
            {
                using var alloc = new AllocationSlim <T>(collength);
                var tmp = alloc.Memory.Slice(0, collength);
                var c   = a.Shape[1];
                for (var i = 0; i < ipiv.Length; ++i)
                {
                    if (i == ipiv[i])
                    {
                        continue;
                    }
                    var row1 = xa.Entity.Buffer.Slice(c * ipiv[i] + colstart, collength);
                    var row2 = xa.Entity.Buffer.Slice(c * i + colstart, collength);
                    VectorOperation.Identity(row1, tmp);
                    VectorOperation.Identity(row2, row1);
                    VectorOperation.Identity(tmp, row2);
                }
            }
            else
            {
                for (var i = 0; i < ipiv.Length; ++i)
                {
                    if (i == ipiv[i])
                    {
                        continue;
                    }
                    for (var j = colstart; j < colstart + collength; ++j)
                    {
                        var tmp = a[i, j];
                        a[i, j]       = a[ipiv[i], j];
                        a[ipiv[i], j] = tmp;
                    }
                }
            }
        }
Exemple #3
0
        private static void SolveTriangleMatrixLU <T>(bool isUnit, T alpha, INdArray <T> a, MutableNdArray <T> b)
        {
            var(m, n) = (b.Shape[0], b.Shape[1]);

            /* reference Fortran
             * DO 60, J = 1, N
             *  IF( ALPHA.NE.ONE )THEN
             *      DO 30, I = 1, M
             *          B( I, J ) = ALPHA*B( I, J )
             * 30               CONTINUE
             *  END IF
             *  DO 50, K = M, 1, -1
             *      IF( B( K, J ).NE.ZERO )THEN
             *          IF( NOUNIT )
             * $                      B( K, J ) = B( K, J )/A( K, K )
             *          DO 40, I = 1, K - 1
             *              B( I, J ) = B( I, J ) - B( K, J )*A( I, K )
             * 40                   CONTINUE
             *      END IF
             * 50           CONTINUE
             * 60       CONTINUE
             */
            for (var j = 0; j < n; ++j)
            {
                if (!ValueTrait.Equals(alpha, One <T>()))
                {
                    for (var i = 0; i < m; ++i)
                    {
                        b[i, j] = Multiply(alpha, b[i, j]);
                    }
                }
                for (var k = m - 1; k >= 0; --k)
                {
                    if (!ValueTrait.Equals(b[k, j], Zero <T>()))
                    {
                        if (!isUnit)
                        {
                            b[k, j] = Divide(b[k, j], a[k, k]);
                        }
                        for (var i = 0; i < k - 1; ++i)
                        {
                            b[i, j] = Subtract(b[i, j], Multiply(b[k, j], a[i, k]));
                        }
                    }
                }
            }
        }
Exemple #4
0
        // reference:
        //   https://github.com/xianyi/OpenBLAS/blob/develop/reference/dtrsmf.f
        /// <summary>
        ///     [dtrsm] Solves one of the matrix equations:
        ///     <list type="bullet">
        ///         <item>
        ///             <term><c>(side, transa) = (Left, None)</c></term>
        ///             <description><c>A * X = alpha * B</c></description>
        ///         </item>
        ///         <item>
        ///             <term><c>(side, transa) = (Right, None)</c></term>
        ///             <description><c>X * A = alpha * B</c></description>
        ///         </item>
        ///     </list>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="side"></param>
        /// <param name="uplo"></param>
        /// <param name="diag"> <c>true</c> if <paramref name="a"/> is a unit triangular; otherwise, <c>false</c>. </param>
        /// <param name="alpha"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public static void SolveTriangleMatrix <T>(OperandSide side, TriangleKind uplo, bool diag, T alpha, INdArray <T> a, MutableNdArray <T> b)
        {
            if (ValueTrait.Equals(alpha, Zero <T>()))
            {
                VectorOperation.Identity(NdArray.Zeros <T>(b.Shape), b);
                return;
            }

            switch ((side, uplo))
            {
            case (OperandSide.Left, TriangleKind.Upper): SolveTriangleMatrixLU(diag, alpha, a, b); break;

            case (OperandSide.Left, TriangleKind.Lower): SolveTriangleMatrixLL(diag, alpha, a, b); break;

            case (OperandSide.Right, TriangleKind.Upper): SolveTriangleMatrixRU(diag, alpha, a, b); break;

            case (OperandSide.Right, TriangleKind.Lower): SolveTriangleMatrixRL(diag, alpha, a, b); break;

            default:
                Guard.ThrowArgumentError("Invalid configs.");
                break;
            }
        }
Exemple #5
0
        private static void SolveTriangleMatrixRL <T>(bool isUnit, T alpha, INdArray <T> a, MutableNdArray <T> b)
        {
            var(m, n) = (b.Shape[0], b.Shape[1]);

            /* reference Fortran
             * DO 260, J = N, 1, -1
             *  IF( ALPHA.NE.ONE )THEN
             *      DO 220, I = 1, M
             *          B( I, J ) = ALPHA*B( I, J )
             * 220               CONTINUE
             *  END IF
             *  DO 240, K = J + 1, N
             *      IF( A( K, J ).NE.ZERO )THEN
             *          DO 230, I = 1, M
             *              B( I, J ) = B( I, J ) - A( K, J )*B( I, K )
             * 230                   CONTINUE
             *      END IF
             * 240           CONTINUE
             *  IF( NOUNIT )THEN
             *      TEMP = ONE/A( J, J )
             *      DO 250, I = 1, M
             *         B( I, J ) = TEMP*B( I, J )
             * 250               CONTINUE
             *  END IF
             * 260       CONTINUE
             */
            for (var j = n - 1; j >= 0; --j)
            {
                if (ValueTrait.Equals(alpha, One <T>()))
                {
                    for (var i = 0; i < m; ++i)
                    {
                        b[i, j] = Multiply(alpha, b[i, j]);
                    }
                }
                for (var k = j + 1; k < n; ++k)
                {
                    if (!ValueTrait.Equals(a[k, j], Zero <T>()))
                    {
                        for (var i = 0; i < m; ++i)
                        {
                            b[i, j] = Subtract(b[i, j], Multiply(a[k, j], b[i, k]));
                        }
                    }
                }
                if (!isUnit)
                {
                    var temp = Divide(One <T>(), a[j, j]);
                    for (var i = 0; i < m; ++i)
                    {
                        b[i, j] = Multiply(temp, b[i, j]);
                    }
                }
            }
        }
Exemple #6
0
        private static void SolveTriangleMatrixRU <T>(bool isUnit, T alpha, INdArray <T> a, MutableNdArray <T> b)
        {
            var(m, n) = (b.Shape[0], b.Shape[1]);

            /* reference Fortran
             * DO 210, J = 1, N
             *  IF( ALPHA.NE.ONE )THEN
             *      DO 170, I = 1, M
             *          B( I, J ) = ALPHA*B( I, J )
             * 170               CONTINUE
             *  END IF
             *  DO 190, K = 1, J - 1
             *      IF( A( K, J ).NE.ZERO )THEN
             *          DO 180, I = 1, M
             *              B( I, J ) = B( I, J ) - A( K, J )*B( I, K )
             * 180                   CONTINUE
             *      END IF
             * 190           CONTINUE
             *  IF( NOUNIT )THEN
             *      TEMP = ONE/A( J, J )
             *      DO 200, I = 1, M
             *          B( I, J ) = TEMP*B( I, J )
             * 200               CONTINUE
             *  END IF
             * 210       CONTINUE
             */
            for (var j = 0; j < n; ++j)
            {
                if (ValueTrait.Equals(alpha, One <T>()))
                {
                    for (var i = 0; i < m; ++i)
                    {
                        b[i, j] = Multiply(alpha, b[i, j]);
                    }
                }
                for (var k = 0; k < j - 1; ++k)
                {
                    if (!ValueTrait.Equals(a[k, j], Zero <T>()))
                    {
                        for (var i = 0; i < m; ++i)
                        {
                            b[i, j] = Subtract(b[i, j], Multiply(a[k, j], b[i, k]));
                        }
                    }
                }
                if (!isUnit)
                {
                    var temp = Divide(One <T>(), a[j, j]);
                    for (var i = 0; i < m; ++i)
                    {
                        b[i, j] = Multiply(temp, b[i, j]);
                    }
                }
            }
        }
Exemple #7
0
        private static void SolveTriangleMatrixLL <T>(bool isUnit, T alpha, INdArray <T> a, MutableNdArray <T> b)
        {
            var(m, n) = (b.Shape[0], b.Shape[1]);

            /* reference Fortran
             * DO 100, J = 1, N
             *  IF( ALPHA.NE.ONE )THEN
             *      DO 70, I = 1, M
             *          B( I, J ) = ALPHA*B( I, J )
             * 70               CONTINUE
             *  END IF
             *  DO 90 K = 1, M
             *      IF( B( K, J ).NE.ZERO )THEN
             *          IF( NOUNIT )
             * $                      B( K, J ) = B( K, J )/A( K, K )
             *          DO 80, I = K + 1, M
             *              B( I, J ) = B( I, J ) - B( K, J )*A( I, K )
             * 80                   CONTINUE
             *      END IF
             * 90           CONTINUE
             * 100       CONTINUE
             */
            for (var j = 0; j < n; ++j)
            {
                if (!ValueTrait.Equals(alpha, One <T>()))
                {
                    for (var i = 0; i < m; ++i)
                    {
                        b[i, j] = Multiply(alpha, b[i, j]);
                    }
                }
                for (var k = 0; k < m; ++k)
                {
                    if (!ValueTrait.Equals(b[k, j], Zero <T>()))
                    {
                        if (!isUnit)
                        {
                            b[k, j] = Divide(b[k, j], b[k, k]);
                        }
                        for (var i = k; i < m; ++i)
                        {
                            b[i, j] = Subtract(b[i, j], Divide(b[k, j], a[i, k]));
                        }
                    }
                }
            }
        }