diff --git a/src/MSUnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs b/src/MSUnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs index 7cac2247..ca7906d1 100644 --- a/src/MSUnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs +++ b/src/MSUnitTests/LinearAlgebraProviderTests/Double/LinearAlgebraProviderTests.cs @@ -44,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double /// /// Gets or sets linear algebra provider to test. /// - protected static ILinearAlgebraProvider Provider + protected static ILinearAlgebraProvider Provider { get; set; @@ -184,6 +184,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double [TestMethod] public void CanComputeMatrixL1Norm() { + var matrix = _matrices["Square3x3"]; + var work = new double[matrix.RowCount]; + var norm = Provider.MatrixNorm(Norm.OneNorm, matrix.RowCount, matrix.ColumnCount, matrix.Data, work); + Assert.AreEqual(1.1, norm); } /// diff --git a/src/MathNet.Numerics.5.1.ReSharper b/src/MathNet.Numerics.5.1.ReSharper index fc99438d..46eefb2a 100644 --- a/src/MathNet.Numerics.5.1.ReSharper +++ b/src/MathNet.Numerics.5.1.ReSharper @@ -35,7 +35,8 @@ NIST's Excel's ipiv blocksize -Dont +Dont +dll diff --git a/src/NativeWrappers/Windows/Local.testsettings b/src/NativeWrappers/Windows/Local.testsettings new file mode 100644 index 00000000..e956c469 --- /dev/null +++ b/src/NativeWrappers/Windows/Local.testsettings @@ -0,0 +1,10 @@ + + + These are default test settings for a local test run. + + + + + + + \ No newline at end of file diff --git a/src/NativeWrappers/Windows/MKLWrapper32Tests/LinearAlgebra/Double/MklLinearAlgebraProviderTests.cs b/src/NativeWrappers/Windows/MKLWrapper32Tests/LinearAlgebra/Double/MklLinearAlgebraProviderTests.cs index 76f40c13..7bebe211 100644 --- a/src/NativeWrappers/Windows/MKLWrapper32Tests/LinearAlgebra/Double/MklLinearAlgebraProviderTests.cs +++ b/src/NativeWrappers/Windows/MKLWrapper32Tests/LinearAlgebra/Double/MklLinearAlgebraProviderTests.cs @@ -28,7 +28,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // -using MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double; +using MathNet.Numerics.UnitTests.LinearAlgebraProviderTests.Double; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MathNet.Numerics.MklWrapperTests.LinearAlgebra.Double @@ -36,6 +36,7 @@ namespace MathNet.Numerics.MklWrapperTests.LinearAlgebra.Double /// /// Unit test container for the MKL linear algebra provider. /// + [TestClass] public class MklLinearAlgebraProviderTests : LinearAlgebraProviderTests { /// diff --git a/src/NativeWrappers/Windows/NativeWrappers.sln b/src/NativeWrappers/Windows/NativeWrappers.sln index a75459c2..2be26165 100644 --- a/src/NativeWrappers/Windows/NativeWrappers.sln +++ b/src/NativeWrappers/Windows/NativeWrappers.sln @@ -16,7 +16,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MKLWrapper64Tests", "MKLWra EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MKLWrapper32Tests", "MKLWrapper32Tests\MKLWrapper32Tests.csproj", "{D0AD591B-0CE6-4A6D-8DEA-01777EE09BC3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{953422F5-A946-434B-81FD-A5A0AF92AAE1}" + ProjectSection(SolutionItems) = preProject + Local.testsettings = Local.testsettings + NativeWrappers1.vsmdi = NativeWrappers1.vsmdi + TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings + EndProjectSection +EndProject Global + GlobalSection(TestCaseManagementSettings) = postSolution + CategoryFile = NativeWrappers1.vsmdi + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms diff --git a/src/NativeWrappers/Windows/NativeWrappers.vsmdi b/src/NativeWrappers/Windows/NativeWrappers.vsmdi new file mode 100644 index 00000000..e14b92a1 --- /dev/null +++ b/src/NativeWrappers/Windows/NativeWrappers.vsmdi @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/NativeWrappers/Windows/TraceAndTestImpact.testsettings b/src/NativeWrappers/Windows/TraceAndTestImpact.testsettings new file mode 100644 index 00000000..aa0b2824 --- /dev/null +++ b/src/NativeWrappers/Windows/TraceAndTestImpact.testsettings @@ -0,0 +1,21 @@ + + + These are test settings for Trace and Test Impact. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProvider.cs b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProvider.cs index 3f612395..8a3fc253 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProvider.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProvider.cs @@ -38,5 +38,60 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra /// public interface ILinearAlgebraProvider : ILinearAlgebraProvider, ILinearAlgebraProvider, ILinearAlgebraProvider, ILinearAlgebraProvider { + /// + /// Computes the requested of the matrix. + /// + /// The type of norm to compute. + /// The number of rows. + /// The number of columns. + /// 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. + /// + float MatrixNorm(Norm norm, int rows, int columns, float[] matrix, float[] work); + + /// + /// Computes the requested of the matrix. + /// + /// The type of norm to compute. + /// The number of rows. + /// The number of columns. + /// 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. + /// + double MatrixNorm(Norm norm, int rows, int columns, double[] matrix, double[] work); + + /// + /// Computes the requested of the matrix. + /// + /// The type of norm to compute. + /// The number of rows. + /// The number of columns. + /// 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. + /// + Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work); + + /// + /// Computes the requested of the matrix. + /// + /// The type of norm to compute. + /// The number of rows. + /// The number of columns. + /// 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. + /// + Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work); } } diff --git a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs index f519d19e..90456694 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs @@ -179,20 +179,6 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra /// T MatrixNorm(Norm norm, int rows, int columns, T[] matrix); - /// - /// Computes the requested of the matrix. - /// - /// The type of norm to compute. - /// The number of rows. - /// The number of columns. - /// 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. - /// - T MatrixNorm(Norm norm, int rows, int columns, T[] matrix, T[] work); - /// /// Multiples two matrices. result = x * y /// diff --git a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs index de2828c7..763dc892 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs @@ -342,7 +342,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra /// /// The requested of the matrix. /// - public virtual Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, Complex[] work) + public virtual Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work) { return MatrixNorm(norm, rows, columns, matrix); } diff --git a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs index e78397a7..e38b66e8 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs @@ -348,7 +348,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra /// /// The requested of the matrix. /// - public virtual Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, Complex32[] work) + public virtual Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work) { return MatrixNorm(norm, rows, columns, matrix); } diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.tt new file mode 100644 index 00000000..ee701bd5 --- /dev/null +++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Common.tt @@ -0,0 +1,8 @@ +<#@ 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.common.include" #> +<#@ include file="..\native.footer.include" #> diff --git a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.tt index dc733440..86a5d533 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.tt +++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex.tt @@ -8,6 +8,6 @@ <# string prefix = "z";#> <# string reff = "ref ";#> <#@ include file="..\native.header.include" #> -<#@ include file="..\native.common.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.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.tt index 6ded98ca..b956a489 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.tt +++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.Complex32.tt @@ -8,6 +8,6 @@ <# string prefix = "c";#> <# string reff = "ref ";#> <#@ include file="..\native.header.include" #> -<#@ include file="..\native.common.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.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.tt index 18ffea33..48c1e051 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.tt +++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.double.tt @@ -8,6 +8,6 @@ <# string prefix = "d";#> <# string reff = "";#> <#@ include file="..\native.header.include" #> -<#@ include file="..\native.common.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.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.tt index 8feb4711..6b003cc9 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.tt +++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.float.tt @@ -8,6 +8,6 @@ <# string prefix = "s";#> <# string reff = "";#> <#@ include file="..\native.header.include" #> -<#@ include file="..\native.common.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.tt b/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.tt index bd1d4cf2..d9ca2895 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.tt +++ b/src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.tt @@ -5,6 +5,5 @@ #> <#@ 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.common.include b/src/Numerics/Algorithms/LinearAlgebra/native.common.include index d8632dd5..6f552d6e 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/native.common.include +++ b/src/Numerics/Algorithms/LinearAlgebra/native.common.include @@ -1,146 +1,157 @@  /// - /// Adds a scaled vector to another: y += alpha*x. + /// Computes the requested of the matrix. /// - /// The vector to update. - /// The value to scale by. - /// The vector to add to . - /// This equivalent to the AXPY BLAS routine. - public override void AddVectorToScaledVector(<#=dataType#>[] y, <#=dataType#> alpha, <#=dataType#>[] x) + /// 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. + /// + public override float MatrixNorm(Norm norm, int rows, int columns, float[] matrix) { - if (y == null) + if (matrix == null) { - throw new ArgumentNullException("y"); + throw new ArgumentNullException("matrix"); } - if (x == null) + if (rows <= 0) { - throw new ArgumentNullException("x"); + throw new ArgumentException(Resources.ArgumentMustBePositive, "rows"); } - if (y.Length != x.Length) + if (columns <= 0) { - throw new ArgumentException(Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentMustBePositive, "columns"); } - if (alpha == <#=zero#>) + if (matrix.Length < rows * columns) { - return; + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix"); } - SafeNativeMethods.<#=prefix#>_axpy(y.Length, <#=reff#>alpha, x, y); + var work = new float[rows]; + return MatrixNorm(norm, rows, columns, matrix, work); } /// - /// Scales an array. Can be used to scale a vector and a matrix. + /// Computes the requested of the matrix. /// - /// The scalar. - /// The values to scale. - /// This is equivalent to the SCAL BLAS routine. - public override void ScaleArray(<#=dataType#> alpha, <#=dataType#>[] x) + /// 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. + /// + public override float MatrixNorm(Norm norm, int rows, int columns, float[] matrix, float[] work) { - if (x == null) + 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 ArgumentNullException("x"); - } - - if (alpha == <#=one#>) + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix"); + } + + if (work.Length < rows) { - return; + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work"); } - SafeNativeMethods.<#=prefix#>_scale(x.Length, <#=reff#>alpha, x); + return SafeNativeMethods.s_norm((byte)norm, rows, columns, matrix, work); } /// - /// Computes the dot product of x and y. + /// Computes the requested of the matrix. /// - /// The vector x. - /// The vector y. - /// The dot product of x and y. - /// This is equivalent to the DOT BLAS routine. - public override <#=dataType#> DotProduct(<#=dataType#>[] x, <#=dataType#>[] y) + /// 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. + /// + public override double MatrixNorm(Norm norm, int rows, int columns, double[] matrix) { - if (y == null) + if (matrix == null) { - throw new ArgumentNullException("y"); + throw new ArgumentNullException("matrix"); } - if (x == null) + if (rows <= 0) { - throw new ArgumentNullException("x"); + throw new ArgumentException(Resources.ArgumentMustBePositive, "rows"); } - if (x.Length != y.Length) + if (columns <= 0) { - throw new ArgumentException(Resources.ArgumentArraysSameLength); + throw new ArgumentException(Resources.ArgumentMustBePositive, "columns"); } - return SafeNativeMethods.<#=prefix#>_dot_product(x.Length, x, y); - } + if (matrix.Length < rows * columns) + { + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix"); + } - /// - /// 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 <#=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) - { - MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, <#=one#>, x, rowsX, columnsX, y, rowsY, columnsY, <#=zero#>, result); + var work = new double[rows]; + return MatrixNorm(norm, rows, columns, matrix, work); } /// - /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c + /// Computes the requested of the matrix. /// - /// 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. - 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) + /// 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. + /// + public override double MatrixNorm(Norm norm, int rows, int columns, double[] matrix, double[] work) { - if (a == null) + if (matrix == null) { - throw new ArgumentNullException("a"); + throw new ArgumentNullException("matrix"); } - if (b == null) + if (rows <= 0) { - throw new ArgumentNullException("b"); + throw new ArgumentException(Resources.ArgumentMustBePositive, "rows"); } - if (c == null) + if (columns <= 0) { - throw new ArgumentNullException("c"); + throw new ArgumentException(Resources.ArgumentMustBePositive, "columns"); } - var m = transposeA == Transpose.DontTranspose ? rowsA : columnsA; - var n = transposeB == Transpose.DontTranspose ? columnsB : rowsB; - var k = transposeA == Transpose.DontTranspose ? columnsA : rowsA; - - if (c.Length != rowsA * columnsB) + if (matrix.Length < rows * columns) { - throw new ArgumentException(Resources.ArgumentMatrixDimensions); + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix"); } - if (columnsA != rowsB) + if (work.Length < rows) { - throw new ArgumentException(Resources.ArgumentMatrixDimensions); + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work"); } - SafeNativeMethods.<#=prefix#>_matrix_multiply(transposeA, transposeB, m, n, k, <#=reff#>alpha, a, b, <#=reff#>beta, c); + return SafeNativeMethods.d_norm((byte)norm, rows, columns, matrix, work); } /// @@ -153,9 +164,30 @@ /// /// The requested of the matrix. /// - public override <#=dataType#> MatrixNorm(Norm norm, int rows, int columns, <#=dataType#>[] matrix) + public override Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix) { - throw new NotImplementedException(); + 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); } /// @@ -170,357 +202,110 @@ /// /// The requested of the matrix. /// - public override <#=dataType#> MatrixNorm(Norm norm, int rows, int columns, <#=dataType#>[] matrix, <#=dataType#>[] work) - { - throw new NotImplementedException(); - } - - /// - /// 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#> - /// 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. - public override void LUFactor(<#=dataType#>[] data, int order, int[] ipiv) + public override Complex32 MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix, float[] work) { - throw new NotImplementedException(); - } - - /// - /// 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. - public override void LUInverse(<#=dataType#>[] a, int order) - { - throw new NotImplementedException(); - } - - /// - /// 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. - public override void LUInverseFactored(<#=dataType#>[] a, int order, int[] ipiv) - { - throw new NotImplementedException(); - } - - /// - /// 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. - public override void LUInverse(<#=dataType#>[] a, int order, <#=dataType#>[] work) - { - throw new NotImplementedException(); - } - - /// - /// 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. - public override void LUInverseFactored(<#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] work) - { - throw new NotImplementedException(); - } - - /// - /// 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 . - /// The B matrix. - /// This is equivalent to the GETRF and GETRS LAPACK routines. - public override void LUSolve(int columnsOfB, <#=dataType#>[] a, int order, <#=dataType#>[] b) - { - throw new NotImplementedException(); - } - - /// - /// 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 . - /// The B matrix. - /// This is equivalent to the GETRS LAPACK routine. - public override void LUSolveFactored(int columnsOfB, <#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] b) - { - throw new NotImplementedException(); - } - - /// - /// Solves A*X=B for X using LU factorization. - /// - /// How to transpose the matrix. - /// The number of columns of B. - /// The square matrix A. - /// The order of the square matrix . - /// The B matrix. - /// This is equivalent to the GETRF and GETRS LAPACK routines. - public override void LUSolve(Transpose transposeA, int columnsOfB, <#=dataType#>[] a, int order, <#=dataType#>[] b) - { - throw new NotImplementedException(); - } + if (matrix == null) + { + throw new ArgumentNullException("matrix"); + } - /// - /// Solves A*X=B for X using a previously factored A matrix. - /// - /// How to transpose the matrix. - /// The number of columns of B. - /// The factored A matrix. - /// The order of the square matrix . - /// The pivot indices of . - /// The B matrix. - /// This is equivalent to the GETRS LAPACK routine. - public override void LUSolveFactored(Transpose transposeA, int columnsOfB, <#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] b) - { - throw new NotImplementedException(); - } + if (rows <= 0) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "rows"); + } - /// - /// 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. - public override void CholeskyFactor(<#=dataType#>[] a, int order) - { - if (a == null) + if (columns <= 0) { - throw new ArgumentNullException("a"); + throw new ArgumentException(Resources.ArgumentMustBePositive, "columns"); } - if (order < 1) + if (matrix.Length < rows * columns) { - throw new ArgumentException(Resources.ArgumentMustBePositive, "order"); + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix"); } - SafeNativeMethods.<#=prefix#>_cholesky_factor(order, a); - } + if (work.Length < rows) + { + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work"); + } - /// - /// Solves A*X=B for X using Cholesky factorization. - /// - /// The square, positive definite matrix A. - /// The number of rows and columns in A. - /// The B matrix. - /// The number of rows in the B matrix. - /// The number of columns in the B matrix. - /// This is equivalent to the POTRF add POTRS LAPACK routines. - /// - public override void CholeskySolve(<#=dataType#>[] a, int orderA, <#=dataType#>[] b, int rowsB, int columnsB) - { - throw new NotImplementedException(); + return SafeNativeMethods.c_norm((byte)norm, rows, columns, matrix, work); } /// - /// Solves A*X=B for X using a previously factored A matrix. + /// Computes the requested of the matrix. /// - /// The square, positive definite matrix A. - /// The number of rows and columns in A. - /// The B matrix. - /// The number of rows in the B matrix. - /// The number of columns in the B matrix. - /// This is equivalent to the POTRS LAPACK routine. - public override void CholeskySolveFactored(<#=dataType#>[] a, int orderA, <#=dataType#>[] b, int rowsB, int columnsB) + /// 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. + /// + public override Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix) { - throw new NotImplementedException(); - } + if (matrix == null) + { + throw new ArgumentNullException("matrix"); + } - /// - /// 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. - /// This is similar to the GEQRF and ORGQR LAPACK routines. - public override void QRFactor(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q) - { - throw new NotImplementedException(); - } + if (rows <= 0) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "rows"); + } - /// - /// 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. - /// 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. - public override void QRFactor(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] work) - { - throw new NotImplementedException(); - } + if (columns <= 0) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "columns"); + } - /// - /// Solves A*X=B for X using 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. - /// The B matrix. - /// The number of columns of B. - /// On exit, the solution matrix. - public override void QRSolve(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) - { - throw new NotImplementedException(); - } + if (matrix.Length < rows * columns) + { + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix"); + } - /// - /// Solves A*X=B for X using 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. - /// 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. - public override void QRSolve(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x, <#=dataType#>[] work) - { - throw new NotImplementedException(); + var work = new double[rows]; + return MatrixNorm(norm, rows, columns, matrix, work); } /// - /// Solves A*X=B for X using a previously QR factored matrix. + /// Computes the requested of the 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. - /// The B matrix. - /// The number of columns of B. - /// On exit, the solution matrix. - public override void QRSolveFactored(<#=dataType#>[] q, <#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) + /// 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. + /// + public override Complex MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix, double[] work) { - throw new NotImplementedException(); - } + if (matrix == null) + { + throw new ArgumentNullException("matrix"); + } - /// - /// 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. - public override void SingularValueDecomposition(bool computeVectors, <#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt) - { - throw new NotImplementedException(); - } + if (rows <= 0) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "rows"); + } - /// - /// 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. - public override void SingularValueDecomposition(bool computeVectors, <#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] work) - { - throw new NotImplementedException(); - } + if (columns <= 0) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "columns"); + } - /// - /// Solves A*X=B for X using the singular value decomposition of A. - /// - /// 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. - /// On exit U contains the left singular vectors. - /// On exit VT contains the transposed right singular vectors. - /// 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#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) - { - throw new NotImplementedException(); - } + if (matrix.Length < rows * columns) + { + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows * columns), "matrix"); + } - /// - /// Solves A*X=B for X using the singular value decomposition of A. - /// - /// 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. - /// On exit U contains the left singular vectors. - /// On exit VT contains the transposed right singular vectors. - /// The B matrix. - /// The number of columns of B. - /// On exit, the solution matrix. - /// 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. - public override void SvdSolve(<#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x, <#=dataType#>[] work) - { - throw new NotImplementedException(); - } + if (work.Length < rows) + { + throw new ArgumentException(string.Format(Resources.ArrayTooSmall, rows), "work"); + } - /// - /// Solves A*X=B for X using a previously SVD decomposed matrix. - /// - /// The number of rows in the A matrix. - /// The number of columns in the A matrix. - /// The s values returned by . - /// The left singular vectors returned by . - /// The right singular vectors returned by . - /// The B matrix. - /// The number of columns of B. - /// On exit, the solution matrix. - public override void SvdSolveFactored(int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) - { - throw new NotImplementedException(); - } + return SafeNativeMethods.z_norm((byte)norm, rows, columns, matrix, work); + } \ No newline at end of file diff --git a/src/Numerics/Algorithms/LinearAlgebra/native.generic.include b/src/Numerics/Algorithms/LinearAlgebra/native.generic.include new file mode 100644 index 00000000..53c88912 --- /dev/null +++ b/src/Numerics/Algorithms/LinearAlgebra/native.generic.include @@ -0,0 +1,494 @@ + /// + /// Adds a scaled vector to another: y += alpha*x. + /// + /// The vector to update. + /// The value to scale by. + /// The vector to add to . + /// This equivalent to the AXPY BLAS routine. + public override void AddVectorToScaledVector(<#=dataType#>[] y, <#=dataType#> alpha, <#=dataType#>[] x) + { + 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 (alpha == <#=zero#>) + { + return; + } + + SafeNativeMethods.<#=prefix#>_axpy(y.Length, <#=reff#>alpha, x, y); + } + + /// + /// Scales an array. Can be used to scale a vector and a matrix. + /// + /// The scalar. + /// The values to scale. + /// This is equivalent to the SCAL BLAS routine. + public override void ScaleArray(<#=dataType#> alpha, <#=dataType#>[] x) + { + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (alpha == <#=one#>) + { + return; + } + + SafeNativeMethods.<#=prefix#>_scale(x.Length, <#=reff#>alpha, x); + } + + /// + /// 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. + 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); + } + + /// + /// 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 <#=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) + { + MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, <#=one#>, x, rowsX, columnsX, y, rowsY, columnsY, <#=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. + 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) + { + 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; + + if (c.Length != rowsA * columnsB) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + if (columnsA != rowsB) + { + throw new ArgumentException(Resources.ArgumentMatrixDimensions); + } + + SafeNativeMethods.<#=prefix#>_matrix_multiply(transposeA, transposeB, m, n, k, <#=reff#>alpha, a, b, <#=reff#>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#> + /// 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. + public override void LUFactor(<#=dataType#>[] data, int order, int[] ipiv) + { + throw new NotImplementedException(); + } + + /// + /// 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. + public override void LUInverse(<#=dataType#>[] a, int order) + { + throw new NotImplementedException(); + } + + /// + /// 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. + public override void LUInverseFactored(<#=dataType#>[] a, int order, int[] ipiv) + { + throw new NotImplementedException(); + } + + /// + /// 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. + public override void LUInverse(<#=dataType#>[] a, int order, <#=dataType#>[] work) + { + throw new NotImplementedException(); + } + + /// + /// 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. + public override void LUInverseFactored(<#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] work) + { + throw new NotImplementedException(); + } + + /// + /// 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 . + /// The B matrix. + /// This is equivalent to the GETRF and GETRS LAPACK routines. + public override void LUSolve(int columnsOfB, <#=dataType#>[] a, int order, <#=dataType#>[] b) + { + throw new NotImplementedException(); + } + + /// + /// 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 . + /// The B matrix. + /// This is equivalent to the GETRS LAPACK routine. + public override void LUSolveFactored(int columnsOfB, <#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] b) + { + throw new NotImplementedException(); + } + + /// + /// Solves A*X=B for X using LU factorization. + /// + /// How to transpose the matrix. + /// The number of columns of B. + /// The square matrix A. + /// The order of the square matrix . + /// The B matrix. + /// This is equivalent to the GETRF and GETRS LAPACK routines. + public override void LUSolve(Transpose transposeA, int columnsOfB, <#=dataType#>[] a, int order, <#=dataType#>[] b) + { + throw new NotImplementedException(); + } + + /// + /// Solves A*X=B for X using a previously factored A matrix. + /// + /// How to transpose the matrix. + /// The number of columns of B. + /// The factored A matrix. + /// The order of the square matrix . + /// The pivot indices of . + /// The B matrix. + /// This is equivalent to the GETRS LAPACK routine. + public override void LUSolveFactored(Transpose transposeA, int columnsOfB, <#=dataType#>[] a, int order, int[] ipiv, <#=dataType#>[] b) + { + throw new NotImplementedException(); + } + + /// + /// 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. + public override void CholeskyFactor(<#=dataType#>[] a, int order) + { + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (order < 1) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "order"); + } + + SafeNativeMethods.<#=prefix#>_cholesky_factor(order, a); + } + + /// + /// Solves A*X=B for X using Cholesky factorization. + /// + /// The square, positive definite matrix A. + /// The number of rows and columns in A. + /// The B matrix. + /// The number of rows in the B matrix. + /// The number of columns in the B matrix. + /// This is equivalent to the POTRF add POTRS LAPACK routines. + /// + public override void CholeskySolve(<#=dataType#>[] a, int orderA, <#=dataType#>[] b, int rowsB, int columnsB) + { + throw new NotImplementedException(); + } + + /// + /// 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. + /// The B matrix. + /// The number of rows in the B matrix. + /// The number of columns in the B matrix. + /// This is equivalent to the POTRS LAPACK routine. + public override void CholeskySolveFactored(<#=dataType#>[] a, int orderA, <#=dataType#>[] b, int rowsB, int columnsB) + { + throw new NotImplementedException(); + } + + /// + /// 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. + /// This is similar to the GEQRF and ORGQR LAPACK routines. + public override void QRFactor(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q) + { + throw new NotImplementedException(); + } + + /// + /// 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. + /// 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. + public override void QRFactor(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] work) + { + throw new NotImplementedException(); + } + + /// + /// Solves A*X=B for X using 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. + /// The B matrix. + /// The number of columns of B. + /// On exit, the solution matrix. + public override void QRSolve(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) + { + throw new NotImplementedException(); + } + + /// + /// Solves A*X=B for X using 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. + /// 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. + public override void QRSolve(<#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] q, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x, <#=dataType#>[] work) + { + throw new NotImplementedException(); + } + + /// + /// 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. + /// The B matrix. + /// The number of columns of B. + /// On exit, the solution matrix. + public override void QRSolveFactored(<#=dataType#>[] q, <#=dataType#>[] r, int rowsR, int columnsR, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) + { + throw new NotImplementedException(); + } + + /// + /// 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. + public override void SingularValueDecomposition(bool computeVectors, <#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt) + { + throw new NotImplementedException(); + } + + /// + /// 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. + public override void SingularValueDecomposition(bool computeVectors, <#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] work) + { + throw new NotImplementedException(); + } + + /// + /// Solves A*X=B for X using the singular value decomposition of A. + /// + /// 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. + /// On exit U contains the left singular vectors. + /// On exit VT contains the transposed right singular vectors. + /// 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#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) + { + throw new NotImplementedException(); + } + + /// + /// Solves A*X=B for X using the singular value decomposition of A. + /// + /// 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. + /// On exit U contains the left singular vectors. + /// On exit VT contains the transposed right singular vectors. + /// The B matrix. + /// The number of columns of B. + /// On exit, the solution matrix. + /// 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. + public override void SvdSolve(<#=dataType#>[] a, int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x, <#=dataType#>[] work) + { + throw new NotImplementedException(); + } + + /// + /// Solves A*X=B for X using a previously SVD decomposed matrix. + /// + /// The number of rows in the A matrix. + /// The number of columns in the A matrix. + /// The s values returned by . + /// The left singular vectors returned by . + /// The right singular vectors returned by . + /// The B matrix. + /// The number of columns of B. + /// On exit, the solution matrix. + public override void SvdSolveFactored(int rowsA, int columnsA, <#=dataType#>[] s, <#=dataType#>[] u, <#=dataType#>[] vt, <#=dataType#>[] b, int columnsB, <#=dataType#>[] x) + { + throw new NotImplementedException(); + } diff --git a/src/Numerics/Algorithms/LinearAlgebra/safe.native.common.include b/src/Numerics/Algorithms/LinearAlgebra/safe.native.common.include index 756685fb..da3dd6a5 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/safe.native.common.include +++ b/src/Numerics/Algorithms/LinearAlgebra/safe.native.common.include @@ -99,7 +99,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#= namespaceSuffix #> #endregion BLAS - #region LAPACK + #region LAPACK [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] internal static extern void s_cholesky_factor(int n, [In, Out] float[] a); @@ -113,4 +113,16 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.<#= namespaceSuffix #> [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] internal static extern void z_cholesky_factor(int n, [In, Out] Complex[] a); - #endregion LAPACK + [DllImport(DllName, ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)] + internal static extern float s_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_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_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_norm(byte norm, int rows, int columns, [In] Complex[] a, [In, Out] double[] work); + + #endregion LAPACK diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index ef2b86d8..66b79f43 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -70,6 +70,11 @@ + + TextTemplatingFileGenerator + MklLinearAlgebraProvider.Common.cs + + SafeNativeMethods.cs @@ -102,6 +107,11 @@ + + MklLinearAlgebraProvider.Common.tt + True + True + MklLinearAlgebraProvider.Complex32.tt True diff --git a/src/Numerics/Properties/Resources.Designer.cs b/src/Numerics/Properties/Resources.Designer.cs index dc4c3628..5c7a637b 100644 --- a/src/Numerics/Properties/Resources.Designer.cs +++ b/src/Numerics/Properties/Resources.Designer.cs @@ -465,6 +465,15 @@ namespace MathNet.Numerics.Properties { } } + /// + /// Looks up a localized string similar to The given array is too small. It must be at least {0} long.. + /// + internal static string ArrayTooSmall { + get { + return ResourceManager.GetString("ArrayTooSmall", resourceCulture); + } + } + /// /// Looks up a localized string similar to Big endian files are not supported.. /// diff --git a/src/Numerics/Properties/Resources.resx b/src/Numerics/Properties/Resources.resx index 9cee9b16..f653a30b 100644 --- a/src/Numerics/Properties/Resources.resx +++ b/src/Numerics/Properties/Resources.resx @@ -348,4 +348,7 @@ Data must contain at least {0} values. + + The given array is too small. It must be at least {0} long. + \ No newline at end of file