diff --git a/.gitignore b/.gitignore
index c11ecba8..805eda64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,8 +10,4 @@ _ReSharper*
bin
*.vsdoc
*.XML
-Version1.cs
-src/Numerics/Algorithms/LinearAlgebra/Mkl/*.cs
-src/Numerics/Algorithms/LinearAlgebra/Acml/*.cs
-src/Numerics/Algorithms/LinearAlgebra/GotoBlas/*.cs
out
\ No newline at end of file
diff --git a/build/t4.bat b/build/t4.bat
deleted file mode 100644
index 0d11a9b7..00000000
--- a/build/t4.bat
+++ /dev/null
@@ -1,36 +0,0 @@
-IF DEFINED CommonProgramFiles(x86) GOTO x64
-
-:x86
-SET common=%CommonProgramFiles%
-GOTO prepare
-
-:x64
-SET common=%CommonProgramFiles(x86)%
-GOTO prepare
-
-:prepare
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Version.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Version.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Silverlight\Version.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Silverlight\Version.tt
-
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Common.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Common.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Complex.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Complex.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Complex32.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.Complex32.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.double.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.double.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.float.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\MklLinearAlgebraProvider.float.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\SafeNativeMethods.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Mkl\SafeNativeMethods.tt
-
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Common.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Common.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Complex.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Complex.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Complex32.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.Complex32.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.double.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.double.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.float.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\GotoBlasLinearAlgebraProvider.float.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\SafeNativeMethods.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\GotoBlas\SafeNativeMethods.tt
-
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Common.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Common.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Complex.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Complex.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Complex32.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.Complex32.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.double.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.double.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.float.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Acml\AcmlLinearAlgebraProvider.float.tt
-"%common%\Microsoft Shared\TextTemplating\10.0\texttransform.exe" -out ..\src\Numerics\Algorithms\LinearAlgebra\Acml\SafeNativeMethods.cs -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" ..\src\Numerics\Algorithms\LinearAlgebra\Acml\SafeNativeMethods.tt
-
-set common =
\ No newline at end of file
diff --git a/src/FSharp/AssemblyInfo.tt b/src/FSharp/AssemblyInfo.tt
deleted file mode 100644
index 57fe2cef..00000000
--- a/src/FSharp/AssemblyInfo.tt
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// 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 Math.NET
-//
-// Permission is hereby granted, free of charge, to any person
-// obtaining a copy of this software and associated documentation
-// files (the "Software"), to deal in the Software without
-// restriction, including without limitation the rights to use,
-// copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following
-// conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-//
-
-namespace MathNet.Numerics
-
-open System.Reflection
-open System.Resources;
-open System.Runtime.CompilerServices
-open System.Runtime.InteropServices
-
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-[]
-
-<#@ template Language="C#"#>
-<# DateTime date = DateTime.UtcNow; #>
-[.<#=date.Month.ToString("0#")#>.<#=date.Day#>.<#=(int)date.TimeOfDay.TotalMinutes#>")>]
-[.<#=date.Month.ToString("0#")#>.<#=date.Day#>.<#=(int)date.TimeOfDay.TotalMinutes#>")>]
-
-()
diff --git a/src/MathNet.Numerics.5.1.ReSharper b/src/MathNet.Numerics.5.1.ReSharper
index c180a3c1..7df958a2 100644
--- a/src/MathNet.Numerics.5.1.ReSharper
+++ b/src/MathNet.Numerics.5.1.ReSharper
@@ -87,7 +87,8 @@ Silverlight
namespace
da
Dont
-Blas
+Blas
+Acml
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Common.tt b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Common.tt
deleted file mode 100644
index b24683c1..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Common.tt
+++ /dev/null
@@ -1,7 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Acml";#>
-<# string title = "AMD Core Math Library (ACML)";#>
-<# string dataType = "Common";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex.cs b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex.cs
new file mode 100644
index 00000000..fa88f11d
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex.cs
@@ -0,0 +1,1089 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Acml
+{
+ using System;
+ using System.Numerics;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// AMD Core Math Library (ACML) linear algebra provider.
+ ///
+ public partial class AcmlLinearAlgebraProvider : ManagedLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == Complex.Zero)
+ {
+ return;
+ }
+
+ SafeNativeMethods.z_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == Complex.One)
+ {
+ return;
+ }
+
+ SafeNativeMethods.z_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to Complex.One and beta set to Complex.Zero, and x and y are not transposed.
+ public override void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex.Zero, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, int rowsA, int columnsA, Complex[] b, int rowsB, int columnsB, Complex beta, Complex[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.z_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always Complex.One
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(Complex[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.z_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new Complex[order];
+ SafeNativeMethods.z_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new Complex[order];
+ SafeNativeMethods.z_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex[] a, int order, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex[] a, int order, int[] ipiv, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(Complex[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.z_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new Complex[columnsR * Control.BlockSize];
+ SafeNativeMethods.z_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau, Complex[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new Complex[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x, Complex[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ var work = new Complex[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new Complex[Math.Min(rowsA, columnsA)];
+ var u = new Complex[rowsA * rowsA];
+ var vt = new Complex[columnsA * columnsA];
+
+ var clone = new Complex[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
+ }
+
+ if (work.Length < (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);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex.tt b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex.tt
deleted file mode 100644
index 344ec72f..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex.tt
+++ /dev/null
@@ -1,13 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Acml";#>
-<# string title = "AMD Core Math Library (ACML)";#>
-<# string dataType = "Complex";#>
-<# string zero = "Complex.Zero";#>
-<# string one = "Complex.One";#>
-<# string prefix = "z";#>
-<# string svd_work = "2 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex32.cs b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex32.cs
new file mode 100644
index 00000000..0cbbc22d
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex32.cs
@@ -0,0 +1,1096 @@
+//
+// 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.
+//
+
+/* This file is automatically generated - do not modify it.
+ Last generated on UTC 2011-04-17 06:45:26Z
+*/
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Acml
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// AMD Core Math Library (ACML) linear algebra provider.
+ ///
+ public partial class AcmlLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == Complex32.Zero)
+ {
+ return;
+ }
+
+ SafeNativeMethods.c_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == Complex32.One)
+ {
+ return;
+ }
+
+ SafeNativeMethods.c_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to Complex32.One and beta set to Complex32.Zero, and x and y are not transposed.
+ public override void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex32.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex32.Zero, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, int rowsA, int columnsA, Complex32[] b, int rowsB, int columnsB, Complex32 beta, Complex32[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.c_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always Complex32.One
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(Complex32[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.c_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex32[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new Complex32[order];
+ SafeNativeMethods.c_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new Complex32[order];
+ SafeNativeMethods.c_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex32[] a, int order, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(Complex32[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.c_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new Complex32[columnsR * Control.BlockSize];
+ SafeNativeMethods.c_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau, Complex32[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new Complex32[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ var work = new Complex32[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new Complex32[Math.Min(rowsA, columnsA)];
+ var u = new Complex32[rowsA * rowsA];
+ var vt = new Complex32[columnsA * columnsA];
+
+ var clone = new Complex32[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
+ }
+
+ if (work.Length < (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);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex32.tt b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex32.tt
deleted file mode 100644
index abbe1f5b..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.Complex32.tt
+++ /dev/null
@@ -1,13 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Acml";#>
-<# string title = "AMD Core Math Library (ACML)";#>
-<# string dataType = "Complex32";#>
-<# string zero = "Complex32.Zero";#>
-<# string one = "Complex32.One";#>
-<# string prefix = "c";#>
-<# string svd_work = "2 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.double.cs b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.double.cs
new file mode 100644
index 00000000..66442c58
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.double.cs
@@ -0,0 +1,1093 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Acml
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// AMD Core Math Library (ACML) linear algebra provider.
+ ///
+ public partial class AcmlLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == 0.0)
+ {
+ return;
+ }
+
+ SafeNativeMethods.d_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(double alpha, double[] x, double[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == 1.0)
+ {
+ return;
+ }
+
+ SafeNativeMethods.d_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to 1.0 and beta set to 0.0, and x and y are not transposed.
+ public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.d_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always 1.0
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(double[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.d_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(double[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new double[order];
+ SafeNativeMethods.d_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(double[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new double[order];
+ SafeNativeMethods.d_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(double[] a, int order, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(double[] a, int order, int[] ipiv, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, double[] a, int order, double[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(double[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.d_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(double[] a, int orderA, double[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new double[columnsR * Control.BlockSize];
+ SafeNativeMethods.d_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau, double[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new double[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x, double[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ 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))];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new double[Math.Min(rowsA, columnsA)];
+ var u = new double[rowsA * rowsA];
+ var vt = new double[columnsA * columnsA];
+
+ var clone = new double[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ 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)))
+ {
+ 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);
+ }
+
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.double.tt b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.double.tt
deleted file mode 100644
index 07105f25..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.double.tt
+++ /dev/null
@@ -1,13 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Acml";#>
-<# string title = "AMD Core Math Library (ACML)";#>
-<# string dataType = "double";#>
-<# string zero = "0.0";#>
-<# string one = "1.0";#>
-<# string prefix = "d";#>
-<# string svd_work = "Math.Max((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5 * Math.Min(rowsA, columnsA))";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.float.cs b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.float.cs
new file mode 100644
index 00000000..4e394c37
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.float.cs
@@ -0,0 +1,1092 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Acml
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// AMD Core Math Library (ACML) linear algebra provider.
+ ///
+ public partial class AcmlLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == 0.0f)
+ {
+ return;
+ }
+
+ SafeNativeMethods.s_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(float alpha, float[] x, float[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == 1.0f)
+ {
+ return;
+ }
+
+ SafeNativeMethods.s_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to 1.0f and beta set to 0.0f, and x and y are not transposed.
+ public override void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0f, x, rowsX, columnsX, y, rowsY, columnsY, 0.0f, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, int rowsA, int columnsA, float[] b, int rowsB, int columnsB, float beta, float[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.s_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always 1.0f
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(float[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.s_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(float[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new float[order];
+ SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(float[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new float[order];
+ SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(float[] a, int order, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(float[] a, int order, int[] ipiv, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, float[] a, int order, float[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(float[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.s_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(float[] a, int orderA, float[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new float[columnsR * Control.BlockSize];
+ SafeNativeMethods.s_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau, float[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new float[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x, float[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ 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))];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new float[Math.Min(rowsA, columnsA)];
+ var u = new float[rowsA * rowsA];
+ var vt = new float[columnsA * columnsA];
+
+ var clone = new float[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ 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)))
+ {
+ 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);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.float.tt b/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.float.tt
deleted file mode 100644
index 64815dfa..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Acml/AcmlLinearAlgebraProvider.float.tt
+++ /dev/null
@@ -1,13 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Acml";#>
-<# string title = "AMD Core Math Library (ACML)";#>
-<# string dataType = "float";#>
-<# string zero = "0.0f";#>
-<# string one = "1.0f";#>
-<# string prefix = "s";#>
-<# string svd_work = "Math.Max((3 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)), 5 * Math.Min(rowsA, columnsA))";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/safe.native.common.include b/src/Numerics/Algorithms/LinearAlgebra/Acml/SafeNativeMethods.cs
similarity index 94%
rename from src/Numerics/Algorithms/LinearAlgebra/safe.native.common.include
rename to src/Numerics/Algorithms/LinearAlgebra/Acml/SafeNativeMethods.cs
index c0d681a2..b56c2306 100644
--- a/src/Numerics/Algorithms/LinearAlgebra/safe.native.common.include
+++ b/src/Numerics/Algorithms/LinearAlgebra/Acml/SafeNativeMethods.cs
@@ -26,15 +26,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-/* This file is automatically generated - do not modify it.
- Last generated on UTC <#=DateTime.UtcNow.ToString("u")#>
-*/
-
using System.Numerics;
using System.Runtime.InteropServices;
using System.Security;
-namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#= namespaceSuffix #>
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Acml
{
///
/// P/Invoke methods to the native math libraries.
@@ -46,7 +42,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#= namespaceSuffix #>
///
/// Name of the native DLL.
///
- private const string DllName = "MathNET.Numerics.<#=library#>.dll";
+ private const string DllName = "MathNET.Numerics.ACML.dll";
#region BLAS
@@ -247,15 +243,17 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#= namespaceSuffix #>
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 compute_vectors, 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);
+ 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 compute_vectors, 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);
+ 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 compute_vectors, 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);
+ 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 compute_vectors, 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);
+ 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
+ }
+}
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Acml/SafeNativeMethods.tt b/src/Numerics/Algorithms/LinearAlgebra/Acml/SafeNativeMethods.tt
deleted file mode 100644
index 93d0dfac..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Acml/SafeNativeMethods.tt
+++ /dev/null
@@ -1,8 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string namespaceSuffix = "Acml";
- string library = "ACML";
-#>
-<#@ include file="..\safe.native.common.include" #>
- }
-}
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/native.norm.include b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Common.cs
similarity index 87%
rename from src/Numerics/Algorithms/LinearAlgebra/native.norm.include
rename to src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Common.cs
index e59856ab..3b5722b0 100644
--- a/src/Numerics/Algorithms/LinearAlgebra/native.norm.include
+++ b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Common.cs
@@ -1,4 +1,46 @@
- ///
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.GotoBlas
+{
+ using System;
+ using System.Numerics;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// GotoBLAS2 linear algebra provider.
+ ///
+ public partial class GotoBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider
+ {
+ ///
/// Computes the requested of the matrix.
///
/// The type of norm to compute.
@@ -316,4 +358,6 @@
}
return SafeNativeMethods.z_matrix_norm((byte)norm, rows, columns, matrix, work);
- }
\ No newline at end of file
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Common.tt b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Common.tt
deleted file mode 100644
index 91e61696..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Common.tt
+++ /dev/null
@@ -1,8 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "GotoBlas";#>
-<# string title = "GotoBLAS2";#>
-<# string dataType = "Common";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.norm.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/native.generic.include b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex.cs
similarity index 82%
rename from src/Numerics/Algorithms/LinearAlgebra/native.generic.include
rename to src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex.cs
index 1ee54ed2..705a1d30 100644
--- a/src/Numerics/Algorithms/LinearAlgebra/native.generic.include
+++ b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex.cs
@@ -1,4 +1,46 @@
- ///
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.GotoBlas
+{
+ using System;
+ using System.Numerics;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// GotoBLAS2 linear algebra provider.
+ ///
+ public partial class GotoBlasLinearAlgebraProvider
+ {
+ ///
/// Adds a scaled vector to another: result = y + alpha*x.
///
/// The vector to update.
@@ -7,7 +49,7 @@
/// The result of the addition.
/// This is similar to the AXPY BLAS routine.
[SecuritySafeCritical]
- public override void AddVectorToScaledVector(<#=dataType#>[] y, <#=dataType#> alpha, <#=dataType#>[] x, <#=dataType#>[] result)
+ public override void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result)
{
if (y == null)
{
@@ -29,12 +71,12 @@
Array.Copy(y, 0, result, 0, y.Length);
}
- if (alpha == <#=zero#>)
+ if (alpha == Complex.Zero)
{
return;
}
- SafeNativeMethods.<#=prefix#>_axpy(y.Length, alpha, x, result);
+ SafeNativeMethods.z_axpy(y.Length, alpha, x, result);
}
///
@@ -45,7 +87,7 @@
/// This result of the scaling.
/// This is similar to the SCAL BLAS routine.
[SecuritySafeCritical]
- public override void ScaleArray(<#=dataType#> alpha, <#=dataType#>[] x, <#=dataType#>[] result)
+ public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{
if (x == null)
{
@@ -57,12 +99,12 @@
Array.Copy(x, 0, result, 0, x.Length);
}
- if (alpha == <#=one#>)
+ if (alpha == Complex.One)
{
return;
}
- SafeNativeMethods.<#=prefix#>_scale(x.Length, alpha, result);
+ SafeNativeMethods.z_scale(x.Length, alpha, result);
}
///
@@ -76,10 +118,10 @@
/// The number of columns in the y matrix.
/// Where to store the result of the multiplication.
/// This is a simplified version of the BLAS GEMM routine with alpha
- /// set to <#=one#> and beta set to <#=zero#>, and x and y are not transposed.
- public override void MatrixMultiply(<#=dataType#>[] x, int rowsX, int columnsX, <#=dataType#>[] y, int rowsY, int columnsY, <#=dataType#>[] result)
+ /// set to Complex.One and beta set to Complex.Zero, and x and y are not transposed.
+ public override void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result)
{
- MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, <#=one#>, x, rowsX, columnsX, y, rowsY, columnsY, <#=zero#>, result);
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex.Zero, result);
}
///
@@ -97,7 +139,7 @@
/// The value to scale the matrix.
/// The c matrix.
[SecuritySafeCritical]
- public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, <#=dataType#> alpha, <#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] b, int rowsB, int columnsB, <#=dataType#> beta, <#=dataType#>[] c)
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, int rowsA, int columnsA, Complex[] b, int rowsB, int columnsB, Complex beta, Complex[] c)
{
if (a == null)
{
@@ -129,20 +171,20 @@
throw new ArgumentException(Resources.ArgumentMatrixDimensions);
}
- SafeNativeMethods.<#=prefix#>_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ SafeNativeMethods.z_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
}
///
/// Computes the LUP factorization of A. P*A = L*U.
///
/// An by matrix. The matrix is overwritten with the
- /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always <#=one#>
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always Complex.One
/// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
/// The order of the square matrix .
/// On exit, it contains the pivot indices. The size of the array must be .
/// This is equivalent to the GETRF LAPACK routine.
[SecuritySafeCritical]
- public override void LUFactor(<#=dataType#>[] data, int order, int[] ipiv)
+ public override void LUFactor(Complex[] data, int order, int[] ipiv)
{
if (data == null)
{
@@ -164,7 +206,7 @@
throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
}
- SafeNativeMethods.<#=prefix#>_lu_factor(order, data, ipiv);
+ SafeNativeMethods.z_lu_factor(order, data, ipiv);
}
///
@@ -174,7 +216,7 @@
/// The order of the square matrix .
/// This is equivalent to the GETRF and GETRI LAPACK routines.
[SecuritySafeCritical]
- public override void LUInverse(<#=dataType#>[] a, int order)
+ public override void LUInverse(Complex[] a, int order)
{
if (a == null)
{
@@ -186,19 +228,8 @@
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
- var work = new <#=dataType#>[order];
-<# if (dataType == "float") { #>
- if (Control.LinearAlgebraProvider is Algorithms.LinearAlgebra.GotoBlas.GotoBlasLinearAlgebraProvider)
- {
- new ManagedLinearAlgebraProvider().LUInverse(a, order, work);
- }
- else
- {
- SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
- }
-<# } else{#>
- SafeNativeMethods.<#=prefix#>_lu_inverse(order, a, work, work.Length);
-<# } #>
+ var work = new Complex[order];
+ SafeNativeMethods.z_lu_inverse(order, a, work, work.Length);
}
///
@@ -209,7 +240,7 @@
/// The pivot indices of .
/// This is equivalent to the GETRI LAPACK routine.
[SecuritySafeCritical]
- public override void LUInverseFactored(<#=dataType#>[] a, int order, int[] ipiv)
+ public override void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{
if (a == null)
{
@@ -231,19 +262,8 @@
throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
}
- var work = new <#=dataType#>[order];
-<# if (dataType == "float") { #>
- if (Control.LinearAlgebraProvider is Algorithms.LinearAlgebra.GotoBlas.GotoBlasLinearAlgebraProvider)
- {
- new ManagedLinearAlgebraProvider().LUInverseFactored(a, order, ipiv, work);
- }
- else
- {
- SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
- }
-<# }else{ #>
- SafeNativeMethods.<#=prefix#>_lu_inverse_factored(order, a, ipiv, work, order);
-<# } #>
+ var work = new Complex[order];
+ SafeNativeMethods.z_lu_inverse_factored(order, a, ipiv, work, order);
}
///
@@ -256,7 +276,7 @@
/// work size value.
/// This is equivalent to the GETRF and GETRI LAPACK routines.
[SecuritySafeCritical]
- public override void LUInverse(<#=dataType#>[] a, int order, <#=dataType#>[] work)
+ public override void LUInverse(Complex[] a, int order, Complex[] work)
{
if (a == null)
{
@@ -278,18 +298,7 @@
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
-<# if (dataType == "float") { #>
- if (Control.LinearAlgebraProvider is Algorithms.LinearAlgebra.GotoBlas.GotoBlasLinearAlgebraProvider)
- {
- new ManagedLinearAlgebraProvider().LUInverse(a, order, work);
- }
- else
- {
- SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
- }
-<# } else{#>
- SafeNativeMethods.<#=prefix#>_lu_inverse(order, a, work, work.Length);
-<# } #>
+ SafeNativeMethods.z_lu_inverse(order, a, work, work.Length);
}
///
@@ -303,7 +312,7 @@
/// work size value.
/// This is equivalent to the GETRI LAPACK routine.
[SecuritySafeCritical]
- public override void LUInverseFactored(<#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] work)
+ public override void LUInverseFactored(Complex[] a, int order, int[] ipiv, Complex[] work)
{
if (a == null)
{
@@ -335,18 +344,7 @@
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
-<# if (dataType == "float") { #>
- if (Control.LinearAlgebraProvider is Algorithms.LinearAlgebra.GotoBlas.GotoBlasLinearAlgebraProvider)
- {
- new ManagedLinearAlgebraProvider().LUInverseFactored(a, order, ipiv, work);
- }
- else
- {
- SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
- }
-<# }else{ #>
- SafeNativeMethods.<#=prefix#>_lu_inverse_factored(order, a, ipiv, work, order);
-<# } #>
+ SafeNativeMethods.z_lu_inverse_factored(order, a, ipiv, work, order);
}
///
@@ -358,7 +356,7 @@
/// On entry the B matrix; on exit the X matrix.
/// This is equivalent to the GETRF and GETRS LAPACK routines.
[SecuritySafeCritical]
- public override void LUSolve(int columnsOfB, <#=dataType#>[] a, int order, <#=dataType#>[] b)
+ public override void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b)
{
if (a == null)
{
@@ -380,7 +378,7 @@
throw new ArgumentException(Resources.ArgumentReferenceDifferent);
}
- SafeNativeMethods.<#=prefix#>_lu_solve(order, columnsOfB, a, b);
+ SafeNativeMethods.z_lu_solve(order, columnsOfB, a, b);
}
///
@@ -393,7 +391,7 @@
/// On entry the B matrix; on exit the X matrix.
/// This is equivalent to the GETRS LAPACK routine.
[SecuritySafeCritical]
- public override void LUSolveFactored(int columnsOfB, <#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] b)
+ public override void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b)
{
if (a == null)
{
@@ -425,7 +423,7 @@
throw new ArgumentException(Resources.ArgumentReferenceDifferent);
}
- SafeNativeMethods.<#=prefix#>_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ SafeNativeMethods.z_lu_solve_factored(order, columnsOfB, a, ipiv, b);
}
///
@@ -436,7 +434,7 @@
/// The number of rows or columns in the matrix.
/// This is equivalent to the POTRF LAPACK routine.
[SecuritySafeCritical]
- public override void CholeskyFactor(<#=dataType#>[] a, int order)
+ public override void CholeskyFactor(Complex[] a, int order)
{
if (a == null)
{
@@ -453,7 +451,7 @@
throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
}
- var info = SafeNativeMethods.<#=prefix#>_cholesky_factor(order, a);
+ var info = SafeNativeMethods.z_cholesky_factor(order, a);
if (info > 0)
{
@@ -471,7 +469,7 @@
/// This is equivalent to the POTRF add POTRS LAPACK routines.
///
[SecuritySafeCritical]
- public override void CholeskySolve(<#=dataType#>[] a, int orderA, <#=dataType#>[] b, int columnsB)
+ public override void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB)
{
if (a == null)
{
@@ -493,7 +491,7 @@
throw new ArgumentException(Resources.ArgumentReferenceDifferent);
}
- SafeNativeMethods.<#=prefix#>_cholesky_solve(orderA, columnsB, a, b);
+ SafeNativeMethods.z_cholesky_solve(orderA, columnsB, a, b);
}
///
@@ -505,7 +503,7 @@
/// The number of columns in the B matrix.
/// This is equivalent to the POTRS LAPACK routine.
[SecuritySafeCritical]
- public override void CholeskySolveFactored(<#=dataType#>[] a, int orderA, <#=dataType#>[] b, int columnsB)
+ public override void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB)
{
if (a == null)
{
@@ -527,7 +525,7 @@
throw new ArgumentException(Resources.ArgumentReferenceDifferent);
}
- SafeNativeMethods.<#=prefix#>_cholesky_solve_factored(orderA, columnsB, a, b);
+ SafeNativeMethods.z_cholesky_solve_factored(orderA, columnsB, a, b);
}
///
@@ -543,7 +541,7 @@
/// to be used by the QR solve routine.
/// This is similar to the GEQRF and ORGQR LAPACK routines.
[SecuritySafeCritical]
- public override void QRFactor(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] tau)
+ public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau)
{
if (r == null)
{
@@ -570,8 +568,8 @@
throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
}
- var work = new <#=dataType#>[columnsR * Control.BlockSize];
- SafeNativeMethods.<#=prefix#>_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ var work = new Complex[columnsR * Control.BlockSize];
+ SafeNativeMethods.z_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
}
///
@@ -590,7 +588,7 @@
/// work size value.
/// This is similar to the GEQRF and ORGQR LAPACK routines.
[SecuritySafeCritical]
- public override void QRFactor(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] tau, <#=dataType#>[] work)
+ public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau, Complex[] work)
{
if (r == null)
{
@@ -628,7 +626,7 @@
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
- SafeNativeMethods.<#=prefix#>_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ SafeNativeMethods.z_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
}
///
@@ -641,7 +639,7 @@
/// The number of columns of B.
/// On exit, the solution matrix.
/// Rows must be greater or equal to columns.
- public override void QRSolve(<#=dataType#>[] a, int rows, int columns, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x)
+ public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x)
{
if (a == null)
{
@@ -678,7 +676,7 @@
throw new ArgumentException(Resources.RowsLessThanColumns);
}
- var work = new <#=dataType#>[columns * Control.BlockSize];
+ var work = new Complex[columns * Control.BlockSize];
QRSolve(a, rows, columns, b, columnsB, x, work);
}
@@ -695,7 +693,7 @@
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.
/// Rows must be greater or equal to columns.
- public override void QRSolve(<#=dataType#>[] a, int rows, int columns, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x, <#=dataType#>[] work)
+ public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, Complex[] work)
{
if (a == null)
{
@@ -743,14 +741,14 @@
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
- SafeNativeMethods.<#=prefix#>_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ SafeNativeMethods.z_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
}
///
/// Solves A*X=B for X using a previously QR factored matrix.
///
- /// The Q matrix obtained by calling .
- /// The R matrix obtained by calling .
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
/// The number of rows in the A matrix.
/// The number of columns in the A matrix.
/// Contains additional information on Q. Only used for the native solver
@@ -760,7 +758,7 @@
/// On exit, the solution matrix.
/// Rows must be greater or equal to columns.
[SecuritySafeCritical]
- public override void QRSolveFactored(<#=dataType#>[] q, <#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] tau, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x)
+ public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x)
{
if (r == null)
{
@@ -807,7 +805,7 @@
throw new ArgumentException(Resources.RowsLessThanColumns);
}
- var work = new <#=dataType#>[columnsR * Control.BlockSize];
+ var work = new Complex[columnsR * Control.BlockSize];
QRSolveFactored(q, r, rowsR, columnsR, tau, b, columnsB, x, work);
}
@@ -816,7 +814,7 @@
///
/// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
/// null for the native provider. The native provider uses the Q portion stored in the R matrix.
- /// The R matrix obtained by calling .
+ /// The R matrix obtained by calling .
/// The number of rows in the A matrix.
/// The number of columns in the A matrix.
/// Contains additional information on Q. Only used for the native solver
@@ -828,7 +826,7 @@
/// but should be N*blocksize. The blocksize is machine dependent. On exit, work[0] contains the optimal
/// work size value.
/// Rows must be greater or equal to columns.
- public override void QRSolveFactored(<#=dataType#>[] q, <#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] tau, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x, <#=dataType#>[] work)
+ public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x, Complex[] work)
{
if (r == null)
{
@@ -886,7 +884,7 @@
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
- SafeNativeMethods.<#=prefix#>_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ SafeNativeMethods.z_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
}
///
@@ -903,7 +901,7 @@
/// right singular vectors.
/// This is equivalent to the GESVD LAPACK routine.
[SecuritySafeCritical]
- public override void SingularValueDecomposition(bool computeVectors, <#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt)
+ public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt)
{
if (a == null)
{
@@ -940,7 +938,7 @@
throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
}
- var work = new <#=dataType#>[<#=svd_work#>];
+ var work = new Complex[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
}
@@ -953,7 +951,7 @@
/// The B matrix.
/// The number of columns of B.
/// On exit, the solution matrix.
- public override void SvdSolve(<#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x)
+ public override void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x)
{
if (a == null)
{
@@ -980,12 +978,12 @@
throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
}
- var work = new <#=dataType#>[<#=svd_work#>];
- var s = new <#=dataType#>[Math.Min(rowsA, columnsA)];
- var u = new <#=dataType#>[rowsA * rowsA];
- var vt = new <#=dataType#>[columnsA * 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 clone = new <#=dataType#>[a.Length];
+ var clone = new Complex[a.Length];
a.Copy(clone);
SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
@@ -1008,7 +1006,7 @@
/// On exit, work[0] contains the optimal work size value.
/// This is equivalent to the GESVD LAPACK routine.
[SecuritySafeCritical]
- public override void SingularValueDecomposition(bool computeVectors, <#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] work)
+ public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] work)
{
if (a == null)
{
@@ -1055,11 +1053,13 @@
throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
}
- if (work.Length < <#=svd_work#>)
+ if (work.Length < (2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA))
{
- work[0] = <#=svd_work#>;
+ work[0] = (2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA);
throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
}
- SafeNativeMethods.<#=prefix#>_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length);
+ SafeNativeMethods.z_svd_factor(computeVectors, rowsA, columnsA, a, s, u, vt, work, work.Length);
}
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex.tt b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex.tt
deleted file mode 100644
index 48d5a776..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex.tt
+++ /dev/null
@@ -1,12 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "GotoBlas";#>
-<# string title = "GotoBLAS2";#>
-<# string dataType = "Complex";#>
-<# string zero = "Complex.Zero";#>
-<# string one = "Complex.One";#>
-<# string prefix = "z";#>
-<# string svd_work = "2 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex32.cs b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex32.cs
new file mode 100644
index 00000000..45e8eeac
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex32.cs
@@ -0,0 +1,1064 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.GotoBlas
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// GotoBLAS2 linear algebra provider.
+ ///
+ public partial class GotoBlasLinearAlgebraProvider
+ {
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == Complex32.Zero)
+ {
+ return;
+ }
+
+ SafeNativeMethods.c_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == Complex32.One)
+ {
+ return;
+ }
+
+ SafeNativeMethods.c_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to Complex32.One and beta set to Complex32.Zero, and x and y are not transposed.
+ public override void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex32.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex32.Zero, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, int rowsA, int columnsA, Complex32[] b, int rowsB, int columnsB, Complex32 beta, Complex32[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.c_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always Complex32.One
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(Complex32[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.c_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex32[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new Complex32[order];
+ SafeNativeMethods.c_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new Complex32[order];
+ SafeNativeMethods.c_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex32[] a, int order, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(Complex32[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.c_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new Complex32[columnsR * Control.BlockSize];
+ SafeNativeMethods.c_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau, Complex32[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new Complex32[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ var work = new Complex32[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new Complex32[Math.Min(rowsA, columnsA)];
+ var u = new Complex32[rowsA * rowsA];
+ var vt = new Complex32[columnsA * columnsA];
+
+ var clone = new Complex32[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
+ }
+
+ if (work.Length < (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);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex32.tt b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex32.tt
deleted file mode 100644
index 6f7dd896..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.Complex32.tt
+++ /dev/null
@@ -1,12 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "GotoBlas";#>
-<# string title = "GotoBLAS2";#>
-<# string dataType = "Complex32";#>
-<# string zero = "Complex32.Zero";#>
-<# string one = "Complex32.One";#>
-<# string prefix = "c";#>
-<# string svd_work = "2 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.double.cs b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.double.cs
new file mode 100644
index 00000000..29824847
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.double.cs
@@ -0,0 +1,1064 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.GotoBlas
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// GotoBLAS2 linear algebra provider.
+ ///
+ public partial class GotoBlasLinearAlgebraProvider
+ {
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == 0.0)
+ {
+ return;
+ }
+
+ SafeNativeMethods.d_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(double alpha, double[] x, double[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == 1.0)
+ {
+ return;
+ }
+
+ SafeNativeMethods.d_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to 1.0 and beta set to 0.0, and x and y are not transposed.
+ public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.d_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always 1.0
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(double[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.d_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(double[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new double[order];
+ SafeNativeMethods.d_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(double[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new double[order];
+ SafeNativeMethods.d_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(double[] a, int order, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(double[] a, int order, int[] ipiv, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, double[] a, int order, double[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(double[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.d_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(double[] a, int orderA, double[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new double[columnsR * Control.BlockSize];
+ SafeNativeMethods.d_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau, double[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new double[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x, double[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ 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))];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new double[Math.Min(rowsA, columnsA)];
+ var u = new double[rowsA * rowsA];
+ var vt = new double[columnsA * columnsA];
+
+ var clone = new double[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ 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)))
+ {
+ 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);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.double.tt b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.double.tt
deleted file mode 100644
index a8588b7a..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.double.tt
+++ /dev/null
@@ -1,12 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "GotoBlas";#>
-<# string title = "GotoBLAS2";#>
-<# string dataType = "double";#>
-<# string zero = "0.0";#>
-<# string one = "1.0";#>
-<# string prefix = "d";#>
-<# string svd_work = "Math.Max((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5 * Math.Min(rowsA, columnsA))";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.float.cs b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.float.cs
new file mode 100644
index 00000000..5dc75c37
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.float.cs
@@ -0,0 +1,1064 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.GotoBlas
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// GotoBLAS2 linear algebra provider.
+ ///
+ public partial class GotoBlasLinearAlgebraProvider
+ {
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == 0.0f)
+ {
+ return;
+ }
+
+ SafeNativeMethods.s_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(float alpha, float[] x, float[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == 1.0f)
+ {
+ return;
+ }
+
+ SafeNativeMethods.s_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to 1.0f and beta set to 0.0f, and x and y are not transposed.
+ public override void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0f, x, rowsX, columnsX, y, rowsY, columnsY, 0.0f, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, int rowsA, int columnsA, float[] b, int rowsB, int columnsB, float beta, float[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.s_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always 1.0f
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(float[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.s_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(float[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new float[order];
+ SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(float[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new float[order];
+ SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(float[] a, int order, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(float[] a, int order, int[] ipiv, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, float[] a, int order, float[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(float[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.s_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(float[] a, int orderA, float[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new float[columnsR * Control.BlockSize];
+ SafeNativeMethods.s_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau, float[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new float[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x, float[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ 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))];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new float[Math.Min(rowsA, columnsA)];
+ var u = new float[rowsA * rowsA];
+ var vt = new float[columnsA * columnsA];
+
+ var clone = new float[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ 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)))
+ {
+ 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);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.float.tt b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.float.tt
deleted file mode 100644
index 542d243e..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/GotoBlasLinearAlgebraProvider.float.tt
+++ /dev/null
@@ -1,12 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "GotoBlas";#>
-<# string title = "GotoBLAS2";#>
-<# string dataType = "float";#>
-<# string zero = "0.0f";#>
-<# string one = "1.0f";#>
-<# string prefix = "s";#>
-<# string svd_work = "Math.Max((3 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)), 5 * Math.Min(rowsA, columnsA))";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/SafeNativeMethods.cs b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/SafeNativeMethods.cs
new file mode 100644
index 00000000..25803fc7
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/SafeNativeMethods.cs
@@ -0,0 +1,259 @@
+//
+// 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.
+//
+
+using System.Numerics;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.GotoBlas
+{
+ ///
+ /// P/Invoke methods to the native math libraries.
+ ///
+ [SuppressUnmanagedCodeSecurity]
+ [SecurityCritical]
+ internal static class SafeNativeMethods
+ {
+ ///
+ /// Name of the native DLL.
+ ///
+ private 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
+ }
+}
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/SafeNativeMethods.tt b/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/SafeNativeMethods.tt
deleted file mode 100644
index f9e0aa4a..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/GotoBlas/SafeNativeMethods.tt
+++ /dev/null
@@ -1,8 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string namespaceSuffix = "GotoBlas";
- string library = "GotoBLAS2";
-#>
-<#@ include file="..\safe.native.common.include" #>
- }
-}
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.cs b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.cs
new file mode 100644
index 00000000..d6eea59e
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.cs
@@ -0,0 +1,363 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
+{
+ using System;
+ using System.Numerics;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// Intel's Math Kernel Library (MKL) linear algebra provider.
+ ///
+ public partial class MklLinearAlgebraProvider : ManagedLinearAlgebraProvider
+ {
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ /// The work array. Only used when
+ /// and needs to be have a length of at least M (number of rows of .
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ /// The work array. Only used when
+ /// and needs to be have a length of at least M (number of rows of .
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ /// The work array. Only used when
+ /// and needs to be have a length of at least M (number of rows of .
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+
+ ///
+ /// Computes the requested of the matrix.
+ ///
+ /// The type of norm to compute.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The matrix to compute the norm from.
+ /// The work array. Only used when
+ /// and needs to be have a length of at least M (number of rows of .
+ ///
+ /// The requested of the matrix.
+ ///
+ [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);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.tt
deleted file mode 100644
index a905fa61..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.tt
+++ /dev/null
@@ -1,8 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Mkl";#>
-<# string title = "Intel's Math Kernel Library (MKL)";#>
-<# string dataType = "Common";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.norm.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs
new file mode 100644
index 00000000..f3fd66e5
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.cs
@@ -0,0 +1,1233 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
+{
+ using System;
+ using System.Numerics;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// Intel's Math Kernel Library (MKL) linear algebra provider.
+ ///
+ public partial class MklLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == Complex.Zero)
+ {
+ return;
+ }
+
+ SafeNativeMethods.z_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == Complex.One)
+ {
+ return;
+ }
+
+ SafeNativeMethods.z_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to Complex.One and beta set to Complex.Zero, and x and y are not transposed.
+ public override void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex.Zero, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, int rowsA, int columnsA, Complex[] b, int rowsB, int columnsB, Complex beta, Complex[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.z_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always Complex.One
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(Complex[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.z_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new Complex[order];
+ SafeNativeMethods.z_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new Complex[order];
+ SafeNativeMethods.z_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex[] a, int order, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex[] a, int order, int[] ipiv, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(Complex[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.z_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.z_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new Complex[columnsR * Control.BlockSize];
+ SafeNativeMethods.z_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau, Complex[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new Complex[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsR, int columnsR, Complex[] tau, Complex[] b, int columnsB, Complex[] x, Complex[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.z_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ var work = new Complex[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new Complex[Math.Min(rowsA, columnsA)];
+ var u = new Complex[rowsA * rowsA];
+ var vt = new Complex[columnsA * columnsA];
+
+ var clone = new Complex[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
+ }
+
+ if (work.Length < (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);
+ }
+
+ ///
+ /// Does a point wise add of two arrays z = x + y. This can be used
+ /// to add vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the addition.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void AddArrays(Complex[] x, Complex[] y, Complex[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.z_vector_add(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise subtraction of two arrays z = x - y. This can be used
+ /// to subtract vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the subtraction.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.z_vector_subtract(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise multiplication of two arrays z = x * y. This can be used
+ /// to multiple elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise multiplication.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.z_vector_multiply(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.z_vector_divide(x.Length, x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.tt
deleted file mode 100644
index 47c43d44..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.tt
+++ /dev/null
@@ -1,14 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Mkl";#>
-<# string title = "Intel's Math Kernel Library (MKL)";#>
-<# string dataType = "Complex";#>
-<# string zero = "Complex.Zero";#>
-<# string one = "Complex.One";#>
-<# string prefix = "z";#>
-<# string svd_work = "2 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.vector.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs
new file mode 100644
index 00000000..95fba8cf
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.cs
@@ -0,0 +1,1232 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// Intel's Math Kernel Library (MKL) linear algebra provider.
+ ///
+ public partial class MklLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == Complex32.Zero)
+ {
+ return;
+ }
+
+ SafeNativeMethods.c_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == Complex32.One)
+ {
+ return;
+ }
+
+ SafeNativeMethods.c_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to Complex32.One and beta set to Complex32.Zero, and x and y are not transposed.
+ public override void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex32.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex32.Zero, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, int rowsA, int columnsA, Complex32[] b, int rowsB, int columnsB, Complex32 beta, Complex32[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.c_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always Complex32.One
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(Complex32[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.c_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex32[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new Complex32[order];
+ SafeNativeMethods.c_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new Complex32[order];
+ SafeNativeMethods.c_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(Complex32[] a, int order, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(Complex32[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.c_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.c_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new Complex32[columnsR * Control.BlockSize];
+ SafeNativeMethods.c_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau, Complex32[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new Complex32[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsR, int columnsR, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, Complex32[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.c_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ var work = new Complex32[(2 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA)];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new Complex32[Math.Min(rowsA, columnsA)];
+ var u = new Complex32[rowsA * rowsA];
+ var vt = new Complex32[columnsA * columnsA];
+
+ var clone = new Complex32[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ throw new ArgumentException(Resources.ArgumentSingleDimensionArray, "work");
+ }
+
+ if (work.Length < (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);
+ }
+
+ ///
+ /// Does a point wise add of two arrays z = x + y. This can be used
+ /// to add vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the addition.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.c_vector_add(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise subtraction of two arrays z = x - y. This can be used
+ /// to subtract vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the subtraction.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.c_vector_subtract(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise multiplication of two arrays z = x * y. This can be used
+ /// to multiple elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise multiplication.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.c_vector_multiply(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.c_vector_divide(x.Length, x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.tt
deleted file mode 100644
index 5a090ced..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.tt
+++ /dev/null
@@ -1,14 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Mkl";#>
-<# string title = "Intel's Math Kernel Library (MKL)";#>
-<# string dataType = "Complex32";#>
-<# string zero = "Complex32.Zero";#>
-<# string one = "Complex32.One";#>
-<# string prefix = "c";#>
-<# string svd_work = "2 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.vector.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.cs b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.cs
new file mode 100644
index 00000000..e7236f26
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.cs
@@ -0,0 +1,1232 @@
+//
+// 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.
+//
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// Intel's Math Kernel Library (MKL) linear algebra provider.
+ ///
+ public partial class MklLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == 0.0)
+ {
+ return;
+ }
+
+ SafeNativeMethods.d_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(double alpha, double[] x, double[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == 1.0)
+ {
+ return;
+ }
+
+ SafeNativeMethods.d_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to 1.0 and beta set to 0.0, and x and y are not transposed.
+ public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.d_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always 1.0
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(double[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.d_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(double[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new double[order];
+ SafeNativeMethods.d_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(double[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new double[order];
+ SafeNativeMethods.d_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(double[] a, int order, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(double[] a, int order, int[] ipiv, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, double[] a, int order, double[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(double[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.d_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(double[] a, int orderA, double[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.d_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new double[columnsR * Control.BlockSize];
+ SafeNativeMethods.d_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau, double[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new double[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(double[] q, double[] r, int rowsR, int columnsR, double[] tau, double[] b, int columnsB, double[] x, double[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.d_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ 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))];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new double[Math.Min(rowsA, columnsA)];
+ var u = new double[rowsA * rowsA];
+ var vt = new double[columnsA * columnsA];
+
+ var clone = new double[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ 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)))
+ {
+ 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);
+ }
+
+ ///
+ /// Does a point wise add of two arrays z = x + y. This can be used
+ /// to add vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the addition.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void AddArrays(double[] x, double[] y, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.d_vector_add(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise subtraction of two arrays z = x - y. This can be used
+ /// to subtract vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the subtraction.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void SubtractArrays(double[] x, double[] y, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.d_vector_subtract(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise multiplication of two arrays z = x * y. This can be used
+ /// to multiple elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise multiplication.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.d_vector_multiply(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseDivideArrays(double[] x, double[] y, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.d_vector_divide(x.Length, x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.tt
deleted file mode 100644
index c56166e4..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.tt
+++ /dev/null
@@ -1,14 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Mkl";#>
-<# string title = "Intel's Math Kernel Library (MKL)";#>
-<# string dataType = "double";#>
-<# string zero = "0.0";#>
-<# string one = "1.0";#>
-<# string prefix = "d";#>
-<# string svd_work = "Math.Max((3 * Math.Min(rowsA, columnsA)) + Math.Max(rowsA, columnsA), 5 * Math.Min(rowsA, columnsA))";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.vector.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.cs b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.cs
new file mode 100644
index 00000000..a95d3e38
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.cs
@@ -0,0 +1,1236 @@
+//
+// 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.
+//
+
+/* This file is automatically generated - do not modify it.
+ Last generated on UTC 2011-04-17 06:45:23Z
+*/
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
+{
+ using System;
+ using System.Security;
+ using Properties;
+
+ ///
+ /// Intel's Math Kernel Library (MKL) linear algebra provider.
+ ///
+ public partial class MklLinearAlgebraProvider
+ {
+ ///
+ /// Computes the dot product of x and y.
+ ///
+ /// The vector x.
+ /// The vector y.
+ /// The dot product of x and y.
+ /// This is equivalent to the DOT BLAS routine.
+ [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);
+ }
+
+ ///
+ /// Adds a scaled vector to another: result = y + alpha*x.
+ ///
+ /// The vector to update.
+ /// The value to scale by.
+ /// The vector to add to .
+ /// The result of the addition.
+ /// This is similar to the AXPY BLAS routine.
+ [SecuritySafeCritical]
+ public override void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (y.Length != x.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ if (!ReferenceEquals(y, result))
+ {
+ Array.Copy(y, 0, result, 0, y.Length);
+ }
+
+ if (alpha == 0.0f)
+ {
+ return;
+ }
+
+ SafeNativeMethods.s_axpy(y.Length, alpha, x, result);
+ }
+
+ ///
+ /// Scales an array. Can be used to scale a vector and a matrix.
+ ///
+ /// The scalar.
+ /// The values to scale.
+ /// This result of the scaling.
+ /// This is similar to the SCAL BLAS routine.
+ [SecuritySafeCritical]
+ public override void ScaleArray(float alpha, float[] x, float[] result)
+ {
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (!ReferenceEquals(x, result))
+ {
+ Array.Copy(x, 0, result, 0, x.Length);
+ }
+
+ if (alpha == 1.0f)
+ {
+ return;
+ }
+
+ SafeNativeMethods.s_scale(x.Length, alpha, result);
+ }
+
+ ///
+ /// Multiples two matrices. result = x * y
+ ///
+ /// The x matrix.
+ /// The number of rows in the x matrix.
+ /// The number of columns in the x matrix.
+ /// The y matrix.
+ /// The number of rows in the y matrix.
+ /// The number of columns in the y matrix.
+ /// Where to store the result of the multiplication.
+ /// This is a simplified version of the BLAS GEMM routine with alpha
+ /// set to 1.0f and beta set to 0.0f, and x and y are not transposed.
+ public override void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result)
+ {
+ MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0f, x, rowsX, columnsX, y, rowsY, columnsY, 0.0f, result);
+ }
+
+ ///
+ /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c
+ ///
+ /// How to transpose the matrix.
+ /// How to transpose the matrix.
+ /// The value to scale matrix.
+ /// The a matrix.
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The b matrix
+ /// The number of rows in the matrix.
+ /// The number of columns in the matrix.
+ /// The value to scale the matrix.
+ /// The c matrix.
+ [SecuritySafeCritical]
+ public override void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, int rowsA, int columnsA, float[] b, int rowsB, int columnsB, float beta, float[] c)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (c == null)
+ {
+ throw new ArgumentNullException("c");
+ }
+
+ var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA;
+ var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB;
+ var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA;
+ var l = transposeB == Transpose.DontTranspose ? rowsB : columnsB;
+
+ if (c.Length != m * n)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ if (k != l)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ }
+
+ SafeNativeMethods.s_matrix_multiply(transposeA, transposeB, m, n, k, alpha, a, b, beta, c);
+ }
+
+ ///
+ /// Computes the LUP factorization of A. P*A = L*U.
+ ///
+ /// An by matrix. The matrix is overwritten with the
+ /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always 1.0f
+ /// for the L factor). The upper triangular factor U is stored on and above the diagonal of .
+ /// The order of the square matrix .
+ /// On exit, it contains the pivot indices. The size of the array must be .
+ /// This is equivalent to the GETRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUFactor(float[] data, int order, int[] ipiv)
+ {
+ if (data == null)
+ {
+ throw new ArgumentNullException("data");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (data.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "data");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ SafeNativeMethods.s_lu_factor(order, data, ipiv);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(float[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var work = new float[order];
+ SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(float[] a, int order, int[] ipiv)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ var work = new float[order];
+ SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Computes the inverse of matrix using LU factorization.
+ ///
+ /// The N by N matrix to invert. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// 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.
+ /// This is equivalent to the GETRF and GETRI LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUInverse(float[] a, int order, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_lu_inverse(order, a, work, work.Length);
+ }
+
+ ///
+ /// Computes the inverse of a previously factored matrix.
+ ///
+ /// The LU factored N by N matrix. Contains the inverse On exit.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// 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.
+ /// This is equivalent to the GETRI LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUInverseFactored(float[] a, int order, int[] ipiv, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (work.Length < order)
+ {
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_lu_inverse_factored(order, a, ipiv, work, order);
+ }
+
+ ///
+ /// Solves A*X=B for X using LU factorization.
+ ///
+ /// The number of columns of B.
+ /// The square matrix A.
+ /// The order of the square matrix .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRF and GETRS LAPACK routines.
+ [SecuritySafeCritical]
+ public override void LUSolve(int columnsOfB, float[] a, int order, float[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_lu_solve(order, columnsOfB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The number of columns of B.
+ /// The factored A matrix.
+ /// The order of the square matrix .
+ /// The pivot indices of .
+ /// On entry the B matrix; on exit the X matrix.
+ /// This is equivalent to the GETRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (ipiv == null)
+ {
+ throw new ArgumentNullException("ipiv");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (ipiv.Length != order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "ipiv");
+ }
+
+ if (b.Length != columnsOfB * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_lu_solve_factored(order, columnsOfB, a, ipiv, b);
+ }
+
+ ///
+ /// Computes the Cholesky factorization of A.
+ ///
+ /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the
+ /// the Cholesky factorization.
+ /// The number of rows or columns in the matrix.
+ /// This is equivalent to the POTRF LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskyFactor(float[] a, int order)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (order < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "order");
+ }
+
+ if (a.Length != order * order)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ var info = SafeNativeMethods.s_cholesky_factor(order, a);
+
+ if (info > 0)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite);
+ }
+ }
+
+ ///
+ /// Solves A*X=B for X using Cholesky factorization.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRF add POTRS LAPACK routines.
+ ///
+ [SecuritySafeCritical]
+ public override void CholeskySolve(float[] a, int orderA, float[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_cholesky_solve(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously factored A matrix.
+ ///
+ /// The square, positive definite matrix A.
+ /// The number of rows and columns in A.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns in the B matrix.
+ /// This is equivalent to the POTRS LAPACK routine.
+ [SecuritySafeCritical]
+ public override void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (b.Length != orderA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (ReferenceEquals(a, b))
+ {
+ throw new ArgumentException(Resources.ArgumentReferenceDifferent);
+ }
+
+ SafeNativeMethods.s_cholesky_solve_factored(orderA, columnsB, a, b);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ var work = new float[columnsR * Control.BlockSize];
+ SafeNativeMethods.s_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Computes the QR factorization of A.
+ ///
+ /// On entry, it is the M by N A matrix to factor. On exit,
+ /// it is overwritten with the R matrix of the QR factorization.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// On exit, A M by M matrix that holds the Q matrix of the
+ /// QR factorization.
+ /// A min(m,n) vector. On exit, contains additional information
+ /// to be used by the QR solve routine.
+ /// 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.
+ /// This is similar to the GEQRF and ORGQR LAPACK routines.
+ [SecuritySafeCritical]
+ public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau, float[] work)
+ {
+ if (r == null)
+ {
+ throw new ArgumentNullException("r");
+ }
+
+ if (q == null)
+ {
+ throw new ArgumentNullException("q");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (r.Length != rowsR * columnsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * columnsR"), "r");
+ }
+
+ if (tau.Length < Math.Min(rowsR, columnsR))
+ {
+ throw new ArgumentException(string.Format(Resources.ArrayTooSmall, "min(m,n)"), "tau");
+ }
+
+ if (q.Length != rowsR * rowsR)
+ {
+ throw new ArgumentException(string.Format(Resources.ArgumentArrayWrongLength, "rowsR * rowsR"), "q");
+ }
+
+ if (work.Length < columnsR * Control.BlockSize)
+ {
+ work[0] = columnsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_factor(rowsR, columnsR, r, tau, q, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ var work = new float[columns * Control.BlockSize];
+ QRSolve(a, rows, columns, b, columnsB, x, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using QR factorization of A.
+ ///
+ /// The A matrix.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (a.Length != rows * columns)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "a");
+ }
+
+ if (b.Length != rows * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ if (x.Length != columns * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "x");
+ }
+
+ if (rows < columns)
+ {
+ throw new ArgumentException(Resources.RowsLessThanColumns);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rows * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_solve(rows, columns, columnsB, a, b, x, work, work.Length);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by calling .
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// Rows must be greater or equal to columns.
+ [SecuritySafeCritical]
+ public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x)
+ {
+ 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);
+ }
+
+ ///
+ /// Solves A*X=B for X using a previously QR factored matrix.
+ ///
+ /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be
+ /// null for the native provider. The native provider uses the Q portion stored in the R matrix.
+ /// The R matrix obtained by calling .
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// Contains additional information on Q. Only used for the native solver
+ /// and can be null for the managed provider.
+ /// On entry the B matrix; on exit the X matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ /// 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.
+ /// Rows must be greater or equal to columns.
+ public override void QRSolveFactored(float[] q, float[] r, int rowsR, int columnsR, float[] tau, float[] b, int columnsB, float[] x, float[] work)
+ {
+ 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 (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ 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);
+ }
+
+ if (work.Length < 1)
+ {
+ work[0] = rowsR * Control.BlockSize;
+ throw new ArgumentException(Resources.WorkArrayTooSmall, "work");
+ }
+
+ SafeNativeMethods.s_qr_solve_factored(rowsR, columnsR, columnsB, r, b, tau, x, work, work.Length);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ 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))];
+ SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt, work);
+ }
+
+ ///
+ /// Solves A*X=B for X using the singular value decomposition of A.
+ ///
+ /// On entry, the M by N matrix to decompose.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The B matrix.
+ /// The number of columns of B.
+ /// On exit, the solution matrix.
+ public override void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (b == null)
+ {
+ throw new ArgumentNullException("b");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (b.Length != rowsA * columnsB)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "b");
+ }
+
+ 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 s = new float[Math.Min(rowsA, columnsA)];
+ var u = new float[rowsA * rowsA];
+ var vt = new float[columnsA * columnsA];
+
+ var clone = new float[a.Length];
+ a.Copy(clone);
+ SingularValueDecomposition(true, clone, rowsA, columnsA, s, u, vt, work);
+ SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
+ }
+
+ ///
+ /// Computes the singular value decomposition of A.
+ ///
+ /// Compute the singular U and VT vectors or not.
+ /// On entry, the M by N matrix to decompose. On exit, A may be overwritten.
+ /// The number of rows in the A matrix.
+ /// The number of columns in the A matrix.
+ /// The singular values of A in ascending value.
+ /// If is true, on exit U contains the left
+ /// singular vectors.
+ /// If is true, on exit VT contains the transposed
+ /// right singular vectors.
+ /// The work array. For real matrices, the work array should be at least
+ /// Max(3*Min(M, N) + Max(M, N), 5*Min(M,N)). For complex matrices, 2*Min(M, N) + Max(M, N).
+ /// On exit, work[0] contains the optimal work size value.
+ /// This is equivalent to the GESVD LAPACK routine.
+ [SecuritySafeCritical]
+ public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] work)
+ {
+ if (a == null)
+ {
+ throw new ArgumentNullException("a");
+ }
+
+ if (s == null)
+ {
+ throw new ArgumentNullException("s");
+ }
+
+ if (u == null)
+ {
+ throw new ArgumentNullException("u");
+ }
+
+ if (vt == null)
+ {
+ throw new ArgumentNullException("vt");
+ }
+
+ if (work == null)
+ {
+ throw new ArgumentNullException("work");
+ }
+
+ if (u.Length != rowsA * rowsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "u");
+ }
+
+ if (vt.Length != columnsA * columnsA)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "vt");
+ }
+
+ if (s.Length != Math.Min(rowsA, columnsA))
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength, "s");
+ }
+
+ if (work.Length == 0)
+ {
+ 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)))
+ {
+ 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);
+ }
+
+ ///
+ /// Does a point wise add of two arrays z = x + y. This can be used
+ /// to add vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the addition.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void AddArrays(float[] x, float[] y, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.s_vector_add(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise subtraction of two arrays z = x - y. This can be used
+ /// to subtract vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the subtraction.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void SubtractArrays(float[] x, float[] y, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.s_vector_subtract(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise multiplication of two arrays z = x * y. This can be used
+ /// to multiple elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise multiplication.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.s_vector_multiply(x.Length, x, y, result);
+ }
+
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public override void PointWiseDivideArrays(float[] x, float[] y, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (x.Length != y.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (x.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.s_vector_divide(x.Length, x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.tt
deleted file mode 100644
index c240be3e..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.tt
+++ /dev/null
@@ -1,14 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string library = "Mkl";#>
-<# string title = "Intel's Math Kernel Library (MKL)";#>
-<# string dataType = "float";#>
-<# string zero = "0.0f";#>
-<# string one = "1.0f";#>
-<# string prefix = "s";#>
-<# string svd_work = "Math.Max((3 * Math.Min(rowsA, columnsA) + Math.Max(rowsA, columnsA)), 5 * Math.Min(rowsA, columnsA))";#>
-<#@ include file="..\native.header.include" #>
-<#@ include file="..\native.dotproduct.include" #>
-<#@ include file="..\native.generic.include" #>
-<#@ include file="..\native.vector.include" #>
-<#@ include file="..\native.footer.include" #>
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.cs b/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.cs
new file mode 100644
index 00000000..4be8e91d
--- /dev/null
+++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.cs
@@ -0,0 +1,311 @@
+//
+// 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.
+//
+
+using System.Numerics;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
+{
+ ///
+ /// P/Invoke methods to the native math libraries.
+ ///
+ [SuppressUnmanagedCodeSecurity]
+ [SecurityCritical]
+ internal static class SafeNativeMethods
+ {
+ ///
+ /// Name of the native DLL.
+ ///
+ private const string DllName = "MathNET.Numerics.MKL.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
+
+ #region Vector Functions
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void s_vector_add(int n, float[] x, float[] y, [In, Out] float[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void s_vector_subtract(int n, float[] x, float[] y, [In, Out] float[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void s_vector_multiply(int n, float[] x, float[] y, [In, Out] float[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void s_vector_divide(int n, float[] x, float[] y, [In, Out] float[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void d_vector_add(int n, double[] x, double[] y, [In, Out] double[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void d_vector_subtract(int n, double[] x, double[] y, [In, Out] double[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void d_vector_multiply(int n, double[] x, double[] y, [In, Out] double[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void d_vector_divide(int n, double[] x, double[] y, [In, Out] double[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void c_vector_add(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void c_vector_subtract(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void c_vector_multiply(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void c_vector_divide(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void z_vector_add(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void z_vector_subtract(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void z_vector_multiply(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
+
+ [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void z_vector_divide(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
+
+ #endregion Vector Functions
+ }
+}
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.tt
deleted file mode 100644
index d9ca2895..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.tt
+++ /dev/null
@@ -1,9 +0,0 @@
-<#@ template language="C#" debug="true" #>
-<#@ output extenstion="cs" #>
-<# string namespaceSuffix = "Mkl";
- string library = "MKL";
-#>
-<#@ include file="..\safe.native.common.include" #>
-<#@ include file="..\safe.native.vector.include" #>
- }
-}
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/native.dotproduct.include b/src/Numerics/Algorithms/LinearAlgebra/native.dotproduct.include
deleted file mode 100644
index ea6462bf..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/native.dotproduct.include
+++ /dev/null
@@ -1,27 +0,0 @@
- ///
- /// Computes the dot product of x and y.
- ///
- /// The vector x.
- /// The vector y.
- /// The dot product of x and y.
- /// This is equivalent to the DOT BLAS routine.
- [SecuritySafeCritical]
- public override <#=dataType#> DotProduct(<#=dataType#>[] x, <#=dataType#>[] 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.<#=prefix#>_dot_product(x.Length, x, y);
- }
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/native.footer.include b/src/Numerics/Algorithms/LinearAlgebra/native.footer.include
deleted file mode 100644
index ba5291f5..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/native.footer.include
+++ /dev/null
@@ -1,2 +0,0 @@
- }
-}
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/native.header.include b/src/Numerics/Algorithms/LinearAlgebra/native.header.include
deleted file mode 100644
index e14dfec2..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/native.header.include
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// 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.
-//
-
-/* This file is automatically generated - do not modify it.
- Last generated on UTC <#=DateTime.UtcNow.ToString("u")#>
-*/
-
-namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#=library#>
-{
- using System;
- using System.Numerics;
- using System.Security;
- using Properties;
-
- ///
- /// <#=title#> linear algebra provider.
- ///
- public partial class <#=library#>LinearAlgebraProvider : ManagedLinearAlgebraProvider
- {
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/native.vector.include b/src/Numerics/Algorithms/LinearAlgebra/native.vector.include
deleted file mode 100644
index f2885eb1..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/native.vector.include
+++ /dev/null
@@ -1,139 +0,0 @@
- ///
- /// Does a point wise add of two arrays z = x + y. This can be used
- /// to add vectors or matrices.
- ///
- /// The array x.
- /// The array y.
- /// The result of the addition.
- /// There is no equivalent BLAS routine, but many libraries
- /// provide optimized (parallel and/or vectorized) versions of this
- /// routine.
- public override void AddArrays(<#=dataType#>[] x, <#=dataType#>[] y, <#=dataType#>[] result)
- {
- if (y == null)
- {
- throw new ArgumentNullException("y");
- }
-
- if (x == null)
- {
- throw new ArgumentNullException("x");
- }
-
- if (x.Length != y.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- if (x.Length != result.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- SafeNativeMethods.<#=prefix#>_vector_add(x.Length, x, y, result);
- }
-
- ///
- /// Does a point wise subtraction of two arrays z = x - y. This can be used
- /// to subtract vectors or matrices.
- ///
- /// The array x.
- /// The array y.
- /// The result of the subtraction.
- /// There is no equivalent BLAS routine, but many libraries
- /// provide optimized (parallel and/or vectorized) versions of this
- /// routine.
- public override void SubtractArrays(<#=dataType#>[] x, <#=dataType#>[] y, <#=dataType#>[] result)
- {
- if (y == null)
- {
- throw new ArgumentNullException("y");
- }
-
- if (x == null)
- {
- throw new ArgumentNullException("x");
- }
-
- if (x.Length != y.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- if (x.Length != result.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- SafeNativeMethods.<#=prefix#>_vector_subtract(x.Length, x, y, result);
- }
-
- ///
- /// Does a point wise multiplication of two arrays z = x * y. This can be used
- /// to multiple elements of vectors or matrices.
- ///
- /// The array x.
- /// The array y.
- /// The result of the point wise multiplication.
- /// There is no equivalent BLAS routine, but many libraries
- /// provide optimized (parallel and/or vectorized) versions of this
- /// routine.
- public override void PointWiseMultiplyArrays(<#=dataType#>[] x, <#=dataType#>[] y, <#=dataType#>[] result)
- {
- if (y == null)
- {
- throw new ArgumentNullException("y");
- }
-
- if (x == null)
- {
- throw new ArgumentNullException("x");
- }
-
- if (x.Length != y.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- if (x.Length != result.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- SafeNativeMethods.<#=prefix#>_vector_multiply(x.Length, x, y, result);
- }
-
- ///
- /// Does a point wise division of two arrays z = x / y. This can be used
- /// to divide elements of vectors or matrices.
- ///
- /// The array x.
- /// The array y.
- /// The result of the point wise division.
- /// There is no equivalent BLAS routine, but many libraries
- /// provide optimized (parallel and/or vectorized) versions of this
- /// routine.
- public override void PointWiseDivideArrays(<#=dataType#>[] x, <#=dataType#>[] y, <#=dataType#>[] result)
- {
- if (y == null)
- {
- throw new ArgumentNullException("y");
- }
-
- if (x == null)
- {
- throw new ArgumentNullException("x");
- }
-
- if (x.Length != y.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- if (x.Length != result.Length)
- {
- throw new ArgumentException(Resources.ArgumentArraysSameLength);
- }
-
- SafeNativeMethods.<#=prefix#>_vector_divide(x.Length, x, y, result);
- }
\ No newline at end of file
diff --git a/src/Numerics/Algorithms/LinearAlgebra/safe.native.vector.include b/src/Numerics/Algorithms/LinearAlgebra/safe.native.vector.include
deleted file mode 100644
index 29b0cc1f..00000000
--- a/src/Numerics/Algorithms/LinearAlgebra/safe.native.vector.include
+++ /dev/null
@@ -1,52 +0,0 @@
-
- #region Vector Functions
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void s_vector_add(int n, float[] x, float[] y, [In, Out] float[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void s_vector_subtract(int n, float[] x, float[] y, [In, Out] float[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void s_vector_multiply(int n, float[] x, float[] y, [In, Out] float[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void s_vector_divide(int n, float[] x, float[] y, [In, Out] float[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void d_vector_add(int n, double[] x, double[] y, [In, Out] double[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void d_vector_subtract(int n, double[] x, double[] y, [In, Out] double[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void d_vector_multiply(int n, double[] x, double[] y, [In, Out] double[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void d_vector_divide(int n, double[] x, double[] y, [In, Out] double[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void c_vector_add(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void c_vector_subtract(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void c_vector_multiply(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void c_vector_divide(int n, Complex32[] x, Complex32[] y, [In, Out] Complex32[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void z_vector_add(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void z_vector_subtract(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void z_vector_multiply(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
-
- [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
- internal static extern void z_vector_divide(int n, Complex[] x, Complex[] y, [In, Out] Complex[] result);
-
- #endregion Vector Functions
\ No newline at end of file
diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj
index 6ffc7d6b..9fe250a4 100644
--- a/src/Numerics/Numerics.csproj
+++ b/src/Numerics/Numerics.csproj
@@ -18,6 +18,8 @@
3.5
+ false
+ publish\trueDisk
@@ -30,10 +32,8 @@
true01.0.0.%2a
- falsefalsetrue
- true
@@ -70,182 +70,34 @@
-
- TextTemplatingFileGenerator
- AcmlLinearAlgebraProvider.Common.cs
-
-
- TextTemplatingFileGenerator
- AcmlLinearAlgebraProvider.Complex.cs
-
-
- TextTemplatingFileGenerator
- AcmlLinearAlgebraProvider.Complex32.cs
-
-
- TextTemplatingFileGenerator
- AcmlLinearAlgebraProvider.double.cs
-
-
- TextTemplatingFileGenerator
- AcmlLinearAlgebraProvider.float.cs
-
-
- TextTemplatingFileGenerator
- SafeNativeMethods.cs
-
-
-
- TextTemplatingFileGenerator
- GotoBlasLinearAlgebraProvider.Common.cs
-
-
- TextTemplatingFileGenerator
- GotoBlasLinearAlgebraProvider.Complex.cs
-
-
- TextTemplatingFileGenerator
- GotoBlasLinearAlgebraProvider.Complex32.cs
-
-
- TextTemplatingFileGenerator
- GotoBlasLinearAlgebraProvider.double.cs
-
-
- TextTemplatingFileGenerator
- GotoBlasLinearAlgebraProvider.float.cs
-
-
- TextTemplatingFileGenerator
- SafeNativeMethods.cs
-
-
- TextTemplatingFileGenerator
- MklLinearAlgebraProvider.Common.cs
-
-
-
- SafeNativeMethods.cs
-
-
-
-
- TextTemplatingFileGenerator
- MklLinearAlgebraProvider.Complex32.cs
-
-
- TextTemplatingFileGenerator
- MklLinearAlgebraProvider.Complex.cs
-
-
- TextTemplatingFileGenerator
- MklLinearAlgebraProvider.float.cs
-
-
- TextTemplatingFileGenerator
- MklLinearAlgebraProvider.double.cs
-
-
- TextTemplatingFileGenerator
- SafeNativeMethods.cs
-
-
-
- AcmlLinearAlgebraProvider.Common.tt
- True
- True
-
- AcmlLinearAlgebraProvider.Complex.tt
- True
- True
- AcmlLinearAlgebraProvider.Complex32.tt
- True
- True
- AcmlLinearAlgebraProvider.double.tt
- True
- True
- AcmlLinearAlgebraProvider.float.tt
- True
- True
- SafeNativeMethods.tt
- True
- True
-
-
- GotoBlasLinearAlgebraProvider.Common.tt
- True
- True
-
-
- GotoBlasLinearAlgebraProvider.Complex.tt
- True
- True
-
-
- GotoBlasLinearAlgebraProvider.Complex32.tt
- True
- True
-
-
- GotoBlasLinearAlgebraProvider.double.tt
- True
- True
-
-
- True
- True
- GotoBlasLinearAlgebraProvider.float.tt
-
-
- SafeNativeMethods.tt
- True
- True
+
+
+
+
+
+
-
- MklLinearAlgebraProvider.Common.tt
- True
- True
-
-
- MklLinearAlgebraProvider.Complex32.tt
- True
- True
-
-
- MklLinearAlgebraProvider.Complex.tt
- True
- True
-
-
- MklLinearAlgebraProvider.float.tt
- True
- True
-
-
- True
- True
- MklLinearAlgebraProvider.double.tt
-
-
- True
- True
- SafeNativeMethods.tt
-
+
+
+
+
+
+
@@ -594,22 +446,8 @@
MathNet.Numerics.snk
-
-
- SafeNativeMethods.cs
-
-
- True
- True
- Version.tt
-
-
-
- TextTemplatingFileGenerator
- Version.cs
-
@@ -635,8 +473,8 @@
- cd $(ProjectDir)..\..\build
-t4.bat
+
+