public static void Test2() { const uint MARGIN = 1; Matrix mA = new Matrix(2 + MARGIN, 3 + MARGIN); Matrix mB = new Matrix(3, 2); Matrix mC = new Matrix(2, 2); mA.SetValue(0 + MARGIN, 0 + MARGIN, 0.11); mA.SetValue(0 + MARGIN, 1 + MARGIN, 0.12); mA.SetValue(0 + MARGIN, 2 + MARGIN, 0.13); mA.SetValue(1 + MARGIN, 0 + MARGIN, 0.21); mA.SetValue(1 + MARGIN, 1 + MARGIN, 0.22); mA.SetValue(1 + MARGIN, 2 + MARGIN, 0.23); mB.SetValue(0, 0, 1011); mB.SetValue(0, 1, 1012); mB.SetValue(1, 0, 1021); mB.SetValue(1, 1, 1022); mB.SetValue(2, 0, 1031); mB.SetValue(2, 1, 1032); MatrixView mViewA = new MatrixView(mA, MARGIN, MARGIN, mA.Columns - MARGIN, mA.Rows - MARGIN); MatrixView mViewB = new MatrixView(mB, 0, 0, mB.Columns, mB.Rows); MatrixView mViewC = new MatrixView(mC, 0, 0, mC.Columns, mC.Rows); Blas.DGemm(Blas.TransposeType.NoTranspose, Blas.TransposeType.NoTranspose, 1.0, mViewA, mViewB, 0.0, ref mViewC); Console.WriteLine(mC.GetValue(0, 0) + " , " + mC.GetValue(0, 1)); Console.WriteLine(mC.GetValue(1, 0) + " , " + mC.GetValue(1, 1)); }
public static void Test() { Matrix mA = new Matrix(2, 3); Matrix mB = new Matrix(3, 2); Matrix mC = new Matrix(2, 2); mA.SetValue(0, 0, 0.11); mA.SetValue(0, 1, 0.12); mA.SetValue(0, 2, 0.13); mA.SetValue(1, 0, 0.21); mA.SetValue(1, 1, 0.22); mA.SetValue(1, 2, 0.23); mB.SetValue(0, 0, 1011); mB.SetValue(0, 1, 1012); mB.SetValue(1, 0, 1021); mB.SetValue(1, 1, 1022); mB.SetValue(2, 0, 1031); mB.SetValue(2, 1, 1032); Blas.DGemm(Blas.TransposeType.NoTranspose, Blas.TransposeType.NoTranspose, 1.0, mA, mB, 0.0, ref mC); Console.WriteLine(mC.GetValue(0, 0) + " , " + mC.GetValue(0, 1)); Console.WriteLine(mC.GetValue(1, 0) + " , " + mC.GetValue(1, 1)); }
/// <summary> /// Decomposes the specified matrix using a LU decomposition. /// </summary> /// <param name="matrix">The matrix to decompose.</param> public void Decompose(Matrix matrix) { LU = matrix.Clone(); pivots = new int[LU.Rows]; for (var i = 0; i < LU.Rows; i++) { pivots[i] = i; } pivotSign = 1; var column = new double[LU.Rows]; for (var j = 0; j < LU.Columns; j++) { for (var i = 0; i < LU.Rows; i++) { column[i] = LU.GetValue(i, j); } // Apply previous transformations. for (var i = 0; i < LU.Rows; i++) { // Most of the time is spent in the following dot product. var kmax = Math.Min(i, j); var s = 0.0; for (var k = 0; k < kmax; k++) { s += LU.GetValue(i, k) * column[k]; } LU.SetValue(i, j, column[i] - s); column[i] -= s; } // Find pivot and exchange if necessary. var p = j; for (var i = j + 1; i < LU.Rows; i++) { if (Math.Abs(column[i]) > Math.Abs(column[p])) { p = i; } } if (p != j) { for (var k = 0; k < LU.Columns; k++) { var t = LU[p, k]; LU.SetValue(p, k, LU[j, k]); LU.SetValue(j, k, t); } Swapper.Swap(pivots, p, j); pivotSign = -pivotSign; } // Compute multipliers. if ((j < LU.Rows) && (LU.GetValue(j, j) != 0.0)) { for (var i = j + 1; i < LU.Rows; i++) { LU.SetValue(i, j, LU.GetValue(i, j) / LU.GetValue(j, j)); } } } }
/// <summary> /// /** Solve A*X = B /// </summary> /// <param name="right">A Matrix with as many rows as A and any number of columns.</param> /// <returns>X so that L*L'*X = B</returns> /// <exception cref="ArgumentNullException"><paramref name="right"/> is a null reference.</exception> /// <exception cref="ArgumentException"><paramref name="right"/> is not square.</exception> public Matrix Solve(Matrix right) { Guard.ArgumentNotNull(right, "b"); if ((right.Columns != 1) || (right.Rows != dimension)) { throw new ArgumentException(haveNonMatchingDimensions); } var x = new double[dimension]; int k; double sum; var m = new double[dimension]; for (var j = 0; j < dimension; j++) { m[j] = right.GetValue(j, 0); } for (var i = 0; i < dimension; i++) { // Solve <c>L * y = b</c>, storing y in x. for (sum = m[i], k = i - 1; k >= 0; k--) { sum -= LeftFactorMatrix[i, k] * x[k]; } x[i] = sum / LeftFactorMatrix[i, i]; } for (var i = dimension - 1; i >= 0; i--) { // Solve L^T * x = y. for (sum = x[i], k = i + 1; k < dimension; k++) { sum -= LeftFactorMatrix[k, i] * x[k]; } x[i] = sum / LeftFactorMatrix[i, i]; } return new Matrix(dimension, 1, x); }
public static void TestInverse() { //---------------------- //| 0.18 | 0.41 | 0.14 | //| 0.60 | 0.24 | 0.30 | //| 0.57 | 0.99 | 0.97 | //---------------------- Matrix matrix = new Matrix(3, 3); Matrix matrix2 = new Matrix(4, 4); matrix.SetValue(0, 0, 0.18); matrix.SetValue(0, 1, 0.41); matrix.SetValue(0, 2, 0.14); matrix.SetValue(1, 0, 0.60); matrix.SetValue(1, 1, 0.24); matrix.SetValue(1, 2, 0.30); matrix.SetValue(2, 0, 0.57); matrix.SetValue(2, 1, 0.99); matrix.SetValue(2, 2, 0.97); double[,] test = matrix.ToArray(); for (uint i = 0; i < matrix.Columns; i++) { for (uint j = 0; j < matrix.Rows; j++) { matrix2.SetValue(i + 1, j + 1, matrix.GetValue(i, j)); } } //LU分解による方法 Matrix inv = new Matrix(3, 3); int sig; Permutation perm = new Permutation(3); perm.Initialize(); LinearAlgebra.LUDecomposition(ref matrix, ref perm, out sig); LinearAlgebra.LUInvert(matrix, perm, ref inv); for (uint i = 0; i < inv.Columns; i++) { for (uint j = 0; j < inv.Rows; j++) { Console.Write(inv.GetValue(i, j).ToString("F4").PadLeft(8) + " | "); } Console.WriteLine(); } Console.WriteLine(); //部分行列のテスト perm.Initialize(); Matrix inv2 = new Matrix(4, 4); MatrixView mView = new MatrixView(matrix2, 1, 1, 3, 3); MatrixView mViewINV = new MatrixView(inv2, 0, 1, 3, 3); LinearAlgebra.LUDecomposition(ref mView, ref perm, out sig); LinearAlgebra.LUInvert(mView, perm, ref mViewINV); for (uint i = 0; i < mViewINV.ColumnSize; i++) { for (uint j = 0; j < mViewINV.RowSize; j++) { Console.Write(mViewINV.GetValue(i, j).ToString("F4").PadLeft(8) + " | "); } Console.WriteLine(); } Console.WriteLine(); for (uint i = 0; i < inv2.Columns; i++) { for (uint j = 0; j < inv2.Rows; j++) { Console.Write(inv2.GetValue(i, j).ToString("F4").PadLeft(8) + " | "); } Console.WriteLine(); } Console.Read(); }
/// <summary> /// Decomposes the specified matrix, using a QR decomposition. /// </summary> /// <param name="matrix">The matrix to decompose.</param> public void Decompose(Matrix matrix) { qr = matrix.Clone(); diagonal = new double[qr.Columns]; // Main loop. for (var k = 0; k < qr.Columns; k++) { // Compute 2-norm of k-th column without under/overflow. double nrm = 0; for (var i = k; i < qr.Rows; i++) { nrm = MathAlgorithms.Hypotenuse(nrm, qr[i, k]); } if (nrm != 0.0) { // Form k-th Householder vector. if (qr.GetValue(k, k) < 0) { nrm = -nrm; } for (var i = k; i < qr.Rows; i++) { qr.SetValue(i, k, qr.GetValue(i, k) / nrm); } qr.SetValue(k, k, qr.GetValue(k, k) + 1.0); // Apply transformation to remaining columns. for (var j = k + 1; j < qr.Columns; j++) { var s = 0.0; for (var i = k; i < qr.Rows; i++) { s += qr.GetValue(i, k) * qr.GetValue(i, j); } s = (-s) / qr.GetValue(k, k); for (var i = k; i < qr.Rows; i++) { qr.SetValue(i, j, qr.GetValue(i, j) + (s * qr.GetValue(i, k))); } } } diagonal[k] = -nrm; } }