Browse Source

Added matrix-matrix multiplication.

la-knuth
Jurgen Van Gael 17 years ago
parent
commit
4032628f10
  1. 102
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  2. 119
      src/Numerics/LinearAlgebra/Double/Matrix.cs
  3. 20
      src/Numerics/Properties/Resources.Designer.cs
  4. 2
      src/Numerics/Properties/Resources.resx

102
src/Numerics/LinearAlgebra/Double/DenseMatrix.cs

@ -225,7 +225,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixSameDimensions);
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
@ -265,11 +265,109 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixSameDimensions);
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
}
/// <summary>
/// Multiplies this dense matrix with another dense matrix and places the results into the result dense matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="NotConformableException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="NotConformableException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public void Multiply(DenseMatrix other, DenseMatrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (result == null)
{
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
Matrix tmp = result.CreateMatrix(result.RowCount, result.ColumnCount);
Multiply(other, tmp);
tmp.CopyTo(result);
}
else
{
Control.LinearAlgebraProvider.MatrixMultiply(this.Data, this.RowCount, this.ColumnCount,
other.Data, other.RowCount, other.ColumnCount, result.Data);
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </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="other">The matrix to multiply with.</param>
/// <exception cref="NotConformableException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
public Matrix Multiply(DenseMatrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (ColumnCount != other.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
Matrix result = CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result;
}
/// <summary>
/// Multiplies two dense matrices.
/// </summary>
/// <param name="leftSide">The left matrix to multiply.</param>
/// <param name="rightSide">The right matrix to multiply.</param>
/// <returns>The result of multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
/// <exception cref="NotConformableException">If the dimensions of <paramref name="leftSide"/> or <paramref name="rightSide"/> don't conform.</exception>
public static DenseMatrix operator *(DenseMatrix leftSide, DenseMatrix rightSide)
{
if (leftSide == null)
{
throw new ArgumentNullException("leftSide");
}
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
if (leftSide.ColumnCount != rightSide.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
return (DenseMatrix)leftSide.Multiply(rightSide);
}
#endregion
}
}

119
src/Numerics/LinearAlgebra/Double/Matrix.cs

@ -436,7 +436,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixSameDimensions);
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Parallel.For(
@ -476,7 +476,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixSameDimensions);
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Matrix ret = leftSide.Clone();
@ -499,7 +499,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixSameDimensions);
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Parallel.For(
@ -539,13 +539,124 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixSameDimensions);
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Matrix ret = leftSide.Clone();
ret.Subtract(rightSide);
return ret;
}
/// <summary>
/// Multiplies this matrix with another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="NotConformableException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="NotConformableException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public virtual void Multiply(Matrix other, Matrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (result == null)
{
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
Matrix tmp = result.CreateMatrix(result.RowCount, result.ColumnCount);
Multiply(other, tmp);
tmp.CopyTo(result);
}
else
{
Parallel.For(0, this.RowCount, j =>
{
for (int i = 0; i != other.ColumnCount; i++)
{
double s = 0;
for (int l = 0; l < this.ColumnCount; l++)
{
s += this.At(j, l) * other.At(l, i);
}
result.At(i, j, s);
}
});
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </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="other">The matrix to multiply with.</param>
/// <exception cref="NotConformableException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
public virtual Matrix Multiply(Matrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (ColumnCount != other.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
Matrix result = CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result;
}
/// <summary>
/// Multiplies two matrices.
/// </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 multiply.</param>
/// <param name="rightSide">The right matrix to multiply.</param>
/// <returns>The result of multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
/// <exception cref="NotConformableException">If the dimensions of <paramref name="leftSide"/> or <paramref name="rightSide"/> don't conform.</exception>
public static Matrix operator *(Matrix leftSide, Matrix rightSide)
{
if (leftSide == null)
{
throw new ArgumentNullException("leftSide");
}
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
if (leftSide.ColumnCount != rightSide.RowCount)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
return leftSide.Multiply(rightSide);
}
#endregion
}
}

20
src/Numerics/Properties/Resources.Designer.cs

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.4200
// Runtime Version:2.0.50727.4927
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -141,6 +141,15 @@ namespace MathNet.Numerics.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Matrix dimensions must agree..
/// </summary>
internal static string ArgumentMatrixDimensions {
get {
return ResourceManager.GetString("ArgumentMatrixDimensions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The matrix indices must not be out of range of the given matrix..
/// </summary>
@ -186,15 +195,6 @@ namespace MathNet.Numerics.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Matrix dimensions must agree..
/// </summary>
internal static string ArgumentMatrixSameDimensions {
get {
return ResourceManager.GetString("ArgumentMatrixSameDimensions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Matrix row dimensions must agree..
/// </summary>

2
src/Numerics/Properties/Resources.resx

@ -135,7 +135,7 @@
<data name="ArgumentMatrixSameColumnDimension" xml:space="preserve">
<value>Matrix column dimensions must agree.</value>
</data>
<data name="ArgumentMatrixSameDimensions" xml:space="preserve">
<data name="ArgumentMatrixDimensions" xml:space="preserve">
<value>Matrix dimensions must agree.</value>
</data>
<data name="ArgumentMatrixSameRowDimension" xml:space="preserve">

Loading…
Cancel
Save