public double Determinant() { if (Width != Height) { return(0.0); } DMatrix result = DMatrixUtility.UnitVector2d(Height); DMatrix clone = Clone(); int max; double tmp = 0.0; int i, j, k; for (k = 0; k < Height; k++) { max = k; for (j = k + 1; j < Height; j++) { if (Math.Abs(clone[j, k]) > Math.Abs(clone[max, k])) { max = j; } } if (max != k) { for (i = 0; i < Width; i++) { (clone[max, i], clone[k, i]) = (clone[k, i], clone[max, i]); (result[max, i], result[k, i]) = (result[k, i], result[max, i]); } } tmp = clone[k, k]; } return(tmp); }
/// <summary> /// 逆行列を計算する。 /// 実装は以下のページを参考(https://qiita.com/sekky0816/items/8c73a7ec32fd9b040127) /// TODO https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2012/december/csharp-matrix-decomposition#%E8%A1%8C%E5%88%97%E5%BC%8F も参考にして組み込む /// </summary> /// <returns></returns> public DMatrix Inv() { if (Width != Height) { return(null); } DMatrix result = DMatrixUtility.UnitVector2d(Height); DMatrix clone = Clone(); int max; double tmp; int i, j, k; for (k = 0; k < Height; k++) { max = k; for (j = k + 1; j < Height; j++) { if (Math.Abs(clone[j, k]) > Math.Abs(clone[max, k])) { max = j; } } if (max != k) { for (i = 0; i < Width; i++) { (clone[max, i], clone[k, i]) = (clone[k, i], clone[max, i]); (result[max, i], result[k, i]) = (result[k, i], result[max, i]); } } tmp = clone[k, k]; for (i = 0; i < Width; i++) { clone[k, i] /= tmp; result[k, i] /= tmp; } for (j = 0; j < Height; j++) { if (j != k) { tmp = clone[j, k] / clone[k, k]; for (i = 0; i < Width; i++) { clone[j, i] -= clone[k, i] * tmp; result[j, i] -= result[k, i] * tmp; } } } } for (j = 0; j < Height; j++) { for (i = 0; i < Width; i++) { if (double.IsNaN(result[j, i])) { return(null); } } } return(result); }