diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs new file mode 100644 index 00000000..5891f66b --- /dev/null +++ b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs @@ -0,0 +1,278 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.LinearAlgebra.Double +{ + using System; + using System.Text; + using Properties; + using Threading; + + /// + /// Defines the base class for Matrix classes. + /// + public abstract partial class Matrix + { + /// + /// Adds another matrix to this matrix. The result will be written into this matrix. + /// + /// The matrix to add to this matrix. + /// If the other matrix is . + /// If the two matrices don't have the same dimensions. + public virtual void Add(Matrix other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) + { + throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); + } + + Parallel.For( + 0, + RowCount, + i => + { + for (int j = 0; j < ColumnCount; j++) + { + At(i, j, At(i, j) + other.At(i, j)); + } + }); + } + + /// + /// 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. + /// + /// The matrix to subtract. + /// If the other matrix is . + /// If the two matrices don't have the same dimensions. + public virtual void Subtract(Matrix other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) + { + throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); + } + + Parallel.For( + 0, + RowCount, + i => + { + for (int j = 0; j < ColumnCount; j++) + { + At(i, j, At(i, j) - other.At(i, j)); + } + }); + } + + /// + /// 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 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(j, i, 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); + } + } +} \ No newline at end of file diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index 19994da6..b53641f5 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs @@ -39,7 +39,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double #if !SILVERLIGHT [Serializable] #endif - public abstract class Matrix : + public abstract partial class Matrix : #if SILVERLIGHT IFormattable, IEquatable #else @@ -636,244 +636,5 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } } - - #region Elementary operations - /// - /// Adds another matrix to this matrix. The result will be written into this matrix. - /// - /// The matrix to add to this matrix. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public virtual void Add(Matrix other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) - { - throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); - } - - Parallel.For( - 0, - RowCount, - i => - { - for (int j = 0; j < ColumnCount; j++) - { - At(i, j, At(i, j) + other.At(i, j)); - } - }); - } - - /// - /// 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. - /// - /// The matrix to subtract. - /// If the other matrix is . - /// If the two matrices don't have the same dimensions. - public virtual void Subtract(Matrix other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (other.RowCount != RowCount || other.ColumnCount != ColumnCount) - { - throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); - } - - Parallel.For( - 0, - RowCount, - i => - { - for (int j = 0; j < ColumnCount; j++) - { - At(i, j, At(i, j) - other.At(i, j)); - } - }); - } - - /// - /// 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 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(j, i, 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/Numerics.csproj b/src/Numerics/Numerics.csproj index fa460739..69b2d078 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -116,6 +116,7 @@ +