From d1769e8e319ae7d71e60b728d8be6ff9affd35cd Mon Sep 17 00:00:00 2001 From: Jurgen Van Gael Date: Tue, 26 Jan 2010 02:33:04 +0800 Subject: [PATCH] Added unit tests for matrix with scalar multiplication. --- .../LinearAlgebra/Double/Matrix.Arithmetic.cs | 243 ++++++++++-------- .../Double/MatrixTests.Arithmetic.cs | 58 ++++- 2 files changed, 196 insertions(+), 105 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs index fc37d6e2..b27cfdaf 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs @@ -38,57 +38,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public abstract partial class Matrix { - /// - /// Multiplies each element of this matrix with a scalar. - /// - /// The scalar to multiply with. - public virtual void Multiply(double scalar) - { - if (Precision.AlmostEqualInDecimalPlaces(1.0, scalar, 15)) - { - return; - } - - Parallel.For( - 0, - RowCount, - i => - { - for (int j = 0; j < ColumnCount; j++) - { - At(i, j, At(i, j) * scalar); - } - }); - } - - /// - /// Multiplies each element of the matrix by a scalar and places results into the result matrix. - /// - /// The scalar to multiply the matrix with. - /// The matrix to multiply. - /// If the result matrix is . - /// If the result matrix's dimensions are not the same as this matrix. - public virtual void Multiply(double scalar, Matrix result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != RowCount) - { - throw new ArgumentException("result", Resources.ArgumentMatrixSameRowDimension); - } - - if (result.ColumnCount != ColumnCount) - { - throw new ArgumentException("result", Resources.ArgumentMatrixSameColumnDimension); - } - - CopyTo(result); - result.Multiply(scalar); - } - /// /// Adds another matrix to this matrix. The result will be written into this matrix. /// @@ -119,39 +68,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double }); } - /// - /// Adds two matrices together and returns the results. - /// - /// This operator will allocate new memory for the result. It will - /// choose the representation of either or depending on which - /// is denser. - /// The left matrix to add. - /// The right matrix to add. - /// The result of the addition. - /// If and don't have the same dimensions. - /// If or is . - public static Matrix operator +(Matrix leftSide, Matrix rightSide) - { - if (rightSide == null) - { - throw new ArgumentNullException("rightSide"); - } - - if (leftSide == null) - { - throw new ArgumentNullException("leftSide"); - } - - if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) - { - throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); - } - - Matrix ret = leftSide.Clone(); - ret.Add(rightSide); - return ret; - } - /// /// Subtracts another matrix from this matrix. The result will be written into this matrix. /// @@ -181,38 +97,55 @@ namespace MathNet.Numerics.LinearAlgebra.Double } }); } + /// + /// Multiplies each element of this matrix with a scalar. + /// + /// The scalar to multiply with. + public virtual void Multiply(double scalar) + { + if (Precision.AlmostEqualInDecimalPlaces(1.0, scalar, 15)) + { + return; + } + + Parallel.For( + 0, + RowCount, + i => + { + for (int j = 0; j < ColumnCount; j++) + { + At(i, j, At(i, j) * scalar); + } + }); + } /// - /// Subtracts two matrices together and returns the results. + /// Multiplies each element of the matrix by a scalar and places results into the result matrix. /// - /// This operator will allocate new memory for the result. It will - /// choose the representation of either or depending on which - /// is denser. - /// The left matrix to subtract. - /// The right matrix to subtract. - /// The result of the addition. - /// If and don't have the same dimensions. - /// If or is . - public static Matrix operator -(Matrix leftSide, Matrix rightSide) + /// The scalar to multiply the matrix with. + /// The matrix to multiply. + /// If the result matrix is . + /// If the result matrix's dimensions are not the same as this matrix. + public virtual void Multiply(double scalar, Matrix result) { - if (rightSide == null) + if (result == null) { - throw new ArgumentNullException("rightSide"); + throw new ArgumentNullException("result"); } - if (leftSide == null) + if (result.RowCount != RowCount) { - throw new ArgumentNullException("leftSide"); + throw new ArgumentException("result", Resources.ArgumentMatrixSameRowDimension); } - if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) + if (result.ColumnCount != ColumnCount) { - throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); + throw new ArgumentException("result", Resources.ArgumentMatrixSameColumnDimension); } - Matrix ret = leftSide.Clone(); - ret.Subtract(rightSide); - return ret; + CopyTo(result); + result.Multiply(scalar); } /// @@ -295,6 +228,110 @@ namespace MathNet.Numerics.LinearAlgebra.Double return result; } + /// + /// Adds two matrices together and returns the results. + /// + /// This operator will allocate new memory for the result. It will + /// choose the representation of either or depending on which + /// is denser. + /// The left matrix to add. + /// The right matrix to add. + /// The result of the addition. + /// If and don't have the same dimensions. + /// If or is . + public static Matrix operator +(Matrix leftSide, Matrix rightSide) + { + if (rightSide == null) + { + throw new ArgumentNullException("rightSide"); + } + + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) + { + throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); + } + + Matrix ret = leftSide.Clone(); + ret.Add(rightSide); + return ret; + } + + /// + /// Subtracts two matrices together and returns the results. + /// + /// This operator will allocate new memory for the result. It will + /// choose the representation of either or depending on which + /// is denser. + /// The left matrix to subtract. + /// The right matrix to subtract. + /// The result of the addition. + /// If and don't have the same dimensions. + /// If or is . + public static Matrix operator -(Matrix leftSide, Matrix rightSide) + { + if (rightSide == null) + { + throw new ArgumentNullException("rightSide"); + } + + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) + { + throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); + } + + Matrix ret = leftSide.Clone(); + ret.Subtract(rightSide); + return ret; + } + + /// + /// Multiplies a Matrix by a constant and returns the result. + /// + /// The matrix to multiply. + /// The constant to multiply the matrix by. + /// The result of the multiplication. + /// If is . + public static Matrix operator *(Matrix leftSide, double rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + Matrix ret = leftSide.Clone(); + ret.Multiply(rightSide); + return ret; + } + + /// + /// Multiplies a Matrix by a constant and returns the result. + /// + /// The matrix to multiply. + /// The constant to multiply the matrix by. + /// The result of the multiplication. + /// If is . + public static Matrix operator *(double leftSide, Matrix rightSide) + { + if (rightSide == null) + { + throw new ArgumentNullException("rightSide"); + } + + Matrix ret = rightSide.Clone(); + ret.Multiply(leftSide); + return ret; + } + /// /// Multiplies two matrices. /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs index b05a3fee..140151e1 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs @@ -28,6 +28,44 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } + [Test] + [Row(0)] + [Row(1)] + [Row(2.2)] + [MultipleAsserts] + public void CanOperatorLeftMultiplyWithScalar(double scalar) + { + var matrix = testMatrices["Singular3x3"]; + var clone = matrix * scalar; + + for (int i = 0; i < matrix.RowCount; i++) + { + for (int j = 0; j < matrix.ColumnCount; j++) + { + Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]); + } + } + } + + [Test] + [Row(0)] + [Row(1)] + [Row(2.2)] + [MultipleAsserts] + public void CanOperatorRightMultiplyWithScalar(double scalar) + { + var matrix = testMatrices["Singular3x3"]; + var clone = matrix * scalar; + + for (int i = 0; i < matrix.RowCount; i++) + { + for (int j = 0; j < matrix.ColumnCount; j++) + { + Assert.AreEqual(matrix[i, j] * scalar, clone[i, j]); + } + } + } + [Test] [Row(0)] [Row(1)] @@ -75,10 +113,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double matrix.Multiply(2.3, result); } + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void OperatorLeftMultiplyWithScalarFailsWhenMatrixIsNull() + { + Matrix matrix = null; + Matrix result = 2.3 * matrix; + } + + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void OperatorRightMultiplyWithScalarFailsWhenMatrixIsNull() + { + Matrix matrix = null; + Matrix result = matrix * 2.3; + } + [Test] [Row("Singular3x3", "Square3x3")] [Row("Singular4x4", "Square4x4")] - public void AddMatrix(string mtxA, string mtxB) + public void CanAddMatrix(string mtxA, string mtxB) { var A = testMatrices[mtxA]; var B = testMatrices[mtxB]; @@ -178,7 +232,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] [Row("Singular3x3", "Square3x3")] [Row("Singular4x4", "Square4x4")] - public void SubtractMatrix(string mtxA, string mtxB) + public void CanSubtractMatrix(string mtxA, string mtxB) { var A = testMatrices[mtxA]; var B = testMatrices[mtxB];