diff --git a/build/build.proj b/build/build.proj index cb636df4..2460f208 100644 --- a/build/build.proj +++ b/build/build.proj @@ -50,11 +50,10 @@ - - + diff --git a/src/NativeWrappers/ATLAS/ATLASWrapper.vcproj b/src/NativeWrappers/ATLAS/ATLASWrapper.vcproj index f3ad54fa..d38c82fd 100644 --- a/src/NativeWrappers/ATLAS/ATLASWrapper.vcproj +++ b/src/NativeWrappers/ATLAS/ATLASWrapper.vcproj @@ -115,7 +115,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - AdditionalIncludeDirectories=""C:\source\mathnet-marcus\src\NativeWrappers\Common";"C:\source\mathnet-marcus\src\NativeWrappers\ATLAS";C:\cygwin\tmp\ATLAS\include" + AdditionalIncludeDirectories=""C:\source\mathnet-marcus\src\NativeWrappers\Common";"C:\source\mathnet-marcus\src\NativeWrappers\ATLAS";"C:\source\mathnet-marcus\src\NativeWrappers\ATLAS\include"" PreprocessorDefinitions="_WINDOWS" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -136,7 +136,7 @@ Name="VCLinkerTool" AdditionalDependencies="libcblas.a libatlas.a liblapack.a" OutputFile="$(OutDir)\MathNET.Numerics.ATLAS.dll" - AdditionalLibraryDirectories="C:\cygwin\tmp\ATLAS\parallel\lib" + AdditionalLibraryDirectories=""C:\source\mathnet-marcus\src\NativeWrappers\ATLAS\lib"" GenerateDebugInformation="true" OptimizeReferences="2" EnableCOMDATFolding="2" diff --git a/src/NativeWrappers/Common/blas.c b/src/NativeWrappers/Common/blas.c index 891ce5c7..02f726fa 100644 --- a/src/NativeWrappers/Common/blas.c +++ b/src/NativeWrappers/Common/blas.c @@ -53,28 +53,28 @@ DLLEXPORT Complex16 z_dot_product(const int n, const Complex16 x[], const Comple return ret; } -DLLEXPORT void s_matrix_multiply(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const float alpha, const float x[], const float y[], const float beta, float c[]){ +DLLEXPORT void s_matrix_multiply(const enum CBLAS_TRANSPOSE transA, const enum CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const float alpha, const float x[], const float y[], const float beta, float c[]){ int lda = transA == CblasNoTrans ? m : k; int ldb = transB == CblasNoTrans ? k : n; cblas_sgemm(CblasColMajor, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m); } -DLLEXPORT void d_matrix_multiply(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const double alpha, const double x[], const double y[], const double beta, double c[]){ +DLLEXPORT void d_matrix_multiply(const enum CBLAS_TRANSPOSE transA, const enum CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const double alpha, const double x[], const double y[], const double beta, double c[]){ int lda = transA == CblasNoTrans ? m : k; int ldb = transB == CblasNoTrans ? k : n; cblas_dgemm(CblasColMajor, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m); } -DLLEXPORT void c_matrix_multiply(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const Complex8 alpha, const Complex8 x[], const Complex8 y[], const Complex8 beta, Complex8 c[]){ +DLLEXPORT void c_matrix_multiply(const enum CBLAS_TRANSPOSE transA, const enum CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const Complex8 alpha, const Complex8 x[], const Complex8 y[], const Complex8 beta, Complex8 c[]){ int lda = transA == CblasNoTrans ? m : k; int ldb = transB == CblasNoTrans ? k : n; cblas_cgemm(CblasColMajor, transA, transB, m, n, k, &alpha, x, lda, y, ldb, &beta, c, m); } -DLLEXPORT void z_matrix_multiply(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const Complex16 alpha, const Complex16 x[], const Complex16 y[], const Complex16 beta, Complex16 c[]){ +DLLEXPORT void z_matrix_multiply(const enum CBLAS_TRANSPOSE transA, const enum CBLAS_TRANSPOSE transB, const int m, const int n, const int k, const Complex16 alpha, const Complex16 x[], const Complex16 y[], const Complex16 beta, Complex16 c[]){ int lda = transA == CblasNoTrans ? m : k; int ldb = transB == CblasNoTrans ? k : n; diff --git a/src/NativeWrappers/MKL/MKLWrapper.vcproj b/src/NativeWrappers/MKL/MKLWrapper.vcproj index 2c56974d..0ce61789 100644 --- a/src/NativeWrappers/MKL/MKLWrapper.vcproj +++ b/src/NativeWrappers/MKL/MKLWrapper.vcproj @@ -194,7 +194,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - AdditionalIncludeDirectories=""C:\source\mathnet-marcus\src\NativeWrappers\Common";"C:\source\mathnet-marcus\src\NativeWrappers\MKL";"C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\include"" + AdditionalIncludeDirectories=""C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\include";"C:\source\mathnet-marcus\src\NativeWrappers\Common";"C:\source\mathnet-marcus\src\NativeWrappers\MKL"" PreprocessorDefinitions="_WINDOWS" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -215,7 +215,7 @@ Name="VCLinkerTool" AdditionalDependencies="mkl_intel_c.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib" OutputFile="$(OutDir)\MathNET.Numerics.MKL.dll" - AdditionalLibraryDirectories=""C:\Program Files (x86)\Intel\Compiler\11.1\046\lib\ia32";"C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\ia32\lib"" + AdditionalLibraryDirectories=""C:\Program Files (x86)\Intel\Compiler\11.1\060\lib\ia32";"C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\ia32\lib"" GenerateDebugInformation="true" OptimizeReferences="2" EnableCOMDATFolding="2" @@ -272,7 +272,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - AdditionalIncludeDirectories=""C:\source\mathnet-marcus\src\NativeWrappers\Common";"C:\source\mathnet-marcus\src\NativeWrappers\MKL";"C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\include"" + AdditionalIncludeDirectories=""C:\source\mathnet-marcus\src\NativeWrappers\Common";"C:\source\mathnet-marcus\src\NativeWrappers\MKL";"C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\include"" PreprocessorDefinitions="_WINDOWS" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -293,7 +293,7 @@ Name="VCLinkerTool" AdditionalDependencies="mkl_intel_lp64.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib" OutputFile="$(OutDir)\MathNET.Numerics.MKL.dll" - AdditionalLibraryDirectories=""C:\Program Files (x86)\Intel\Compiler\11.1\046\lib\intel64";"C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\em64t\lib"" + AdditionalLibraryDirectories=""C:\Program Files (x86)\Intel\Compiler\11.1\060\lib\intel64";"C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\em64t\lib"" GenerateDebugInformation="true" OptimizeReferences="2" EnableCOMDATFolding="2" diff --git a/src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs b/src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs index 2a2a92a4..d8b46db5 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs @@ -24,7 +24,7 @@ /* This file is automatically generated - do not modify it. Change NativeLinearAlgebraProvider.include instead. - Last generated on: 2/19/2010 4:32:24 PM + Last generated on: 3/1/2010 11:25:28 AM */ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas { @@ -287,7 +287,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int aRows, int aColumns, double[] b, int bRows, int bColumns, double beta, double[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.d_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c); } /// @@ -854,7 +883,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, int aRows, int aColumns, float[] b, int bRows, int bColumns, float beta, float[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.s_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c); } /// @@ -1421,7 +1479,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, int aRows, int aColumns, Complex[] b, int bRows, int bColumns, Complex beta, Complex[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.z_matrix_multiply(transposeA, transposeB, m, n, k, ref alpha, a, b, ref beta, c); } /// @@ -1988,7 +2075,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, int aRows, int aColumns, Complex32[] b, int bRows, int bColumns, Complex32 beta, Complex32[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.c_matrix_multiply(transposeA, transposeB, m, n, k, ref alpha, a, b, ref beta, c); } /// diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs index 83a7d283..b978a484 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs @@ -24,7 +24,7 @@ /* This file is automatically generated - do not modify it. Change NativeLinearAlgebraProvider.include instead. - Last generated on: 2/19/2010 4:32:27 PM + Last generated on: 3/1/2010 11:24:47 AM */ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl { @@ -286,7 +286,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int aRows, int aColumns, double[] b, int bRows, int bColumns, double beta, double[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.d_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c); } /// @@ -853,7 +882,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, int aRows, int aColumns, float[] b, int bRows, int bColumns, float beta, float[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.s_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c); } /// @@ -1420,7 +1478,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, int aRows, int aColumns, Complex[] b, int bRows, int bColumns, Complex beta, Complex[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.z_matrix_multiply(transposeA, transposeB, m, n, k, ref alpha, a, b, ref beta, c); } /// @@ -1987,7 +2074,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, int aRows, int aColumns, Complex32[] b, int bRows, int bColumns, Complex32 beta, Complex32[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.c_matrix_multiply(transposeA, transposeB, m, n, k, ref alpha, a, b, ref beta, c); } /// diff --git a/src/Numerics/Algorithms/LinearAlgebra/NativeAlgebraProvider.include b/src/Numerics/Algorithms/LinearAlgebra/NativeAlgebraProvider.include index 61966dac..d770143d 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/NativeAlgebraProvider.include +++ b/src/Numerics/Algorithms/LinearAlgebra/NativeAlgebraProvider.include @@ -301,7 +301,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#> public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int aRows, int aColumns, double[] b, int bRows, int bColumns, double beta, double[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.d_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c); } /// @@ -880,7 +909,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#> public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, int aRows, int aColumns, float[] b, int bRows, int bColumns, float beta, float[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.s_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c); } /// @@ -1459,7 +1517,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#> public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, int aRows, int aColumns, Complex[] b, int bRows, int bColumns, Complex beta, Complex[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.z_matrix_multiply(transposeA, transposeB, m, n, k, ref alpha, a, b, ref beta, c); } /// @@ -2038,7 +2125,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#> public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, int aRows, int aColumns, Complex32[] b, int bRows, int bColumns, Complex32 beta, Complex32[] c) { - throw new NotImplementedException(); + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (c == null) + { + throw new ArgumentNullException("c"); + } + + var m = transposeA == Transpose.DontTranspose ? aRows : aColumns; + var n = transposeB == Transpose.DontTranspose ? bColumns : bRows; + var k = transposeA == Transpose.DontTranspose ? aColumns : aRows; + + if( c.Length != aRows * bColumns) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (aColumns != bRows) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.c_matrix_multiply(transposeA, transposeB, m, n, k, ref alpha, a, b, ref beta, c); } /// diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index ff584ad2..de0346c3 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -78,7 +78,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double : base(rows, columns) { Data = new double[rows * columns]; - for (int i = 0; i < Data.Length; i++) + for (var i = 0; i < Data.Length; i++) { Data[i] = value; } @@ -105,12 +105,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double public DenseMatrix(double[,] array) : base(array.GetLength(0), array.GetLength(1)) { - Data = new double[array.GetLength(0) * array.GetLength(1)]; - for (int i = 0; i < array.GetLength(0); i++) + var rows = array.GetLength(0); + var columns = array.GetLength(1); + Data = new double[rows * columns]; + for (var i = 0; i < rows; i++) { - for (int j = 0; j < array.GetLength(1); j++) + for (var j = 0; j < columns; j++) { - At(i, j, array[i, j]); + Data[(j * rows) + i] = array[i, j]; } } } @@ -119,14 +121,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Gets the matrix's data. /// /// The matrix's data. - internal double[] Data - { - get; - private set; - } + internal double[] Data { get; private set; } /// - /// Creates a DenseMatrix for the given number of rows and columns. + /// Creates a DenseMatrix for the given number of rows and columns. /// /// /// The number of rows. @@ -135,7 +133,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The number of columns. /// /// - /// A DenseMatrix with the given dimensions. + /// A DenseMatrix with the given dimensions. /// public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) { @@ -197,6 +195,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } #region Elementary operations + /// /// Adds another matrix to this matrix. The result will be written into this matrix. /// @@ -205,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// If the two matrices don't have the same dimensions. public override void Add(Matrix other) { - DenseMatrix m = other as DenseMatrix; + var m = other as DenseMatrix; if (m == null) { base.Add(other); @@ -245,7 +244,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// If the two matrices don't have the same dimensions. public override void Subtract(Matrix other) { - DenseMatrix m = other as DenseMatrix; + var m = other as DenseMatrix; if (m == null) { base.Subtract(other); @@ -273,7 +272,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); } - + Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data); } @@ -295,7 +294,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// 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) + public override void Multiply(Matrix other, Matrix result) { if (other == null) { @@ -317,20 +316,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException(Resources.ArgumentMatrixDimensions); } - Control.LinearAlgebraProvider.MatrixMultiply(this.Data, this.RowCount, this.ColumnCount, other.Data, other.RowCount, other.ColumnCount, result.Data); + var m = other as DenseMatrix; + var r = result as DenseMatrix; + + if (m == null || r == null) + { + base.Multiply(other, result); + } + else + { + Control.LinearAlgebraProvider.MatrixMultiply( + Data, + RowCount, + ColumnCount, + m.Data, + m.RowCount, + m.ColumnCount, + r.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 . /// The result of multiplication. - public Matrix Multiply(DenseMatrix other) + public override Matrix Multiply(Matrix other) { if (other == null) { @@ -342,8 +355,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException(Resources.ArgumentMatrixDimensions); } - DenseMatrix result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount); - this.Multiply(other, result); + var m = other as DenseMatrix; + if (m == null) + { + return base.Multiply(other); + } + + var result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount); + Multiply(other, result); return result; } @@ -374,6 +393,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double return (DenseMatrix)leftSide.Multiply(rightSide); } + #endregion } -} +} \ No newline at end of file diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs index db90d14f..e219cd22 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs @@ -348,9 +348,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// 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 . diff --git a/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs b/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs index b047f380..afcc5622 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs @@ -6,7 +6,7 @@ using MbUnit.Framework; [TestFixture] - public abstract class LinearAlgebraProviderTests + public abstract class LinearAlgebraProviderTests : MatrixLoader { protected ILinearAlgebraProvider Provider{ get; set;} @@ -109,17 +109,60 @@ } - [Test, Ignore] - public void CanMatrixMultiply(double[] x, int xRows, int xColumns, double[] y, int yRows, int yColumns, double[] result) + [Test, MultipleAsserts] + [Row("Singular3x3", "Square3x3")] + [Row("Singular4x4", "Square4x4")] + [Row("Wide2x3", "Square3x3")] + [Row("Wide2x3", "Tall3x2")] + [Row("Tall3x2", "Wide2x3")] + public void CanMatrixMultiply(string nameX, string nameY) { + var x = (DenseMatrix)testMatrices[nameX]; + var y = (DenseMatrix)testMatrices[nameY]; + var c = (DenseMatrix)CreateMatrix(x.RowCount, y.ColumnCount); + Provider.MatrixMultiply(x.Data, x.RowCount, x.ColumnCount, y.Data, y.RowCount, y.ColumnCount, c.Data); + + for (int i = 0; i < c.RowCount; i++) + { + for (int j = 0; j < c.ColumnCount; j++) + { + AssertHelpers.AlmostEqual(x.GetRow(i) * y.GetColumn(j), c[i, j], 15); + } + } } - [Test, Ignore] - public void CanMatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, - int aRows, int aColumns, double[] b, int bRows, int bColumns, double beta, double[] c) + [Test, MultipleAsserts] + [Row("Singular3x3", "Square3x3")] + [Row("Singular4x4", "Square4x4")] + [Row("Wide2x3", "Square3x3")] + [Row("Wide2x3", "Tall3x2")] + [Row("Tall3x2", "Wide2x3")] + public void CanMatrixMultiplyWithUpdate(string nameX, string nameY) { + var x = (DenseMatrix)testMatrices[nameX]; + var y = (DenseMatrix)testMatrices[nameY]; + var c = (DenseMatrix)CreateMatrix(x.RowCount, y.ColumnCount); + Provider.MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 2.0, x.Data, x.RowCount, x.ColumnCount, y.Data, y.RowCount, y.ColumnCount, 1.0, c.Data); + + for (int i = 0; i < c.RowCount; i++) + { + for (int j = 0; j < c.ColumnCount; j++) + { + AssertHelpers.AlmostEqual(2 * (x.GetRow(i) * y.GetColumn(j)), c[i, j], 15); + } + } + + Provider.MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 2.0, x.Data, x.RowCount, x.ColumnCount, y.Data, y.RowCount, y.ColumnCount, 1.0, c.Data); + + for (int i = 0; i < c.RowCount; i++) + { + for (int j = 0; j < c.ColumnCount; j++) + { + AssertHelpers.AlmostEqual(4 * (x.GetRow(i) * y.GetColumn(j)), c[i, j], 15); + } + } } [Test, Ignore] @@ -269,5 +312,25 @@ { } + + protected override Matrix CreateMatrix(int rows, int columns) + { + return new DenseMatrix(rows, columns); + } + + protected override Matrix CreateMatrix(double[,] data) + { + return new DenseMatrix(data); + } + + protected override Vector CreateVector(int size) + { + return new DenseVector(size); + } + + protected override Vector CreateVector(double[] data) + { + return new DenseVector(data); + } } } \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs index ba37da29..05d9a6a6 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs @@ -7,34 +7,8 @@ using MbUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { [TestFixture] - public abstract partial class MatrixTests + public abstract partial class MatrixTests : MatrixLoader { - protected Dictionary testData2D; - protected Dictionary testMatrices; - - protected abstract Matrix CreateMatrix(int rows, int columns); - protected abstract Matrix CreateMatrix(double[,] data); - protected abstract Vector CreateVector(int size); - protected abstract Vector CreateVector(double[] data); - - [SetUp] - public void SetupMatrices() - { - testData2D = new Dictionary(); - testData2D.Add("Singular3x3", new double[,] { { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 } }); - testData2D.Add("Square3x3", new double[,] { { -1.1, -2.2, -3.3 }, { 0, 1.1, 2.2 }, { -4.4, 5.5, 6.6 } }); - testData2D.Add("Square4x4", new double[,] { { -1.1, -2.2, -3.3, -4.4 }, { 0, 1.1, 2.2, 3.3 }, { 1.0, 2.1, 6.2, 4.3 }, { -4.4, 5.5, 6.6, -7.7 } }); - testData2D.Add("Singular4x4", new double[,] { { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 } }); - testData2D.Add("Tall3x2", new double[,] { { -1.1, -2.2 }, { 0, 1.1 }, { -4.4, 5.5 } }); - testData2D.Add("Wide2x3", new double[,] { { -1.1, -2.2, -3.3 }, { 0, 1.1, 2.2 } }); - - testMatrices = new Dictionary(); - foreach(var name in testData2D.Keys) - { - testMatrices.Add(name, CreateMatrix(testData2D[name])); - } - } - [Test] [Row("Singular3x3")] [Row("Square3x3")] diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index e78afe4c..303682a3 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -90,6 +90,7 @@ +