diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index 14f091e2..5e8930d4 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/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); } + + /// + /// Multiplies this dense matrix with another dense matrix and places the results into the result dense matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + /// If the other matrix is . + /// If the result matrix is . + /// If this.Columns != other.Rows. + /// If the result matrix's dimensions are not the this.Rows x other.Columns. + 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); + } + } + + /// + /// Multiplies this matrix with another matrix and returns the result. + /// + /// This operator will allocate new memory for the result. It will + /// choose the representation of either or depending on which + /// is denser. + /// The matrix to multiply with. + /// If this.Columns != other.Rows. + /// If the other matrix is . + 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; + } + + /// + /// Multiplies two dense matrices. + /// + /// The left matrix to multiply. + /// The right matrix to multiply. + /// The result of multiplication. + /// If or is . + /// If the dimensions of or don't conform. + 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 } } diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index 6adb3f11..03f2dce7 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/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; } + + /// + /// Multiplies this matrix with another matrix and places the results into the result matrix. + /// + /// The matrix to multiply with. + /// The result of the multiplication. + /// If the other matrix is . + /// If the result matrix is . + /// If this.Columns != other.Rows. + /// If the result matrix's dimensions are not the this.Rows x other.Columns. + 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); + } + }); + } + } + + /// + /// Multiplies this matrix with another matrix and returns the result. + /// + /// This operator will allocate new memory for the result. It will + /// choose the representation of either or depending on which + /// is denser. + /// The matrix to multiply with. + /// If this.Columns != other.Rows. + /// If the other matrix is . + 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; + } + + /// + /// Multiplies two matrices. + /// + /// 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 multiply. + /// The right matrix to multiply. + /// The result of multiplication. + /// If or is . + /// If the dimensions of or don't conform. + 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 } } \ No newline at end of file diff --git a/src/Numerics/Properties/Resources.Designer.cs b/src/Numerics/Properties/Resources.Designer.cs index cc006619..0382e396 100644 --- a/src/Numerics/Properties/Resources.Designer.cs +++ b/src/Numerics/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // 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 { } } + /// + /// Looks up a localized string similar to Matrix dimensions must agree.. + /// + internal static string ArgumentMatrixDimensions { + get { + return ResourceManager.GetString("ArgumentMatrixDimensions", resourceCulture); + } + } + /// /// Looks up a localized string similar to The matrix indices must not be out of range of the given matrix.. /// @@ -186,15 +195,6 @@ namespace MathNet.Numerics.Properties { } } - /// - /// Looks up a localized string similar to Matrix dimensions must agree.. - /// - internal static string ArgumentMatrixSameDimensions { - get { - return ResourceManager.GetString("ArgumentMatrixSameDimensions", resourceCulture); - } - } - /// /// Looks up a localized string similar to Matrix row dimensions must agree.. /// diff --git a/src/Numerics/Properties/Resources.resx b/src/Numerics/Properties/Resources.resx index 88081ee6..bb058353 100644 --- a/src/Numerics/Properties/Resources.resx +++ b/src/Numerics/Properties/Resources.resx @@ -135,7 +135,7 @@ Matrix column dimensions must agree. - + Matrix dimensions must agree.