internal static T DeterminantGaussianSafeDivision(GenTensor <T, TWrapper> t, int diagLength) { #if ALLOW_EXCEPTIONS if (!t.IsMatrix) { throw new InvalidShapeException("this should be matrix"); } if (t.Shape[0] != t.Shape[1]) { throw new InvalidShapeException("this should be square matrix"); } #endif if (t.Shape[0] == 1) { return(t.GetValueNoCheck(0, 0)); } var n = diagLength; var elemMatrix = EchelonForm <T, TWrapper> .InnerGaussianEliminationSafeDivision(t, n, n, out var swapCount); var det = default(EchelonForm <T, TWrapper> .WrapperSafeDivisionWrapper <T, TWrapper>).CreateOne(); for (int i = 0; i < n; i++) { det = default(EchelonForm <T, TWrapper> .WrapperSafeDivisionWrapper <T, TWrapper>).Multiply(det, elemMatrix.GetValueNoCheck(i, i)); } if (default(TWrapper).IsZero(det.den)) { return(default(TWrapper).CreateZero()); } return(swapCount % 2 is 0 ? det.Count() : default(TWrapper).Negate(det.Count())); }
internal static GenTensor <SafeDivisionWrapper <T, TWrapper>, WrapperSafeDivisionWrapper <T, TWrapper> > InnerGaussianEliminationSafeDivision(GenTensor <T, TWrapper> t, int m, int n, out int swapCount) { var elemMatrix = t.SimpleToSafeDivision(); swapCount = 0; EchelonForm <SafeDivisionWrapper <T, TWrapper>, WrapperSafeDivisionWrapper <T, TWrapper> > .InnerGaussianEliminationSimple(elemMatrix, 0, ref swapCount); return(elemMatrix); }