public static GenTensor <T, TWrapper> Adjoint(GenTensor <T, TWrapper> t) { #if ALLOW_EXCEPTIONS if (!t.IsSquareMatrix) { throw new InvalidShapeException("Matrix should be square"); } #endif var diagLength = t.Shape.shape[0]; if (diagLength is 1) { return(GenTensor <T, TWrapper> .CreateIdentityMatrix(1)); } var res = GenTensor <T, TWrapper> .CreateSquareMatrix(diagLength); var temp = SquareMatrixFactory <T, TWrapper> .GetMatrix(diagLength - 1); if (diagLength == 1) { res.SetValueNoCheck(default(TWrapper).CreateOne(), 0, 0); return(res); } var toNegate = false; for (int x = 0; x < diagLength; x++) { for (int y = 0; y < diagLength; y++) { GetCofactorMatrix(t, temp, x, y, diagLength); var cofactor = Determinant <T, TWrapper> .DeterminantGaussianSafeDivision(temp, diagLength - 1); // TODO: is this statement correct? toNegate = (x + y) % 2 == 1; var minor = toNegate ? default(TWrapper).Negate(cofactor) : cofactor; res.SetValueNoCheck(minor, y, x); } } return(res); }
public static void InvertMatrix(GenTensor <T, TWrapper> t) { #if ALLOW_EXCEPTIONS if (!t.IsSquareMatrix) { throw new InvalidShapeException("this should be a square matrix"); } #endif var diagLength = t.Shape.shape[0]; if (diagLength is 1) { t.SetValueNoCheck( default(TWrapper).Divide( default(TWrapper).CreateOne(), t.GetValueNoCheck(0, 0) ), 0, 0); return; } var det = Determinant <T, TWrapper> .DeterminantGaussianSafeDivision(t); #if ALLOW_EXCEPTIONS if (default(TWrapper).IsZero(det)) { throw new InvalidDeterminantException("Cannot invert a singular matrix"); } #endif var adj = Adjoint(t); for (int x = 0; x < diagLength; x++) { for (int y = 0; y < diagLength; y++) { t.SetValueNoCheck( default(TWrapper).Divide( adj.GetValueNoCheck(x, y), det ), x, y ); } } }