Browse Source

Sealing providers

dependabot/nuget/NUnit3TestAdapter-4.2.0
Christoph Ruegg 5 years ago
parent
commit
d0583cbcda
  1. 2
      MathNet.Numerics.sln.DotSettings
  2. 14
      src/Numerics.Tests/IntegralTransformsTests/MatchingReferenceTransformTest.cs
  3. 3
      src/Numerics/Providers/FourierTransform/FourierTransformControl.cs
  4. 24
      src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.Bluestein.cs
  5. 26
      src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.Radix2.cs
  6. 90
      src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.Scaling.cs
  7. 60
      src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs
  8. 3
      src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs
  9. 62
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs
  10. 62
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs
  11. 58
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs
  12. 58
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs
  13. 12
      src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.cs
  14. 4
      src/Numerics/Providers/SparseSolver/ManagedSparseSolverProvider.cs
  15. 16
      src/Numerics/Providers/SparseSolver/SparseSolverControl.cs
  16. 355
      src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Complex.cs
  17. 356
      src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Complex32.cs
  18. 356
      src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Double.cs
  19. 356
      src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Single.cs
  20. 8
      src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.cs
  21. 4
      src/Providers.MKL/FourierTransform/MklFourierTransformProvider.cs
  22. 103
      src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Complex.cs
  23. 103
      src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Complex32.cs
  24. 103
      src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Double.cs
  25. 103
      src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Single.cs
  26. 9
      src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.cs
  27. 2
      src/Providers.MKL/SparseSolver/MklSparseSolverProvider.cs
  28. 266
      src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Complex.cs
  29. 268
      src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Complex32.cs
  30. 268
      src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Double.cs
  31. 268
      src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Single.cs
  32. 8
      src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.cs

2
MathNet.Numerics.sln.DotSettings

@ -54,7 +54,9 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
 OTHER DEALINGS IN THE SOFTWARE.
&lt;/copyright&gt;</s:String> &lt;/copyright&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BLAS/@EntryIndexedValue">BLAS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CDF/@EntryIndexedValue">CDF</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CDF/@EntryIndexedValue">CDF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CUDA/@EntryIndexedValue">CUDA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DFT/@EntryIndexedValue">DFT</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DFT/@EntryIndexedValue">DFT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FFT/@EntryIndexedValue">FFT</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FFT/@EntryIndexedValue">FFT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ILU/@EntryIndexedValue">ILU</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ILU/@EntryIndexedValue">ILU</s:String>

14
src/Numerics.Tests/IntegralTransformsTests/MatchingReferenceTransformTest.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2018 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -321,7 +321,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{ {
// 65536 = 2^16 // 65536 = 2^16
var samples = Generate.RandomComplex32(65536, GetUniform(1)); var samples = Generate.RandomComplex32(65536, GetUniform(1));
Verify(samples, 5, FourierTransformScaling.NoScaling, FourierTransformControl.CreateManaged().Forward, FourierTransformControl.Provider.Forward); Verify(samples, 5, FourierTransformScaling.NoScaling, ManagedFourierTransformProvider.Instance.Forward, FourierTransformControl.Provider.Forward);
} }
[Test] [Test]
@ -329,7 +329,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{ {
// 65536 = 2^16 // 65536 = 2^16
var samples = Generate.RandomComplex(65536, GetUniform(1)); var samples = Generate.RandomComplex(65536, GetUniform(1));
Verify(samples, 10, FourierTransformScaling.NoScaling, FourierTransformControl.CreateManaged().Forward, FourierTransformControl.Provider.Forward); Verify(samples, 10, FourierTransformScaling.NoScaling, ManagedFourierTransformProvider.Instance.Forward, FourierTransformControl.Provider.Forward);
} }
[Test] [Test]
@ -337,7 +337,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{ {
// 30870 = 2*3*3*5*7*7*7 // 30870 = 2*3*3*5*7*7*7
var samples = Generate.RandomComplex32(30870, GetUniform(1)); var samples = Generate.RandomComplex32(30870, GetUniform(1));
Verify(samples, 5, FourierTransformScaling.NoScaling, FourierTransformControl.CreateManaged().Forward, FourierTransformControl.Provider.Forward); Verify(samples, 5, FourierTransformScaling.NoScaling, ManagedFourierTransformProvider.Instance.Forward, FourierTransformControl.Provider.Forward);
} }
[Test] [Test]
@ -345,21 +345,21 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{ {
// 30870 = 2*3*3*5*7*7*7 // 30870 = 2*3*3*5*7*7*7
var samples = Generate.RandomComplex(30870, GetUniform(1)); var samples = Generate.RandomComplex(30870, GetUniform(1));
Verify(samples, 10, FourierTransformScaling.NoScaling, FourierTransformControl.CreateManaged().Forward, FourierTransformControl.Provider.Forward); Verify(samples, 10, FourierTransformScaling.NoScaling, ManagedFourierTransformProvider.Instance.Forward, FourierTransformControl.Provider.Forward);
} }
[Test] [Test]
public void ProviderMatchesManagedProviderArbitraryLarge32_GH286() public void ProviderMatchesManagedProviderArbitraryLarge32_GH286()
{ {
var samples = Generate.RandomComplex32(46500, GetUniform(1)); var samples = Generate.RandomComplex32(46500, GetUniform(1));
Verify(samples, 5, FourierTransformScaling.NoScaling, FourierTransformControl.CreateManaged().Forward, FourierTransformControl.Provider.Forward); Verify(samples, 5, FourierTransformScaling.NoScaling, ManagedFourierTransformProvider.Instance.Forward, FourierTransformControl.Provider.Forward);
} }
[Test] [Test]
public void ProviderMatchesManagedProviderArbitraryLarge64_GH286() public void ProviderMatchesManagedProviderArbitraryLarge64_GH286()
{ {
var samples = Generate.RandomComplex(46500, GetUniform(1)); var samples = Generate.RandomComplex(46500, GetUniform(1));
Verify(samples, 10, FourierTransformScaling.NoScaling, FourierTransformControl.CreateManaged().Forward, FourierTransformControl.Provider.Forward); Verify(samples, 10, FourierTransformScaling.NoScaling, ManagedFourierTransformProvider.Instance.Forward, FourierTransformControl.Provider.Forward);
} }
[Test, Explicit("Long-Running")] [Test, Explicit("Long-Running")]

3
src/Numerics/Providers/FourierTransform/FourierTransformControl.cs

@ -79,8 +79,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
} }
} }
public static IFourierTransformProvider CreateManaged() => new ManagedFourierTransformProvider(); public static void UseManaged() => Provider = ManagedFourierTransformProvider.Instance;
public static void UseManaged() => Provider = CreateManaged();
public static void UseNativeMKL() => Provider = MklProbe.Create(); public static void UseNativeMKL() => Provider = MklProbe.Create();
public static bool TryUseNativeMKL() => TryUse(MklProbe.TryCreate()); public static bool TryUseNativeMKL() => TryUse(MklProbe.TryCreate());

24
src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.Bluestein.cs

@ -2,7 +2,7 @@
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// https://numerics.mathdotnet.com // https://numerics.mathdotnet.com
// //
// Copyright (c) 2009-2018 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -32,7 +32,7 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.FourierTransform namespace MathNet.Numerics.Providers.FourierTransform
{ {
internal partial class ManagedFourierTransformProvider public partial class ManagedFourierTransformProvider
{ {
/// <summary> /// <summary>
/// Sequences with length greater than Math.Sqrt(Int32.MaxValue) + 1 /// Sequences with length greater than Math.Sqrt(Int32.MaxValue) + 1
@ -45,7 +45,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary> /// </summary>
/// <param name="n">Number of samples.</param> /// <param name="n">Number of samples.</param>
/// <returns>Bluestein sequence exp(I*Pi*k^2/N)</returns> /// <returns>Bluestein sequence exp(I*Pi*k^2/N)</returns>
private static Complex32[] BluesteinSequence32(int n) static Complex32[] BluesteinSequence32(int n)
{ {
double s = Constants.Pi / n; double s = Constants.Pi / n;
var sequence = new Complex32[n]; var sequence = new Complex32[n];
@ -77,7 +77,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary> /// </summary>
/// <param name="n">Number of samples.</param> /// <param name="n">Number of samples.</param>
/// <returns>Bluestein sequence exp(I*Pi*k^2/N)</returns> /// <returns>Bluestein sequence exp(I*Pi*k^2/N)</returns>
private static Complex[] BluesteinSequence(int n) static Complex[] BluesteinSequence(int n)
{ {
double s = Constants.Pi / n; double s = Constants.Pi / n;
var sequence = new Complex[n]; var sequence = new Complex[n];
@ -108,7 +108,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Convolution with the bluestein sequence (Parallel Version). /// Convolution with the bluestein sequence (Parallel Version).
/// </summary> /// </summary>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void BluesteinConvolutionParallel(Complex32[] samples) static void BluesteinConvolutionParallel(Complex32[] samples)
{ {
int n = samples.Length; int n = samples.Length;
Complex32[] sequence = BluesteinSequence32(n); Complex32[] sequence = BluesteinSequence32(n);
@ -163,7 +163,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Convolution with the bluestein sequence (Parallel Version). /// Convolution with the bluestein sequence (Parallel Version).
/// </summary> /// </summary>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void BluesteinConvolutionParallel(Complex[] samples) static void BluesteinConvolutionParallel(Complex[] samples)
{ {
int n = samples.Length; int n = samples.Length;
Complex[] sequence = BluesteinSequence(n); Complex[] sequence = BluesteinSequence(n);
@ -218,7 +218,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Swap the real and imaginary parts of each sample. /// Swap the real and imaginary parts of each sample.
/// </summary> /// </summary>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void SwapRealImaginary(Complex32[] samples) static void SwapRealImaginary(Complex32[] samples)
{ {
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
@ -230,7 +230,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Swap the real and imaginary parts of each sample. /// Swap the real and imaginary parts of each sample.
/// </summary> /// </summary>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void SwapRealImaginary(Complex[] samples) static void SwapRealImaginary(Complex[] samples)
{ {
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
@ -241,7 +241,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors. /// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary> /// </summary>
private static void BluesteinForward(Complex[] samples) static void BluesteinForward(Complex[] samples)
{ {
BluesteinConvolutionParallel(samples); BluesteinConvolutionParallel(samples);
} }
@ -249,7 +249,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors. /// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary> /// </summary>
private static void BluesteinInverse(Complex[] spectrum) static void BluesteinInverse(Complex[] spectrum)
{ {
SwapRealImaginary(spectrum); SwapRealImaginary(spectrum);
BluesteinConvolutionParallel(spectrum); BluesteinConvolutionParallel(spectrum);
@ -259,7 +259,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors. /// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary> /// </summary>
private static void BluesteinForward(Complex32[] samples) static void BluesteinForward(Complex32[] samples)
{ {
BluesteinConvolutionParallel(samples); BluesteinConvolutionParallel(samples);
} }
@ -267,7 +267,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors. /// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary> /// </summary>
private static void BluesteinInverse(Complex32[] spectrum) static void BluesteinInverse(Complex32[] spectrum)
{ {
SwapRealImaginary(spectrum); SwapRealImaginary(spectrum);
BluesteinConvolutionParallel(spectrum); BluesteinConvolutionParallel(spectrum);

26
src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.Radix2.cs

@ -2,7 +2,7 @@
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// https://numerics.mathdotnet.com // https://numerics.mathdotnet.com
// //
// Copyright (c) 2009-2018 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -33,14 +33,14 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.FourierTransform namespace MathNet.Numerics.Providers.FourierTransform
{ {
internal partial class ManagedFourierTransformProvider public partial class ManagedFourierTransformProvider
{ {
/// <summary> /// <summary>
/// Radix-2 Reorder Helper Method /// Radix-2 Reorder Helper Method
/// </summary> /// </summary>
/// <typeparam name="T">Sample type</typeparam> /// <typeparam name="T">Sample type</typeparam>
/// <param name="samples">Sample vector</param> /// <param name="samples">Sample vector</param>
private static void Radix2Reorder<T>(T[] samples) static void Radix2Reorder<T>(T[] samples)
{ {
var j = 0; var j = 0;
for (var i = 0; i < samples.Length - 1; i++) for (var i = 0; i < samples.Length - 1; i++)
@ -73,7 +73,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
#if !NET40 #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif #endif
private static void Radix2Step(Complex32[] samples, int exponentSign, int levelSize, int k) static void Radix2Step(Complex32[] samples, int exponentSign, int levelSize, int k)
{ {
// Twiddle Factor // Twiddle Factor
var exponent = (exponentSign * k) * Constants.Pi / levelSize; var exponent = (exponentSign * k) * Constants.Pi / levelSize;
@ -99,7 +99,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
#if !NET40 #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif #endif
private static void Radix2Step(Complex[] samples, int exponentSign, int levelSize, int k) static void Radix2Step(Complex[] samples, int exponentSign, int levelSize, int k)
{ {
// Twiddle Factor // Twiddle Factor
var exponent = (exponentSign * k) * Constants.Pi / levelSize; var exponent = (exponentSign * k) * Constants.Pi / levelSize;
@ -118,7 +118,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors. /// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary> /// </summary>
private static void Radix2Forward(Complex32[] data) static void Radix2Forward(Complex32[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -133,7 +133,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors. /// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary> /// </summary>
private static void Radix2Forward(Complex[] data) static void Radix2Forward(Complex[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -148,7 +148,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors. /// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary> /// </summary>
private static void Radix2Inverse(Complex32[] data) static void Radix2Inverse(Complex32[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -163,7 +163,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors. /// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary> /// </summary>
private static void Radix2Inverse(Complex[] data) static void Radix2Inverse(Complex[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -178,7 +178,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version). /// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary> /// </summary>
private static void Radix2ForwardParallel(Complex32[] data) static void Radix2ForwardParallel(Complex32[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -198,7 +198,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version). /// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary> /// </summary>
private static void Radix2ForwardParallel(Complex[] data) static void Radix2ForwardParallel(Complex[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -218,7 +218,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version). /// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary> /// </summary>
private static void Radix2InverseParallel(Complex32[] data) static void Radix2InverseParallel(Complex32[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -238,7 +238,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version). /// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary> /// </summary>
private static void Radix2InverseParallel(Complex[] data) static void Radix2InverseParallel(Complex[] data)
{ {
Radix2Reorder(data); Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2) for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)

90
src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.Scaling.cs

@ -0,0 +1,90 @@
// <copyright file="ManagedFourierTransformProvider.Scaling.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// https://numerics.mathdotnet.com
//
// Copyright (c) 2009-2021 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.FourierTransform
{
public partial class ManagedFourierTransformProvider
{
/// <summary>
/// Fully rescale the FFT result.
/// </summary>
/// <param name="samples">Sample Vector.</param>
static void FullRescale(Complex32[] samples)
{
var scalingFactor = (float)1.0 / samples.Length;
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Fully rescale the FFT result.
/// </summary>
/// <param name="samples">Sample Vector.</param>
static void FullRescale(Complex[] samples)
{
var scalingFactor = 1.0 / samples.Length;
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Half rescale the FFT result (e.g. for symmetric transforms).
/// </summary>
/// <param name="samples">Sample Vector.</param>
static void HalfRescale(Complex32[] samples)
{
var scalingFactor = (float)Math.Sqrt(1.0 / samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Fully rescale the FFT result (e.g. for symmetric transforms).
/// </summary>
/// <param name="samples">Sample Vector.</param>
static void HalfRescale(Complex[] samples)
{
var scalingFactor = Math.Sqrt(1.0 / samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
}
}

60
src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs

@ -2,7 +2,7 @@
// Math.NET Numerics, part of the Math.NET Project // Math.NET Numerics, part of the Math.NET Project
// https://numerics.mathdotnet.com // https://numerics.mathdotnet.com
// //
// Copyright (c) 2009-2018 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -31,8 +31,10 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.FourierTransform namespace MathNet.Numerics.Providers.FourierTransform
{ {
internal partial class ManagedFourierTransformProvider : IFourierTransformProvider public sealed partial class ManagedFourierTransformProvider : IFourierTransformProvider
{ {
public static ManagedFourierTransformProvider Instance { get; } = new ManagedFourierTransformProvider();
/// <summary> /// <summary>
/// Try to find out whether the provider is available, at least in principle. /// Try to find out whether the provider is available, at least in principle.
/// Verification may still fail if available, but it will certainly fail if unavailable. /// Verification may still fail if available, but it will certainly fail if unavailable.
@ -53,7 +55,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Frees memory buffers, caches and handles allocated in or to the provider. /// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards. /// Does not unload the provider itself, it is still usable afterwards.
/// </summary> /// </summary>
public virtual void FreeResources() public void FreeResources()
{ {
} }
@ -335,57 +337,5 @@ namespace MathNet.Numerics.Providers.FourierTransform
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
/// <summary>
/// Fully rescale the FFT result.
/// </summary>
/// <param name="samples">Sample Vector.</param>
private static void FullRescale(Complex32[] samples)
{
var scalingFactor = (float)1.0 / samples.Length;
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Fully rescale the FFT result.
/// </summary>
/// <param name="samples">Sample Vector.</param>
private static void FullRescale(Complex[] samples)
{
var scalingFactor = 1.0 / samples.Length;
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Half rescale the FFT result (e.g. for symmetric transforms).
/// </summary>
/// <param name="samples">Sample Vector.</param>
private static void HalfRescale(Complex32[] samples)
{
var scalingFactor = (float)Math.Sqrt(1.0 / samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Fully rescale the FFT result (e.g. for symmetric transforms).
/// </summary>
/// <param name="samples">Sample Vector.</param>
private static void HalfRescale(Complex[] samples)
{
var scalingFactor = Math.Sqrt(1.0 / samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
} }
} }

3
src/Numerics/Providers/LinearAlgebra/LinearAlgebraControl.cs

@ -86,8 +86,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
} }
} }
public static ILinearAlgebraProvider CreateManaged() => new ManagedLinearAlgebraProvider(); public static void UseManaged() => Provider = ManagedLinearAlgebraProvider.Instance;
public static void UseManaged() => Provider = CreateManaged();
public static void UseNativeMKL() => Provider = MklProbe.Create(); public static void UseNativeMKL() => Provider = MklProbe.Create();
public static bool TryUseNativeMKL() => TryUse(MklProbe.TryCreate()); public static bool TryUseNativeMKL() => TryUse(MklProbe.TryCreate());

62
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2020 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -48,7 +48,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The vector to add to <paramref name="y"/>.</param> /// <param name="x">The vector to add to <paramref name="y"/>.</param>
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
public virtual void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result) public void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param> /// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
public virtual void ScaleArray(Complex alpha, Complex[] x, Complex[] result) public void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{ {
if (x == null) if (x == null)
{ {
@ -121,7 +121,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary> /// </summary>
/// <param name="x">The values to conjugate.</param> /// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param> /// <param name="result">This result of the conjugation.</param>
public virtual void ConjugateArray(Complex[] x, Complex[] result) public void ConjugateArray(Complex[] x, Complex[] result)
{ {
if (x == null) if (x == null)
{ {
@ -141,7 +141,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param> /// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual Complex DotProduct(Complex[] x, Complex[] y) public Complex DotProduct(Complex[] x, Complex[] y)
{ {
if (y == null) if (y == null)
{ {
@ -177,7 +177,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void AddArrays(Complex[] x, Complex[] y, Complex[] result) public void AddArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -215,7 +215,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void SubtractArrays(Complex[] x, Complex[] y, Complex[] result) public void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -253,7 +253,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result) public void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -291,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result) public void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -332,7 +332,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result) public void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -373,7 +373,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns> /// <returns>
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
public virtual double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{ {
switch (norm) switch (norm)
{ {
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0 and beta set to 0.0, and x and y are not transposed.</remarks>
public virtual void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result) public void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result)
{ {
if (x == null) if (x == null)
{ {
@ -551,7 +551,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param> /// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param>
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
public virtual void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex alpha, Complex[] a, int rowsA, int columnsA, Complex[] b, int rowsB, int columnsB, Complex beta, Complex[] c) public 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) if (a == null)
{ {
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="data"/>.</param> /// <param name="order">The order of the square matrix <paramref name="data"/>.</param>
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
public virtual void LUFactor(Complex[] data, int order, int[] ipiv) public void LUFactor(Complex[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -777,7 +777,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param> /// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
public virtual void LUInverse(Complex[] a, int order) public void LUInverse(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
public virtual void LUInverseFactored(Complex[] a, int order, int[] ipiv) public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -841,7 +841,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public virtual void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b) public void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
public virtual void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b) public void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param> /// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
public virtual void CholeskyFactor(Complex[] a, int order) public void CholeskyFactor(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -1070,7 +1070,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks>
public virtual void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1106,7 +1106,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
public virtual void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau) public void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1249,7 +1249,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void ThinQRFactor(Complex[] a, int rowsA, int columnsA, Complex[] r, Complex[] tau) public void ThinQRFactor(Complex[] a, int rowsA, int columnsA, Complex[] r, Complex[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1435,7 +1435,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full) public void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -1507,7 +1507,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -1633,7 +1633,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed /// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
public virtual void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt) public void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -2294,7 +2294,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x) public void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x)
{ {
if (a == null) if (a == null)
{ {
@ -2342,7 +2342,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolveFactored(int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] b, int columnsB, Complex[] x) public void SvdSolveFactored(int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] b, int columnsB, Complex[] x)
{ {
if (s == null) if (s == null)
{ {
@ -2437,7 +2437,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public virtual void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD) public void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -3229,7 +3229,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary> /// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed. /// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </summary> /// </summary>
protected static void GetRow(Transpose transpose, int rowindx, int numRows, int numCols, Complex[] matrix, Complex[] row) static void GetRow(Transpose transpose, int rowindx, int numRows, int numCols, Complex[] matrix, Complex[] row)
{ {
if (transpose == Transpose.DontTranspose) if (transpose == Transpose.DontTranspose)
{ {
@ -3255,7 +3255,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary> /// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed. /// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </summary> /// </summary>
protected static void GetColumn(Transpose transpose, int colindx, int numRows, int numCols, Complex[] matrix, Complex[] column) static void GetColumn(Transpose transpose, int colindx, int numRows, int numCols, Complex[] matrix, Complex[] column)
{ {
if (transpose == Transpose.DontTranspose) if (transpose == Transpose.DontTranspose)
{ {

62
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2020 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -48,7 +48,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The vector to add to <paramref name="y"/>.</param> /// <param name="x">The vector to add to <paramref name="y"/>.</param>
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
public virtual void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result) public void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -93,7 +93,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param> /// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
public virtual void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result) public void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (x == null) if (x == null)
{ {
@ -122,7 +122,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary> /// </summary>
/// <param name="x">The values to conjugate.</param> /// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param> /// <param name="result">This result of the conjugation.</param>
public virtual void ConjugateArray(Complex32[] x, Complex32[] result) public void ConjugateArray(Complex32[] x, Complex32[] result)
{ {
if (x == null) if (x == null)
{ {
@ -142,7 +142,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param> /// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual Complex32 DotProduct(Complex32[] x, Complex32[] y) public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{ {
if (y == null) if (y == null)
{ {
@ -178,7 +178,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -216,7 +216,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -254,7 +254,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -292,7 +292,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -333,7 +333,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -372,7 +372,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="columns">The number of columns.</param> /// <param name="columns">The number of columns.</param>
/// <param name="matrix">The matrix to compute the norm from.</param> /// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>The requested <see cref="Norm"/> of the matrix.</returns> /// <returns>The requested <see cref="Norm"/> of the matrix.</returns>
public virtual double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{ {
switch (norm) switch (norm)
{ {
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0 and beta set to 0.0, and x and y are not transposed.</remarks>
public virtual void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result) public void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result)
{ {
if (x == null) if (x == null)
{ {
@ -551,7 +551,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param> /// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param>
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
public virtual void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, Complex32 alpha, Complex32[] a, int rowsA, int columnsA, Complex32[] b, int rowsB, int columnsB, Complex32 beta, Complex32[] c) public 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) if (a == null)
{ {
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="data"/>.</param> /// <param name="order">The order of the square matrix <paramref name="data"/>.</param>
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
public virtual void LUFactor(Complex32[] data, int order, int[] ipiv) public void LUFactor(Complex32[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -777,7 +777,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param> /// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
public virtual void LUInverse(Complex32[] a, int order) public void LUInverse(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
public virtual void LUInverseFactored(Complex32[] a, int order, int[] ipiv) public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -841,7 +841,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public virtual void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b) public void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
public virtual void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b) public void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param> /// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
public virtual void CholeskyFactor(Complex32[] a, int order) public void CholeskyFactor(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -1070,7 +1070,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks>
public virtual void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1106,7 +1106,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
public virtual void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau) public void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1249,7 +1249,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void ThinQRFactor(Complex32[] a, int rowsA, int columnsA, Complex32[] r, Complex32[] tau) public void ThinQRFactor(Complex32[] a, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1435,7 +1435,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full) public void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -1505,7 +1505,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -1631,7 +1631,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed /// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
public virtual void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt) public void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -2292,7 +2292,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x) public void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x)
{ {
if (a == null) if (a == null)
{ {
@ -2340,7 +2340,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolveFactored(int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] b, int columnsB, Complex32[] x) public void SvdSolveFactored(int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] b, int columnsB, Complex32[] x)
{ {
if (s == null) if (s == null)
{ {
@ -2435,7 +2435,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public virtual void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD) public void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -3231,7 +3231,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary> /// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed. /// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </summary> /// </summary>
protected static void GetRow(Transpose transpose, int rowindx, int numRows, int numCols, Complex32[] matrix, Complex32[] row) static void GetRow(Transpose transpose, int rowindx, int numRows, int numCols, Complex32[] matrix, Complex32[] row)
{ {
if (transpose == Transpose.DontTranspose) if (transpose == Transpose.DontTranspose)
{ {
@ -3257,7 +3257,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary> /// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed. /// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </summary> /// </summary>
protected static void GetColumn(Transpose transpose, int colindx, int numRows, int numCols, Complex32[] matrix, Complex32[] column) static void GetColumn(Transpose transpose, int colindx, int numRows, int numCols, Complex32[] matrix, Complex32[] column)
{ {
if (transpose == Transpose.DontTranspose) if (transpose == Transpose.DontTranspose)
{ {

58
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2020 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -48,7 +48,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The vector to add to <paramref name="y"/>.</param> /// <param name="x">The vector to add to <paramref name="y"/>.</param>
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
public virtual void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result) public void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param> /// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
public virtual void ScaleArray(double alpha, double[] x, double[] result) public void ScaleArray(double alpha, double[] x, double[] result)
{ {
if (x == null) if (x == null)
{ {
@ -121,7 +121,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary> /// </summary>
/// <param name="x">The values to conjugate.</param> /// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param> /// <param name="result">This result of the conjugation.</param>
public virtual void ConjugateArray(double[] x, double[] result) public void ConjugateArray(double[] x, double[] result)
{ {
if (x == null) if (x == null)
{ {
@ -141,7 +141,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param> /// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual double DotProduct(double[] x, double[] y) public double DotProduct(double[] x, double[] y)
{ {
if (y == null) if (y == null)
{ {
@ -177,7 +177,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void AddArrays(double[] x, double[] y, double[] result) public void AddArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -215,7 +215,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void SubtractArrays(double[] x, double[] y, double[] result) public void SubtractArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -253,7 +253,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseMultiplyArrays(double[] x, double[] y, double[] result) public void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -291,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseDivideArrays(double[] x, double[] y, double[] result) public void PointWiseDivideArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -332,7 +332,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWisePowerArrays(double[] x, double[] y, double[] result) public void PointWisePowerArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -373,7 +373,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns> /// <returns>
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
public virtual double MatrixNorm(Norm norm, int rows, int columns, double[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, double[] matrix)
{ {
switch (norm) switch (norm)
{ {
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0 and beta set to 0.0, and x and y are not transposed.</remarks>
public virtual void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) public void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result)
{ {
if (x == null) if (x == null)
{ {
@ -551,7 +551,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param> /// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param>
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
public virtual void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, double alpha, double[] a, int rowsA, int columnsA, double[] b, int rowsB, int columnsB, double beta, double[] c) public 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) if (a == null)
{ {
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="data"/>.</param> /// <param name="order">The order of the square matrix <paramref name="data"/>.</param>
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
public virtual void LUFactor(double[] data, int order, int[] ipiv) public void LUFactor(double[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -777,7 +777,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param> /// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
public virtual void LUInverse(double[] a, int order) public void LUInverse(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
public virtual void LUInverseFactored(double[] a, int order, int[] ipiv) public void LUInverseFactored(double[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -841,7 +841,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public virtual void LUSolve(int columnsOfB, double[] a, int order, double[] b) public void LUSolve(int columnsOfB, double[] a, int order, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
public virtual void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b) public void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param> /// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
public virtual void CholeskyFactor(double[] a, int order) public void CholeskyFactor(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -1070,7 +1070,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks>
public virtual void CholeskySolve(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolve(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1106,7 +1106,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
public virtual void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau) public void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1248,7 +1248,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void ThinQRFactor(double[] a, int rowsA, int columnsA, double[] r, double[] tau) public void ThinQRFactor(double[] a, int rowsA, int columnsA, double[] r, double[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1434,7 +1434,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full) public void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -1504,7 +1504,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -1630,7 +1630,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed /// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
public virtual void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt) public void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -2352,7 +2352,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x) public void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x)
{ {
if (a == null) if (a == null)
{ {
@ -2399,7 +2399,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolveFactored(int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] b, int columnsB, double[] x) public void SvdSolveFactored(int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] b, int columnsB, double[] x)
{ {
if (s == null) if (s == null)
{ {
@ -2494,7 +2494,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public virtual void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD) public void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

58
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2020 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -48,7 +48,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The vector to add to <paramref name="y"/>.</param> /// <param name="x">The vector to add to <paramref name="y"/>.</param>
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
public virtual void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result) public void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param> /// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
public virtual void ScaleArray(float alpha, float[] x, float[] result) public void ScaleArray(float alpha, float[] x, float[] result)
{ {
if (x == null) if (x == null)
{ {
@ -121,7 +121,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary> /// </summary>
/// <param name="x">The values to conjugate.</param> /// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param> /// <param name="result">This result of the conjugation.</param>
public virtual void ConjugateArray(float[] x, float[] result) public void ConjugateArray(float[] x, float[] result)
{ {
if (x == null) if (x == null)
{ {
@ -141,7 +141,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param> /// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual float DotProduct(float[] x, float[] y) public float DotProduct(float[] x, float[] y)
{ {
if (y == null) if (y == null)
{ {
@ -177,7 +177,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void AddArrays(float[] x, float[] y, float[] result) public void AddArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -215,7 +215,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void SubtractArrays(float[] x, float[] y, float[] result) public void SubtractArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -253,7 +253,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseMultiplyArrays(float[] x, float[] y, float[] result) public void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -291,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWiseDivideArrays(float[] x, float[] y, float[] result) public void PointWiseDivideArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -332,7 +332,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public virtual void PointWisePowerArrays(float[] x, float[] y, float[] result) public void PointWisePowerArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -373,7 +373,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns> /// <returns>
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
public virtual double MatrixNorm(Norm norm, int rows, int columns, float[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{ {
switch (norm) switch (norm)
{ {
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0 and beta set to 0.0, and x and y are not transposed.</remarks>
public virtual void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result) public void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result)
{ {
if (x == null) if (x == null)
{ {
@ -551,7 +551,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param> /// <param name="columnsB">The number of columns in the <paramref name="b"/> matrix.</param>
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
public virtual void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, float alpha, float[] a, int rowsA, int columnsA, float[] b, int rowsB, int columnsB, float beta, float[] c) public 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) if (a == null)
{ {
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="data"/>.</param> /// <param name="order">The order of the square matrix <paramref name="data"/>.</param>
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
public virtual void LUFactor(float[] data, int order, int[] ipiv) public void LUFactor(float[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -777,7 +777,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param> /// <param name="a">The N by N matrix to invert. Contains the inverse On exit.</param>
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
public virtual void LUInverse(float[] a, int order) public void LUInverse(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
public virtual void LUInverseFactored(float[] a, int order, int[] ipiv) public void LUInverseFactored(float[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -841,7 +841,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
public virtual void LUSolve(int columnsOfB, float[] a, int order, float[] b) public void LUSolve(int columnsOfB, float[] a, int order, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
public virtual void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b) public void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param> /// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
public virtual void CholeskyFactor(float[] a, int order) public void CholeskyFactor(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -1070,7 +1070,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.</remarks>
public virtual void CholeskySolve(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolve(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1106,7 +1106,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
public virtual void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau) public void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1249,7 +1249,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="tau">A min(m,n) vector. On exit, contains additional information /// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public virtual void ThinQRFactor(float[] a, int rowsA, int columnsA, float[] r, float[] tau) public void ThinQRFactor(float[] a, int rowsA, int columnsA, float[] r, float[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -1437,7 +1437,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full) public void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -1507,7 +1507,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
public virtual void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -1633,7 +1633,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed /// <param name="vt">If <paramref name="computeVectors"/> is <c>true</c>, on exit VT contains the transposed
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
public virtual void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt) public void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -2357,7 +2357,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x) public void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x)
{ {
if (a == null) if (a == null)
{ {
@ -2405,7 +2405,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public virtual void SvdSolveFactored(int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] b, int columnsB, float[] x) public void SvdSolveFactored(int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] b, int columnsB, float[] x)
{ {
if (s == null) if (s == null)
{ {
@ -2500,7 +2500,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public virtual void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD) public void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

12
src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2020 Math.NET // Copyright (c) 2009-2021 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -34,13 +34,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary> /// <summary>
/// The managed linear algebra provider. /// The managed linear algebra provider.
/// </summary> /// </summary>
public partial class ManagedLinearAlgebraProvider : ILinearAlgebraProvider public sealed partial class ManagedLinearAlgebraProvider : ILinearAlgebraProvider
{ {
public static ManagedLinearAlgebraProvider Instance { get; } = new ManagedLinearAlgebraProvider();
/// <summary> /// <summary>
/// Try to find out whether the provider is available, at least in principle. /// Try to find out whether the provider is available, at least in principle.
/// Verification may still fail if available, but it will certainly fail if unavailable. /// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary> /// </summary>
public virtual bool IsAvailable() public bool IsAvailable()
{ {
return true; return true;
} }
@ -48,7 +50,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary> /// <summary>
/// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider /// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider
/// </summary> /// </summary>
public virtual void InitializeVerify() public void InitializeVerify()
{ {
} }
@ -56,7 +58,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// Frees memory buffers, caches and handles allocated in or to the provider. /// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards. /// Does not unload the provider itself, it is still usable afterwards.
/// </summary> /// </summary>
public virtual void FreeResources() public void FreeResources()
{ {
} }

4
src/Numerics/Providers/SparseSolver/ManagedSparseSolverProvider.cs

@ -6,8 +6,10 @@ namespace MathNet.Numerics.Providers.SparseSolver
/// <summary> /// <summary>
/// The managed sparse solver provider /// The managed sparse solver provider
/// </summary> /// </summary>
internal class ManagedSparseSolverProvider : ISparseSolverProvider public sealed class ManagedSparseSolverProvider : ISparseSolverProvider
{ {
public static ManagedSparseSolverProvider Instance { get; } = new ManagedSparseSolverProvider();
/// <summary> /// <summary>
/// Try to find out whether the provider is available, at least in principle. /// Try to find out whether the provider is available, at least in principle.
/// Verification may still fail if available, but it will certainly fail if unavailable. /// Verification may still fail if available, but it will certainly fail if unavailable.

16
src/Numerics/Providers/SparseSolver/SparseSolverControl.cs

@ -79,8 +79,7 @@ namespace MathNet.Numerics.Providers.SparseSolver
} }
} }
public static ISparseSolverProvider CreateManaged() => new ManagedSparseSolverProvider(); public static void UseManaged() => Provider = ManagedSparseSolverProvider.Instance;
public static void UseManaged() => Provider = CreateManaged();
public static void UseNativeMKL() => Provider = MklProbe.Create(); public static void UseNativeMKL() => Provider = MklProbe.Create();
public static bool TryUseNativeMKL() => TryUse(MklProbe.TryCreate()); public static bool TryUseNativeMKL() => TryUse(MklProbe.TryCreate());
@ -117,19 +116,6 @@ namespace MathNet.Numerics.Providers.SparseSolver
} }
} }
public static bool TryUse(Lazy<IProviderCreator<ISparseSolverProvider>> providerCreator)
{
try
{
return TryUse(providerCreator.Value?.CreateProvider());
}
catch
{
// intentionally swallow exceptions here - use the explicit variants if you're interested in why
return false;
}
}
/// <summary> /// <summary>
/// Use the best provider available. /// Use the best provider available.
/// </summary> /// </summary>

355
src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Complex.cs

@ -29,6 +29,7 @@
using System; using System;
using System.Security; using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra; using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex; using Complex = System.Numerics.Complex;
@ -39,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary> /// </summary>
internal partial class CudaLinearAlgebraProvider internal partial class CudaLinearAlgebraProvider
{ {
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{
return ManagedLinearAlgebraProvider.Instance.MatrixNorm(norm, rows, columns, matrix);
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -47,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override Complex DotProduct(Complex[] x, Complex[] y) public Complex DotProduct(Complex[] x, Complex[] y)
{ {
if (y == null) if (y == null)
{ {
@ -67,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
return SafeNativeMethods.z_dot_product(_blasHandle, x.Length, x, y); return SafeNativeMethods.z_dot_product(_blasHandle, x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}
/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = Complex.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -76,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result) public void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -114,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result) public void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{ {
if (x == null) if (x == null)
{ {
@ -134,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SafeNativeMethods.z_scale(_blasHandle, x.Length, alpha, result); SafeNativeMethods.z_scale(_blasHandle, x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(Complex[] x, Complex[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i].Conjugate();
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -146,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to Complex.One and beta set to Complex.Zero, and x and y are not transposed.</remarks>
public override void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex.Zero, result);
} }
@ -166,7 +390,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -211,7 +435,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(Complex[] data, int order, int[] ipiv) public void LUFactor(Complex[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -243,7 +467,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(Complex[] a, int order) public void LUInverse(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -266,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(Complex[] a, int order, int[] ipiv) public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -300,7 +524,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b) public void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -335,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b) public void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -378,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(Complex[] a, int order) public void CholeskyFactor(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -408,7 +632,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -442,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -467,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
Solver(SafeNativeMethods.z_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b)); Solver(SafeNativeMethods.z_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b));
} }
/// <summary>
/// Computes the QR factorization of A.
/// </summary>
/// <param name="r">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. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="q">On exit, A M by M matrix that holds the Q matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau)
{
ManagedLinearAlgebraProvider.Instance.QRFactor(r, rowsR, columnsR, q, tau);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
{
ManagedLinearAlgebraProvider.Instance.ThinQRFactor(q, rowsA, columnsA, r, tau);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolve(a, rows, columns, b, columnsB, x, method);
}
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, method);
}
/// <summary> /// <summary>
/// Solves A*X=B for X using the singular value decomposition of A. /// Solves A*X=B for X using the singular value decomposition of A.
/// </summary> /// </summary>
@ -476,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x) public void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x)
{ {
if (a == null) if (a == null)
{ {
@ -513,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] b, int columnsB, Complex[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -527,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt) public void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -565,8 +874,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
} }
if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd
base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); ManagedLinearAlgebraProvider.Instance.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt);
else Solver(SafeNativeMethods.z_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); else Solver(SafeNativeMethods.z_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt));
} }
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The length of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD)
{
ManagedLinearAlgebraProvider.Instance.EigenDecomp(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD);
}
} }
} }

356
src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Complex32.cs

@ -29,7 +29,9 @@
using System; using System;
using System.Security; using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra; using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
{ {
@ -38,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary> /// </summary>
internal partial class CudaLinearAlgebraProvider internal partial class CudaLinearAlgebraProvider
{ {
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{
return ManagedLinearAlgebraProvider.Instance.MatrixNorm(norm, rows, columns, matrix);
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -46,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override Complex32 DotProduct(Complex32[] x, Complex32[] y) public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{ {
if (y == null) if (y == null)
{ {
@ -66,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
return SafeNativeMethods.c_dot_product(_blasHandle, x.Length, x, y); return SafeNativeMethods.c_dot_product(_blasHandle, x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}
/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < y.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < y.Length; i++)
{
result[i] = Complex32.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -75,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result) public void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -113,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result) public void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (x == null) if (x == null)
{ {
@ -133,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SafeNativeMethods.c_scale(_blasHandle, x.Length, alpha, result); SafeNativeMethods.c_scale(_blasHandle, x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(Complex32[] x, Complex32[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i].Conjugate();
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -145,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to Complex32.One and beta set to Complex32.Zero, and x and y are not transposed.</remarks>
public override void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex32.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex32.Zero, result);
} }
@ -165,7 +390,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -210,7 +435,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(Complex32[] data, int order, int[] ipiv) public void LUFactor(Complex32[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -242,7 +467,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(Complex32[] a, int order) public void LUInverse(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -265,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv) public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -299,7 +524,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b) public void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -334,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b) public void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -377,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(Complex32[] a, int order) public void CholeskyFactor(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -407,7 +632,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -441,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -466,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
Solver(SafeNativeMethods.c_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b)); Solver(SafeNativeMethods.c_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b));
} }
/// <summary>
/// Computes the QR factorization of A.
/// </summary>
/// <param name="r">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. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="q">On exit, A M by M matrix that holds the Q matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau)
{
ManagedLinearAlgebraProvider.Instance.QRFactor(r, rowsR, columnsR, q, tau);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
{
ManagedLinearAlgebraProvider.Instance.ThinQRFactor(q, rowsA, columnsA, r, tau);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolve(a, rows, columns, b, columnsB, x, method);
}
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, method);
}
/// <summary> /// <summary>
/// Solves A*X=B for X using the singular value decomposition of A. /// Solves A*X=B for X using the singular value decomposition of A.
/// </summary> /// </summary>
@ -475,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x) public void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x)
{ {
if (a == null) if (a == null)
{ {
@ -512,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] b, int columnsB, Complex32[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -526,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt) public void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -564,8 +874,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
} }
if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd
base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); ManagedLinearAlgebraProvider.Instance.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt);
else Solver(SafeNativeMethods.c_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); else Solver(SafeNativeMethods.c_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt));
} }
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The length of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD)
{
ManagedLinearAlgebraProvider.Instance.EigenDecomp(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD);
}
} }
} }

356
src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Double.cs

@ -29,7 +29,9 @@
using System; using System;
using System.Security; using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra; using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
{ {
@ -38,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary> /// </summary>
internal partial class CudaLinearAlgebraProvider internal partial class CudaLinearAlgebraProvider
{ {
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public double MatrixNorm(Norm norm, int rows, int columns, double[] matrix)
{
return ManagedLinearAlgebraProvider.Instance.MatrixNorm(norm, rows, columns, matrix);
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -46,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double DotProduct(double[] x, double[] y) public double DotProduct(double[] x, double[] y)
{ {
if (y == null) if (y == null)
{ {
@ -66,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
return SafeNativeMethods.d_dot_product(_blasHandle, x.Length, x, y); return SafeNativeMethods.d_dot_product(_blasHandle, x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}
/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = Math.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -75,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result) public void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -113,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(double alpha, double[] x, double[] result) public void ScaleArray(double alpha, double[] x, double[] result)
{ {
if (x == null) if (x == null)
{ {
@ -133,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SafeNativeMethods.d_scale(_blasHandle, x.Length, alpha, result); SafeNativeMethods.d_scale(_blasHandle, x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(double[] x, double[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (!ReferenceEquals(x, result))
{
x.CopyTo(result, 0);
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -145,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0 and beta set to 0.0, and x and y are not transposed.</remarks>
public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result);
} }
@ -165,7 +390,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -210,7 +435,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(double[] data, int order, int[] ipiv) public void LUFactor(double[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -242,7 +467,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(double[] a, int order) public void LUInverse(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -265,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(double[] a, int order, int[] ipiv) public void LUInverseFactored(double[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -299,7 +524,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, double[] a, int order, double[] b) public void LUSolve(int columnsOfB, double[] a, int order, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -334,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b) public void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -377,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(double[] a, int order) public void CholeskyFactor(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -407,7 +632,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolve(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -441,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -466,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
Solver(SafeNativeMethods.d_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b)); Solver(SafeNativeMethods.d_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b));
} }
/// <summary>
/// Computes the QR factorization of A.
/// </summary>
/// <param name="r">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. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="q">On exit, A M by M matrix that holds the Q matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau)
{
ManagedLinearAlgebraProvider.Instance.QRFactor(r, rowsR, columnsR, q, tau);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
{
ManagedLinearAlgebraProvider.Instance.ThinQRFactor(q, rowsA, columnsA, r, tau);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolve(a, rows, columns, b, columnsB, x, method);
}
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, method);
}
/// <summary> /// <summary>
/// Solves A*X=B for X using the singular value decomposition of A. /// Solves A*X=B for X using the singular value decomposition of A.
/// </summary> /// </summary>
@ -475,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x) public void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x)
{ {
if (a == null) if (a == null)
{ {
@ -512,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] b, int columnsB, double[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -526,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt) public void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -564,8 +874,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
} }
if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd
base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); ManagedLinearAlgebraProvider.Instance.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt);
else Solver (SafeNativeMethods.d_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); else Solver (SafeNativeMethods.d_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt));
} }
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The length of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD)
{
ManagedLinearAlgebraProvider.Instance.EigenDecomp(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD);
}
} }
} }

356
src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.Single.cs

@ -29,7 +29,9 @@
using System; using System;
using System.Security; using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra; using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
{ {
@ -38,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary> /// </summary>
internal partial class CudaLinearAlgebraProvider internal partial class CudaLinearAlgebraProvider
{ {
/// <summary>
/// Computes the requested <see cref="Norm"/> of the matrix.
/// </summary>
/// <param name="norm">The type of norm to compute.</param>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="matrix">The matrix to compute the norm from.</param>
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </returns>
public double MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{
return ManagedLinearAlgebraProvider.Instance.MatrixNorm(norm, rows, columns, matrix);
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -46,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override float DotProduct(float[] x, float[] y) public float DotProduct(float[] x, float[] y)
{ {
if (y == null) if (y == null)
{ {
@ -66,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
return SafeNativeMethods.s_dot_product(_blasHandle, x.Length, x, y); return SafeNativeMethods.s_dot_product(_blasHandle, x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}
/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = (float)Math.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -75,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result) public void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -113,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(float alpha, float[] x, float[] result) public void ScaleArray(float alpha, float[] x, float[] result)
{ {
if (x == null) if (x == null)
{ {
@ -133,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SafeNativeMethods.s_scale(_blasHandle, x.Length, alpha, result); SafeNativeMethods.s_scale(_blasHandle, x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(float[] x, float[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (!ReferenceEquals(x, result))
{
x.CopyTo(result, 0);
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -145,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0f and beta set to 0.0f, and x and y are not transposed.</remarks>
public override void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0f, x, rowsX, columnsX, y, rowsY, columnsY, 0.0f, result);
} }
@ -165,7 +390,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -210,7 +435,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(float[] data, int order, int[] ipiv) public void LUFactor(float[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -242,7 +467,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(float[] a, int order) public void LUInverse(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -265,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(float[] a, int order, int[] ipiv) public void LUInverseFactored(float[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -299,7 +524,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, float[] a, int order, float[] b) public void LUSolve(int columnsOfB, float[] a, int order, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -334,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b) public void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -377,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(float[] a, int order) public void CholeskyFactor(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -407,7 +632,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolve(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -441,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -466,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
Solver(SafeNativeMethods.s_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b)); Solver(SafeNativeMethods.s_cholesky_solve_factored(_solverHandle, orderA, columnsB, a, b));
} }
/// <summary>
/// Computes the QR factorization of A.
/// </summary>
/// <param name="r">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. </param>
/// <param name="rowsR">The number of rows in the A matrix.</param>
/// <param name="columnsR">The number of columns in the A matrix.</param>
/// <param name="q">On exit, A M by M matrix that holds the Q matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau)
{
ManagedLinearAlgebraProvider.Instance.QRFactor(r, rowsR, columnsR, q, tau);
}
/// <summary>
/// Computes the thin QR factorization of A where M &gt; N.
/// </summary>
/// <param name="q">On entry, it is the M by N A matrix to factor. On exit,
/// it is overwritten with the Q matrix of the QR factorization.</param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="r">On exit, A N by N matrix that holds the R matrix of the
/// QR factorization.</param>
/// <param name="tau">A min(m,n) vector. On exit, contains additional information
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
public void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
{
ManagedLinearAlgebraProvider.Instance.ThinQRFactor(q, rowsA, columnsA, r, tau);
}
/// <summary>
/// Solves A*X=B for X using QR factorization of A.
/// </summary>
/// <param name="a">The A matrix.</param>
/// <param name="rows">The number of rows in the A matrix.</param>
/// <param name="columns">The number of columns in the A matrix.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolve(a, rows, columns, b, columnsB, x, method);
}
/// <summary>
/// Solves A*X=B for X using a previously QR factored matrix.
/// </summary>
/// <param name="q">The Q matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>.</param>
/// <param name="r">The R matrix obtained by calling <see cref="QRFactor(double[],int,int,double[],double[])"/>. </param>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="tau">Contains additional information on Q. Only used for the native solver
/// and can be <c>null</c> for the managed provider.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks>
public void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{
ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, method);
}
/// <summary> /// <summary>
/// Solves A*X=B for X using the singular value decomposition of A. /// Solves A*X=B for X using the singular value decomposition of A.
/// </summary> /// </summary>
@ -475,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x) public void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x)
{ {
if (a == null) if (a == null)
{ {
@ -512,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] b, int columnsB, float[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -526,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt) public void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -564,8 +874,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
} }
if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd if (columnsA > rowsA || !computeVectors) // see remarks http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd
base.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt); ManagedLinearAlgebraProvider.Instance.SingularValueDecomposition(computeVectors, a, rowsA, columnsA, s, u, vt);
else Solver(SafeNativeMethods.s_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt)); else Solver(SafeNativeMethods.s_svd_factor(_solverHandle, computeVectors, rowsA, columnsA, a, s, u, vt));
} }
/// <summary>
/// Computes the eigenvalues and eigenvectors of a matrix.
/// </summary>
/// <param name="isSymmetric">Whether the matrix is symmetric or not.</param>
/// <param name="order">The order of the matrix.</param>
/// <param name="matrix">The matrix to decompose. The length of the array must be order * order.</param>
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD)
{
ManagedLinearAlgebraProvider.Instance.EigenDecomp(isSymmetric, order, matrix, matrixEv, vectorEv, matrixD);
}
} }
} }

8
src/Providers.CUDA/LinearAlgebra/CudaLinearAlgebraProvider.cs

@ -35,7 +35,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <summary> /// <summary>
/// NVidia's CUDA Toolkit linear algebra provider. /// NVidia's CUDA Toolkit linear algebra provider.
/// </summary> /// </summary>
internal partial class CudaLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable internal sealed partial class CudaLinearAlgebraProvider : ILinearAlgebraProvider, IDisposable
{ {
const int MinimumCompatibleRevision = 1; const int MinimumCompatibleRevision = 1;
@ -53,7 +53,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// Try to find out whether the provider is available, at least in principle. /// Try to find out whether the provider is available, at least in principle.
/// Verification may still fail if available, but it will certainly fail if unavailable. /// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary> /// </summary>
public override bool IsAvailable() public bool IsAvailable()
{ {
return CudaProvider.IsAvailable(hintPath: _hintPath); return CudaProvider.IsAvailable(hintPath: _hintPath);
} }
@ -62,7 +62,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// Initialize and verify that the provided is indeed available. /// Initialize and verify that the provided is indeed available.
/// If calling this method fails, consider to fall back to alternatives like the managed provider. /// If calling this method fails, consider to fall back to alternatives like the managed provider.
/// </summary> /// </summary>
public override void InitializeVerify() public void InitializeVerify()
{ {
int revision = CudaProvider.Load(hintPath: _hintPath); int revision = CudaProvider.Load(hintPath: _hintPath);
if (revision < MinimumCompatibleRevision) if (revision < MinimumCompatibleRevision)
@ -86,7 +86,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// Frees memory buffers, caches and handles allocated in or to the provider. /// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards. /// Does not unload the provider itself, it is still usable afterwards.
/// </summary> /// </summary>
public override void FreeResources() public void FreeResources()
{ {
CudaProvider.FreeResources(); CudaProvider.FreeResources();
} }

4
src/Providers.MKL/FourierTransform/MklFourierTransformProvider.cs

@ -34,7 +34,7 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.MKL.FourierTransform namespace MathNet.Numerics.Providers.MKL.FourierTransform
{ {
internal class MklFourierTransformProvider : IFourierTransformProvider, IDisposable internal sealed class MklFourierTransformProvider : IFourierTransformProvider, IDisposable
{ {
const int MinimumCompatibleRevision = 11; const int MinimumCompatibleRevision = 11;
@ -91,7 +91,7 @@ namespace MathNet.Numerics.Providers.MKL.FourierTransform
/// Does not unload the provider itself, it is still usable afterwards. /// Does not unload the provider itself, it is still usable afterwards.
/// </summary> /// </summary>
[SecuritySafeCritical] [SecuritySafeCritical]
public virtual void FreeResources() public void FreeResources()
{ {
Kernel kernel = Interlocked.Exchange(ref _kernel, null); Kernel kernel = Interlocked.Exchange(ref _kernel, null);
if (kernel != null) if (kernel != null)

103
src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Complex.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override Complex DotProduct(Complex[] x, Complex[] y) public Complex DotProduct(Complex[] x, Complex[] y)
{ {
if (y == null) if (y == null)
{ {
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result) public void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result) public void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{ {
if (x == null) if (x == null)
{ {
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SafeNativeMethods.z_scale(x.Length, alpha, result); SafeNativeMethods.z_scale(x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(Complex[] x, Complex[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i].Conjugate();
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to Complex.One and beta set to Complex.Zero, and x and y are not transposed.</remarks>
public override void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex.Zero, result);
} }
@ -203,7 +221,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +266,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(Complex[] data, int order, int[] ipiv) public void LUFactor(Complex[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +303,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(Complex[] a, int order) public void LUInverse(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(Complex[] a, int order, int[] ipiv) public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +385,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b) public void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b) public void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -465,7 +483,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(Complex[] a, int order) public void CholeskyFactor(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -505,7 +523,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -549,7 +567,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -592,7 +610,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau) public void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -640,7 +658,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau) public void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -687,7 +705,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full) public void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -757,7 +775,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -829,7 +847,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -842,7 +860,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x) public void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x)
{ {
if (a == null) if (a == null)
{ {
@ -879,6 +897,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] b, int columnsB, Complex[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -893,7 +927,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt) public void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -958,7 +992,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void AddArrays(Complex[] x, Complex[] y, Complex[] result) public void AddArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -993,7 +1027,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void SubtractArrays(Complex[] x, Complex[] y, Complex[] result) public void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1028,7 +1062,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result) public void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1063,13 +1097,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result) public void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
base.PointWisePowerArrays(x, y, result);
}
if (y == null) if (y == null)
{ {
throw new ArgumentNullException(nameof(y)); throw new ArgumentNullException(nameof(y));
@ -1090,6 +1119,16 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
throw new ArgumentException("The array arguments must have the same length."); throw new ArgumentException("The array arguments must have the same length.");
} }
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
for (int i = 0; i < y.Length; i++)
{
result[i] = Complex.Pow(x[i], y[i]);
}
return;
}
SafeNativeMethods.z_vector_power(x.Length, x, y, result); SafeNativeMethods.z_vector_power(x.Length, x, y, result);
} }
@ -1103,7 +1142,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result) public void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1137,7 +1176,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD) public void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

103
src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Complex32.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override Complex32 DotProduct(Complex32[] x, Complex32[] y) public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{ {
if (y == null) if (y == null)
{ {
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result) public void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result) public void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (x == null) if (x == null)
{ {
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SafeNativeMethods.c_scale(x.Length, alpha, result); SafeNativeMethods.c_scale(x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(Complex32[] x, Complex32[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i].Conjugate();
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to Complex32.One and beta set to Complex32.Zero, and x and y are not transposed.</remarks>
public override void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex32.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex32.Zero, result);
} }
@ -203,7 +221,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +266,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(Complex32[] data, int order, int[] ipiv) public void LUFactor(Complex32[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +303,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(Complex32[] a, int order) public void LUInverse(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv) public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +385,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b) public void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b) public void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -460,7 +478,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(Complex32[] a, int order) public void CholeskyFactor(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -500,7 +518,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -544,7 +562,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -587,7 +605,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau) public void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -635,7 +653,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau) public void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -682,7 +700,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full) public void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -752,7 +770,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -824,7 +842,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -837,7 +855,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x) public void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x)
{ {
if (a == null) if (a == null)
{ {
@ -874,6 +892,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] b, int columnsB, Complex32[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -888,7 +922,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt) public void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -953,7 +987,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -988,7 +1022,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1023,7 +1057,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1058,7 +1092,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1093,13 +1127,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result) public void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{ {
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
base.PointWisePowerArrays(x, y, result);
}
if (y == null) if (y == null)
{ {
throw new ArgumentNullException(nameof(y)); throw new ArgumentNullException(nameof(y));
@ -1120,6 +1149,16 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
throw new ArgumentException("The array arguments must have the same length."); throw new ArgumentException("The array arguments must have the same length.");
} }
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
for (int i = 0; i < y.Length; i++)
{
result[i] = Complex32.Pow(x[i], y[i]);
}
return;
}
SafeNativeMethods.c_vector_power(x.Length, x, y, result); SafeNativeMethods.c_vector_power(x.Length, x, y, result);
} }
@ -1132,7 +1171,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD) public void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

103
src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Double.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, double[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, double[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double DotProduct(double[] x, double[] y) public double DotProduct(double[] x, double[] y)
{ {
if (y == null) if (y == null)
{ {
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result) public void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(double alpha, double[] x, double[] result) public void ScaleArray(double alpha, double[] x, double[] result)
{ {
if (x == null) if (x == null)
{ {
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SafeNativeMethods.d_scale(x.Length, alpha, result); SafeNativeMethods.d_scale(x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(double[] x, double[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (!ReferenceEquals(x, result))
{
x.CopyTo(result, 0);
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0 and beta set to 0.0, and x and y are not transposed.</remarks>
public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result);
} }
@ -203,7 +221,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +266,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(double[] data, int order, int[] ipiv) public void LUFactor(double[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +303,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(double[] a, int order) public void LUInverse(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(double[] a, int order, int[] ipiv) public void LUInverseFactored(double[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +385,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, double[] a, int order, double[] b) public void LUSolve(int columnsOfB, double[] a, int order, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b) public void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -460,7 +478,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(double[] a, int order) public void CholeskyFactor(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -505,7 +523,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolve(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -549,7 +567,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -592,7 +610,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau) public void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -640,7 +658,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau) public void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -687,7 +705,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full) public void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -757,7 +775,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -829,7 +847,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -842,7 +860,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x) public void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x)
{ {
if (a == null) if (a == null)
{ {
@ -879,6 +897,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] b, int columnsB, double[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -893,7 +927,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt) public void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -958,7 +992,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void AddArrays(double[] x, double[] y, double[] result) public void AddArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -993,7 +1027,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void SubtractArrays(double[] x, double[] y, double[] result) public void SubtractArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1028,7 +1062,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseMultiplyArrays(double[] x, double[] y, double[] result) public void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1063,7 +1097,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseDivideArrays(double[] x, double[] y, double[] result) public void PointWiseDivideArrays(double[] x, double[] y, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1098,13 +1132,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWisePowerArrays(double[] x, double[] y, double[] result) public void PointWisePowerArrays(double[] x, double[] y, double[] result)
{ {
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
base.PointWisePowerArrays(x, y, result);
}
if (y == null) if (y == null)
{ {
throw new ArgumentNullException(nameof(y)); throw new ArgumentNullException(nameof(y));
@ -1125,6 +1154,16 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
throw new ArgumentException("The array arguments must have the same length."); throw new ArgumentException("The array arguments must have the same length.");
} }
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
for (int i = 0; i < y.Length; i++)
{
result[i] = Math.Pow(x[i], y[i]);
}
return;
}
SafeNativeMethods.d_vector_power(x.Length, x, y, result); SafeNativeMethods.d_vector_power(x.Length, x, y, result);
} }
@ -1137,7 +1176,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD) public void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

103
src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.Single.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, float[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override float DotProduct(float[] x, float[] y) public float DotProduct(float[] x, float[] y)
{ {
if (y == null) if (y == null)
{ {
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result) public void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(float alpha, float[] x, float[] result) public void ScaleArray(float alpha, float[] x, float[] result)
{ {
if (x == null) if (x == null)
{ {
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SafeNativeMethods.s_scale(x.Length, alpha, result); SafeNativeMethods.s_scale(x.Length, alpha, result);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(float[] x, float[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (!ReferenceEquals(x, result))
{
x.CopyTo(result, 0);
}
}
/// <summary> /// <summary>
/// Multiples two matrices. <c>result = x * y</c> /// Multiples two matrices. <c>result = x * y</c>
/// </summary> /// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0f and beta set to 0.0f, and x and y are not transposed.</remarks>
public override void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0f, x, rowsX, columnsX, y, rowsY, columnsY, 0.0f, result);
} }
@ -203,7 +221,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +266,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(float[] data, int order, int[] ipiv) public void LUFactor(float[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +303,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(float[] a, int order) public void LUInverse(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(float[] a, int order, int[] ipiv) public void LUInverseFactored(float[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +385,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, float[] a, int order, float[] b) public void LUSolve(int columnsOfB, float[] a, int order, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b) public void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -460,7 +478,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(float[] a, int order) public void CholeskyFactor(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -500,7 +518,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolve(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -544,7 +562,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -587,7 +605,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau) public void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -635,7 +653,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau) public void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -682,7 +700,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full) public void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -752,7 +770,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -824,7 +842,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -837,7 +855,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x) public void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x)
{ {
if (a == null) if (a == null)
{ {
@ -874,6 +892,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] b, int columnsB, float[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -888,7 +922,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt) public void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -953,7 +987,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void AddArrays(float[] x, float[] y, float[] result) public void AddArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -988,7 +1022,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void SubtractArrays(float[] x, float[] y, float[] result) public void SubtractArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1023,7 +1057,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseMultiplyArrays(float[] x, float[] y, float[] result) public void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1058,7 +1092,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWiseDivideArrays(float[] x, float[] y, float[] result) public void PointWiseDivideArrays(float[] x, float[] y, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -1093,13 +1127,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries /// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this /// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks> /// routine.</remarks>
public override void PointWisePowerArrays(float[] x, float[] y, float[] result) public void PointWisePowerArrays(float[] x, float[] y, float[] result)
{ {
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
base.PointWisePowerArrays(x, y, result);
}
if (y == null) if (y == null)
{ {
throw new ArgumentNullException(nameof(y)); throw new ArgumentNullException(nameof(y));
@ -1120,6 +1149,16 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
throw new ArgumentException("The array arguments must have the same length."); throw new ArgumentException("The array arguments must have the same length.");
} }
if (_vectorFunctionsMajor != 0 || _vectorFunctionsMinor < 1)
{
for (int i = 0; i < y.Length; i++)
{
result[i] = (float)Math.Pow(x[i], y[i]);
}
return;
}
SafeNativeMethods.s_vector_power(x.Length, x, y, result); SafeNativeMethods.s_vector_power(x.Length, x, y, result);
} }
@ -1132,7 +1171,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD) public void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

9
src/Providers.MKL/LinearAlgebra/MklLinearAlgebraProvider.cs

@ -28,6 +28,7 @@
// </copyright> // </copyright>
using System; using System;
using System.Numerics;
using System.Security; using System.Security;
using MathNet.Numerics.Providers.LinearAlgebra; using MathNet.Numerics.Providers.LinearAlgebra;
@ -47,7 +48,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <summary> /// <summary>
/// Intel's Math Kernel Library (MKL) linear algebra provider. /// Intel's Math Kernel Library (MKL) linear algebra provider.
/// </summary> /// </summary>
internal partial class MklLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable internal sealed partial class MklLinearAlgebraProvider : ILinearAlgebraProvider, IDisposable
{ {
const int MinimumCompatibleRevision = 4; const int MinimumCompatibleRevision = 4;
@ -80,7 +81,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// Try to find out whether the provider is available, at least in principle. /// Try to find out whether the provider is available, at least in principle.
/// Verification may still fail if available, but it will certainly fail if unavailable. /// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary> /// </summary>
public override bool IsAvailable() public bool IsAvailable()
{ {
return MklProvider.IsAvailable(hintPath: _hintPath); return MklProvider.IsAvailable(hintPath: _hintPath);
} }
@ -90,7 +91,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// If calling this method fails, consider to fall back to alternatives like the managed provider. /// If calling this method fails, consider to fall back to alternatives like the managed provider.
/// </summary> /// </summary>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void InitializeVerify() public void InitializeVerify()
{ {
int revision = MklProvider.Load(_hintPath, _consistency, _precision, _accuracy); int revision = MklProvider.Load(_hintPath, _consistency, _precision, _accuracy);
if (revision < MinimumCompatibleRevision) if (revision < MinimumCompatibleRevision)
@ -114,7 +115,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// Frees memory buffers, caches and handles allocated in or to the provider. /// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards. /// Does not unload the provider itself, it is still usable afterwards.
/// </summary> /// </summary>
public override void FreeResources() public void FreeResources()
{ {
MklProvider.FreeResources(); MklProvider.FreeResources();
} }

2
src/Providers.MKL/SparseSolver/MklSparseSolverProvider.cs

@ -6,7 +6,7 @@ namespace MathNet.Numerics.Providers.MKL.SparseSolver
/// <summary> /// <summary>
/// Intel's Math Kernel Library (MKL) sparse solver provider. /// Intel's Math Kernel Library (MKL) sparse solver provider.
/// </summary> /// </summary>
internal partial class MklSparseSolverProvider : ISparseSolverProvider, IDisposable internal sealed partial class MklSparseSolverProvider : ISparseSolverProvider, IDisposable
{ {
const int MinimumCompatibleRevision = 14; const int MinimumCompatibleRevision = 14;

266
src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Complex.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, Complex[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.z_matrix_norm((byte)norm, rows, columns, matrix); return SafeNativeMethods.z_matrix_norm((byte)norm, rows, columns, matrix);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(Complex[] x, Complex[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i].Conjugate();
}
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override Complex DotProduct(Complex[] x, Complex[] y) public Complex DotProduct(Complex[] x, Complex[] y)
{ {
if (y == null) if (y == null)
{ {
@ -104,6 +122,194 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.z_dot_product(x.Length, x, y); return SafeNativeMethods.z_dot_product(x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = Complex.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -113,7 +319,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result) public void AddVectorToScaledVector(Complex[] y, Complex alpha, Complex[] x, Complex[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +357,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result) public void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{ {
if (x == null) if (x == null)
{ {
@ -183,7 +389,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to Complex.One and beta set to Complex.Zero, and x and y are not transposed.</remarks>
public override void MatrixMultiply(Complex[] x, int rowsX, int columnsX, Complex[] y, int rowsY, int columnsY, Complex[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex.Zero, result);
} }
@ -203,7 +409,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +454,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(Complex[] data, int order, int[] ipiv) public void LUFactor(Complex[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +491,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(Complex[] a, int order) public void LUInverse(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +529,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(Complex[] a, int order, int[] ipiv) public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +573,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b) public void LUSolve(int columnsOfB, Complex[] a, int order, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +618,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b) public void LUSolveFactored(int columnsOfB, Complex[] a, int order, int[] ipiv, Complex[] b)
{ {
if (a == null) if (a == null)
{ {
@ -465,7 +671,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(Complex[] a, int order) public void CholeskyFactor(Complex[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -505,7 +711,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolve(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -549,7 +755,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB) public void CholeskySolveFactored(Complex[] a, int orderA, Complex[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -592,7 +798,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau) public void QRFactor(Complex[] r, int rowsR, int columnsR, Complex[] q, Complex[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -640,7 +846,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau) public void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -687,7 +893,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full) public void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -757,7 +963,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(Complex[] q, Complex[] r, int rowsA, int columnsA, Complex[] tau, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -829,7 +1035,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -842,7 +1048,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x) public void SvdSolve(Complex[] a, int rowsA, int columnsA, Complex[] b, int columnsB, Complex[] x)
{ {
if (a == null) if (a == null)
{ {
@ -879,6 +1085,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex[],int,int,Complex[],Complex[],Complex[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt, Complex[] b, int columnsB, Complex[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -893,7 +1115,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt) public void SingularValueDecomposition(bool computeVectors, Complex[] a, int rowsA, int columnsA, Complex[] s, Complex[] u, Complex[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -957,7 +1179,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD) public void EigenDecomp(bool isSymmetric, int order, Complex[] matrix, Complex[] matrixEv, Complex[] vectorEv, Complex[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

268
src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Complex32.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.c_matrix_norm((byte)norm, rows, columns, matrix); return SafeNativeMethods.c_matrix_norm((byte)norm, rows, columns, matrix);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(Complex32[] x, Complex32[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i].Conjugate();
}
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override Complex32 DotProduct(Complex32[] x, Complex32[] y) public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{ {
if (y == null) if (y == null)
{ {
@ -104,6 +122,196 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.c_dot_product(x.Length, x, y); return SafeNativeMethods.c_dot_product(x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}
/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = Complex32.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -113,7 +321,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result) public void AddVectorToScaledVector(Complex32[] y, Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +359,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result) public void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
{ {
if (x == null) if (x == null)
{ {
@ -183,7 +391,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to Complex32.One and beta set to Complex32.Zero, and x and y are not transposed.</remarks>
public override void MatrixMultiply(Complex32[] x, int rowsX, int columnsX, Complex32[] y, int rowsY, int columnsY, Complex32[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, Complex32.One, x, rowsX, columnsX, y, rowsY, columnsY, Complex32.Zero, result);
} }
@ -203,7 +411,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +456,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(Complex32[] data, int order, int[] ipiv) public void LUFactor(Complex32[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +493,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(Complex32[] a, int order) public void LUInverse(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +531,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv) public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +575,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b) public void LUSolve(int columnsOfB, Complex32[] a, int order, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +620,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b) public void LUSolveFactored(int columnsOfB, Complex32[] a, int order, int[] ipiv, Complex32[] b)
{ {
if (a == null) if (a == null)
{ {
@ -460,7 +668,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(Complex32[] a, int order) public void CholeskyFactor(Complex32[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -500,7 +708,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolve(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -544,7 +752,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB) public void CholeskySolveFactored(Complex32[] a, int orderA, Complex32[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -587,7 +795,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau) public void QRFactor(Complex32[] r, int rowsR, int columnsR, Complex32[] q, Complex32[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -635,7 +843,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau) public void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -682,7 +890,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full) public void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -752,7 +960,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(Complex32[] q, Complex32[] r, int rowsA, int columnsA, Complex32[] tau, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -824,7 +1032,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -837,7 +1045,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x) public void SvdSolve(Complex32[] a, int rowsA, int columnsA, Complex32[] b, int columnsB, Complex32[] x)
{ {
if (a == null) if (a == null)
{ {
@ -874,6 +1082,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,Complex32[],int,int,Complex32[],Complex32[],Complex32[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt, Complex32[] b, int columnsB, Complex32[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -888,7 +1112,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt) public void SingularValueDecomposition(bool computeVectors, Complex32[] a, int rowsA, int columnsA, Complex32[] s, Complex32[] u, Complex32[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -952,7 +1176,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD) public void EigenDecomp(bool isSymmetric, int order, Complex32[] matrix, Complex32[] matrixEv, Complex[] vectorEv, Complex32[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

268
src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Double.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, double[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, double[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.d_matrix_norm((byte)norm, rows, columns, matrix); return SafeNativeMethods.d_matrix_norm((byte)norm, rows, columns, matrix);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(double[] x, double[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (!ReferenceEquals(x, result))
{
x.CopyTo(result, 0);
}
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double DotProduct(double[] x, double[] y) public double DotProduct(double[] x, double[] y)
{ {
if (y == null) if (y == null)
{ {
@ -104,6 +122,196 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.d_dot_product(x.Length, x, y); return SafeNativeMethods.d_dot_product(x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}
/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = Math.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -113,7 +321,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result) public void AddVectorToScaledVector(double[] y, double alpha, double[] x, double[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +359,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(double alpha, double[] x, double[] result) public void ScaleArray(double alpha, double[] x, double[] result)
{ {
if (x == null) if (x == null)
{ {
@ -183,7 +391,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0 and beta set to 0.0, and x and y are not transposed.</remarks>
public override void MatrixMultiply(double[] x, int rowsX, int columnsX, double[] y, int rowsY, int columnsY, double[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0, x, rowsX, columnsX, y, rowsY, columnsY, 0.0, result);
} }
@ -203,7 +411,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +456,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(double[] data, int order, int[] ipiv) public void LUFactor(double[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +493,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(double[] a, int order) public void LUInverse(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +531,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(double[] a, int order, int[] ipiv) public void LUInverseFactored(double[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +575,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, double[] a, int order, double[] b) public void LUSolve(int columnsOfB, double[] a, int order, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +620,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b) public void LUSolveFactored(int columnsOfB, double[] a, int order, int[] ipiv, double[] b)
{ {
if (a == null) if (a == null)
{ {
@ -460,7 +668,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(double[] a, int order) public void CholeskyFactor(double[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -505,7 +713,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolve(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -549,7 +757,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB) public void CholeskySolveFactored(double[] a, int orderA, double[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -592,7 +800,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau) public void QRFactor(double[] r, int rowsR, int columnsR, double[] q, double[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -640,7 +848,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau) public void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -687,7 +895,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full) public void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -757,7 +965,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(double[] q, double[] r, int rowsA, int columnsA, double[] tau, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -829,7 +1037,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -842,7 +1050,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x) public void SvdSolve(double[] a, int rowsA, int columnsA, double[] b, int columnsB, double[] x)
{ {
if (a == null) if (a == null)
{ {
@ -879,6 +1087,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,double[],int,int,double[],double[],double[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, double[] s, double[] u, double[] vt, double[] b, int columnsB, double[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -893,7 +1117,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt) public void SingularValueDecomposition(bool computeVectors, double[] a, int rowsA, int columnsA, double[] s, double[] u, double[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -957,7 +1181,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD) public void EigenDecomp(bool isSymmetric, int order, double[] matrix, double[] matrixEv, Complex[] vectorEv, double[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

268
src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.Single.cs

@ -51,7 +51,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// The requested <see cref="Norm"/> of the matrix. /// The requested <see cref="Norm"/> of the matrix.
/// </returns> /// </returns>
[SecuritySafeCritical] [SecuritySafeCritical]
public override double MatrixNorm(Norm norm, int rows, int columns, float[] matrix) public double MatrixNorm(Norm norm, int rows, int columns, float[] matrix)
{ {
if (matrix == null) if (matrix == null)
{ {
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.s_matrix_norm((byte)norm, rows, columns, matrix); return SafeNativeMethods.s_matrix_norm((byte)norm, rows, columns, matrix);
} }
/// <summary>
/// Conjugates an array. Can be used to conjugate a vector and a matrix.
/// </summary>
/// <param name="x">The values to conjugate.</param>
/// <param name="result">This result of the conjugation.</param>
public void ConjugateArray(float[] x, float[] result)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (!ReferenceEquals(x, result))
{
x.CopyTo(result, 0);
}
}
/// <summary> /// <summary>
/// Computes the dot product of x and y. /// Computes the dot product of x and y.
/// </summary> /// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns> /// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks> /// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override float DotProduct(float[] x, float[] y) public float DotProduct(float[] x, float[] y)
{ {
if (y == null) if (y == null)
{ {
@ -104,6 +122,196 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
return SafeNativeMethods.s_dot_product(x.Length, x, y); return SafeNativeMethods.s_dot_product(x.Length, x, y);
} }
/// <summary>
/// Does a point wise add of two arrays <c>z = x + y</c>. This can be used
/// to add vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the addition.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void AddArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] + y[i];
}
}
/// <summary>
/// Does a point wise subtraction of two arrays <c>z = x - y</c>. This can be used
/// to subtract vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the subtraction.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void SubtractArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] - y[i];
}
}
/// <summary>
/// Does a point wise multiplication of two arrays <c>z = x * y</c>. This can be used
/// to multiple elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise multiplication.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] * y[i];
}
}
/// <summary>
/// Does a point wise division of two arrays <c>z = x / y</c>. This can be used
/// to divide elements of vectors or matrices.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise division.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWiseDivideArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = x[i] / y[i];
}
}
/// <summary>
/// Does a point wise power of two arrays <c>z = x ^ y</c>. This can be used
/// to raise elements of vectors or matrices to the powers of another vector or matrix.
/// </summary>
/// <param name="x">The array x.</param>
/// <param name="y">The array y.</param>
/// <param name="result">The result of the point wise power.</param>
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public void PointWisePowerArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (y.Length != x.Length || y.Length != result.Length)
{
throw new ArgumentException("All vectors must have the same dimensionality.");
}
for (int i = 0; i < result.Length; i++)
{
result[i] = (float)Math.Pow(x[i], y[i]);
}
}
/// <summary> /// <summary>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>. /// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary> /// </summary>
@ -113,7 +321,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param> /// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks> /// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result) public void AddVectorToScaledVector(float[] y, float alpha, float[] x, float[] result)
{ {
if (y == null) if (y == null)
{ {
@ -151,7 +359,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param> /// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks> /// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ScaleArray(float alpha, float[] x, float[] result) public void ScaleArray(float alpha, float[] x, float[] result)
{ {
if (x == null) if (x == null)
{ {
@ -183,7 +391,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">Where to store the result of the multiplication.</param> /// <param name="result">Where to store the result of the multiplication.</param>
/// <remarks>This is a simplified version of the BLAS GEMM routine with alpha /// <remarks>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.</remarks> /// set to 1.0f and beta set to 0.0f, and x and y are not transposed.</remarks>
public override void MatrixMultiply(float[] x, int rowsX, int columnsX, float[] y, int rowsY, int columnsY, float[] result) public 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); MatrixMultiplyWithUpdate(Transpose.DontTranspose, Transpose.DontTranspose, 1.0f, x, rowsX, columnsX, y, rowsY, columnsY, 0.0f, result);
} }
@ -203,7 +411,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param> /// <param name="beta">The value to scale the <paramref name="c"/> matrix.</param>
/// <param name="c">The c matrix.</param> /// <param name="c">The c matrix.</param>
[SecuritySafeCritical] [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) public 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) if (a == null)
{ {
@ -248,7 +456,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param> /// <param name="ipiv">On exit, it contains the pivot indices. The size of the array must be <paramref name="order"/>.</param>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUFactor(float[] data, int order, int[] ipiv) public void LUFactor(float[] data, int order, int[] ipiv)
{ {
if (data == null) if (data == null)
{ {
@ -285,7 +493,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The order of the square matrix <paramref name="a"/>.</param> /// <param name="order">The order of the square matrix <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverse(float[] a, int order) public void LUInverse(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -323,7 +531,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param> /// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUInverseFactored(float[] a, int order, int[] ipiv) public void LUInverseFactored(float[] a, int order, int[] ipiv)
{ {
if (a == null) if (a == null)
{ {
@ -367,7 +575,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks> /// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolve(int columnsOfB, float[] a, int order, float[] b) public void LUSolve(int columnsOfB, float[] a, int order, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -412,7 +620,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param> /// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b) public void LUSolveFactored(int columnsOfB, float[] a, int order, int[] ipiv, float[] b)
{ {
if (a == null) if (a == null)
{ {
@ -460,7 +668,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param> /// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskyFactor(float[] a, int order) public void CholeskyFactor(float[] a, int order)
{ {
if (a == null) if (a == null)
{ {
@ -500,7 +708,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines. /// <remarks>This is equivalent to the POTRF add POTRS LAPACK routines.
/// </remarks> /// </remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolve(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolve(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -544,7 +752,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param> /// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks> /// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB) public void CholeskySolveFactored(float[] a, int orderA, float[] b, int columnsB)
{ {
if (a == null) if (a == null)
{ {
@ -587,7 +795,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau) public void QRFactor(float[] r, int rowsR, int columnsR, float[] q, float[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -635,7 +843,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param> /// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks> /// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau) public void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
{ {
if (r == null) if (r == null)
{ {
@ -682,7 +890,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full) public void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{ {
if (a == null) if (a == null)
{ {
@ -752,7 +960,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param> /// <param name="method">The type of QR factorization to perform. <seealso cref="QRMethod"/></param>
/// <remarks>Rows must be greater or equal to columns.</remarks> /// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full) public void QRSolveFactored(float[] q, float[] r, int rowsA, int columnsA, float[] tau, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{ {
if (r == null) if (r == null)
{ {
@ -824,7 +1032,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
{ {
// we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this. // we don't have access to the raw Q matrix any more(it is stored in R in the full QR), need to think about this.
// let just call the managed version in the meantime. The heavy lifting has already been done. -marcus // let just call the managed version in the meantime. The heavy lifting has already been done. -marcus
base.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin); ManagedLinearAlgebraProvider.Instance.QRSolveFactored(q, r, rowsA, columnsA, tau, b, columnsB, x, QRMethod.Thin);
} }
} }
@ -837,7 +1045,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">The B matrix.</param> /// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param> /// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param> /// <param name="x">On exit, the solution matrix.</param>
public override void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x) public void SvdSolve(float[] a, int rowsA, int columnsA, float[] b, int columnsB, float[] x)
{ {
if (a == null) if (a == null)
{ {
@ -874,6 +1082,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x); SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
} }
/// <summary>
/// Solves A*X=B for X using a previously SVD decomposed matrix.
/// </summary>
/// <param name="rowsA">The number of rows in the A matrix.</param>
/// <param name="columnsA">The number of columns in the A matrix.</param>
/// <param name="s">The s values returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="u">The left singular vectors returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="vt">The right singular vectors returned by <see cref="SingularValueDecomposition(bool,float[],int,int,float[],float[],float[])"/>.</param>
/// <param name="b">The B matrix.</param>
/// <param name="columnsB">The number of columns of B.</param>
/// <param name="x">On exit, the solution matrix.</param>
public void SvdSolveFactored(int rowsA, int columnsA, float[] s, float[] u, float[] vt, float[] b, int columnsB, float[] x)
{
ManagedLinearAlgebraProvider.Instance.SvdSolveFactored(rowsA, columnsA, s, u, vt, b, columnsB, x);
}
/// <summary> /// <summary>
/// Computes the singular value decomposition of A. /// Computes the singular value decomposition of A.
/// </summary> /// </summary>
@ -888,7 +1112,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param> /// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks> /// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[SecuritySafeCritical] [SecuritySafeCritical]
public override void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt) public void SingularValueDecomposition(bool computeVectors, float[] a, int rowsA, int columnsA, float[] s, float[] u, float[] vt)
{ {
if (a == null) if (a == null)
{ {
@ -952,7 +1176,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param> /// <param name="matrixEv">On output, the matrix contains the eigen vectors. The length of the array must be order * order.</param>
/// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param> /// <param name="vectorEv">On output, the eigen values (λ) of matrix in ascending value. The length of the array must <paramref name="order"/>.</param>
/// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param> /// <param name="matrixD">On output, the block diagonal eigenvalue matrix. The length of the array must be order * order.</param>
public override void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD) public void EigenDecomp(bool isSymmetric, int order, float[] matrix, float[] matrixEv, Complex[] vectorEv, float[] matrixD)
{ {
if (matrix == null) if (matrix == null)
{ {

8
src/Providers.OpenBLAS/LinearAlgebra/OpenBlasLinearAlgebraProvider.cs

@ -53,7 +53,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <summary> /// <summary>
/// OpenBLAS linear algebra provider. /// OpenBLAS linear algebra provider.
/// </summary> /// </summary>
internal partial class OpenBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable internal sealed partial class OpenBlasLinearAlgebraProvider : ILinearAlgebraProvider, IDisposable
{ {
const int MinimumCompatibleRevision = 1; const int MinimumCompatibleRevision = 1;
@ -69,7 +69,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// Try to find out whether the provider is available, at least in principle. /// Try to find out whether the provider is available, at least in principle.
/// Verification may still fail if available, but it will certainly fail if unavailable. /// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary> /// </summary>
public override bool IsAvailable() public bool IsAvailable()
{ {
return OpenBlasProvider.IsAvailable(hintPath: _hintPath); return OpenBlasProvider.IsAvailable(hintPath: _hintPath);
} }
@ -78,7 +78,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// Initialize and verify that the provided is indeed available. /// Initialize and verify that the provided is indeed available.
/// If not, fall back to alternatives like the managed provider /// If not, fall back to alternatives like the managed provider
/// </summary> /// </summary>
public override void InitializeVerify() public void InitializeVerify()
{ {
int revision = OpenBlasProvider.Load(hintPath: _hintPath); int revision = OpenBlasProvider.Load(hintPath: _hintPath);
if (revision < MinimumCompatibleRevision) if (revision < MinimumCompatibleRevision)
@ -99,7 +99,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// Frees memory buffers, caches and handles allocated in or to the provider. /// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards. /// Does not unload the provider itself, it is still usable afterwards.
/// </summary> /// </summary>
public override void FreeResources() public void FreeResources()
{ {
OpenBlasProvider.FreeResources(); OpenBlasProvider.FreeResources();
} }

Loading…
Cancel
Save