Browse Source

matrix: finished added native multiplication and some other minor fixes

la-knuth
Marcus Cuda 17 years ago
parent
commit
691cd446b5
  1. 3
      build/build.proj
  2. 4
      src/NativeWrappers/ATLAS/ATLASWrapper.vcproj
  3. 8
      src/NativeWrappers/Common/blas.c
  4. 8
      src/NativeWrappers/MKL/MKLWrapper.vcproj
  5. 126
      src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs
  6. 126
      src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs
  7. 124
      src/Numerics/Algorithms/LinearAlgebra/NativeAlgebraProvider.include
  8. 68
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  9. 3
      src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs
  10. 75
      src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs
  11. 28
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
  12. 1
      src/UnitTests/UnitTests.csproj

3
build/build.proj

@ -50,11 +50,10 @@
</Target> </Target>
<Target Name="CSharpCompile"> <Target Name="CSharpCompile">
<MSBuild Projects="../src/Numerics/Numerics.csproj" Properties="Configuration=$(Config);Optimize=$(Optimize)" />
<MSBuild Projects="../src/UnitTests/UnitTests.csproj" Properties="Configuration=$(Config);Optimize=$(Optimize)" /> <MSBuild Projects="../src/UnitTests/UnitTests.csproj" Properties="Configuration=$(Config);Optimize=$(Optimize)" />
</Target> </Target>
<Target Name="CSharpTest" > <Target Name="CSharpTest" DependsOnTargets="CSharpCompile">
<Gallio.MSBuildTasks.Gallio ContinueOnError="False" IgnoreFailures="False" Files="../src/UnitTests/bin/Debug/MathNet.Numerics.UnitTests.dll"/> <Gallio.MSBuildTasks.Gallio ContinueOnError="False" IgnoreFailures="False" Files="../src/UnitTests/bin/Debug/MathNet.Numerics.UnitTests.dll"/>
</Target> </Target>

4
src/NativeWrappers/ATLAS/ATLASWrapper.vcproj

@ -115,7 +115,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="&quot;C:\source\mathnet-marcus\src\NativeWrappers\Common&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\ATLAS&quot;;C:\cygwin\tmp\ATLAS\include" AdditionalIncludeDirectories="&quot;C:\source\mathnet-marcus\src\NativeWrappers\Common&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\ATLAS&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\ATLAS\include&quot;"
PreprocessorDefinitions="_WINDOWS" PreprocessorDefinitions="_WINDOWS"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"
@ -136,7 +136,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="libcblas.a libatlas.a liblapack.a" AdditionalDependencies="libcblas.a libatlas.a liblapack.a"
OutputFile="$(OutDir)\MathNET.Numerics.ATLAS.dll" OutputFile="$(OutDir)\MathNET.Numerics.ATLAS.dll"
AdditionalLibraryDirectories="C:\cygwin\tmp\ATLAS\parallel\lib" AdditionalLibraryDirectories="&quot;C:\source\mathnet-marcus\src\NativeWrappers\ATLAS\lib&quot;"
GenerateDebugInformation="true" GenerateDebugInformation="true"
OptimizeReferences="2" OptimizeReferences="2"
EnableCOMDATFolding="2" EnableCOMDATFolding="2"

8
src/NativeWrappers/Common/blas.c

@ -53,28 +53,28 @@ DLLEXPORT Complex16 z_dot_product(const int n, const Complex16 x[], const Comple
return ret; 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 lda = transA == CblasNoTrans ? m : k;
int ldb = transB == CblasNoTrans ? k : n; int ldb = transB == CblasNoTrans ? k : n;
cblas_sgemm(CblasColMajor, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m); 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 lda = transA == CblasNoTrans ? m : k;
int ldb = transB == CblasNoTrans ? k : n; int ldb = transB == CblasNoTrans ? k : n;
cblas_dgemm(CblasColMajor, transA, transB, m, n, k, alpha, x, lda, y, ldb, beta, c, m); 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 lda = transA == CblasNoTrans ? m : k;
int ldb = transB == CblasNoTrans ? k : n; int ldb = transB == CblasNoTrans ? k : n;
cblas_cgemm(CblasColMajor, transA, transB, m, n, k, &alpha, x, lda, y, ldb, &beta, c, m); 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 lda = transA == CblasNoTrans ? m : k;
int ldb = transB == CblasNoTrans ? k : n; int ldb = transB == CblasNoTrans ? k : n;

8
src/NativeWrappers/MKL/MKLWrapper.vcproj

@ -194,7 +194,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="&quot;C:\source\mathnet-marcus\src\NativeWrappers\Common&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\MKL&quot;;&quot;C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\include&quot;" AdditionalIncludeDirectories="&quot;C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\include&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\Common&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\MKL&quot;"
PreprocessorDefinitions="_WINDOWS" PreprocessorDefinitions="_WINDOWS"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"
@ -215,7 +215,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="mkl_intel_c.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib" AdditionalDependencies="mkl_intel_c.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib"
OutputFile="$(OutDir)\MathNET.Numerics.MKL.dll" OutputFile="$(OutDir)\MathNET.Numerics.MKL.dll"
AdditionalLibraryDirectories="&quot;C:\Program Files (x86)\Intel\Compiler\11.1\046\lib\ia32&quot;;&quot;C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\ia32\lib&quot;" AdditionalLibraryDirectories="&quot;C:\Program Files (x86)\Intel\Compiler\11.1\060\lib\ia32&quot;;&quot;C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\ia32\lib&quot;"
GenerateDebugInformation="true" GenerateDebugInformation="true"
OptimizeReferences="2" OptimizeReferences="2"
EnableCOMDATFolding="2" EnableCOMDATFolding="2"
@ -272,7 +272,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="&quot;C:\source\mathnet-marcus\src\NativeWrappers\Common&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\MKL&quot;;&quot;C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\include&quot;" AdditionalIncludeDirectories="&quot;C:\source\mathnet-marcus\src\NativeWrappers\Common&quot;;&quot;C:\source\mathnet-marcus\src\NativeWrappers\MKL&quot;;&quot;C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\include&quot;"
PreprocessorDefinitions="_WINDOWS" PreprocessorDefinitions="_WINDOWS"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"
@ -293,7 +293,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="mkl_intel_lp64.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib" AdditionalDependencies="mkl_intel_lp64.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib"
OutputFile="$(OutDir)\MathNET.Numerics.MKL.dll" OutputFile="$(OutDir)\MathNET.Numerics.MKL.dll"
AdditionalLibraryDirectories="&quot;C:\Program Files (x86)\Intel\Compiler\11.1\046\lib\intel64&quot;;&quot;C:\Program Files (x86)\Intel\Compiler\11.1\046\mkl\em64t\lib&quot;" AdditionalLibraryDirectories="&quot;C:\Program Files (x86)\Intel\Compiler\11.1\060\lib\intel64&quot;;&quot;C:\Program Files (x86)\Intel\Compiler\11.1\060\mkl\em64t\lib&quot;"
GenerateDebugInformation="true" GenerateDebugInformation="true"
OptimizeReferences="2" OptimizeReferences="2"
EnableCOMDATFolding="2" EnableCOMDATFolding="2"

126
src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs

@ -24,7 +24,7 @@
/* This file is automatically generated - do not modify it. /* This file is automatically generated - do not modify it.
Change NativeLinearAlgebraProvider.include instead. 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 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, 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) 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);
} }
/// <summary> /// <summary>
@ -854,7 +883,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, 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) 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);
} }
/// <summary> /// <summary>
@ -1421,7 +1479,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, 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) 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);
} }
/// <summary> /// <summary>
@ -1988,7 +2075,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, 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) 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);
} }
/// <summary> /// <summary>

126
src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs

@ -24,7 +24,7 @@
/* This file is automatically generated - do not modify it. /* This file is automatically generated - do not modify it.
Change NativeLinearAlgebraProvider.include instead. 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 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, 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) 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);
} }
/// <summary> /// <summary>
@ -853,7 +882,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, 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) 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);
} }
/// <summary> /// <summary>
@ -1420,7 +1478,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, 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) 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);
} }
/// <summary> /// <summary>
@ -1987,7 +2074,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, 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) 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);
} }
/// <summary> /// <summary>

124
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, 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) 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);
} }
/// <summary> /// <summary>
@ -880,7 +909,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#>
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, 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) 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);
} }
/// <summary> /// <summary>
@ -1459,7 +1517,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#>
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, 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) 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);
} }
/// <summary> /// <summary>
@ -2038,7 +2125,36 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#>
public void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, 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) 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);
} }
/// <summary> /// <summary>

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

@ -78,7 +78,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
: base(rows, columns) : base(rows, columns)
{ {
Data = new double[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; Data[i] = value;
} }
@ -105,12 +105,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(double[,] array) public DenseMatrix(double[,] array)
: base(array.GetLength(0), array.GetLength(1)) : base(array.GetLength(0), array.GetLength(1))
{ {
Data = new double[array.GetLength(0) * array.GetLength(1)]; var rows = array.GetLength(0);
for (int i = 0; i < array.GetLength(0); i++) 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. /// Gets the matrix's data.
/// </summary> /// </summary>
/// <value>The matrix's data.</value> /// <value>The matrix's data.</value>
internal double[] Data internal double[] Data { get; private set; }
{
get;
private set;
}
/// <summary> /// <summary>
/// Creates a <strong>DenseMatrix</strong> for the given number of rows and columns. /// Creates a <c>DenseMatrix</c> for the given number of rows and columns.
/// </summary> /// </summary>
/// <param name="numberOfRows"> /// <param name="numberOfRows">
/// The number of rows. /// The number of rows.
@ -135,7 +133,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The number of columns. /// The number of columns.
/// </param> /// </param>
/// <returns> /// <returns>
/// A <strong>DenseMatrix</strong> with the given dimensions. /// A <c>DenseMatrix</c> with the given dimensions.
/// </returns> /// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns)
{ {
@ -197,6 +195,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
#region Elementary operations #region Elementary operations
/// <summary> /// <summary>
/// Adds another matrix to this matrix. The result will be written into this matrix. /// Adds another matrix to this matrix. The result will be written into this matrix.
/// </summary> /// </summary>
@ -205,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Add(Matrix other) public override void Add(Matrix other)
{ {
DenseMatrix m = other as DenseMatrix; var m = other as DenseMatrix;
if (m == null) if (m == null)
{ {
base.Add(other); base.Add(other);
@ -245,7 +244,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception> /// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override void Subtract(Matrix other) public override void Subtract(Matrix other)
{ {
DenseMatrix m = other as DenseMatrix; var m = other as DenseMatrix;
if (m == null) if (m == null)
{ {
base.Subtract(other); base.Subtract(other);
@ -273,7 +272,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{ {
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
} }
Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data); Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
} }
@ -295,7 +294,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception> /// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public void Multiply(DenseMatrix other, DenseMatrix result) public override void Multiply(Matrix other, Matrix result)
{ {
if (other == null) if (other == null)
{ {
@ -317,20 +316,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentMatrixDimensions); 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);
}
} }
/// <summary> /// <summary>
/// Multiplies this matrix with another matrix and returns the result. /// Multiplies this matrix with another matrix and returns the result.
/// </summary> /// </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> /// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns> /// <returns>The result of multiplication.</returns>
public Matrix Multiply(DenseMatrix other) public override Matrix Multiply(Matrix other)
{ {
if (other == null) if (other == null)
{ {
@ -342,8 +355,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentMatrixDimensions); throw new ArgumentException(Resources.ArgumentMatrixDimensions);
} }
DenseMatrix result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount); var m = other as DenseMatrix;
this.Multiply(other, result); if (m == null)
{
return base.Multiply(other);
}
var result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result; return result;
} }
@ -374,6 +393,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return (DenseMatrix)leftSide.Multiply(rightSide); return (DenseMatrix)leftSide.Multiply(rightSide);
} }
#endregion #endregion
} }
} }

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

@ -348,9 +348,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary> /// <summary>
/// Multiplies this matrix with another matrix and returns the result. /// Multiplies this matrix with another matrix and returns the result.
/// </summary> /// </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> /// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception> /// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception> /// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>

75
src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs

@ -6,7 +6,7 @@
using MbUnit.Framework; using MbUnit.Framework;
[TestFixture] [TestFixture]
public abstract class LinearAlgebraProviderTests public abstract class LinearAlgebraProviderTests : MatrixLoader
{ {
protected ILinearAlgebraProvider<double> Provider{ get; set;} protected ILinearAlgebraProvider<double> Provider{ get; set;}
@ -109,17 +109,60 @@
} }
[Test, Ignore] [Test, MultipleAsserts]
public void CanMatrixMultiply(double[] x, int xRows, int xColumns, double[] y, int yRows, int yColumns, double[] result) [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] [Test, MultipleAsserts]
public void CanMatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, [Row("Singular3x3", "Square3x3")]
int aRows, int aColumns, double[] b, int bRows, int bColumns, double beta, double[] c) [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] [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);
}
} }
} }

28
src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs

@ -7,34 +7,8 @@ using MbUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{ {
[TestFixture] [TestFixture]
public abstract partial class MatrixTests public abstract partial class MatrixTests : MatrixLoader
{ {
protected Dictionary<string, double[,]> testData2D;
protected Dictionary<string, Matrix> 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<string, double[,]>();
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<string, Matrix>();
foreach(var name in testData2D.Keys)
{
testMatrices.Add(name, CreateMatrix(testData2D[name]));
}
}
[Test] [Test]
[Row("Singular3x3")] [Row("Singular3x3")]
[Row("Square3x3")] [Row("Square3x3")]

1
src/UnitTests/UnitTests.csproj

@ -90,6 +90,7 @@
<Compile Include="InterpolationTests\InterpolationFunctionalContract.cs" /> <Compile Include="InterpolationTests\InterpolationFunctionalContract.cs" />
<Compile Include="InterpolationTests\InterpolationInfrastructureContract.cs" /> <Compile Include="InterpolationTests\InterpolationInfrastructureContract.cs" />
<Compile Include="InterpolationTests\InterpolationFunctionalTest.cs" /> <Compile Include="InterpolationTests\InterpolationFunctionalTest.cs" />
<Compile Include="LinearAlgebraTests\Double\MatrixLoader.cs" />
<Compile Include="LinearAlgebraTests\Double\MatrixTests.Arithmetic.cs" /> <Compile Include="LinearAlgebraTests\Double\MatrixTests.Arithmetic.cs" />
<Compile Include="LinearAlgebraTests\Double\LinearAlgebraProviderTests.cs" /> <Compile Include="LinearAlgebraTests\Double\LinearAlgebraProviderTests.cs" />
<Compile Include="LinearAlgebraTests\Double\ManagedLinearAlgebraProviderTests.cs" /> <Compile Include="LinearAlgebraTests\Double\ManagedLinearAlgebraProviderTests.cs" />

Loading…
Cancel
Save