Ejemplo n.º 1
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;
                    }
                }
            }
        }
Ejemplo n.º 2
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;
            }
        }