internal T DeterminantLaplace(int diagLength) { if (diagLength == 1) { return(ConstantsAndFunctions <T> .Forward(this.GetValueNoCheck(0, 0))); } var det = ConstantsAndFunctions <T> .CreateZero(); var sign = ConstantsAndFunctions <T> .CreateOne(); var temp = SquareMatrixFactory <T> .GetMatrix(diagLength); for (int i = 0; i < diagLength; i++) { GetCofactor(this, temp, 0, i, diagLength); det = ConstantsAndFunctions <T> .Add(det, ConstantsAndFunctions <T> .Multiply( sign, ConstantsAndFunctions <T> .Multiply( this.GetValueNoCheck(0, i), temp.DeterminantLaplace(diagLength - 1) )) ); sign = ConstantsAndFunctions <T> .Negate(sign); } return(det); }
/// <summary> /// Finds matrix multiplication result /// a and b are matrices /// a.Shape[1] should be equal to b.Shape[0] /// the resulting matrix is [a.Shape[0] x b.Shape[1]] shape /// /// O(N^3) /// </summary> public static GenTensor <T> MatrixMultiply(GenTensor <T> a, GenTensor <T> b) { #if ALLOW_EXCEPTIONS if (!a.IsMatrix || !b.IsMatrix) { throw new InvalidShapeException($"Both {nameof(a)} and {nameof(b)} should be matrices"); } if (a.Shape[1] != b.Shape[0]) { throw new InvalidShapeException($"{nameof(a)}'s height must be equal to {nameof(b)}'s width"); } #endif var width = a.Shape[0]; var height = b.Shape[1]; var row = a.Shape[1]; var res = CreateMatrix(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { var s = ConstantsAndFunctions <T> .CreateZero(); for (int i = 0; i < row; i++) { var v1 = a.GetValueNoCheck(x, i); var v2 = b.GetValueNoCheck(i, y); s = ConstantsAndFunctions <T> .Add(s, ConstantsAndFunctions <T> .Multiply(v1, v2)); } res.SetValueNoCheck(s, x, y); } } return(res); }
private static void InitIfNotInitted() { if (isFracInitted) { return; } isFracInitted = true; ConstantsAndFunctions <SafeDivisionWrapper <T> > .Add = (a, b) => new SafeDivisionWrapper <T>( ConstantsAndFunctions <T> .Add( ConstantsAndFunctions <T> .Multiply(a.num, b.den), ConstantsAndFunctions <T> .Multiply(a.den, b.num) ), ConstantsAndFunctions <T> .Multiply(a.den, b.den) ); ConstantsAndFunctions <SafeDivisionWrapper <T> > .Subtract = (a, b) => new SafeDivisionWrapper <T>( ConstantsAndFunctions <T> .Subtract( ConstantsAndFunctions <T> .Multiply(a.num, b.den), ConstantsAndFunctions <T> .Multiply(a.den, b.num) ), ConstantsAndFunctions <T> .Multiply(a.den, b.den) ); ConstantsAndFunctions <SafeDivisionWrapper <T> > .Multiply = (a, b) => new SafeDivisionWrapper <T>( ConstantsAndFunctions <T> .Multiply(a.num, b.num), ConstantsAndFunctions <T> .Multiply(a.den, b.den) ); ConstantsAndFunctions <SafeDivisionWrapper <T> > .Divide = (a, b) => new SafeDivisionWrapper <T>( ConstantsAndFunctions <T> .Multiply(a.num, b.den), ConstantsAndFunctions <T> .Multiply(a.den, b.num) ); ConstantsAndFunctions <SafeDivisionWrapper <T> > .CreateOne = () => new SafeDivisionWrapper <T>(ConstantsAndFunctions <T> .CreateOne()); }
/// <summary> /// Finds the scalar product of two vectors /// /// O(N) /// </summary> public static T VectorDotProduct(GenTensor <T> a, GenTensor <T> b) { #if ALLOW_EXCEPTIONS if (!a.IsVector || !b.IsVector) { throw new InvalidShapeException($"{nameof(a)} and {nameof(b)} should be vectors"); } if (a.Shape[0] != b.Shape[0]) { throw new InvalidShapeException($"{nameof(a)}'s length should be the same as {nameof(b)}'s"); } #endif var res = ConstantsAndFunctions <T> .CreateZero(); for (int i = 0; i < a.Shape[0]; i++) { res = ConstantsAndFunctions <T> .Add(res, ConstantsAndFunctions <T> .Multiply(a.GetValueNoCheck(i), b.GetValueNoCheck(i))); } return(res); }
public static GenTensor <T> PiecewiseAdd(GenTensor <T> a, T b) => CreateTensor(a.Shape, ind => ConstantsAndFunctions <T> .Add(a[ind], b));