/// <summary> /// Solves simultaneous linear equations. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="a"> [<c>a.Rank == 2 && a.Shape[0] == a.Shape[1]</c>] </param> /// <param name="b"> [<c>(b.Rank == 1 || b.Rank == 2) && b.Shape[0] == a.Shape[0]</c>] </param> /// <returns></returns> /// <exception cref="ShapeMismatchException"> /// <para> When <c>n := a.Shape[0]</c>, </para> /// <para> - If <c>b.Shape == {n}</c>, then <c>$ReturnValue.Shape == {n}</c>. </para> /// <para> /// - If <c>b.Shape == {n, p}</c>, then <c>$ReturnValue.Shape == {n, p}</c>. /// Each column of return value is the solution against corresponding column of b. /// </para> /// </exception> public static NdArray <T> Solve <T>(this INdArray <T> a, INdArray <T> b) { Guard.AssertShapeMatch(a.Rank == 2 && a.Shape[0] == a.Shape[1], "a.Rank == 2 && a.Shape[0] == a.Shape[1]"); if (b.Rank == 1 && b.Shape[0] == a.Shape[0]) { var(l, u, perms) = a.LUWithPermutationsLegacy(); var x = NdArray.CreateMutable(new T[b.Shape[0]]); SolveCore(l, u, perms, b, x); return(x.MoveToImmutable()); } if (b.Rank == 2 && b.Shape[0] == a.Shape[0]) { var(l, u, perms) = a.LUWithPermutationsLegacy(); var x = NdArray.CreateMutable(new T[b.Shape[0], b.Shape[1]]); var col = b.Shape[1]; for (var j = 0; j < col; ++j) { var bj = b[Range.Whole, new Index(j, false)]; var xj = x[Range.Whole, new Index(j, false)]; SolveCore(l, u, perms, bj, xj); } return(x.MoveToImmutable()); } Guard.ThrowShapeMismatch("(b.Rank == 1 || b.Rank == 2) && b.Shape[0] == a.Shape[0]"); throw new NotSupportedException(); }
/// <summary> /// Calculates a matrix determinant. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="ndArray"></param> /// <param name="strategy"></param> /// <returns></returns> public static T Determinant <T>(this INdArray <T> ndArray, IIterationStrategy?strategy = default) { Guard.AssertShapeMatch(ndArray.Shape.Length == 2 && ndArray.Shape[0] == ndArray.Shape[1], "x must be a square matrix."); var(_, u, permutations) = ndArray.LUWithPermutationsLegacy(strategy); var n = ndArray.Shape[0]; var x = One <T>(); for (var i = 0; i < n; ++i) { x = Multiply(x, u[i, i]); } if (permutations.Count % 2 == 1) { x = UnaryNegate(x); } return(x); }