Browse Source

matrix: finished added native multiplication and some other minor fixes

pull/36/head
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 Name="CSharpCompile">
<MSBuild Projects="../src/Numerics/Numerics.csproj" Properties="Configuration=$(Config);Optimize=$(Optimize)" />
<MSBuild Projects="../src/UnitTests/UnitTests.csproj" Properties="Configuration=$(Config);Optimize=$(Optimize)" />
</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"/>
</Target>

4
src/NativeWrappers/ATLAS/ATLASWrapper.vcproj

@ -115,7 +115,7 @@
Name="VCCLCompilerTool"
Optimization="2"
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"
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="&quot;C:\source\mathnet-marcus\src\NativeWrappers\ATLAS\lib&quot;"
GenerateDebugInformation="true"
OptimizeReferences="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;
}
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;

8
src/NativeWrappers/MKL/MKLWrapper.vcproj

@ -194,7 +194,7 @@
Name="VCCLCompilerTool"
Optimization="2"
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"
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="&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"
OptimizeReferences="2"
EnableCOMDATFolding="2"
@ -272,7 +272,7 @@
Name="VCCLCompilerTool"
Optimization="2"
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"
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="&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"
OptimizeReferences="2"
EnableCOMDATFolding="2"

126
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);
}
/// <summary>
@ -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);
}
/// <summary>
@ -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);
}
/// <summary>
@ -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);
}
/// <summary>

126
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);
}
/// <summary>
@ -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);
}
/// <summary>
@ -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);
}
/// <summary>
@ -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);
}
/// <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,
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>
@ -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);
}
/// <summary>
@ -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);
}
/// <summary>
@ -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);
}
/// <summary>

68
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.
/// </summary>
/// <value>The matrix's data.</value>
internal double[] Data
{
get;
private set;
}
internal double[] Data { get; private set; }
/// <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>
/// <param name="numberOfRows">
/// The number of rows.
@ -135,7 +133,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The number of columns.
/// </param>
/// <returns>
/// A <strong>DenseMatrix</strong> with the given dimensions.
/// A <c>DenseMatrix</c> with the given dimensions.
/// </returns>
public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns)
{
@ -197,6 +195,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
#region Elementary operations
/// <summary>
/// Adds another matrix to this matrix. The result will be written into this matrix.
/// </summary>
@ -205,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
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
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
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
/// <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 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)
{
@ -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);
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </summary>
/// <remarks>This operator will allocate new memory for the result. It will
/// choose the representation of either <paramref name="leftSide"/> or <paramref name="rightSide"/> depending on which
/// is denser.</remarks>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
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
}
}
}

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

@ -348,9 +348,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </summary>
/// <remarks>This operator will allocate new memory for the result. It will
/// choose the representation of either <paramref name="leftSide"/> or <paramref name="rightSide"/> depending on which
/// is denser.</remarks>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</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;
[TestFixture]
public abstract class LinearAlgebraProviderTests
public abstract class LinearAlgebraProviderTests : MatrixLoader
{
protected ILinearAlgebraProvider<double> 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);
}
}
}

28
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<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]
[Row("Singular3x3")]
[Row("Square3x3")]

1
src/UnitTests/UnitTests.csproj

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

Loading…
Cancel
Save