public void CanCheckRankOfSquareSingular(int order) { var matrixA = new DenseMatrix(order, order); matrixA[0, 0] = 1; matrixA[order - 1, order - 1] = 1; for (var i = 1; i < order - 1; i++) { matrixA[i, i - 1] = 1; matrixA[i, i + 1] = 1; matrixA[i - 1, i] = 1; matrixA[i + 1, i] = 1; } var factorSvd = matrixA.Svd(); Assert.AreEqual(factorSvd.Determinant, Complex32.Zero); Assert.AreEqual(factorSvd.Rank, order - 1); }
public void CanCheckRankOfSquareSingular([Values(10, 50, 100)] int order) { var A = new DenseMatrix(order, order); A[0, 0] = 1; A[order - 1, order - 1] = 1; for (var i = 1; i < order - 1; i++) { A[i, i - 1] = 1; A[i, i + 1] = 1; A[i - 1, i] = 1; A[i + 1, i] = 1; } var factorEvd = A.Evd(); Assert.AreEqual(factorEvd.Determinant, Complex32.Zero); Assert.AreEqual(factorEvd.Rank, order - 1); }
public void CanAddSparseMatricesBothWays() { var m1 = new SparseMatrix(1, 3); var m2 = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); var sum1 = m1 + m2; var sum2 = m2 + m1; Assert.IsTrue(sum1.Equals(m2)); Assert.IsTrue(sum1.Equals(sum2)); var sparseResult = new SparseMatrix(1, 3); sparseResult.Add(m2, sparseResult); Assert.IsTrue(sparseResult.Equals(sum1)); sparseResult = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); sparseResult.Add(m1, sparseResult); Assert.IsTrue(sparseResult.Equals(sum1)); sparseResult = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); m1.Add(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(sum1)); sparseResult = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); sparseResult.Add(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(2*sum1)); var denseResult = new DenseMatrix(1, 3); denseResult.Add(m2, denseResult); Assert.IsTrue(denseResult.Equals(sum1)); denseResult = DenseMatrix.OfArray(new Complex32[,] {{0, 1, 1}}); denseResult.Add(m1, denseResult); Assert.IsTrue(denseResult.Equals(sum1)); var m3 = DenseMatrix.OfArray(new Complex32[,] {{0, 1, 1}}); var sum3 = m1 + m3; var sum4 = m3 + m1; Assert.IsTrue(sum3.Equals(m3)); Assert.IsTrue(sum3.Equals(sum4)); }
/// <summary> /// Initializes a square <see cref="DenseMatrix"/> with all zero's except for ones on the diagonal. /// </summary> /// <param name="order">the size of the square matrix.</param> /// <returns>A dense identity matrix.</returns> /// <exception cref="ArgumentException"> /// If <paramref name="order"/> is less than one. /// </exception> public static DenseMatrix Identity(int order) { var m = new DenseMatrix(order); for (var i = 0; i < order; i++) { m.Data[(i * order) + i] = 1.0f; } return m; }
/// <summary> /// Create a new dense matrix with the diagonal as a copy of the given vector. /// This new matrix will be independent from the vector. /// A new memory block will be allocated for storing the matrix. /// </summary> public static DenseMatrix OfDiagonalVector(int rows, int columns, Vector<Complex32> diagonal) { var m = new DenseMatrix(rows, columns); m.SetDiagonal(diagonal); return m; }
/// <summary> /// Create a new dense matrix with the diagonal as a copy of the given array. /// This new matrix will be independent from the array. /// A new memory block will be allocated for storing the matrix. /// </summary> public static DenseMatrix OfDiagonalArray(int rows, int columns, Complex32[] diagonal) { var m = new DenseMatrix(rows, columns); m.SetDiagonal(diagonal); return m; }
public void LUFailsWithNonSquareMatrix() { var matrix = new DenseMatrix(3, 1); Assert.That(() => matrix.LU(), Throws.ArgumentException); }
/// <summary> /// Adds another matrix to this matrix. /// </summary> /// <param name="other">The matrix to add to this matrix.</param> /// <returns>The result of the addition.</returns> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> public override Matrix<Complex32> Add(Matrix<Complex32> other) { if (other == null) { throw new ArgumentNullException("other"); } if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) { throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions); } Matrix<Complex32> result; if (other is DiagonalMatrix) { result = new DiagonalMatrix(RowCount, ColumnCount); } else { result = new DenseMatrix(RowCount, ColumnCount); } Add(other, result); return result; }
/// <summary> /// Subtracts another matrix from this matrix. /// </summary> /// <param name="other">The matrix to subtract.</param> /// <returns>The result of the subtraction.</returns> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> public override Matrix<Complex32> Subtract(Matrix<Complex32> other) { if (other == null) { throw new ArgumentNullException("other"); } if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) { throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other"); } Matrix<Complex32> result; if (other is DiagonalMatrix) { result = new DiagonalMatrix(RowCount, ColumnCount); } else { result = new DenseMatrix(RowCount, ColumnCount); } Subtract(other, result); return result; }
public void CanComputeThinQRFactorTallMatrixWithWorkArray() { var matrix = _matrices["Tall3x2"]; var r = new Complex32[matrix.ColumnCount*matrix.ColumnCount]; var tau = new Complex32[3]; var q = new Complex32[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, q, q.Length); var work = new Complex32[matrix.ColumnCount*Control.BlockSize]; Control.LinearAlgebraProvider.ThinQRFactor(q, matrix.RowCount, matrix.ColumnCount, r, tau, work); var mq = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, q); var mr = new DenseMatrix(matrix.ColumnCount, matrix.ColumnCount, r); var a = mq*mr; for (var row = 0; row < matrix.RowCount; row++) { for (var col = 0; col < matrix.ColumnCount; col++) { AssertHelpers.AlmostEqualRelative(matrix[row, col], a[row, col], 5); } } }
public void CanComputeQRFactorWideMatrix() { var matrix = _matrices["Wide2x3"]; var r = new Complex32[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, r, r.Length); var tau = new Complex32[3]; var q = new Complex32[matrix.RowCount*matrix.RowCount]; Control.LinearAlgebraProvider.QRFactor(r, matrix.RowCount, matrix.ColumnCount, q, tau); var mr = new DenseMatrix(matrix.RowCount, matrix.ColumnCount, r).UpperTriangle(); var mq = new DenseMatrix(matrix.RowCount, matrix.RowCount, q); var a = mq*mr; for (var row = 0; row < matrix.RowCount; row++) { for (var col = 0; col < matrix.ColumnCount; col++) { AssertHelpers.AlmostEqualRelative(matrix[row, col], a[row, col], 5); } } }
public void CanSolveUsingCholesky() { var matrix = new DenseMatrix(3, 3, new Complex32[] {1, 1, 1, 1, 2, 3, 1, 3, 6}); var a = new Complex32[] {1, 1, 1, 1, 2, 3, 1, 3, 6}; var b = new[] {new Complex32(1.0f, 0.0f), 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}; Control.LinearAlgebraProvider.CholeskySolve(a, 3, b, 2); AssertHelpers.AlmostEqualRelative(b[0], 0, 5); AssertHelpers.AlmostEqualRelative(b[1], 1, 5); AssertHelpers.AlmostEqualRelative(b[2], 0, 5); AssertHelpers.AlmostEqualRelative(b[3], 3, 5); AssertHelpers.AlmostEqualRelative(b[4], 1, 5); AssertHelpers.AlmostEqualRelative(b[5], 0, 5); NotModified(3, 3, a, matrix); }
public void CanMultiplyTallAndWideMatricesWithUpdate() { var x = _matrices["Tall3x2"]; var y = _matrices["Wide2x3"]; var c = new DenseMatrix(x.RowCount, y.ColumnCount); Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 2.2f, x.Values, x.RowCount, x.ColumnCount, y.Values, y.RowCount, y.ColumnCount, 1.0f, c.Values); for (var i = 0; i < c.RowCount; i++) { for (var j = 0; j < c.ColumnCount; j++) { var test = 2.2f*x.Row(i)*y.Column(j); // if they are both close to zero, skip if (Math.Abs(test.Real) < 1e-7 && Math.Abs(c[i, j].Real) < 1e-7) { continue; } AssertHelpers.AlmostEqualRelative(2.2f*x.Row(i)*y.Column(j), c[i, j], 5); } } }
public void CanMultiplyWideAndTallMatricesWithUpdate() { var x = _matrices["Wide2x3"]; var y = _matrices["Tall3x2"]; var c = new DenseMatrix(x.RowCount, y.ColumnCount); Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 2.2f, x.Values, x.RowCount, x.ColumnCount, y.Values, y.RowCount, y.ColumnCount, 1.0f, c.Values); for (var i = 0; i < c.RowCount; i++) { for (var j = 0; j < c.ColumnCount; j++) { AssertHelpers.AlmostEqualRelative(2.2f*x.Row(i)*y.Column(j), c[i, j], 5); } } }
public void CanMultiplyTallAndWideMatrices() { var x = _matrices["Tall3x2"]; var y = _matrices["Wide2x3"]; var c = new DenseMatrix(x.RowCount, y.ColumnCount); Control.LinearAlgebraProvider.MatrixMultiply(x.Values, x.RowCount, x.ColumnCount, y.Values, y.RowCount, y.ColumnCount, c.Values); for (var i = 0; i < c.RowCount; i++) { for (var j = 0; j < c.ColumnCount; j++) { AssertHelpers.AlmostEqualRelative(x.Row(i)*y.Column(j), c[i, j], 5); } } }
public void CanSolveUsingSvdTallMatrixOnFactoredMatrix() { var matrix = _matrices["Tall3x2"]; var a = new Complex32[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, a, a.Length); var s = new Complex32[matrix.ColumnCount]; var u = new Complex32[matrix.RowCount*matrix.RowCount]; var vt = new Complex32[matrix.ColumnCount*matrix.ColumnCount]; Control.LinearAlgebraProvider.SingularValueDecomposition(true, a, matrix.RowCount, matrix.ColumnCount, s, u, vt); var b = new[] {new Complex32(1.0f, 0.0f), 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}; var x = new Complex32[matrix.ColumnCount*2]; Control.LinearAlgebraProvider.SvdSolveFactored(matrix.RowCount, matrix.ColumnCount, s, u, vt, b, 2, x); var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; AssertHelpers.AlmostEqual(test[0, 0], x[0], 5); AssertHelpers.AlmostEqual(test[1, 0], x[1], 5); AssertHelpers.AlmostEqual(test[0, 1], x[2], 5); AssertHelpers.AlmostEqual(test[1, 1], x[3], 5); }
/// <summary> /// Returns the conjugate transpose of this matrix. /// </summary> /// <returns>The conjugate transpose of this matrix.</returns> public override Matrix<Complex32> ConjugateTranspose() { var ret = new DenseMatrix(_columnCount, _rowCount); for (var j = 0; j < _columnCount; j++) { var index = j * _rowCount; for (var i = 0; i < _rowCount; i++) { ret._data[(i * _columnCount) + j] = _data[index + i].Conjugate(); } } return ret; }
public void CanSolveUsingQRTallMatrixUsingWorkArray() { var matrix = _matrices["Tall3x2"]; var a = new Complex32[matrix.RowCount*matrix.ColumnCount]; Array.Copy(matrix.Values, a, a.Length); var b = new[] {new Complex32(1.0f, 0.0f), 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}; var x = new Complex32[matrix.ColumnCount*2]; var work = new Complex32[matrix.RowCount*matrix.RowCount]; Control.LinearAlgebraProvider.QRSolve(a, matrix.RowCount, matrix.ColumnCount, b, 2, x, work); NotModified(3, 2, a, matrix); var mb = new DenseMatrix(matrix.RowCount, 2, b); var test = (matrix.Transpose()*matrix).Inverse()*matrix.Transpose()*mb; AssertHelpers.AlmostEqualRelative(test[0, 0], x[0], 5); AssertHelpers.AlmostEqualRelative(test[1, 0], x[1], 5); AssertHelpers.AlmostEqualRelative(test[0, 1], x[2], 5); AssertHelpers.AlmostEqualRelative(test[1, 1], x[3], 5); }
/// <summary> /// Outer product of two vectors /// </summary> /// <param name="u">First vector</param> /// <param name="v">Second vector</param> /// <returns>Matrix M[i,j] = u[i]*v[j] </returns> /// <exception cref="ArgumentNullException">If the u vector is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the v vector is <see langword="null" />.</exception> public static DenseMatrix OuterProduct(DenseVector u, DenseVector v) { if (u == null) { throw new ArgumentNullException("u"); } if (v == null) { throw new ArgumentNullException("v"); } var matrix = new DenseMatrix(u.Count, v.Count); CommonParallel.For( 0, u.Count, i => { for (var j = 0; j < v.Count; j++) { matrix.At(i, j, u._values[i] * v._values[j]); } }); return matrix; }
public void CanSolveUsingQRSquareMatrixOnFactoredMatrix() { var matrix = _matrices["Square3x3"]; var a = new Complex32[matrix.RowCount*matrix.RowCount]; Array.Copy(matrix.Values, a, a.Length); var tau = new Complex32[matrix.ColumnCount]; var q = new Complex32[matrix.ColumnCount*matrix.ColumnCount]; Control.LinearAlgebraProvider.QRFactor(a, matrix.RowCount, matrix.ColumnCount, q, tau); var b = new[] {new Complex32(1.0f, 0.0f), 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}; var x = new Complex32[matrix.ColumnCount*2]; Control.LinearAlgebraProvider.QRSolveFactored(q, a, matrix.RowCount, matrix.ColumnCount, tau, b, 2, x); var mx = new DenseMatrix(matrix.ColumnCount, 2, x); var mb = matrix*mx; AssertHelpers.AlmostEqualRelative(mb[0, 0], b[0], 5); AssertHelpers.AlmostEqualRelative(mb[1, 0], b[1], 5); AssertHelpers.AlmostEqualRelative(mb[2, 0], b[2], 5); AssertHelpers.AlmostEqualRelative(mb[0, 1], b[3], 5); AssertHelpers.AlmostEqualRelative(mb[1, 1], b[4], 4); AssertHelpers.AlmostEqualRelative(mb[2, 1], b[5], 4); }
public void CanSolveForRandomMatrixWhenResultMatrixGiven(int order) { var matrixA = Matrix<Complex32>.Build.Random(order, order, 1); var matrixACopy = matrixA.Clone(); var factorLU = matrixA.LU(); var matrixB = Matrix<Complex32>.Build.Random(order, order, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); factorLU.Solve(matrixB, matrixX); // The solution X row dimension is equal to the column dimension of A Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount); // The solution X has the same number of columns as B Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount); var matrixBReconstruct = matrixA * matrixX; // Check the reconstruction. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-3f); Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-3f); } } // Make sure A didn't change. for (var i = 0; i < matrixA.RowCount; i++) { for (var j = 0; j < matrixA.ColumnCount; j++) { Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]); } } // Make sure B didn't change. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]); } } }
public void CanSubtractSparseMatricesBothWays() { var m1 = new SparseMatrix(1, 3); var m2 = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); var diff1 = m1 - m2; var diff2 = m2 - m1; Assert.IsTrue(diff1.Equals(m2.Negate())); Assert.IsTrue(diff1.Equals(diff2.Negate())); var sparseResult = new SparseMatrix(1, 3); sparseResult.Subtract(m2, sparseResult); Assert.IsTrue(sparseResult.Equals(diff1)); sparseResult = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); sparseResult.Subtract(m1, sparseResult); Assert.IsTrue(sparseResult.Equals(diff2)); sparseResult = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); m1.Subtract(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(diff1)); sparseResult = SparseMatrix.OfArray(new Complex32[,] { { 0, 1, 1 } }); sparseResult.Subtract(sparseResult, sparseResult); Assert.IsTrue(sparseResult.Equals(0*diff1)); var denseResult = new DenseMatrix(1, 3); denseResult.Subtract(m2, denseResult); Assert.IsTrue(denseResult.Equals(diff1)); denseResult = DenseMatrix.OfArray(new Complex32[,] {{0, 1, 1}}); denseResult.Subtract(m1, denseResult); Assert.IsTrue(denseResult.Equals(diff2)); var m3 = DenseMatrix.OfArray(new Complex32[,] {{0, 1, 1}}); var diff3 = m1 - m3; var diff4 = m3 - m1; Assert.IsTrue(diff3.Equals(m3.Negate())); Assert.IsTrue(diff3.Equals(diff4.Negate())); }
/// <summary> /// Create a new dense matrix with the diagonal as a copy of the given array. /// This new matrix will be independent from the array. /// A new memory block will be allocated for storing the matrix. /// </summary> public static DenseMatrix OfDiagonalArray(Complex32[] diagonal) { var m = new DenseMatrix(diagonal.Length, diagonal.Length); m.SetDiagonal(diagonal); return m; }
public void CanSolveForRandomMatrixWhenResultMatrixGivenUsingThinQR(int order) { var matrixA = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixACopy = matrixA.Clone(); var factorQR = matrixA.QR(QRMethod.Thin); var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); factorQR.Solve(matrixB, matrixX); // The solution X row dimension is equal to the column dimension of A Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount); // The solution X has the same number of columns as B Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount); var matrixBReconstruct = matrixA * matrixX; // Check the reconstruction. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-3); Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-3); } } // Make sure A didn't change. for (var i = 0; i < matrixA.RowCount; i++) { for (var j = 0; j < matrixA.ColumnCount; j++) { Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]); } } // Make sure B didn't change. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]); } } }
/// <summary> /// Create a new dense matrix with the diagonal as a copy of the given vector. /// This new matrix will be independent from the vector. /// A new memory block will be allocated for storing the matrix. /// </summary> public static DenseMatrix OfDiagonalVector(Vector<Complex32> diagonal) { var m = new DenseMatrix(diagonal.Count, diagonal.Count); m.SetDiagonal(diagonal); return m; }
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order) { var matrixA = MatrixLoader.GenerateRandomPositiveDefiniteHermitianDenseMatrix(order); MatrixHelpers.ForceConjugateSymmetric(matrixA); var matrixACopy = matrixA.Clone(); var factorEvd = matrixA.Evd(); var matrixB = MatrixLoader.GenerateRandomDenseMatrix(order, order); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(order, order); factorEvd.Solve(matrixB, matrixX); // The solution X row dimension is equal to the column dimension of A Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount); // The solution X has the same number of columns as B Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount); var matrixBReconstruct = matrixA * matrixX; // Check the reconstruction. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-2f); Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-2f); } } // Make sure A didn't change. for (var i = 0; i < matrixA.RowCount; i++) { for (var j = 0; j < matrixA.ColumnCount; j++) { Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]); } } // Make sure B didn't change. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]); } } }
/// <summary> /// Returns the transpose of this matrix. /// </summary> /// <returns>The transpose of this matrix.</returns> public override Matrix<Complex32> Transpose() { var ret = new DenseMatrix(_columnCount, _rowCount); for (var j = 0; j < _columnCount; j++) { var index = j * _rowCount; for (var i = 0; i < _rowCount; i++) { ret._values[(i * _columnCount) + j] = _values[index + i]; } } return ret; }
public void CanSolveForRandomMatrixWhenResultMatrixGiven(int row, int col) { var matrixA = Matrix<Complex32>.Build.RandomPositiveDefinite(row, 1); var matrixACopy = matrixA.Clone(); var chol = matrixA.Cholesky(); var matrixB = Matrix<Complex32>.Build.Random(row, col, 1); var matrixBCopy = matrixB.Clone(); var matrixX = new DenseMatrix(row, col); chol.Solve(matrixB, matrixX); Assert.AreEqual(matrixB.RowCount, matrixX.RowCount); Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount); var matrixBReconstruct = matrixA * matrixX; // Check the reconstruction. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 0.03f); Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 0.03f); } } // Make sure A didn't change. for (var i = 0; i < matrixA.RowCount; i++) { for (var j = 0; j < matrixA.ColumnCount; j++) { Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]); } } // Make sure B didn't change. for (var i = 0; i < matrixB.RowCount; i++) { for (var j = 0; j < matrixB.ColumnCount; j++) { Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]); } } }
/// <summary> /// Returns the conjugate transpose of this matrix. /// </summary> /// <returns>The conjugate transpose of this matrix.</returns> public override Matrix<Complex32> ConjugateTranspose() { var ret = new DenseMatrix(ColumnCount, RowCount); for (var j = 0; j < ColumnCount; j++) { var index = j * RowCount; for (var i = 0; i < RowCount; i++) { ret.Data[(i * ColumnCount) + j] = Data[index + i].Conjugate(); } } return ret; }
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order) { var A = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1); MatrixHelpers.ForceHermitian(A); var ACopy = A.Clone(); var evd = A.Evd(); var B = Matrix<Complex32>.Build.Random(order, order, 2); var BCopy = B.Clone(); var X = new DenseMatrix(order, order); evd.Solve(B, X); // The solution X row dimension is equal to the column dimension of A Assert.AreEqual(A.ColumnCount, X.RowCount); // The solution X has the same number of columns as B Assert.AreEqual(B.ColumnCount, X.ColumnCount); var BReconstruct = A * X; // Check the reconstruction. AssertHelpers.AlmostEqual(B, BReconstruct, 1); // Make sure A/B didn't change. AssertHelpers.AlmostEqual(ACopy, A, 14); AssertHelpers.AlmostEqual(BCopy, B, 14); }