Browse Source

Added unit tests for matrix with scalar multiplication.

pull/36/head
Jurgen Van Gael 17 years ago
parent
commit
d1769e8e31
  1. 243
      src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs
  2. 58
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.Arithmetic.cs

243
src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs

@ -38,57 +38,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
public abstract partial class Matrix
{
/// <summary>
/// Multiplies each element of this matrix with a scalar.
/// </summary>
/// <param name="scalar">The scalar to multiply with.</param>
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);
}
});
}
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="scalar">The scalar to multiply the matrix with.</param>
/// <param name="result">The matrix to multiply.</param>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
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);
}
/// <summary>
/// Adds another matrix to this matrix. The result will be written into this matrix.
/// </summary>
@ -119,39 +68,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
});
}
/// <summary>
/// Adds two matrices together and returns the results.
/// </summary>
/// <remarks>This operator will allocate new memory for the result. It will
/// choose the representation of either <paramref name="leftSide"/> or <paramref name="rightSide"/> depending on which
/// is denser.</remarks>
/// <param name="leftSide">The left matrix to add.</param>
/// <param name="rightSide">The right matrix to add.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
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;
}
/// <summary>
/// Subtracts another matrix from this matrix. The result will be written into this matrix.
/// </summary>
@ -181,38 +97,55 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
});
}
/// <summary>
/// Multiplies each element of this matrix with a scalar.
/// </summary>
/// <param name="scalar">The scalar to multiply with.</param>
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);
}
});
}
/// <summary>
/// Subtracts two matrices together and returns the results.
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <remarks>This operator will allocate new memory for the result. It will
/// choose the representation of either <paramref name="leftSide"/> or <paramref name="rightSide"/> depending on which
/// is denser.</remarks>
/// <param name="leftSide">The left matrix to subtract.</param>
/// <param name="rightSide">The right matrix to subtract.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Matrix operator -(Matrix leftSide, Matrix rightSide)
/// <param name="scalar">The scalar to multiply the matrix with.</param>
/// <param name="result">The matrix to multiply.</param>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
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);
}
/// <summary>
@ -295,6 +228,110 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return result;
}
/// <summary>
/// Adds two matrices together and returns the results.
/// </summary>
/// <remarks>This operator will allocate new memory for the result. It will
/// choose the representation of either <paramref name="leftSide"/> or <paramref name="rightSide"/> depending on which
/// is denser.</remarks>
/// <param name="leftSide">The left matrix to add.</param>
/// <param name="rightSide">The right matrix to add.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
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;
}
/// <summary>
/// Subtracts two matrices together and returns the results.
/// </summary>
/// <remarks>This operator will allocate new memory for the result. It will
/// choose the representation of either <paramref name="leftSide"/> or <paramref name="rightSide"/> depending on which
/// is denser.</remarks>
/// <param name="leftSide">The left matrix to subtract.</param>
/// <param name="rightSide">The right matrix to subtract.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> don't have the same dimensions.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
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;
}
/// <summary>
/// Multiplies a <strong>Matrix</strong> by a constant and returns the result.
/// </summary>
/// <param name="leftSide">The matrix to multiply.</param>
/// <param name="rightSide">The constant to multiply the matrix by.</param>
/// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception>
public static Matrix operator *(Matrix leftSide, double rightSide)
{
if (leftSide == null)
{
throw new ArgumentNullException("leftSide");
}
Matrix ret = leftSide.Clone();
ret.Multiply(rightSide);
return ret;
}
/// <summary>
/// Multiplies a <strong>Matrix</strong> by a constant and returns the result.
/// </summary>
/// <param name="leftSide">The matrix to multiply.</param>
/// <param name="rightSide">The constant to multiply the matrix by.</param>
/// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Matrix operator *(double leftSide, Matrix rightSide)
{
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
Matrix ret = rightSide.Clone();
ret.Multiply(leftSide);
return ret;
}
/// <summary>
/// Multiplies two matrices.
/// </summary>

58
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];

Loading…
Cancel
Save