Browse Source

Merge branch 'OpenBLAS'

Conflicts:
	src/Numerics/Control.cs
	src/Numerics/Properties/AssemblyInfo.cs
	src/UnitTests/UseLinearAlgebraProvider.cs
pull/312/head
Christoph Ruegg 11 years ago
parent
commit
fefa816717
  1. 109
      MathNet.Numerics.NativeProviders.sln
  2. 89
      src/NativeProviders/OpenBLAS/blas.c
  3. 77
      src/NativeProviders/OpenBLAS/capabilities.cpp
  4. 39
      src/NativeProviders/OpenBLAS/complex.h
  5. 712
      src/NativeProviders/OpenBLAS/lapack.cpp
  6. 220
      src/NativeProviders/Windows/OpenBLAS/OpenBLASWrapper.vcxproj
  7. 41
      src/NativeProviders/Windows/OpenBLAS/OpenBLASWrapper.vcxproj.filters
  8. 5
      src/Numerics/Control.cs
  9. 13
      src/Numerics/Numerics.csproj
  10. 1
      src/Numerics/Properties/AssemblyInfo.cs
  11. 367
      src/Numerics/Providers/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.cs
  12. 263
      src/Numerics/Providers/LinearAlgebra/GotoBlas/SafeNativeMethods.cs
  13. 436
      src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex.cs
  14. 437
      src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex32.cs
  15. 437
      src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Double.cs
  16. 437
      src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Single.cs
  17. 107
      src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs
  18. 303
      src/Numerics/Providers/LinearAlgebra/OpenBlas/SafeNativeMethods.cs
  19. 55
      src/Numerics/Providers/LinearAlgebra/ProviderCapabilities.cs
  20. 3
      src/UnitTests/UnitTests-MKL.csproj
  21. 351
      src/UnitTests/UnitTests-OpenBLAS.csproj
  22. 2
      src/UnitTests/UseLinearAlgebraProvider.cs

109
MathNet.Numerics.NativeProviders.sln

@ -22,6 +22,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CUDA", "src\NativeProviders
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-CUDA", "src\UnitTests\UnitTests-CUDA.csproj", "{E79C0395-01DC-4BC9-B86C-ED45790892C5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenBLAS", "src\NativeProviders\Windows\OpenBLAS\OpenBLASWrapper.vcxproj", "{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-OpenBLAS", "src\UnitTests\UnitTests-OpenBLAS.csproj", "{96B903EF-3EE1-4569-803C-0482D2F5ED37}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -40,6 +44,10 @@ Global
Release-MKL|Mixed Platforms = Release-MKL|Mixed Platforms
Release-MKL|Win32 = Release-MKL|Win32
Release-MKL|x64 = Release-MKL|x64
Release-OpenBLAS|Any CPU = Release-OpenBLAS|Any CPU
Release-OpenBLAS|Mixed Platforms = Release-OpenBLAS|Mixed Platforms
Release-OpenBLAS|Win32 = Release-OpenBLAS|Win32
Release-OpenBLAS|x64 = Release-OpenBLAS|x64
Release-Signed|Any CPU = Release-Signed|Any CPU
Release-Signed|Mixed Platforms = Release-Signed|Mixed Platforms
Release-Signed|Win32 = Release-Signed|Win32
@ -72,6 +80,11 @@ Global
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-MKL|Win32.Build.0 = Release|Win32
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-MKL|x64.ActiveCfg = Release|x64
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-MKL|x64.Build.0 = Release|x64
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Win32
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Win32
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-OpenBLAS|Mixed Platforms.Build.0 = Release|Win32
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-OpenBLAS|Win32.ActiveCfg = Release|Win32
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-OpenBLAS|x64.ActiveCfg = Release|x64
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Any CPU.ActiveCfg = Release|Win32
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Win32
{C0B0DBA9-7FB0-4C87-BDB1-3EED19DC2B8F}.Release-Signed|Mixed Platforms.Build.0 = Release|Win32
@ -95,6 +108,10 @@ Global
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-MKL|Mixed Platforms.ActiveCfg = Release|Win32
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-MKL|Win32.ActiveCfg = Release|Win32
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-MKL|x64.ActiveCfg = Release|x64
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Win32
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Win32
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-OpenBLAS|Win32.ActiveCfg = Release|Win32
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-OpenBLAS|x64.ActiveCfg = Release|x64
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Any CPU.ActiveCfg = Release|Win32
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Win32
{2362B8AC-C52B-45E4-A1BF-C682A4DB4220}.Release-Signed|Win32.ActiveCfg = Release|Win32
@ -133,6 +150,14 @@ Global
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-MKL|Win32.Build.0 = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-MKL|x64.ActiveCfg = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-MKL|x64.Build.0 = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|Any CPU.Build.0 = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|Mixed Platforms.Build.0 = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|Win32.ActiveCfg = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|Win32.Build.0 = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|x64.ActiveCfg = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-OpenBLAS|x64.Build.0 = Release|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.ActiveCfg = Release-Signed|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Any CPU.Build.0 = Release-Signed|Any CPU
{B7CAE5F4-A23F-4438-B5BE-41226618B695}.Release-Signed|Mixed Platforms.ActiveCfg = Release-Signed|Any CPU
@ -165,6 +190,12 @@ Global
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-MKL|Win32.Build.0 = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-MKL|x64.ActiveCfg = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-MKL|x64.Build.0 = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|Any CPU.Build.0 = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|Mixed Platforms.Build.0 = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|Win32.ActiveCfg = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-OpenBLAS|x64.ActiveCfg = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Any CPU.Build.0 = Release|Any CPU
{3515A344-AB5F-41C7-A14C-04A79B3FFAB1}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
@ -197,6 +228,11 @@ Global
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-MKL|Mixed Platforms.Build.0 = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-MKL|Win32.ActiveCfg = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-MKL|x64.ActiveCfg = Release|x64
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-OpenBLAS|Mixed Platforms.Build.0 = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-OpenBLAS|Win32.ActiveCfg = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-OpenBLAS|x64.ActiveCfg = Release|x64
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-Signed|Any CPU.ActiveCfg = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Win32
{5A52B796-7F41-4C90-8DE2-F3F391C4482C}.Release-Signed|Mixed Platforms.Build.0 = Release|Win32
@ -229,12 +265,85 @@ Global
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-MKL|Mixed Platforms.Build.0 = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-MKL|Win32.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-MKL|x64.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|Any CPU.Build.0 = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|Mixed Platforms.Build.0 = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|Win32.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-OpenBLAS|x64.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Any CPU.Build.0 = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Mixed Platforms.Build.0 = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|Win32.ActiveCfg = Release|Any CPU
{E79C0395-01DC-4BC9-B86C-ED45790892C5}.Release-Signed|x64.ActiveCfg = Release|Any CPU
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Debug|Win32.ActiveCfg = Debug|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Debug|Win32.Build.0 = Debug|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Debug|x64.ActiveCfg = Debug|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Debug|x64.Build.0 = Debug|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release|Any CPU.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release|Mixed Platforms.Build.0 = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release|Win32.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release|Win32.Build.0 = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release|x64.ActiveCfg = Release|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release|x64.Build.0 = Release|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-CUDA|Any CPU.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-CUDA|Mixed Platforms.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-CUDA|Win32.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-CUDA|x64.ActiveCfg = Release|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-MKL|Any CPU.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-MKL|Mixed Platforms.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-MKL|Win32.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-MKL|x64.ActiveCfg = Release|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-OpenBLAS|Win32.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-OpenBLAS|Win32.Build.0 = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-OpenBLAS|x64.ActiveCfg = Release|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-OpenBLAS|x64.Build.0 = Release|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-Signed|Any CPU.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-Signed|Mixed Platforms.Build.0 = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-Signed|Win32.ActiveCfg = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-Signed|Win32.Build.0 = Release|Win32
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-Signed|x64.ActiveCfg = Release|x64
{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}.Release-Signed|x64.Build.0 = Release|x64
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Debug|Win32.ActiveCfg = Debug|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Debug|x64.ActiveCfg = Debug|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release|Any CPU.Build.0 = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release|Win32.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release|x64.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-CUDA|Any CPU.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-CUDA|Mixed Platforms.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-CUDA|Win32.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-CUDA|x64.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-MKL|Any CPU.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-MKL|Mixed Platforms.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-MKL|Win32.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-MKL|x64.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-OpenBLAS|Any CPU.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-OpenBLAS|Mixed Platforms.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-OpenBLAS|Win32.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-OpenBLAS|Win32.Build.0 = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-OpenBLAS|x64.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-OpenBLAS|x64.Build.0 = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|Any CPU.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|Any CPU.Build.0 = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|Mixed Platforms.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|Mixed Platforms.Build.0 = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|Win32.ActiveCfg = Release|Any CPU
{96B903EF-3EE1-4569-803C-0482D2F5ED37}.Release-Signed|x64.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

89
src/NativeProviders/OpenBLAS/blas.c

@ -0,0 +1,89 @@
#include "cblas.h"
#include "wrapper_common.h"
#if GCC
extern "C" {
#endif
DLLEXPORT void s_axpy(const blasint n, const float alpha, const float x[], float y[]){
cblas_saxpy(n, alpha, x, 1, y, 1);
}
DLLEXPORT void d_axpy(const blasint n, const double alpha, const double x[], double y[]){
cblas_daxpy(n, alpha, x, 1, y, 1);
}
DLLEXPORT void c_axpy(const blasint n, const openblas_complex_float alpha, const openblas_complex_float x[], openblas_complex_float y[]){
cblas_caxpy(n, (float*)&alpha, (float*)x, 1, (float*)y, 1);
}
DLLEXPORT void z_axpy(const blasint n, const openblas_complex_double alpha, const openblas_complex_double x[], openblas_complex_double y[]){
cblas_zaxpy(n, (double*)&alpha, (double*)x, 1, (double*)y, 1);
}
DLLEXPORT void s_scale(const blasint n, const float alpha, float x[]){
cblas_sscal(n, alpha, x, 1);
}
DLLEXPORT void d_scale(const blasint n, const double alpha, double x[]){
cblas_dscal(n, alpha, x, 1);
}
DLLEXPORT void c_scale(const blasint n, const openblas_complex_float alpha, openblas_complex_float x[]){
cblas_cscal(n, (float*)&alpha, (float*)x, 1);
}
DLLEXPORT void z_scale(const blasint n, const openblas_complex_double alpha, openblas_complex_double x[]){
cblas_zscal(n, (double*)&alpha, (double*)x, 1);
}
DLLEXPORT float s_dot_product(const blasint n, const float x[], const float y[]){
return cblas_sdot(n, x, 1, y, 1);
}
DLLEXPORT double d_dot_product(const blasint n, const double x[], const double y[]){
return cblas_ddot(n, x, 1, y, 1);
}
DLLEXPORT openblas_complex_float c_dot_product(const blasint n, const openblas_complex_float x[], const openblas_complex_float y[]){
openblas_complex_float ret;
cblas_cdotu_sub(n, (float*)x, 1, (float*)y, 1, &ret);
return ret;
}
DLLEXPORT openblas_complex_double z_dot_product(const blasint n, const openblas_complex_double x[], const openblas_complex_double y[]){
openblas_complex_double ret;
cblas_zdotu_sub(n, (double*)x, 1, (double*)y, 1, &ret);
return ret;
}
DLLEXPORT void s_matrix_multiply(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, const blasint m, const blasint n, const blasint k, const float alpha, const float x[], const float y[], const float beta, float c[]){
blasint lda = transA == CblasNoTrans ? m : k;
blasint 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 blasint m, const blasint n, const blasint k, const double alpha, const double x[], const double y[], const double beta, double c[]){
blasint lda = transA == CblasNoTrans ? m : k;
blasint 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 blasint m, const blasint n, const blasint k, const openblas_complex_float alpha, const openblas_complex_float x[], const openblas_complex_float y[], const openblas_complex_float beta, openblas_complex_float c[]){
blasint lda = transA == CblasNoTrans ? m : k;
blasint ldb = transB == CblasNoTrans ? k : n;
cblas_cgemm(CblasColMajor, transA, transB, m, n, k, (float*)&alpha, (float*)x, lda, (float*)y, ldb, (float*)&beta, (float*)c, m);
}
DLLEXPORT void z_matrix_multiply(CBLAS_TRANSPOSE transA, CBLAS_TRANSPOSE transB, const blasint m, const blasint n, const blasint k, const openblas_complex_double alpha, const openblas_complex_double x[], const openblas_complex_double y[], const openblas_complex_double beta, openblas_complex_double c[]){
blasint lda = transA == CblasNoTrans ? m : k;
blasint ldb = transB == CblasNoTrans ? k : n;
cblas_zgemm(CblasColMajor, transA, transB, m, n, k, (double*)&alpha, (double*)x, lda, (double*)y, ldb, (double*)&beta, (double*)c, m);
}
#if GCC
}
#endif

77
src/NativeProviders/OpenBLAS/capabilities.cpp

@ -0,0 +1,77 @@
#include "wrapper_common.h"
#include "cblas.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
Capability is supported if >0
Actual number can be increased over time to indicate
extensions/revisions (that do not break compatibility)
*/
DLLEXPORT int query_capability(const int capability)
{
switch (capability)
{
// SANITY CHECKS
case 0: return 0;
case 1: return -1;
// PLATFORM
case 8:
#ifdef _M_IX86
return 1;
#else
return 0;
#endif
case 9:
#ifdef _M_X64
return 1;
#else
return 0;
#endif
case 10:
#ifdef _M_IA64
return 1;
#else
return 0;
#endif
// COMMON/SHARED
case 64: return 7; // revision
case 66: return 1; // threading control
// LINEAR ALGEBRA
case 128: return 1; // basic dense linear algebra
default: return 0; // unknown or not supported
}
}
DLLEXPORT void set_max_threads(const blasint num_threads)
{
openblas_set_num_threads(num_threads);
}
DLLEXPORT char* get_build_config()
{
return openblas_get_config();
}
DLLEXPORT char* get_cpu_core()
{
return openblas_get_corename();
}
DLLEXPORT int get_parallel_type()
{
return openblas_get_parallel();
}
#ifdef __cplusplus
}
#endif /* __cplusplus */

39
src/NativeProviders/OpenBLAS/complex.h

@ -0,0 +1,39 @@
template <typename _T>
struct complex
{
_T real, imag;
complex(_T _real = 0, _T _imag = 0)
{
real = _real;
imag = _imag;
}
complex(const complex<_T>& right)
{
real = right.real;
imag = right.imag;
}
complex& operator=(const complex& right)
{
real = right.real;
imag = right.imag;
return *this;
}
complex& operator=(const _T& right)
{
real = right;
imag = 0;
return *this;
}
template<typename _Other> inline
complex& operator=(const complex<_Other>& right)
{
real = (_T)right.real;
imag = (_T)right.imag;
return *this;
}
};

712
src/NativeProviders/OpenBLAS/lapack.cpp

@ -0,0 +1,712 @@
#include "cblas.h"
#include "complex.h"
#define LAPACK_COMPLEX_CUSTOM
#define lapack_complex_float complex<float>
#define lapack_complex_double complex<double>
#include "lapacke.h"
#include "lapack_common.h"
#include "wrapper_common.h"
#include <algorithm>
template<typename T, typename GETRF>
inline lapack_int lu_factor(lapack_int m, T a[], lapack_int ipiv[], GETRF getrf)
{
lapack_int info = 0;
getrf(&m, &m, a, &m, ipiv, &info);
shift_ipiv_down(m, ipiv);
return info;
};
template<typename T, typename GETRF, typename GETRI>
inline lapack_int lu_inverse(lapack_int n, T a[], T work[], lapack_int lwork, GETRF getrf, GETRI getri)
{
lapack_int* ipiv = new lapack_int[n];
lapack_int info = 0;
getrf(&n, &n, a, &n, ipiv, &info);
if (info != 0)
{
delete[] ipiv;
return info;
}
getri(&n, a, &n, ipiv, work, &lwork, &info);
delete[] ipiv;
return info;
};
template<typename T, typename GETRI>
inline lapack_int lu_inverse_factored(lapack_int n, T a[], lapack_int ipiv[], T work[], lapack_int lwork, GETRI getri)
{
shift_ipiv_up(n, ipiv);
lapack_int info = 0;
getri(&n, a, &n, ipiv, work, &lwork, &info);
shift_ipiv_down(n, ipiv);
return info;
}
template<typename T, typename GETRS>
inline lapack_int lu_solve_factored(lapack_int n, lapack_int nrhs, T a[], lapack_int ipiv[], T b[], GETRS getrs)
{
shift_ipiv_up(n, ipiv);
lapack_int info = 0;
char trans ='N';
getrs(&trans, &n, &nrhs, a, &n, ipiv, b, &n, &info);
shift_ipiv_down(n, ipiv);
return info;
}
template<typename T, typename GETRF, typename GETRS>
inline lapack_int lu_solve(lapack_int n, lapack_int nrhs, T a[], T b[], GETRF getrf, GETRS getrs)
{
T* clone = Clone(n, n, a);
lapack_int* ipiv = new lapack_int[n];
lapack_int info = 0;
getrf(&n, &n, clone, &n, ipiv, &info);
if (info != 0)
{
delete[] ipiv;
delete[] clone;
return info;
}
char trans ='N';
getrs(&trans, &n, &nrhs, clone, &n, ipiv, b, &n, &info);
delete[] ipiv;
delete[] clone;
return info;
}
template<typename T, typename POTRF>
inline lapack_int cholesky_factor(lapack_int n, T* a, POTRF potrf)
{
char uplo = 'L';
lapack_int info = 0;
potrf(&uplo, &n, a, &n, &info);
T zero = T();
for (lapack_int i = 0; i < n; ++i)
{
lapack_int index = i * n;
for (lapack_int j = 0; j < n && i > j; ++j)
{
a[index + j] = zero;
}
}
return info;
}
template<typename T, typename POTRF, typename POTRS>
inline lapack_int cholesky_solve(lapack_int n, lapack_int nrhs, T a[], T b[], POTRF potrf, POTRS potrs)
{
T* clone = Clone(n, n, a);
char uplo = 'L';
lapack_int info = 0;
potrf(&uplo, &n, clone, &n, &info);
if (info != 0)
{
delete[] clone;
return info;
}
potrs(&uplo, &n, &nrhs, clone, &n, b, &n, &info);
delete[] clone;
return info;
}
template<typename T, typename POTRS>
inline lapack_int cholesky_solve_factored(lapack_int n, lapack_int nrhs, T a[], T b[], POTRS potrs)
{
char uplo = 'L';
lapack_int info = 0;
potrs(&uplo, &n, &nrhs, a, &n, b, &n, &info);
return info;
}
template<typename T, typename GEQRF, typename ORGQR>
inline lapack_int qr_factor(lapack_int m, lapack_int n, T r[], T tau[], T q[], T work[], lapack_int len, GEQRF geqrf, ORGQR orgqr)
{
lapack_int info = 0;
geqrf(&m, &n, r, &m, tau, work, &len, &info);
for (lapack_int i = 0; i < m; ++i)
{
for (lapack_int j = 0; j < m && j < n; ++j)
{
if (i > j)
{
q[j * m + i] = r[j * m + i];
}
}
}
//compute the q elements explicitly
if (m <= n)
{
orgqr(&m, &m, &m, q, &m, tau, work, &len, &info);
}
else
{
orgqr(&m, &m, &n, q, &m, tau, work, &len, &info);
}
return info;
}
template<typename T, typename GEQRF, typename ORGQR>
inline lapack_int qr_thin_factor(lapack_int m, lapack_int n, T q[], T tau[], T r[], T work[], lapack_int len, GEQRF geqrf, ORGQR orgqr)
{
lapack_int info = 0;
geqrf(&m, &n, q, &m, tau, work, &len, &info);
for (lapack_int i = 0; i < n; ++i)
{
for (lapack_int j = 0; j < n; ++j)
{
if (i <= j)
{
r[j * n + i] = q[j * m + i];
}
}
}
orgqr(&m, &n, &n, q, &m, tau, work, &len, &info);
return info;
}
template<typename T, typename GELS>
inline lapack_int qr_solve(lapack_int m, lapack_int n, lapack_int bn, T a[], T b[], T x[], T work[], lapack_int len, GELS gels)
{
T* clone_a = Clone(m, n, a);
T* clone_b = Clone(m, bn, b);
char N = 'N';
lapack_int info = 0;
gels(&N, &m, &n, &bn, clone_a, &m, clone_b, &m, work, &len, &info);
copyBtoX(m, n, bn, clone_b, x);
delete[] clone_a;
delete[] clone_b;
return info;
}
template<typename T, typename ORMQR, typename TRSM>
inline lapack_int qr_solve_factored(lapack_int m, lapack_int n, lapack_int bn, T r[], T b[], T tau[], T x[], T work[], lapack_int len, ORMQR ormqr, TRSM trsm)
{
T* clone_b = Clone(m, bn, b);
char side ='L';
char tran = 'T';
lapack_int info = 0;
ormqr(&side, &tran, &m, &bn, &n, r, &m, tau, clone_b, &m, work, &len, &info);
trsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, n, bn, 1.0, r, m, clone_b, m);
copyBtoX(m, n, bn, clone_b, x);
delete[] clone_b;
return info;
}
template<typename T, typename R, typename UNMQR, typename TRSM>
inline lapack_int complex_qr_solve_factored(lapack_int m, lapack_int n, lapack_int bn, T r[], T b[], T tau[], T x[], T work[], lapack_int len, UNMQR unmqr, TRSM trsm)
{
T* clone_b = Clone(m, bn, b);
char side ='L';
char tran = 'C';
lapack_int info = 0;
unmqr(&side, &tran, &m, &bn, &n, r, &m, tau, clone_b, &m, work, &len, &info);
T one = { 1.0f, 0.0f };
trsm(CblasColMajor, CblasLeft, CblasUpper, CblasNoTrans, CblasNonUnit, n, bn, reinterpret_cast<R*>(&one), reinterpret_cast<R*>(r), m, reinterpret_cast<R*>(clone_b), m);
copyBtoX(m, n, bn, clone_b, x);
delete[] clone_b;
return info;
}
template<typename T, typename GESVD>
inline lapack_int svd_factor(bool compute_vectors, lapack_int m, lapack_int n, T a[], T s[], T u[], T v[], T work[], lapack_int len, GESVD gesvd)
{
lapack_int info = 0;
char job = compute_vectors ? 'A' : 'N';
gesvd(&job, &job, &m, &n, a, &m, s, u, &m, v, &n, work, &len, &info);
return info;
}
template<typename T, typename R, typename GESVD>
inline lapack_int complex_svd_factor(bool compute_vectors, lapack_int m, lapack_int n, T a[], T s[], T u[], T v[], T work[], lapack_int len, GESVD gesvd)
{
lapack_int info = 0;
lapack_int dim_s = std::min(m,n);
R* rwork = new R[5 * dim_s];
R* s_local = new R[dim_s];
char job = compute_vectors ? 'A' : 'N';
gesvd(&job, &job, &m, &n, a, &m, s_local, u, &m, v, &n, work, &len, rwork, &info);
for (lapack_int index = 0; index < dim_s; ++index)
{
s[index] = s_local[index];
}
delete[] rwork;
delete[] s_local;
return info;
}
template<typename T, typename R, typename GEES, typename TREVC>
inline lapack_int eigen_factor(lapack_int n, T a[], T vectors[], R values[], T d[], GEES gees, TREVC trevc)
{
T* clone_a = Clone(n, n, a);
T* wr = new T[n];
T* wi = new T[n];
lapack_int sdim;
lapack_int info = gees(LAPACK_COL_MAJOR, 'V', 'N', nullptr, n, clone_a, n, &sdim, wr, wi, vectors, n);
if (info != 0)
{
delete[] clone_a;
delete[] wr;
delete[] wi;
return info;
}
lapack_int m;
info = trevc(LAPACK_COL_MAJOR, 'R', 'B', nullptr, n, clone_a, n, nullptr, n, vectors, n, n, &m);
if (info != 0)
{
delete[] clone_a;
delete[] wr;
delete[] wi;
return info;
}
for (lapack_int index = 0; index < n; ++index)
{
values[index] = R(wr[index], wi[index]);
}
for (lapack_int i = 0; i < n; ++i)
{
lapack_int in = i * n;
d[in + i] = wr[i];
if (wi[i] > 0)
{
d[in + n + i] = wi[i];
}
else if (wi[i] < 0)
{
d[in - n + i] = wi[i];
}
}
delete[] clone_a;
delete[] wr;
delete[] wi;
return info;
}
template<typename T, typename GEES, typename TREVC>
inline lapack_int eigen_complex_factor(lapack_int n, T a[], T vectors[], lapack_complex_double values[], T d[], GEES gees, TREVC trevc)
{
T* clone_a = Clone(n, n, a);
T* w = new T[n];
lapack_int sdim;
lapack_int info = gees(LAPACK_COL_MAJOR, 'V', 'N', nullptr, n, clone_a, n, &sdim, w, vectors, n);
if (info != 0)
{
delete[] clone_a;
delete[] w;
return info;
}
lapack_int m;
info = trevc(LAPACK_COL_MAJOR, 'R', 'B', nullptr, n, clone_a, n, nullptr, n, vectors, n, n, &m);
if (info != 0)
{
delete[] clone_a;
delete[] w;
return info;
}
for (lapack_int i = 0; i < n; ++i)
{
values[i] = w[i];
d[i * n + i] = w[i];
}
delete[] clone_a;
delete[] w;
return info;
}
template<typename R, typename T, typename SYEV>
inline lapack_int sym_eigen_factor(lapack_int n, T a[], T vectors[], lapack_complex_double values[], T d[], SYEV syev)
{
T* clone_a = Clone(n, n, a);
R* w = new R[n];
lapack_int info = syev(LAPACK_COL_MAJOR, 'V', 'U', n, clone_a, n, w);
if (info != 0)
{
delete[] clone_a;
delete[] w;
return info;
}
memcpy(vectors, clone_a, n*n*sizeof(T));
for (lapack_int index = 0; index < n; ++index)
{
values[index] = lapack_complex_double(w[index]);
}
for (lapack_int j = 0; j < n; ++j)
{
lapack_int jn = j*n;
for (lapack_int i = 0; i < n; ++i)
{
if (i == j)
{
d[jn + i] = w[i];
}
}
}
delete[] clone_a;
delete[] w;
return info;
}
extern "C" {
DLLEXPORT float s_matrix_norm(char norm, lapack_int m, lapack_int n, float a[], float work[])
{
return LAPACKE_slange_work(CblasColMajor, norm, m, n, a, m, work);
}
DLLEXPORT double d_matrix_norm(char norm, lapack_int m, lapack_int n, double a[], double work[])
{
return LAPACKE_dlange_work(CblasColMajor, norm, m, n, a, m, work);
}
DLLEXPORT float c_matrix_norm(char norm, lapack_int m, lapack_int n, lapack_complex_float a[], float work[])
{
return LAPACKE_clange_work(CblasColMajor, norm, m, n, a, m, work);
}
DLLEXPORT double z_matrix_norm(char norm, lapack_int m, lapack_int n, lapack_complex_double a[], double work[])
{
return LAPACKE_zlange_work(CblasColMajor, norm, m, n, a, m, work);
}
DLLEXPORT lapack_int s_lu_factor(lapack_int m, float a[], lapack_int ipiv[])
{
return lu_factor(m, a, ipiv, LAPACK_sgetrf);
}
DLLEXPORT lapack_int d_lu_factor(lapack_int m, double a[], lapack_int ipiv[])
{
return lu_factor(m, a, ipiv, LAPACK_dgetrf);
}
DLLEXPORT lapack_int c_lu_factor(lapack_int m, lapack_complex_float a[], lapack_int ipiv[])
{
return lu_factor(m, a, ipiv, LAPACK_cgetrf);
}
DLLEXPORT lapack_int z_lu_factor(lapack_int m, lapack_complex_double a[], lapack_int ipiv[])
{
return lu_factor(m, a, ipiv, LAPACK_zgetrf);
}
DLLEXPORT lapack_int s_lu_inverse(lapack_int n, float a[], float work[], lapack_int lwork)
{
return lu_inverse(n, a, work, lwork, LAPACK_sgetrf, LAPACK_sgetri);
}
DLLEXPORT lapack_int d_lu_inverse(lapack_int n, double a[], double work[], lapack_int lwork)
{
return lu_inverse(n, a, work, lwork, LAPACK_dgetrf, LAPACK_dgetri);
}
DLLEXPORT lapack_int c_lu_inverse(lapack_int n, lapack_complex_float a[], lapack_complex_float work[], lapack_int lwork)
{
return lu_inverse(n, a, work, lwork, LAPACK_cgetrf, LAPACK_cgetri);
}
DLLEXPORT lapack_int z_lu_inverse(lapack_int n, lapack_complex_double a[], lapack_complex_double work[], lapack_int lwork)
{
return lu_inverse(n, a, work, lwork, LAPACK_zgetrf, LAPACK_zgetri);
}
DLLEXPORT lapack_int s_lu_inverse_factored(lapack_int n, float a[], lapack_int ipiv[], float work[], lapack_int lwork)
{
return lu_inverse_factored(n, a, ipiv, work, lwork, LAPACK_sgetri);
}
DLLEXPORT lapack_int d_lu_inverse_factored(lapack_int n, double a[], lapack_int ipiv[], double work[], lapack_int lwork)
{
return lu_inverse_factored(n, a, ipiv, work, lwork, LAPACK_dgetri);
}
DLLEXPORT lapack_int c_lu_inverse_factored(lapack_int n, lapack_complex_float a[], lapack_int ipiv[], lapack_complex_float work[], lapack_int lwork)
{
return lu_inverse_factored(n, a, ipiv, work, lwork, LAPACK_cgetri);
}
DLLEXPORT lapack_int z_lu_inverse_factored(lapack_int n, lapack_complex_double a[], lapack_int ipiv[], lapack_complex_double work[], lapack_int lwork)
{
return lu_inverse_factored(n, a, ipiv, work, lwork, LAPACK_zgetri);
}
DLLEXPORT lapack_int s_lu_solve_factored(lapack_int n, lapack_int nrhs, float a[], lapack_int ipiv[], float b[])
{
return lu_solve_factored(n, nrhs, a, ipiv, b, LAPACK_sgetrs);
}
DLLEXPORT lapack_int d_lu_solve_factored(lapack_int n, lapack_int nrhs, double a[], lapack_int ipiv[], double b[])
{
return lu_solve_factored(n, nrhs, a, ipiv, b, LAPACK_dgetrs);
}
DLLEXPORT lapack_int c_lu_solve_factored(lapack_int n, lapack_int nrhs, lapack_complex_float a[], lapack_int ipiv[], lapack_complex_float b[])
{
return lu_solve_factored(n, nrhs, a, ipiv, b, LAPACK_cgetrs);
}
DLLEXPORT lapack_int z_lu_solve_factored(lapack_int n, lapack_int nrhs, lapack_complex_double a[], lapack_int ipiv[], lapack_complex_double b[])
{
return lu_solve_factored(n, nrhs, a, ipiv, b, LAPACK_zgetrs);
}
DLLEXPORT lapack_int s_lu_solve(lapack_int n, lapack_int nrhs, float a[], float b[])
{
return lu_solve(n, nrhs, a, b, LAPACK_sgetrf, LAPACK_sgetrs);
}
DLLEXPORT lapack_int d_lu_solve(lapack_int n, lapack_int nrhs, double a[], double b[])
{
return lu_solve(n, nrhs, a, b, LAPACK_dgetrf, LAPACK_dgetrs);
}
DLLEXPORT lapack_int c_lu_solve(lapack_int n, lapack_int nrhs, lapack_complex_float a[], lapack_complex_float b[])
{
return lu_solve(n, nrhs, a, b, LAPACK_cgetrf, LAPACK_cgetrs);
}
DLLEXPORT lapack_int z_lu_solve(lapack_int n, lapack_int nrhs, lapack_complex_double a[], lapack_complex_double b[])
{
return lu_solve(n, nrhs, a, b, LAPACK_zgetrf, LAPACK_zgetrs);
}
DLLEXPORT lapack_int s_cholesky_factor(lapack_int n, float a[])
{
return cholesky_factor(n, a, LAPACK_spotrf);
}
DLLEXPORT lapack_int d_cholesky_factor(lapack_int n, double* a)
{
return cholesky_factor(n, a, LAPACK_dpotrf);
}
DLLEXPORT lapack_int c_cholesky_factor(lapack_int n, lapack_complex_float a[])
{
return cholesky_factor(n, a, LAPACK_cpotrf);
}
DLLEXPORT lapack_int z_cholesky_factor(lapack_int n, lapack_complex_double a[])
{
return cholesky_factor(n, a, LAPACK_zpotrf);
}
DLLEXPORT lapack_int s_cholesky_solve(lapack_int n, lapack_int nrhs, float a[], float b[])
{
return cholesky_solve(n, nrhs, a, b, LAPACK_spotrf, LAPACK_spotrs);
}
DLLEXPORT lapack_int d_cholesky_solve(lapack_int n, lapack_int nrhs, double a[], double b[])
{
return cholesky_solve(n, nrhs, a, b, LAPACK_dpotrf, LAPACK_dpotrs);
}
DLLEXPORT lapack_int c_cholesky_solve(lapack_int n, lapack_int nrhs, lapack_complex_float a[], lapack_complex_float b[])
{
return cholesky_solve(n, nrhs, a, b, LAPACK_cpotrf, LAPACK_cpotrs);
}
DLLEXPORT lapack_int z_cholesky_solve(lapack_int n, lapack_int nrhs, lapack_complex_double a[], lapack_complex_double b[])
{
return cholesky_solve(n, nrhs, a, b, LAPACK_zpotrf, LAPACK_zpotrs);
}
DLLEXPORT lapack_int s_cholesky_solve_factored(lapack_int n, lapack_int nrhs, float a[], float b[])
{
return cholesky_solve_factored(n, nrhs, a, b, LAPACK_spotrs);
}
DLLEXPORT lapack_int d_cholesky_solve_factored(lapack_int n, lapack_int nrhs, double a[], double b[])
{
return cholesky_solve_factored(n, nrhs, a, b, LAPACK_dpotrs);
}
DLLEXPORT lapack_int c_cholesky_solve_factored(lapack_int n, lapack_int nrhs, lapack_complex_float a[], lapack_complex_float b[])
{
return cholesky_solve_factored(n, nrhs, a, b, LAPACK_cpotrs);
}
DLLEXPORT lapack_int z_cholesky_solve_factored(lapack_int n, lapack_int nrhs, lapack_complex_double a[], lapack_complex_double b[])
{
return cholesky_solve_factored(n, nrhs, a, b, LAPACK_zpotrs);
}
DLLEXPORT lapack_int s_qr_factor(lapack_int m, lapack_int n, float r[], float tau[], float q[], float work[], lapack_int len)
{
return qr_factor(m, n, r, tau, q, work, len, LAPACK_sgeqrf, LAPACK_sorgqr);
}
DLLEXPORT lapack_int s_qr_thin_factor(lapack_int m, lapack_int n, float q[], float tau[], float r[], float work[], lapack_int len)
{
return qr_thin_factor(m, n, q, tau, r, work, len, LAPACK_sgeqrf, LAPACK_sorgqr);
}
DLLEXPORT lapack_int d_qr_factor(lapack_int m, lapack_int n, double r[], double tau[], double q[], double work[], lapack_int len)
{
return qr_factor(m, n, r, tau, q, work, len, LAPACK_dgeqrf, LAPACK_dorgqr);
}
DLLEXPORT lapack_int d_qr_thin_factor(lapack_int m, lapack_int n, double q[], double tau[], double r[], double work[], lapack_int len)
{
return qr_thin_factor(m, n, q, tau, r, work, len, LAPACK_dgeqrf, LAPACK_dorgqr);
}
DLLEXPORT lapack_int c_qr_factor(lapack_int m, lapack_int n, lapack_complex_float r[], lapack_complex_float tau[], lapack_complex_float q[], lapack_complex_float work[], lapack_int len)
{
return qr_factor(m, n, r, tau, q, work, len, LAPACK_cgeqrf, LAPACK_cungqr);
}
DLLEXPORT lapack_int c_qr_thin_factor(lapack_int m, lapack_int n, lapack_complex_float q[], lapack_complex_float tau[], lapack_complex_float r[], lapack_complex_float work[], lapack_int len)
{
return qr_thin_factor(m, n, q, tau, r, work, len, LAPACK_cgeqrf, LAPACK_cungqr);
}
DLLEXPORT lapack_int z_qr_factor(lapack_int m, lapack_int n, lapack_complex_double r[], lapack_complex_double tau[], lapack_complex_double q[], lapack_complex_double work[], lapack_int len)
{
return qr_factor(m, n, r, tau, q, work, len, LAPACK_zgeqrf, LAPACK_zungqr);
}
DLLEXPORT lapack_int z_qr_thin_factor(lapack_int m, lapack_int n, lapack_complex_double q[], lapack_complex_double tau[], lapack_complex_double r[], lapack_complex_double work[], lapack_int len)
{
return qr_thin_factor(m, n, q, tau, r, work, len, LAPACK_zgeqrf, LAPACK_zungqr);
}
DLLEXPORT lapack_int s_qr_solve(lapack_int m, lapack_int n, lapack_int bn, float a[], float b[], float x[], float work[], lapack_int len)
{
return qr_solve(m, n, bn, a, b, x, work, len, LAPACK_sgels);
}
DLLEXPORT lapack_int d_qr_solve(lapack_int m, lapack_int n, lapack_int bn, double a[], double b[], double x[], double work[], lapack_int len)
{
return qr_solve(m, n, bn, a, b, x, work, len, LAPACK_dgels);
}
DLLEXPORT lapack_int c_qr_solve(lapack_int m, lapack_int n, lapack_int bn, lapack_complex_float a[], lapack_complex_float b[], lapack_complex_float x[], lapack_complex_float work[], lapack_int len)
{
return qr_solve(m, n, bn, a, b, x, work, len, LAPACK_cgels);
}
DLLEXPORT lapack_int z_qr_solve(lapack_int m, lapack_int n, lapack_int bn, lapack_complex_double a[], lapack_complex_double b[], lapack_complex_double x[], lapack_complex_double work[], lapack_int len)
{
return qr_solve(m, n, bn, a, b, x, work, len, LAPACK_zgels);
}
DLLEXPORT lapack_int s_qr_solve_factored(lapack_int m, lapack_int n, lapack_int bn, float r[], float b[], float tau[], float x[], float work[], lapack_int len)
{
return qr_solve_factored(m, n, bn, r, b, tau, x, work, len, LAPACK_sormqr, cblas_strsm);
}
DLLEXPORT lapack_int d_qr_solve_factored(lapack_int m, lapack_int n, lapack_int bn, double r[], double b[], double tau[], double x[], double work[], lapack_int len)
{
return qr_solve_factored(m, n, bn, r, b, tau, x, work, len, LAPACK_dormqr, cblas_dtrsm);
}
DLLEXPORT lapack_int c_qr_solve_factored(lapack_int m, lapack_int n, lapack_int bn, lapack_complex_float r[], lapack_complex_float b[], lapack_complex_float tau[], lapack_complex_float x[], lapack_complex_float work[], lapack_int len)
{
return complex_qr_solve_factored<lapack_complex_float, float>(m, n, bn, r, b, tau, x, work, len, LAPACK_cunmqr, cblas_ctrsm);
}
DLLEXPORT lapack_int z_qr_solve_factored(lapack_int m, lapack_int n, lapack_int bn, lapack_complex_double r[], lapack_complex_double b[], lapack_complex_double tau[], lapack_complex_double x[], lapack_complex_double work[], lapack_int len)
{
return complex_qr_solve_factored<lapack_complex_double, double>(m, n, bn, r, b, tau, x, work, len, LAPACK_zunmqr, cblas_ztrsm);
}
DLLEXPORT lapack_int s_svd_factor(bool compute_vectors, lapack_int m, lapack_int n, float a[], float s[], float u[], float v[], float work[], lapack_int len)
{
return svd_factor(compute_vectors, m, n, a, s, u, v, work, len, LAPACK_sgesvd);
}
DLLEXPORT lapack_int d_svd_factor(bool compute_vectors, lapack_int m, lapack_int n, double a[], double s[], double u[], double v[], double work[], lapack_int len)
{
return svd_factor(compute_vectors, m, n, a, s, u, v, work, len, LAPACK_dgesvd);
}
DLLEXPORT lapack_int c_svd_factor(bool compute_vectors, lapack_int m, lapack_int n, lapack_complex_float a[], lapack_complex_float s[], lapack_complex_float u[], lapack_complex_float v[], lapack_complex_float work[], lapack_int len)
{
return complex_svd_factor<lapack_complex_float, float>(compute_vectors, m, n, a, s, u, v, work, len, LAPACK_cgesvd);
}
DLLEXPORT lapack_int z_svd_factor(bool compute_vectors, lapack_int m, lapack_int n, lapack_complex_double a[], lapack_complex_double s[], lapack_complex_double u[], lapack_complex_double v[], lapack_complex_double work[], lapack_int len)
{
return complex_svd_factor<lapack_complex_double, double>(compute_vectors, m, n, a, s, u, v, work, len, LAPACK_zgesvd);
}
DLLEXPORT lapack_int s_eigen(bool isSymmetric, lapack_int n, float a[], float vectors[], lapack_complex_double values[], float d[])
{
if (isSymmetric)
{
return sym_eigen_factor<float>(n, a, vectors, values, d, LAPACKE_ssyev);
}
else
{
return eigen_factor(n, a, vectors, values, d, LAPACKE_sgees, LAPACKE_strevc);
}
}
DLLEXPORT lapack_int d_eigen(bool isSymmetric, lapack_int n, double a[], double vectors[], lapack_complex_double values[], double d[])
{
if (isSymmetric)
{
return sym_eigen_factor<double>(n, a, vectors, values, d, LAPACKE_dsyev);
}
else
{
return eigen_factor(n, a, vectors, values, d, LAPACKE_dgees, LAPACKE_dtrevc);
}
}
DLLEXPORT lapack_int c_eigen(bool isSymmetric, lapack_int n, lapack_complex_float a[], lapack_complex_float vectors[], lapack_complex_double values[], lapack_complex_float d[])
{
if (isSymmetric)
{
return sym_eigen_factor<float>(n, a, vectors, values, d, LAPACKE_cheev);
}
else
{
return eigen_complex_factor(n, a, vectors, values, d, LAPACKE_cgees, LAPACKE_ctrevc);
}
}
DLLEXPORT lapack_int z_eigen(bool isSymmetric, lapack_int n, lapack_complex_double a[], lapack_complex_double vectors[], lapack_complex_double values[], lapack_complex_double d[])
{
if (isSymmetric)
{
return sym_eigen_factor<double>(n, a, vectors, values, d, LAPACKE_zheev);
}
else
{
return eigen_complex_factor(n, a, vectors, values, d, LAPACKE_zgees, LAPACKE_ztrevc);
}
}
}

220
src/NativeProviders/Windows/OpenBLAS/OpenBLASWrapper.vcxproj

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{CB4011B6-E9A7-480B-A7B1-8492039DAAD1}</ProjectGuid>
<RootNamespace>OpenBLASWrapper</RootNamespace>
<ProjectName>OpenBLAS</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros">
<OpenBlasPath Condition="'$(OPENBLASPATH)' == ''">$(ProjectDir)..\..\..\..\..\libs\OpenBLAS</OpenBlasPath>
<OpenBLASIncludeDir>$(OpenBlasPath)\include\</OpenBLASIncludeDir>
<OpenBLASLibDir>$(OpenBlasPath)\x86\</OpenBLASLibDir>
<OpenBLASLibDir_x64>$(OpenBlasPath)\x64\</OpenBLASLibDir_x64>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)..\..\..\..\out\OpenBLAS\Windows\x86\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>MathNet.Numerics.OpenBLAS</TargetName>
<IncludePath>$(OpenBLASIncludeDir);$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)..\..\..\..\out\OpenBLAS\Windows\x64\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>MathNet.Numerics.OpenBLAS</TargetName>
<IncludePath>$(OpenBLASIncludeDir);$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)..\..\..\..\out\OpenBLAS\Windows\x86\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>MathNet.Numerics.OpenBLAS</TargetName>
<IncludePath>$(OpenBLASIncludeDir);$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)..\..\..\..\out\OpenBLAS\Windows\x64\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<TargetName>MathNet.Numerics.OpenBLAS</TargetName>
<IncludePath>$(OpenBLASIncludeDir);$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\Common;$(ProjectDir)..\..\OpenBLAS;$(OpenBLASIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<AdditionalDependencies>libopenblas.dll.a;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<TargetMachine>MachineX86</TargetMachine>
<ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
<AdditionalLibraryDirectories>$(OpenBLASLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>copy "$(OpenBLASLibDir)*.dll" $(OutputPath)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\Common;$(ProjectDir)..\..\OpenBLAS;$(OpenBLASIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
<AdditionalDependencies>libopenblas.dll.a;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<TargetMachine>MachineX64</TargetMachine>
<ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
<AdditionalLibraryDirectories>$(OpenBLASLibDir_x64);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>copy "$(OpenBLASLibDir_x64)*.dll" $(OutputPath)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\Common;$(ProjectDir)..\..\OpenBLAS;$(OpenBLASIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<AdditionalOptions>/Qvec-report:1 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>libopenblas.dll.a;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
<ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
<AdditionalLibraryDirectories>$(OpenBLASLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>copy "$(OpenBLASLibDir)*.dll" $(OutputPath)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\Common;$(ProjectDir)..\..\OpenBLAS;$(OpenBLASIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<AdditionalOptions>/Qvec-report:1 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>libopenblas.dll.a;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
<ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
<AdditionalLibraryDirectories>$(OpenBLASLibDir_x64);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>copy "$(OpenBLASLibDir_x64)*.dll" $(OutputPath)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\Common\WindowsDLL.cpp" />
<ClCompile Include="..\..\OpenBLAS\blas.c" />
<ClCompile Include="..\..\OpenBLAS\capabilities.cpp" />
<ClCompile Include="..\..\OpenBLAS\lapack.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\Common\resource.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\OpenBLAS\complex.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

41
src/NativeProviders/Windows/OpenBLAS/OpenBLASWrapper.vcxproj.filters

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\OpenBLAS\blas.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\OpenBLAS\lapack.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\Common\WindowsDLL.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\OpenBLAS\capabilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\Common\resource.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\OpenBLAS\complex.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

5
src/Numerics/Control.cs

@ -136,6 +136,11 @@ namespace MathNet.Numerics
{
LinearAlgebraProvider = new Providers.LinearAlgebra.Cuda.CudaLinearAlgebraProvider();
}
public static void UseNativeOpenBLAS()
{
LinearAlgebraProvider = new Providers.LinearAlgebra.OpenBlas.OpenBlasLinearAlgebraProvider();
}
#endif
/// <summary>

13
src/Numerics/Numerics.csproj

@ -163,12 +163,12 @@
<Compile Include="Providers\LinearAlgebra\Cuda\CudaLinearAlgebraProvider.Double.cs" />
<Compile Include="Providers\LinearAlgebra\Cuda\CudaLinearAlgebraProvider.Single.cs" />
<Compile Include="Providers\LinearAlgebra\Cuda\SafeNativeMethods.cs" />
<Compile Include="Providers\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.cs" />
<Compile Include="Providers\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Complex.cs" />
<Compile Include="Providers\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Complex32.cs" />
<Compile Include="Providers\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Double.cs" />
<Compile Include="Providers\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Single.cs" />
<Compile Include="Providers\LinearAlgebra\GotoBlas\SafeNativeMethods.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.Complex.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.Complex32.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.Double.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\OpenBlasLinearAlgebraProvider.Single.cs" />
<Compile Include="Providers\LinearAlgebra\OpenBlas\SafeNativeMethods.cs" />
<Compile Include="Providers\LinearAlgebra\ManagedLinearAlgebraProvider.Complex32.cs" />
<Compile Include="Providers\LinearAlgebra\ManagedLinearAlgebraProvider.Complex.cs" />
<Compile Include="Providers\LinearAlgebra\ManagedLinearAlgebraProvider.Double.cs" />
@ -198,6 +198,7 @@
<Compile Include="LinearAlgebra\Vector.BCL.cs" />
<Compile Include="LinearAlgebra\Vector.Operators.cs" />
<Compile Include="Exceptions.cs" />
<Compile Include="Providers\LinearAlgebra\ProviderCapabilities.cs" />
<Compile Include="Providers\NativeProviderLoader.cs" />
<Compile Include="Random\SystemRandomSource.cs" />
<Compile Include="Random\RandomSeed.cs" />

1
src/Numerics/Properties/AssemblyInfo.cs

@ -77,6 +77,7 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests")]
[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTestsMKL")]
[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTestsCUDA")]
[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTestsOpenBLAS")]
[assembly: InternalsVisibleTo("Performance")]
#endif

367
src/Numerics/Providers/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.cs

@ -1,367 +0,0 @@
// <copyright file="GotoBlasLinearAlgebraProvider.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2011 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVEGOTO
using MathNet.Numerics.Properties;
using System;
using System.Numerics;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
{
/// <summary>
/// GotoBLAS2 linear algebra provider.
/// </summary>
public partial class GotoBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider
{
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override float MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
var work = new float[rows];
return MatrixNorm(norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <param name="work">The work array. Only used when <see cref="Norm.InfinityNorm"/>
/// and needs to be have a length of at least M (number of rows of <paramref name="matrix"/>.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override float MatrixNorm(Norm norm, int rows, int columns, float[] matrix, float[] work)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
if (work.Length < rows)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work");
}
return SafeNativeMethods.s_matrix_norm((byte) norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, double[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
var work = new double[rows];
return MatrixNorm(norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <param name="work">The work array. Only used when <see cref="Norm.InfinityNorm"/>
/// and needs to be have a length of at least M (number of rows of <paramref name="matrix"/>.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, double[] matrix, double[] work)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
if (work.Length < rows)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work");
}
return SafeNativeMethods.d_matrix_norm((byte) norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
var work = new float[rows];
return MatrixNorm(norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <param name="work">The work array. Only used when <see cref="Norm.InfinityNorm"/>
/// and needs to be have a length of at least M (number of rows of <paramref name="matrix"/>.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
if (work.Length < rows)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work");
}
return SafeNativeMethods.c_matrix_norm((byte) norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
var work = new double[rows];
return MatrixNorm(norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <param name="work">The work array. Only used when <see cref="Norm.InfinityNorm"/>
/// and needs to be have a length of at least M (number of rows of <paramref name="matrix"/>.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows*columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows*columns), "matrix");
}
if (work.Length < rows)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work");
}
return SafeNativeMethods.z_matrix_norm((byte) norm, rows, columns, matrix, work);
}
}
}
#endif

263
src/Numerics/Providers/LinearAlgebra/GotoBlas/SafeNativeMethods.cs

@ -1,263 +0,0 @@
// <copyright file="SafeNativeMethods.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVEGOTO
using System.Numerics;
using System.Runtime.InteropServices;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
{
/// <summary>
/// P/Invoke methods to the native math libraries.
/// </summary>
[SuppressUnmanagedCodeSecurity]
[SecurityCritical]
internal static class SafeNativeMethods
{
/// <summary>
/// Name of the native DLL.
/// </summary>
const string DllName = "MathNET.Numerics.GotoBLAS2.dll";
#region BLAS
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void s_axpy(int n, float alpha, float[] x, [In, Out] float[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void d_axpy(int n, double alpha, double[] x, [In, Out] double[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void c_axpy(int n, Complex32 alpha, Complex32[] x, [In, Out] Complex32[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void z_axpy(int n, Complex alpha, Complex[] x, [In, Out] Complex[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void s_scale(int n, float alpha, [Out] float[] x);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void d_scale(int n, double alpha, [Out] double[] x);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void c_scale(int n, Complex32 alpha, [In, Out] Complex32[] x);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void z_scale(int n, Complex alpha, [In, Out] Complex[] x);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float s_dot_product(int n, float[] x, float[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern double d_dot_product(int n, double[] x, double[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern Complex32 c_dot_product(int n, Complex32[] x, Complex32[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern Complex z_dot_product(int n, Complex[] x, Complex[] y);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void s_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, float alpha, float[] x, float[] y, float beta, [In, Out] float[] c);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void d_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, double alpha, double[] x, double[] y, double beta, [In, Out] double[] c);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void c_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, Complex32 alpha, Complex32[] x, Complex32[] y, Complex32 beta, [In, Out] Complex32[] c);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void z_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, Complex alpha, Complex[] x, Complex[] y, Complex beta, [In, Out] Complex[] c);
#endregion BLAS
#region LAPACK
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float s_matrix_norm(byte norm, int rows, int columns, [In] float[] a, [In, Out] float[] work);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float d_matrix_norm(byte norm, int rows, int columns, [In] double[] a, [In, Out] double[] work);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float c_matrix_norm(byte norm, int rows, int columns, [In] Complex32[] a, [In, Out] float[] work);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern double z_matrix_norm(byte norm, int rows, int columns, [In] Complex[] a, [In, Out] double[] work);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_cholesky_factor(int n, [In, Out] float[] a);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_cholesky_factor(int n, [In, Out] double[] a);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_cholesky_factor(int n, [In, Out] Complex32[] a);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_cholesky_factor(int n, [In, Out] Complex[] a);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_factor(int n, [In, Out] float[] a, [In, Out] int[] ipiv);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_factor(int n, [In, Out] double[] a, [In, Out] int[] ipiv);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_factor(int n, [In, Out] Complex32[] a, [In, Out] int[] ipiv);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_factor(int n, [In, Out] Complex[] a, [In, Out] int[] ipiv);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_inverse(int n, [In, Out] float[] a, [In, Out] float[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_inverse(int n, [In, Out] double[] a, [In, Out] double[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_inverse(int n, [In, Out] Complex32[] a, [In, Out] Complex32[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_inverse(int n, [In, Out] Complex[] a, [In, Out] Complex[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_inverse_factored(int n, [In, Out] float[] a, [In, Out] int[] ipiv, [In, Out] float[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_inverse_factored(int n, [In, Out] double[] a, [In, Out] int[] ipiv, [In, Out] double[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_inverse_factored(int n, [In, Out] Complex32[] a, [In, Out] int[] ipiv, [In, Out] Complex32[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_inverse_factored(int n, [In, Out] Complex[] a, [In, Out] int[] ipiv, [In, Out] Complex[] work, int lwork);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_solve_factored(int n, int nrhs, float[] a, [In, Out] int[] ipiv, [In, Out] float[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_solve_factored(int n, int nrhs, double[] a, [In, Out] int[] ipiv, [In, Out] double[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_solve_factored(int n, int nrhs, Complex32[] a, [In, Out] int[] ipiv, [In, Out] Complex32[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_solve_factored(int n, int nrhs, Complex[] a, [In, Out] int[] ipiv, [In, Out] Complex[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_solve(int n, int nrhs, float[] a, [In, Out] float[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_solve(int n, int nrhs, double[] a, [In, Out] double[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_solve(int n, int nrhs, Complex32[] a, [In, Out] Complex32[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_solve(int n, int nrhs, Complex[] a, [In, Out] Complex[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_cholesky_solve(int n, int nrhs, float[] a, [In, Out] float[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_cholesky_solve(int n, int nrhs, double[] a, [In, Out] double[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_cholesky_solve(int n, int nrhs, Complex32[] a, [In, Out] Complex32[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_cholesky_solve(int n, int nrhs, Complex[] a, [In, Out] Complex[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_cholesky_solve_factored(int n, int nrhs, float[] a, [In, Out] float[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_cholesky_solve_factored(int n, int nrhs, double[] a, [In, Out] double[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_cholesky_solve_factored(int n, int nrhs, Complex32[] a, [In, Out] Complex32[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_cholesky_solve_factored(int n, int nrhs, Complex[] a, [In, Out] Complex[] b);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_qr_factor(int m, int n, [In, Out] float[] r, [In, Out] float[] tau, [In, Out] float[] q, [In, Out] float[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_qr_factor(int m, int n, [In, Out] double[] r, [In, Out] double[] tau, [In, Out] double[] q, [In, Out] double[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_qr_factor(int m, int n, [In, Out] Complex32[] r, [In, Out] Complex32[] tau, [In, Out] Complex32[] q, [In, Out] Complex32[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_qr_factor(int m, int n, [In, Out] Complex[] r, [In, Out] Complex[] tau, [In, Out] Complex[] q, [In, Out] Complex[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_qr_solve(int m, int n, int bn, float[] r, float[] b, [In, Out] float[] x, [In, Out] float[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_qr_solve(int m, int n, int bn, double[] r, double[] b, [In, Out] double[] x, [In, Out] double[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_qr_solve(int m, int n, int bn, Complex32[] r, Complex32[] b, [In, Out] Complex32[] x, [In, Out] Complex32[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_qr_solve(int m, int n, int bn, Complex[] r, Complex[] b, [In, Out] Complex[] x, [In, Out] Complex[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_qr_solve_factored(int m, int n, int bn, float[] r, float[] b, float[] tau, [In, Out] float[] x, [In, Out] float[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_qr_solve_factored(int m, int n, int bn, double[] r, double[] b, double[] tau, [In, Out] double[] x, [In, Out] double[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_qr_solve_factored(int m, int n, int bn, Complex32[] r, Complex32[] b, Complex32[] tau, [In, Out] Complex32[] x, [In, Out] Complex32[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_qr_solve_factored(int m, int n, int bn, Complex[] r, Complex[] b, Complex[] tau, [In, Out] Complex[] x, [In, Out] Complex[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_svd_factor(bool computeVectors, int m, int n, [In, Out] float[] a, [In, Out] float[] s, [In, Out] float[] u, [In, Out] float[] v, [In, Out] float[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_svd_factor(bool computeVectors, int m, int n, [In, Out] double[] a, [In, Out] double[] s, [In, Out] double[] u, [In, Out] double[] v, [In, Out] double[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_svd_factor(bool computeVectors, int m, int n, [In, Out] Complex32[] a, [In, Out] Complex32[] s, [In, Out] Complex32[] u, [In, Out] Complex32[] v, [In, Out] Complex32[] work, int len);
[DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_svd_factor(bool computeVectors, int m, int n, [In, Out] Complex[] a, [In, Out] Complex[] s, [In, Out] Complex[] u, [In, Out] Complex[] v, [In, Out] Complex[] work, int len);
#endregion LAPACK
}
}
#endif

436
src/Numerics/Providers/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex.cs → src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex.cs

@ -1,10 +1,10 @@
// <copyright file="GotoBlasLinearAlgebraProvider.Complex.cs" company="Math.NET">
// <copyright file="OpenBlasLinearAlgebraProvider.Complex.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2011 Math.NET
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,7 +28,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVEGOTO
#if NATIVE
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
@ -36,13 +36,78 @@ using System;
using System.Numerics;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
{
/// <summary>
/// GotoBLAS2 linear algebra provider.
/// OpenBLAS linear algebra provider.
/// </summary>
public partial class GotoBlasLinearAlgebraProvider
public partial class OpenBlasLinearAlgebraProvider
{
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows * columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix");
}
var work = new double[rows];
return SafeNativeMethods.z_matrix_norm((byte)norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the dot product of x and y.
/// </summary>
/// <param name="x">The vector x.</param>
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex DotProduct(Complex[] x, Complex[] y)
{
if (y == null)
{
throw new ArgumentNullException("y");
}
if (x == null)
{
throw new ArgumentNullException("x");
}
if (x.Length != y.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
}
return SafeNativeMethods.z_dot_product(x.Length, x, y);
}
/// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -164,7 +229,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
if (c.Length != m*n)
if (c.Length != m * n)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
@ -199,7 +264,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (data.Length != order*order)
if (data.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
}
@ -226,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -255,7 +320,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -286,7 +351,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -327,7 +392,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -366,12 +431,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -406,7 +471,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -416,7 +481,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -449,7 +514,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -484,7 +549,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -518,7 +583,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -556,7 +621,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -566,12 +631,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
var work = new Complex[columnsR*Control.BlockSize];
var work = new Complex[columnsR * Control.BlockSize];
SafeNativeMethods.z_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
}
@ -608,7 +673,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -618,14 +683,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
if (work.Length < columnsR*Control.BlockSize)
if (work.Length < columnsR * Control.BlockSize)
{
work[0] = columnsR*Control.BlockSize;
work[0] = columnsR * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -633,54 +698,123 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
{
if (a == null)
if (r == null)
{
throw new ArgumentNullException("a");
throw new ArgumentNullException("r");
}
if (b == null)
if (q == null)
{
throw new ArgumentNullException("b");
throw new ArgumentNullException("q");
}
if (x == null)
if (q.Length != rowsA * columnsA)
{
throw new ArgumentNullException("x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (a.Length != rows*columns)
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (b.Length != rows*columnsB)
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
var work = new Complex[columnsA * Control.BlockSize];
SafeNativeMethods.z_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau, Complex[] work)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (x.Length != columns*columnsB)
if (q == null)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentNullException("q");
}
if (rows < columns)
if (work == null)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentNullException("q");
}
if (q.Length != rowsA * columnsA)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(
string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
if (work.Length < columnsA * Control.BlockSize)
{
work[0] = columnsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
var work = new Complex[columns*Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work);
SafeNativeMethods.z_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{
var work = new Complex[columns * Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work, method);
}
/// <summary>
@ -695,7 +829,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, Complex[] work, QRMethod method = QRMethod.Full)
{
if (a == null)
@ -718,17 +854,17 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (a.Length != rows*columns)
if (a.Length != rows * columns)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != rows*columnsB)
if (b.Length != rows * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columns*columnsB)
if (x.Length != columns * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
@ -740,7 +876,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
if (work.Length < 1)
{
work[0] = rows*Control.BlockSize;
work[0] = rows * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -750,8 +886,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(Complex[],int,int,Complex[],Complex[],QRMethod)"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex[],int,int,Complex[],Complex[],QRMethod)"/>. </param>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(Complex[],int,int,Complex[],Complex[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex[],int,int,Complex[],Complex[])"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
@ -759,57 +895,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (q == null)
{
throw new ArgumentNullException("q");
}
if (b == null)
{
throw new ArgumentNullException("q");
}
if (x == null)
{
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
}
if (q.Length != rowsR*rowsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
}
if (b.Length != rowsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
if (rowsR < columnsR)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
}
var work = new Complex[columnsR*Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work);
var work = new Complex[columnsR * Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work, method);
}
/// <summary>
@ -817,9 +909,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// </summary>
/// <param name="q">The Q matrix obtained by QR factor. This is only used for the managed provider and can be
/// <c>null</c> for the native provider. The native provider uses the Q portion stored in the R matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex[],int,int,Complex[],Complex[],QRMethod)"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex[],int,int,Complex[],Complex[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
@ -828,8 +920,10 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array - only used in the native provider. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x, Complex[] work, QRMethod method = QRMethod.Full)
[SecuritySafeCritical]
public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, Complex[] work, QRMethod method = QRMethod.Full)
{
if (r == null)
{
@ -856,38 +950,54 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
int rowsQ, columnsQ, rowsR, columnsR;
if (method == QRMethod.Full)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
rowsQ = columnsQ = rowsR = rowsA;
columnsR = columnsA;
}
else
{
rowsQ = rowsA;
columnsQ = rowsR = columnsR = columnsA;
}
if (q.Length != rowsR*rowsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsR * columnsR), "r");
}
if (b.Length != rowsR*columnsB)
if (q.Length != rowsQ * columnsQ)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsQ * columnsQ), "q");
}
if (x.Length != columnsR*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsA * columnsB), "b");
}
if (rowsR < columnsR)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, columnsA * columnsB), "x");
}
if (work.Length < 1)
{
work[0] = rowsR*Control.BlockSize;
work[0] = rowsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.z_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
if (method == QRMethod.Full)
{
SafeNativeMethods.z_qr_solve_factored(rowsA, columnsA, columnsB, r, b, tau, x, work, work.Length);
}
else
{
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
}
}
/// <summary>
@ -926,12 +1036,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("vt");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -941,7 +1051,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
}
var work = new Complex[(2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
var work = new Complex[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
}
@ -971,20 +1081,20 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("x");
}
if (b.Length != rowsA*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsA*columnsB)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
var work = new Complex[(2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
var work = new Complex[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
var s = new Complex[Math.Min(rowsA, columnsA)];
var u = new Complex[rowsA*rowsA];
var vt = new Complex[columnsA*columnsA];
var u = new Complex[rowsA * rowsA];
var vt = new Complex[columnsA * columnsA];
var clone = new Complex[a.Length];
a.Copy(clone);
@ -1036,12 +1146,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -1056,13 +1166,73 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
}
if (work.Length < (2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA))
if (work.Length < (2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA))
{
work[0] = (2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA);
work[0] = (2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA);
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.z_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length);
if (SafeNativeMethods.z_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length) > 0)
{
throw new NonConvergenceException();
}
}
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The lenth of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The lenth of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the arry must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The lenth of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (matrix.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrix");
}
if (matrixEv == null)
{
throw new ArgumentNullException("matrixEv");
}
if (matrixEv.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixEv");
}
if (vectorEv == null)
{
throw new ArgumentNullException("vectorEv");
}
if (vectorEv.Length != order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order), "vectorEv");
}
if (matrixD == null)
{
throw new ArgumentNullException("matrixD");
}
if (matrixD.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixD");
}
if (SafeNativeMethods.z_eigen(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD) > 0)
{
throw new NonConvergenceException();
}
}
}
}

437
src/Numerics/Providers/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex32.cs → src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Complex32.cs

@ -1,10 +1,10 @@
// <copyright file="GotoBlasLinearAlgebraProvider.Complex32.cs" company="Math.NET">
// <copyright file="OpenBlasLinearAlgebraProvider.Complex32.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2011 Math.NET
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,20 +28,86 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVEGOTO
#if NATIVE
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
using System;
using System.Numerics;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
{
/// <summary>
/// GotoBLAS2 linear algebra provider.
/// OpenBLAS linear algebra provider.
/// </summary>
public partial class GotoBlasLinearAlgebraProvider
public partial class OpenBlasLinearAlgebraProvider
{
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows * columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix");
}
var work = new float[rows];
return SafeNativeMethods.c_matrix_norm((byte)norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the dot product of x and y.
/// </summary>
/// <param name="x">The vector x.</param>
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex32 DotProduct(Complex32[] x, Complex32[] y)
{
if (y == null)
{
throw new ArgumentNullException("y");
}
if (x == null)
{
throw new ArgumentNullException("x");
}
if (x.Length != y.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
}
return SafeNativeMethods.c_dot_product(x.Length, x, y);
}
/// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -163,7 +229,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
if (c.Length != m*n)
if (c.Length != m * n)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
@ -198,7 +264,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (data.Length != order*order)
if (data.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
}
@ -225,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -254,7 +320,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -285,7 +351,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -326,7 +392,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -365,12 +431,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -405,7 +471,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -415,7 +481,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -448,7 +514,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -483,7 +549,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -517,7 +583,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -555,7 +621,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -565,12 +631,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
var work = new Complex32[columnsR*Control.BlockSize];
var work = new Complex32[columnsR * Control.BlockSize];
SafeNativeMethods.c_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
}
@ -607,7 +673,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -617,14 +683,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
if (work.Length < columnsR*Control.BlockSize)
if (work.Length < columnsR * Control.BlockSize)
{
work[0] = columnsR*Control.BlockSize;
work[0] = columnsR * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -632,54 +698,123 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
{
if (a == null)
if (r == null)
{
throw new ArgumentNullException("a");
throw new ArgumentNullException("r");
}
if (b == null)
if (q == null)
{
throw new ArgumentNullException("b");
throw new ArgumentNullException("q");
}
if (x == null)
if (q.Length != rowsA * columnsA)
{
throw new ArgumentNullException("x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (a.Length != rows*columns)
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (b.Length != rows*columnsB)
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
var work = new Complex32[columnsA * Control.BlockSize];
SafeNativeMethods.c_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau, Complex32[] work)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (x.Length != columns*columnsB)
if (q == null)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentNullException("q");
}
if (rows < columns)
if (work == null)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentNullException("q");
}
if (q.Length != rowsA * columnsA)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(
string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
if (work.Length < columnsA * Control.BlockSize)
{
work[0] = columnsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
var work = new Complex32[columns*Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work);
SafeNativeMethods.c_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{
var work = new Complex32[columns * Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work, method);
}
/// <summary>
@ -694,7 +829,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work, QRMethod method = QRMethod.Full)
{
if (a == null)
@ -717,17 +854,17 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (a.Length != rows*columns)
if (a.Length != rows * columns)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != rows*columnsB)
if (b.Length != rows * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columns*columnsB)
if (x.Length != columns * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
@ -739,7 +876,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
if (work.Length < 1)
{
work[0] = rows*Control.BlockSize;
work[0] = rows * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -749,8 +886,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(Complex32[],int,int,Complex32[],Complex32[],QRMethod)"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex32[],int,int,Complex32[],Complex32[],QRMethod)"/>. </param>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(Complex32[],int,int,Complex32[],Complex32[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex32[],int,int,Complex32[],Complex32[])"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
@ -758,57 +895,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (q == null)
{
throw new ArgumentNullException("q");
}
if (b == null)
{
throw new ArgumentNullException("q");
}
if (x == null)
{
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
}
if (q.Length != rowsR*rowsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
}
if (b.Length != rowsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
if (rowsR < columnsR)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
}
var work = new Complex32[columnsR*Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work);
var work = new Complex32[columnsR * Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work, method);
}
/// <summary>
@ -816,9 +909,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// </summary>
/// <param name="q">The Q matrix obtained by QR factor. This is only used for the managed provider and can be
/// <c>null</c> for the native provider. The native provider uses the Q portion stored in the R matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex32[],int,int,Complex32[],Complex32[],QRMethod)"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(Complex32[],int,int,Complex32[],Complex32[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
@ -827,8 +920,10 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array - only used in the native provider. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work, QRMethod method = QRMethod.Full)
[SecuritySafeCritical]
public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work, QRMethod method = QRMethod.Full)
{
if (r == null)
{
@ -855,38 +950,54 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
int rowsQ, columnsQ, rowsR, columnsR;
if (method == QRMethod.Full)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
rowsQ = columnsQ = rowsR = rowsA;
columnsR = columnsA;
}
else
{
rowsQ = rowsA;
columnsQ = rowsR = columnsR = columnsA;
}
if (q.Length != rowsR*rowsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsR * columnsR), "r");
}
if (b.Length != rowsR*columnsB)
if (q.Length != rowsQ * columnsQ)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsQ * columnsQ), "q");
}
if (x.Length != columnsR*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsA * columnsB), "b");
}
if (rowsR < columnsR)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, columnsA * columnsB), "x");
}
if (work.Length < 1)
{
work[0] = rowsR*Control.BlockSize;
work[0] = rowsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.c_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
if (method == QRMethod.Full)
{
SafeNativeMethods.c_qr_solve_factored(rowsA, columnsA, columnsB, r, b, tau, x, work, work.Length);
}
else
{
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
}
}
/// <summary>
@ -925,12 +1036,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("vt");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -940,7 +1051,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
}
var work = new Complex32[(2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
var work = new Complex32[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
}
@ -970,20 +1081,20 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("x");
}
if (b.Length != rowsA*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsA*columnsB)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
var work = new Complex32[(2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
var work = new Complex32[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
var s = new Complex32[Math.Min(rowsA, columnsA)];
var u = new Complex32[rowsA*rowsA];
var vt = new Complex32[columnsA*columnsA];
var u = new Complex32[rowsA * rowsA];
var vt = new Complex32[columnsA * columnsA];
var clone = new Complex32[a.Length];
a.Copy(clone);
@ -1035,12 +1146,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -1055,13 +1166,73 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
}
if (work.Length < (2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA))
if (work.Length < (2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA))
{
work[0] = (2*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA);
work[0] = (2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA);
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.c_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length);
if (SafeNativeMethods.c_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length) > 0)
{
throw new NonConvergenceException();
}
}
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The lenth of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The lenth of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the arry must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The lenth of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (matrix.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrix");
}
if (matrixEv == null)
{
throw new ArgumentNullException("matrixEv");
}
if (matrixEv.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixEv");
}
if (vectorEv == null)
{
throw new ArgumentNullException("vectorEv");
}
if (vectorEv.Length != order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order), "vectorEv");
}
if (matrixD == null)
{
throw new ArgumentNullException("matrixD");
}
if (matrixD.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixD");
}
if (SafeNativeMethods.c_eigen(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD) > 0)
{
throw new NonConvergenceException();
}
}
}
}

437
src/Numerics/Providers/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Double.cs → src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Double.cs

@ -1,10 +1,10 @@
// <copyright file="GotoBlasLinearAlgebraProvider.Double.cs" company="Math.NET">
// <copyright file="OpenBlasLinearAlgebraProvider.Double.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2011 Math.NET
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,20 +28,86 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVEGOTO
#if NATIVE
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
using System;
using System.Numerics;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
{
/// <summary>
/// GotoBLAS2 linear algebra provider.
/// OpenBLAS linear algebra provider.
/// </summary>
public partial class GotoBlasLinearAlgebraProvider
public partial class OpenBlasLinearAlgebraProvider
{
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, double[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows * columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix");
}
var work = new double[rows];
return SafeNativeMethods.d_matrix_norm((byte)norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the dot product of x and y.
/// </summary>
/// <param name="x">The vector x.</param>
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override double DotProduct(double[] x, double[] y)
{
if (y == null)
{
throw new ArgumentNullException("y");
}
if (x == null)
{
throw new ArgumentNullException("x");
}
if (x.Length != y.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
}
return SafeNativeMethods.d_dot_product(x.Length, x, y);
}
/// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -163,7 +229,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
if (c.Length != m*n)
if (c.Length != m * n)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
@ -198,7 +264,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (data.Length != order*order)
if (data.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
}
@ -225,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -254,7 +320,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -285,7 +351,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -326,7 +392,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -365,12 +431,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -405,7 +471,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -415,7 +481,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -448,7 +514,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -483,7 +549,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -517,7 +583,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -555,7 +621,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -565,12 +631,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
var work = new double[columnsR*Control.BlockSize];
var work = new double[columnsR * Control.BlockSize];
SafeNativeMethods.d_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
}
@ -607,7 +673,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -617,14 +683,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
if (work.Length < columnsR*Control.BlockSize)
if (work.Length < columnsR * Control.BlockSize)
{
work[0] = columnsR*Control.BlockSize;
work[0] = columnsR * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -632,54 +698,123 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
{
if (a == null)
if (r == null)
{
throw new ArgumentNullException("a");
throw new ArgumentNullException("r");
}
if (b == null)
if (q == null)
{
throw new ArgumentNullException("b");
throw new ArgumentNullException("q");
}
if (x == null)
if (q.Length != rowsA * columnsA)
{
throw new ArgumentNullException("x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (a.Length != rows*columns)
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (b.Length != rows*columnsB)
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
var work = new double[columnsA * Control.BlockSize];
SafeNativeMethods.d_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau, double[] work)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (x.Length != columns*columnsB)
if (q == null)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentNullException("q");
}
if (rows < columns)
if (work == null)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentNullException("q");
}
if (q.Length != rowsA * columnsA)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(
string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
if (work.Length < columnsA * Control.BlockSize)
{
work[0] = columnsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
var work = new double[columns*Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work);
SafeNativeMethods.d_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{
var work = new double[columns * Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work, method);
}
/// <summary>
@ -694,7 +829,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, double[] work, QRMethod method = QRMethod.Full)
{
if (a == null)
@ -717,17 +854,17 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (a.Length != rows*columns)
if (a.Length != rows * columns)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != rows*columnsB)
if (b.Length != rows * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columns*columnsB)
if (x.Length != columns * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
@ -739,7 +876,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
if (work.Length < 1)
{
work[0] = rows*Control.BlockSize;
work[0] = rows * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -749,8 +886,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[],QRMethod)"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[],QRMethod)"/>. </param>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
@ -758,57 +895,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (q == null)
{
throw new ArgumentNullException("q");
}
if (b == null)
{
throw new ArgumentNullException("q");
}
if (x == null)
{
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
}
if (q.Length != rowsR*rowsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
}
if (b.Length != rowsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
if (rowsR < columnsR)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
}
var work = new double[columnsR*Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work);
var work = new double[columnsR * Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work, method);
}
/// <summary>
@ -816,9 +909,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// </summary>
/// <param name="q">The Q matrix obtained by QR factor. This is only used for the managed provider and can be
/// <c>null</c> for the native provider. The native provider uses the Q portion stored in the R matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[],QRMethod)"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
@ -827,8 +920,10 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array - only used in the native provider. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x, double[] work, QRMethod method = QRMethod.Full)
[SecuritySafeCritical]
public override void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, double[] work, QRMethod method = QRMethod.Full)
{
if (r == null)
{
@ -855,38 +950,54 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
int rowsQ, columnsQ, rowsR, columnsR;
if (method == QRMethod.Full)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
rowsQ = columnsQ = rowsR = rowsA;
columnsR = columnsA;
}
else
{
rowsQ = rowsA;
columnsQ = rowsR = columnsR = columnsA;
}
if (q.Length != rowsR*rowsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsR * columnsR), "r");
}
if (b.Length != rowsR*columnsB)
if (q.Length != rowsQ * columnsQ)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsQ * columnsQ), "q");
}
if (x.Length != columnsR*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsA * columnsB), "b");
}
if (rowsR < columnsR)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, columnsA * columnsB), "x");
}
if (work.Length < 1)
{
work[0] = rowsR*Control.BlockSize;
work[0] = rowsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.d_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
if (method == QRMethod.Full)
{
SafeNativeMethods.d_qr_solve_factored(rowsA, columnsA, columnsB, r, b, tau, x, work, work.Length);
}
else
{
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
}
}
/// <summary>
@ -925,12 +1036,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("vt");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -940,7 +1051,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
}
var work = new double[Math.Max((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5*Math.Min(rowsA, columnsA))];
var work = new double[Math.Max((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5 * Math.Min(rowsA, columnsA))];
SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
}
@ -970,20 +1081,20 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("x");
}
if (b.Length != rowsA*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsA*columnsB)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
var work = new double[Math.Max((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5*Math.Min(rowsA, columnsA))];
var work = new double[Math.Max((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5 * Math.Min(rowsA, columnsA))];
var s = new double[Math.Min(rowsA, columnsA)];
var u = new double[rowsA*rowsA];
var vt = new double[columnsA*columnsA];
var u = new double[rowsA * rowsA];
var vt = new double[columnsA * columnsA];
var clone = new double[a.Length];
a.Copy(clone);
@ -1035,12 +1146,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -1055,13 +1166,73 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
}
if (work.Length < Math.Max((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5*Math.Min(rowsA, columnsA)))
if (work.Length < Math.Max((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5 * Math.Min(rowsA, columnsA)))
{
work[0] = Math.Max((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5*Math.Min(rowsA, columnsA));
work[0] = Math.Max((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5 * Math.Min(rowsA, columnsA));
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.d_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length);
if (SafeNativeMethods.d_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length) > 0)
{
throw new NonConvergenceException();
}
}
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The lenth of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The lenth of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the arry must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The lenth of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (matrix.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrix");
}
if (matrixEv == null)
{
throw new ArgumentNullException("matrixEv");
}
if (matrixEv.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixEv");
}
if (vectorEv == null)
{
throw new ArgumentNullException("vectorEv");
}
if (vectorEv.Length != order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order), "vectorEv");
}
if (matrixD == null)
{
throw new ArgumentNullException("matrixD");
}
if (matrixD.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixD");
}
if (SafeNativeMethods.d_eigen(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD) > 0)
{
throw new NonConvergenceException();
}
}
}
}

437
src/Numerics/Providers/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Single.cs → src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.Single.cs

@ -1,10 +1,10 @@
// <copyright file="GotoBlasLinearAlgebraProvider.Single.cs" company="Math.NET">
// <copyright file="OpenBlasLinearAlgebraProvider.Single.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2011 Math.NET
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,20 +28,86 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVEGOTO
#if NATIVE
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Properties;
using System;
using System.Numerics;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
{
/// <summary>
/// GotoBLAS2 linear algebra provider.
/// OpenBLAS linear algebra provider.
/// </summary>
public partial class GotoBlasLinearAlgebraProvider
public partial class OpenBlasLinearAlgebraProvider
{
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows in the matrix.</param>
/// <param name="columns">The number of columns in the matrix.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
[SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (rows <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "rows");
}
if (columns <= 0)
{
throw new ArgumentException(Resources.ArgumentMustBePositive, "columns");
}
if (matrix.Length < rows * columns)
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix");
}
var work = new float[rows];
return SafeNativeMethods.s_matrix_norm((byte)norm, rows, columns, matrix, work);
}
/// <summary>
/// Computes the dot product of x and y.
/// </summary>
/// <param name="x">The vector x.</param>
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override float DotProduct(float[] x, float[] y)
{
if (y == null)
{
throw new ArgumentNullException("y");
}
if (x == null)
{
throw new ArgumentNullException("x");
}
if (x.Length != y.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength);
}
return SafeNativeMethods.s_dot_product(x.Length, x, y);
}
/// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -163,7 +229,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
if (c.Length != m*n)
if (c.Length != m * n)
{
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
@ -198,7 +264,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (data.Length != order*order)
if (data.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
}
@ -225,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -254,7 +320,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -285,7 +351,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -326,7 +392,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -365,12 +431,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("a");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -405,7 +471,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("ipiv");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -415,7 +481,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
}
if (b.Length != columnsOfB*order)
if (b.Length != columnsOfB * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -448,7 +514,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
}
if (a.Length != order*order)
if (a.Length != order * order)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
@ -483,7 +549,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -517,7 +583,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("b");
}
if (b.Length != orderA*columnsB)
if (b.Length != orderA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
@ -555,7 +621,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -565,12 +631,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
var work = new float[columnsR*Control.BlockSize];
var work = new float[columnsR * Control.BlockSize];
SafeNativeMethods.s_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
}
@ -607,7 +673,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
}
@ -617,14 +683,14 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (q.Length != rowsR*rowsR)
if (q.Length != rowsR * rowsR)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
if (work.Length < columnsR*Control.BlockSize)
if (work.Length < columnsR * Control.BlockSize)
{
work[0] = columnsR*Control.BlockSize;
work[0] = columnsR * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -632,54 +698,123 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
{
if (a == null)
if (r == null)
{
throw new ArgumentNullException("a");
throw new ArgumentNullException("r");
}
if (b == null)
if (q == null)
{
throw new ArgumentNullException("b");
throw new ArgumentNullException("q");
}
if (x == null)
if (q.Length != rowsA * columnsA)
{
throw new ArgumentNullException("x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (a.Length != rows*columns)
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (b.Length != rows*columnsB)
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
var work = new float[columnsA * Control.BlockSize];
SafeNativeMethods.s_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau, float[] work)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (x.Length != columns*columnsB)
if (q == null)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentNullException("q");
}
if (rows < columns)
if (work == null)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentNullException("q");
}
if (q.Length != rowsA * columnsA)
{
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "q");
}
if (tau.Length < Math.Min(rowsA, columnsA))
{
throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
}
if (r.Length != columnsA * columnsA)
{
throw new ArgumentException(
string.Format(Resources.ArgumentArrayWrongLength, "columnsA * columnsA"), "r");
}
if (work.Length < columnsA * Control.BlockSize)
{
work[0] = columnsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
var work = new float[columns*Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work);
SafeNativeMethods.s_qr_thin_factor(rowsA, columnsA, q, tau, r, work, work.Length);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{
var work = new float[columns * Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work, method);
}
/// <summary>
@ -694,7 +829,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, float[] work, QRMethod method = QRMethod.Full)
{
if (a == null)
@ -717,17 +854,17 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (a.Length != rows*columns)
if (a.Length != rows * columns)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
if (b.Length != rows*columnsB)
if (b.Length != rows * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columns*columnsB)
if (x.Length != columns * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
@ -739,7 +876,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
if (work.Length < 1)
{
work[0] = rows*Control.BlockSize;
work[0] = rows * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
@ -749,8 +886,8 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(float[],int,int,float[],float[],QRMethod)"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(float[],int,int,float[],float[],QRMethod)"/>. </param>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(float[],int,int,float[],float[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(float[],int,int,float[],float[])"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
@ -758,57 +895,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{
if (r == null)
{
throw new ArgumentNullException("r");
}
if (q == null)
{
throw new ArgumentNullException("q");
}
if (b == null)
{
throw new ArgumentNullException("q");
}
if (x == null)
{
throw new ArgumentNullException("q");
}
if (r.Length != rowsR*columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
}
if (q.Length != rowsR*rowsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
}
if (b.Length != rowsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsR*columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
}
if (rowsR < columnsR)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
}
var work = new float[columnsR*Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work);
var work = new float[columnsR * Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work, method);
}
/// <summary>
@ -816,9 +909,9 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// </summary>
/// <param name="q">The Q matrix obtained by QR factor. This is only used for the managed provider and can be
/// <c>null</c> for the native provider. The native provider uses the Q portion stored in the R matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(float[],int,int,float[],float[],QRMethod)"/>. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(float[],int,int,float[],float[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
@ -827,8 +920,10 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
/// <param name="work">The work array - only used in the native provider. The array must have a length of at least N,
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x, float[] work, QRMethod method = QRMethod.Full)
[SecuritySafeCritical]
public override void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, float[] work, QRMethod method = QRMethod.Full)
{
if (r == null)
{
@ -855,38 +950,54 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (r.Length != rowsR*columnsR)
int rowsQ, columnsQ, rowsR, columnsR;
if (method == QRMethod.Full)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "r");
rowsQ = columnsQ = rowsR = rowsA;
columnsR = columnsA;
}
else
{
rowsQ = rowsA;
columnsQ = rowsR = columnsR = columnsA;
}
if (q.Length != rowsR*rowsR)
if (r.Length != rowsR * columnsR)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "q");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsR * columnsR), "r");
}
if (b.Length != rowsR*columnsB)
if (q.Length != rowsQ * columnsQ)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsQ * columnsQ), "q");
}
if (x.Length != columnsR*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, rowsA * columnsB), "b");
}
if (rowsR < columnsR)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.RowsLessThanColumns);
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, columnsA * columnsB), "x");
}
if (work.Length < 1)
{
work[0] = rowsR*Control.BlockSize;
work[0] = rowsA * Control.BlockSize;
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.s_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
if (method == QRMethod.Full)
{
SafeNativeMethods.s_qr_solve_factored(rowsA, columnsA, columnsB, r, b, tau, x, work, work.Length);
}
else
{
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
}
}
/// <summary>
@ -925,12 +1036,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("vt");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -940,7 +1051,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
}
var work = new float[Math.Max(((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5*Math.Min(rowsA, columnsA))];
var work = new float[Math.Max(((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5 * Math.Min(rowsA, columnsA))];
SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
}
@ -970,20 +1081,20 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("x");
}
if (b.Length != rowsA*columnsB)
if (b.Length != rowsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
if (x.Length != columnsA*columnsB)
if (x.Length != columnsA * columnsB)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
var work = new float[Math.Max(((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5*Math.Min(rowsA, columnsA))];
var work = new float[Math.Max(((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5 * Math.Min(rowsA, columnsA))];
var s = new float[Math.Min(rowsA, columnsA)];
var u = new float[rowsA*rowsA];
var vt = new float[columnsA*columnsA];
var u = new float[rowsA * rowsA];
var vt = new float[columnsA * columnsA];
var clone = new float[a.Length];
a.Copy(clone);
@ -1035,12 +1146,12 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentNullException("work");
}
if (u.Length != rowsA*rowsA)
if (u.Length != rowsA * rowsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
}
if (vt.Length != columnsA*columnsA)
if (vt.Length != columnsA * columnsA)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
}
@ -1055,13 +1166,73 @@ namespace MathNet.Numerics.Providers.LinearAlgebra.GotoBlas
throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
}
if (work.Length < Math.Max(((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5*Math.Min(rowsA, columnsA)))
if (work.Length < Math.Max(((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5 * Math.Min(rowsA, columnsA)))
{
work[0] = Math.Max(((3*Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5*Math.Min(rowsA, columnsA));
work[0] = Math.Max(((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)), 5 * Math.Min(rowsA, columnsA));
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
SafeNativeMethods.s_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length);
if (SafeNativeMethods.s_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length) > 0)
{
throw new NonConvergenceException();
}
}
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The lenth of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The lenth of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the arry must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The lenth of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD)
{
if (matrix == null)
{
throw new ArgumentNullException("matrix");
}
if (matrix.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrix");
}
if (matrixEv == null)
{
throw new ArgumentNullException("matrixEv");
}
if (matrixEv.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixEv");
}
if (vectorEv == null)
{
throw new ArgumentNullException("vectorEv");
}
if (vectorEv.Length != order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order), "vectorEv");
}
if (matrixD == null)
{
throw new ArgumentNullException("matrixD");
}
if (matrixD.Length != order * order)
{
throw new ArgumentException(String.Format(Resources.ArgumentArrayWrongLength, order * order), "matrixD");
}
if (SafeNativeMethods.s_eigen(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD) > 0)
{
throw new NonConvergenceException();
}
}
}
}

107
src/Numerics/Providers/LinearAlgebra/OpenBlas/OpenBlasLinearAlgebraProvider.cs

@ -0,0 +1,107 @@
// <copyright file="OpenBlasLinearAlgebraProvider.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVE
using MathNet.Numerics.Properties;
using System;
using System.Numerics;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
{
public enum ParallelType : int
{
Sequential = 0,
Thread = 1,
OpenMP = 2
}
/// <summary>
/// OpenBLAS linear algebra provider.
/// </summary>
public partial class OpenBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider
{
bool _nativeIX86;
bool _nativeX64;
bool _nativeIA64;
bool _nativeARM;
public OpenBlasLinearAlgebraProvider()
{
}
public override void InitializeVerify()
{
int linearAlgebra;
try
{
// Load the native library
NativeProviderLoader.TryLoad(SafeNativeMethods.DllName);
_nativeIX86 = SafeNativeMethods.query_capability((int)ProviderPlatform.x86) > 0;
_nativeX64 = SafeNativeMethods.query_capability((int)ProviderPlatform.x64) > 0;
_nativeIA64 = SafeNativeMethods.query_capability((int)ProviderPlatform.ia64) > 0;
_nativeARM = SafeNativeMethods.query_capability((int)ProviderPlatform.arm) > 0;
linearAlgebra = SafeNativeMethods.query_capability((int)ProviderCapability.LinearAlgebra);
}
catch (DllNotFoundException e)
{
throw new NotSupportedException("OpenBLAS Native Provider not found.", e);
}
catch (BadImageFormatException e)
{
throw new NotSupportedException("OpenBLAS Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e);
}
catch (EntryPointNotFoundException e)
{
throw new NotSupportedException("OpenBLAS Native Provider does not support capability querying and is therefore not compatible. Consider upgrading to a newer version.", e);
}
// set threading settings, if supported
if (SafeNativeMethods.query_capability((int)ProviderConfig.Threading) > 0)
{
SafeNativeMethods.set_max_threads(Control.MaxDegreeOfParallelism);
}
}
public override string ToString()
{
return string.Format("OpenBLAS\r\nProvider revision: {0}\r\nCPU core name: {1}\r\nLibrary config: {1})",
SafeNativeMethods.query_capability((int)ProviderConfig.Revision),
SafeNativeMethods.get_cpu_core(),
SafeNativeMethods.get_build_config());
}
}
}
#endif

303
src/Numerics/Providers/LinearAlgebra/OpenBlas/SafeNativeMethods.cs

@ -0,0 +1,303 @@
// <copyright file="SafeNativeMethods.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
#if NATIVE
using System.Numerics;
using System.Runtime.InteropServices;
using System.Security;
namespace MathNet.Numerics.Providers.LinearAlgebra.OpenBlas
{
/// <summary>
/// P/Invoke methods to the native math libraries.
/// </summary>
[SuppressUnmanagedCodeSecurity]
[SecurityCritical]
internal static class SafeNativeMethods
{
/// <summary>
/// Name of the native DLL.
/// </summary>
const string _DllName = "MathNET.Numerics.OpenBLAS.dll";
internal static string DllName { get { return _DllName; } }
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int query_capability(int capability);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern string get_build_config();
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern string get_cpu_core();
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern ParallelType get_parallel_type();
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void set_max_threads(int num_threads);
#region BLAS
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void s_axpy(int n, float alpha, float[] x, [In, Out] float[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void d_axpy(int n, double alpha, double[] x, [In, Out] double[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void c_axpy(int n, Complex32 alpha, Complex32[] x, [In, Out] Complex32[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void z_axpy(int n, Complex alpha, Complex[] x, [In, Out] Complex[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void s_scale(int n, float alpha, [Out] float[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void d_scale(int n, double alpha, [Out] double[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void c_scale(int n, Complex32 alpha, [In, Out] Complex32[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void z_scale(int n, Complex alpha, [In, Out] Complex[] x);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float s_dot_product(int n, float[] x, float[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern double d_dot_product(int n, double[] x, double[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern Complex32 c_dot_product(int n, Complex32[] x, Complex32[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern Complex z_dot_product(int n, Complex[] x, Complex[] y);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void s_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, float alpha, float[] x, float[] y, float beta, [In, Out] float[] c);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void d_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, double alpha, double[] x, double[] y, double beta, [In, Out] double[] c);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void c_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, Complex32 alpha, Complex32[] x, Complex32[] y, Complex32 beta, [In, Out] Complex32[] c);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern void z_matrix_multiply(Transpose transA, Transpose transB, int m, int n, int k, Complex alpha, Complex[] x, Complex[] y, Complex beta, [In, Out] Complex[] c);
#endregion BLAS
#region LAPACK
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float s_matrix_norm(byte norm, int rows, int columns, [In] float[] a, [In, Out] float[] work);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float d_matrix_norm(byte norm, int rows, int columns, [In] double[] a, [In, Out] double[] work);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern float c_matrix_norm(byte norm, int rows, int columns, [In] Complex32[] a, [In, Out] float[] work);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern double z_matrix_norm(byte norm, int rows, int columns, [In] Complex[] a, [In, Out] double[] work);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_factor(int n, [In, Out] float[] a, [In, Out] int[] ipiv);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_factor(int n, [In, Out] double[] a, [In, Out] int[] ipiv);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_factor(int n, [In, Out] Complex32[] a, [In, Out] int[] ipiv);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_factor(int n, [In, Out] Complex[] a, [In, Out] int[] ipiv);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_inverse(int n, [In, Out] float[] a, [In, Out] float[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_inverse(int n, [In, Out] double[] a, [In, Out] double[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_inverse(int n, [In, Out] Complex32[] a, [In, Out] Complex32[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_inverse(int n, [In, Out] Complex[] a, [In, Out] Complex[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_inverse_factored(int n, [In, Out] float[] a, [In, Out] int[] ipiv, [In, Out] float[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_inverse_factored(int n, [In, Out] double[] a, [In, Out] int[] ipiv, [In, Out] double[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_inverse_factored(int n, [In, Out] Complex32[] a, [In, Out] int[] ipiv, [In, Out] Complex32[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_inverse_factored(int n, [In, Out] Complex[] a, [In, Out] int[] ipiv, [In, Out] Complex[] work, int lwork);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_solve_factored(int n, int nrhs, float[] a, [In, Out] int[] ipiv, [In, Out] float[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_solve_factored(int n, int nrhs, double[] a, [In, Out] int[] ipiv, [In, Out] double[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_solve_factored(int n, int nrhs, Complex32[] a, [In, Out] int[] ipiv, [In, Out] Complex32[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_solve_factored(int n, int nrhs, Complex[] a, [In, Out] int[] ipiv, [In, Out] Complex[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_lu_solve(int n, int nrhs, float[] a, [In, Out] float[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_lu_solve(int n, int nrhs, double[] a, [In, Out] double[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_lu_solve(int n, int nrhs, Complex32[] a, [In, Out] Complex32[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_lu_solve(int n, int nrhs, Complex[] a, [In, Out] Complex[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_cholesky_factor(int n, [In, Out] float[] a);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_cholesky_factor(int n, [In, Out] double[] a);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_cholesky_factor(int n, [In, Out] Complex32[] a);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_cholesky_factor(int n, [In, Out] Complex[] a);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_cholesky_solve(int n, int nrhs, float[] a, [In, Out] float[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_cholesky_solve(int n, int nrhs, double[] a, [In, Out] double[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_cholesky_solve(int n, int nrhs, Complex32[] a, [In, Out] Complex32[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_cholesky_solve(int n, int nrhs, Complex[] a, [In, Out] Complex[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_cholesky_solve_factored(int n, int nrhs, float[] a, [In, Out] float[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_cholesky_solve_factored(int n, int nrhs, double[] a, [In, Out] double[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_cholesky_solve_factored(int n, int nrhs, Complex32[] a, [In, Out] Complex32[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_cholesky_solve_factored(int n, int nrhs, Complex[] a, [In, Out] Complex[] b);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_qr_factor(int m, int n, [In, Out] float[] r, [In, Out] float[] tau, [In, Out] float[] q, [In, Out] float[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_qr_thin_factor(int m, int n, [In, Out] float[] q, [In, Out] float[] tau, [In, Out] float[] r, [In, Out] float[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_qr_factor(int m, int n, [In, Out] double[] r, [In, Out] double[] tau, [In, Out] double[] q, [In, Out] double[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_qr_thin_factor(int m, int n, [In, Out] double[] q, [In, Out] double[] tau, [In, Out] double[] r, [In, Out] double[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_qr_factor(int m, int n, [In, Out] Complex32[] r, [In, Out] Complex32[] tau, [In, Out] Complex32[] q, [In, Out] Complex32[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_qr_thin_factor(int m, int n, [In, Out] Complex32[] q, [In, Out] Complex32[] tau, [In, Out] Complex32[] r, [In, Out] Complex32[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_qr_factor(int m, int n, [In, Out] Complex[] r, [In, Out] Complex[] tau, [In, Out] Complex[] q, [In, Out] Complex[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_qr_thin_factor(int m, int n, [In, Out] Complex[] q, [In, Out] Complex[] tau, [In, Out] Complex[] r, [In, Out] Complex[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_qr_solve(int m, int n, int bn, float[] r, float[] b, [In, Out] float[] x, [In, Out] float[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_qr_solve(int m, int n, int bn, double[] r, double[] b, [In, Out] double[] x, [In, Out] double[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_qr_solve(int m, int n, int bn, Complex32[] r, Complex32[] b, [In, Out] Complex32[] x, [In, Out] Complex32[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_qr_solve(int m, int n, int bn, Complex[] r, Complex[] b, [In, Out] Complex[] x, [In, Out] Complex[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_qr_solve_factored(int m, int n, int bn, float[] r, float[] b, float[] tau, [In, Out] float[] x, [In, Out] float[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_qr_solve_factored(int m, int n, int bn, double[] r, double[] b, double[] tau, [In, Out] double[] x, [In, Out] double[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_qr_solve_factored(int m, int n, int bn, Complex32[] r, Complex32[] b, Complex32[] tau, [In, Out] Complex32[] x, [In, Out] Complex32[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_qr_solve_factored(int m, int n, int bn, Complex[] r, Complex[] b, Complex[] tau, [In, Out] Complex[] x, [In, Out] Complex[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_svd_factor(bool computeVectors, int m, int n, [In, Out] float[] a, [In, Out] float[] s, [In, Out] float[] u, [In, Out] float[] v, [In, Out] float[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_svd_factor(bool computeVectors, int m, int n, [In, Out] double[] a, [In, Out] double[] s, [In, Out] double[] u, [In, Out] double[] v, [In, Out] double[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_svd_factor(bool computeVectors, int m, int n, [In, Out] Complex32[] a, [In, Out] Complex32[] s, [In, Out] Complex32[] u, [In, Out] Complex32[] v, [In, Out] Complex32[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_svd_factor(bool computeVectors, int m, int n, [In, Out] Complex[] a, [In, Out] Complex[] s, [In, Out] Complex[] u, [In, Out] Complex[] v, [In, Out] Complex[] work, int len);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int s_eigen(bool isSymmetric, int n, [In, Out] float[] a, [In, Out] float[] vectors, [In, Out] Complex[] values, [In, Out] float[] d);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int d_eigen(bool isSymmetric, int n, [In, Out] double[] a, [In, Out] double[] vectors, [In, Out] Complex[] values, [In, Out] double[] d);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int c_eigen(bool isSymmetric, int n, [In, Out] Complex32[] a, [In, Out] Complex32[] vectors, [In, Out] Complex[] values, [In, Out] Complex32[] d);
[DllImport(_DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
internal static extern int z_eigen(bool isSymmetric, int n, [In, Out] Complex[] a, [In, Out] Complex[] vectors, [In, Out] Complex[] values, [In, Out] Complex[] d);
#endregion LAPACK
}
}
#endif

55
src/Numerics/Providers/LinearAlgebra/ProviderCapabilities.cs

@ -0,0 +1,55 @@
// <copyright file="ProviderCapabilities.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2015 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.Providers.LinearAlgebra
{
public enum ProviderPlatform : int
{
x86 = 8,
x64 = 9,
ia64 = 10,
arm = 11,
}
public enum ProviderConfig : int
{
Revision = 64,
Precision = 65,
Threading = 66,
Memory = 67,
}
public enum ProviderCapability : int
{
LinearAlgebra = 128,
Optimization = 256,
FFT = 384,
}
}

3
src/UnitTests/UnitTests-MKL.csproj

@ -345,4 +345,7 @@
<Paket>True</Paket>
</Reference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
</Project>

351
src/UnitTests/UnitTests-OpenBLAS.csproj

@ -0,0 +1,351 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{96B903EF-3EE1-4569-803C-0482D2F5ED37}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MathNet.Numerics.UnitTests</RootNamespace>
<AssemblyName>MathNet.Numerics.UnitTestsOpenBLAS</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DefineConstants>TRACE;NATIVE;OPENBLAS;</DefineConstants>
<OutputPath>..\..\out\OpenBLAS\Windows\</OutputPath>
<IntermediateOutputPath>..\..\obj\OpenBLAS\Windows\AnyCPU\</IntermediateOutputPath>
<BaseIntermediateOutputPath>..\..\obj\OpenBLAS\Windows\AnyCPU\</BaseIntermediateOutputPath>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<NoWarn>1591</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineConstants>TRACE;DEBUG;NATIVE;OPENBLAS;</DefineConstants>
<OutputPath>..\..\out\OpenBLAS\Windows\</OutputPath>
<IntermediateOutputPath>..\..\obj\OpenBLAS\Windows\AnyCPU\</IntermediateOutputPath>
<BaseIntermediateOutputPath>..\..\obj\OpenBLAS\Windows\AnyCPU\</BaseIntermediateOutputPath>
<Optimize>false</Optimize>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>1591</NoWarn>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="Properties\Settings.Designer.cs">
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\data\Codeplex-5667.csv">
<Link>data\Codeplex-5667.csv</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Github-Cureos-1.csv">
<Link>data\Github-Cureos-1.csv</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\A.mat">
<Link>data\Matlab\A.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\collection-nocompress.mat">
<Link>data\Matlab\collection-nocompress.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\collection.mat">
<Link>data\Matlab\collection.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\complex.mat">
<Link>data\Matlab\complex.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\sparse-large.mat">
<Link>data\Matlab\sparse-large.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\sparse-small.mat">
<Link>data\Matlab\sparse-small.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\sparse_complex.mat">
<Link>data\Matlab\sparse_complex.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\Matlab\v.mat">
<Link>data\Matlab\v.mat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\AtmWtAgt.dat">
<Link>data\NIST\AtmWtAgt.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Bennett5.dat">
<Link>data\NIST\Bennett5.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\BoxBOD.dat">
<Link>data\NIST\BoxBOD.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Chwirut1.dat">
<Link>data\NIST\Chwirut1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Chwirut2.dat">
<Link>data\NIST\Chwirut2.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\DanWood.dat">
<Link>data\NIST\DanWood.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Eckerle4.dat">
<Link>data\NIST\Eckerle4.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\ENSO.dat">
<Link>data\NIST\ENSO.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Filip.dat">
<Link>data\NIST\Filip.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Gauss1.dat">
<Link>data\NIST\Gauss1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Gauss2.dat">
<Link>data\NIST\Gauss2.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Gauss3.dat">
<Link>data\NIST\Gauss3.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Hahn1.dat">
<Link>data\NIST\Hahn1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Kirby2.dat">
<Link>data\NIST\Kirby2.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Lanczos1.dat">
<Link>data\NIST\Lanczos1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Lanczos2.dat">
<Link>data\NIST\Lanczos2.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Lanczos3.dat">
<Link>data\NIST\Lanczos3.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Lew.dat">
<Link>data\NIST\Lew.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Longley.dat">
<Link>data\NIST\Longley.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Lottery.dat">
<Link>data\NIST\Lottery.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Mavro.dat">
<Link>data\NIST\Mavro.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\MGH09.dat">
<Link>data\NIST\MGH09.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\MGH10.dat">
<Link>data\NIST\MGH10.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\MGH17.dat">
<Link>data\NIST\MGH17.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Michelso.dat">
<Link>data\NIST\Michelso.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Misra1a.dat">
<Link>data\NIST\Misra1a.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Misra1b.dat">
<Link>data\NIST\Misra1b.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Misra1c.dat">
<Link>data\NIST\Misra1c.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Misra1d.dat">
<Link>data\NIST\Misra1d.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Nelson.dat">
<Link>data\NIST\Nelson.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\NoInt1.dat">
<Link>data\NIST\NoInt1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\NoInt2.dat">
<Link>data\NIST\NoInt2.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Norris.dat">
<Link>data\NIST\Norris.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\NumAcc1.dat">
<Link>data\NIST\NumAcc1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\NumAcc2.dat">
<Link>data\NIST\NumAcc2.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\NumAcc3.dat">
<Link>data\NIST\NumAcc3.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\NumAcc4.dat">
<Link>data\NIST\NumAcc4.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Pontius.dat">
<Link>data\NIST\Pontius.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Rat42.dat">
<Link>data\NIST\Rat42.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Rat43.dat">
<Link>data\NIST\Rat43.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Roszman1.dat">
<Link>data\NIST\Roszman1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SiRstvt.dat">
<Link>data\NIST\SiRstvt.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs01t.dat">
<Link>data\NIST\SmLs01t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs02t.dat">
<Link>data\NIST\SmLs02t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs03t.dat">
<Link>data\NIST\SmLs03t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs04t.dat">
<Link>data\NIST\SmLs04t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs05t.dat">
<Link>data\NIST\SmLs05t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs06t.dat">
<Link>data\NIST\SmLs06t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs07t.dat">
<Link>data\NIST\SmLs07t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs08t.dat">
<Link>data\NIST\SmLs08t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\SmLs09t.dat">
<Link>data\NIST\SmLs09t.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Thurber.dat">
<Link>data\NIST\Thurber.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Wampler1.dat">
<Link>data\NIST\Wampler1.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Wampler2.dat">
<Link>data\NIST\Wampler2.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Wampler3.dat">
<Link>data\NIST\Wampler3.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Wampler4.dat">
<Link>data\NIST\Wampler4.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="..\..\data\NIST\Wampler5.dat">
<Link>data\NIST\Wampler5.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="App.config" />
<None Include="..\..\data\NIST\Meixner.dat">
<Link>data\NIST\Meixner.dat</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="paket.references" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Numerics\Numerics.csproj">
<Project>{b7cae5f4-a23f-4438-b5be-41226618b695}</Project>
<Name>Numerics</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\..\packages\NUnit\lib\nunit.framework.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
</Project>

2
src/UnitTests/UseLinearAlgebraProvider.cs

@ -43,6 +43,8 @@ namespace MathNet.Numerics.UnitTests
Control.UseNativeMKL();
#elif CUDA
Control.UseNativeCUDA();
#elif OPENBLAS
Control.UseNativeOpenBLAS();
#endif
#endif
}

Loading…
Cancel
Save