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
OTHER DEALINGS IN THE SOFTWARE.
&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/=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/=FFT/@EntryIndexedValue">FFT</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://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
// obtaining a copy of this software and associated documentation
@ -321,7 +321,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
// 65536 = 2^16
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]
@ -329,7 +329,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
// 65536 = 2^16
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]
@ -337,7 +337,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
// 30870 = 2*3*3*5*7*7*7
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]
@ -345,21 +345,21 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
// 30870 = 2*3*3*5*7*7*7
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]
public void ProviderMatchesManagedProviderArbitraryLarge32_GH286()
{
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]
public void ProviderMatchesManagedProviderArbitraryLarge64_GH286()
{
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")]

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 = CreateManaged();
public static void UseManaged() => Provider = ManagedFourierTransformProvider.Instance;
public static void UseNativeMKL() => Provider = MklProbe.Create();
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
// 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
// obtaining a copy of this software and associated documentation
@ -32,7 +32,7 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.FourierTransform
{
internal partial class ManagedFourierTransformProvider
public partial class ManagedFourierTransformProvider
{
/// <summary>
/// Sequences with length greater than Math.Sqrt(Int32.MaxValue) + 1
@ -45,7 +45,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary>
/// <param name="n">Number of samples.</param>
/// <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;
var sequence = new Complex32[n];
@ -77,7 +77,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// </summary>
/// <param name="n">Number of samples.</param>
/// <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;
var sequence = new Complex[n];
@ -108,7 +108,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Convolution with the bluestein sequence (Parallel Version).
/// </summary>
/// <param name="samples">Sample Vector.</param>
private static void BluesteinConvolutionParallel(Complex32[] samples)
static void BluesteinConvolutionParallel(Complex32[] samples)
{
int n = samples.Length;
Complex32[] sequence = BluesteinSequence32(n);
@ -163,7 +163,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Convolution with the bluestein sequence (Parallel Version).
/// </summary>
/// <param name="samples">Sample Vector.</param>
private static void BluesteinConvolutionParallel(Complex[] samples)
static void BluesteinConvolutionParallel(Complex[] samples)
{
int n = samples.Length;
Complex[] sequence = BluesteinSequence(n);
@ -218,7 +218,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Swap the real and imaginary parts of each sample.
/// </summary>
/// <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++)
{
@ -230,7 +230,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Swap the real and imaginary parts of each sample.
/// </summary>
/// <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++)
{
@ -241,7 +241,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary>
private static void BluesteinForward(Complex[] samples)
static void BluesteinForward(Complex[] samples)
{
BluesteinConvolutionParallel(samples);
}
@ -249,7 +249,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary>
private static void BluesteinInverse(Complex[] spectrum)
static void BluesteinInverse(Complex[] spectrum)
{
SwapRealImaginary(spectrum);
BluesteinConvolutionParallel(spectrum);
@ -259,7 +259,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary>
private static void BluesteinForward(Complex32[] samples)
static void BluesteinForward(Complex32[] samples)
{
BluesteinConvolutionParallel(samples);
}
@ -267,7 +267,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Bluestein generic FFT for arbitrary sized sample vectors.
/// </summary>
private static void BluesteinInverse(Complex32[] spectrum)
static void BluesteinInverse(Complex32[] spectrum)
{
SwapRealImaginary(spectrum);
BluesteinConvolutionParallel(spectrum);

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

@ -2,7 +2,7 @@
// Math.NET Numerics, part of the Math.NET Project
// 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
// obtaining a copy of this software and associated documentation
@ -33,14 +33,14 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.FourierTransform
{
internal partial class ManagedFourierTransformProvider
public partial class ManagedFourierTransformProvider
{
/// <summary>
/// Radix-2 Reorder Helper Method
/// </summary>
/// <typeparam name="T">Sample type</typeparam>
/// <param name="samples">Sample vector</param>
private static void Radix2Reorder<T>(T[] samples)
static void Radix2Reorder<T>(T[] samples)
{
var j = 0;
for (var i = 0; i < samples.Length - 1; i++)
@ -73,7 +73,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
#if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#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
var exponent = (exponentSign * k) * Constants.Pi / levelSize;
@ -99,7 +99,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
#if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#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
var exponent = (exponentSign * k) * Constants.Pi / levelSize;
@ -118,7 +118,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary>
private static void Radix2Forward(Complex32[] data)
static void Radix2Forward(Complex32[] data)
{
Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -133,7 +133,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary>
private static void Radix2Forward(Complex[] data)
static void Radix2Forward(Complex[] data)
{
Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -148,7 +148,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary>
private static void Radix2Inverse(Complex32[] data)
static void Radix2Inverse(Complex32[] data)
{
Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -163,7 +163,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sized sample vectors.
/// </summary>
private static void Radix2Inverse(Complex[] data)
static void Radix2Inverse(Complex[] data)
{
Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -178,7 +178,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary>
private static void Radix2ForwardParallel(Complex32[] data)
static void Radix2ForwardParallel(Complex32[] data)
{
Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -198,7 +198,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary>
private static void Radix2ForwardParallel(Complex[] data)
static void Radix2ForwardParallel(Complex[] data)
{
Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -218,7 +218,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary>
private static void Radix2InverseParallel(Complex32[] data)
static void Radix2InverseParallel(Complex32[] data)
{
Radix2Reorder(data);
for (var levelSize = 1; levelSize < data.Length; levelSize *= 2)
@ -238,7 +238,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Radix-2 generic FFT for power-of-two sample vectors (Parallel Version).
/// </summary>
private static void Radix2InverseParallel(Complex[] data)
static void Radix2InverseParallel(Complex[] data)
{
Radix2Reorder(data);
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
// 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
// obtaining a copy of this software and associated documentation
@ -31,8 +31,10 @@ using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.FourierTransform
{
internal partial class ManagedFourierTransformProvider : IFourierTransformProvider
public sealed partial class ManagedFourierTransformProvider : IFourierTransformProvider
{
public static ManagedFourierTransformProvider Instance { get; } = new ManagedFourierTransformProvider();
/// <summary>
/// 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.
@ -53,7 +55,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Frees memory buffers, caches and handles allocated in or to the provider.
/// Does not unload the provider itself, it is still usable afterwards.
/// </summary>
public virtual void FreeResources()
public void FreeResources()
{
}
@ -335,57 +337,5 @@ namespace MathNet.Numerics.Providers.FourierTransform
{
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 = CreateManaged();
public static void UseManaged() => Provider = ManagedLinearAlgebraProvider.Instance;
public static void UseNativeMKL() => Provider = MklProbe.Create();
public static bool TryUseNativeMKL() => TryUse(MklProbe.TryCreate());

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

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// 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
// 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="result">The result of the addition.</param>
/// <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)
{
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param>
/// <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)
{
@ -121,7 +121,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary>
/// <param name="x">The values to conjugate.</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)
{
@ -141,7 +141,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual Complex DotProduct(Complex[] x, Complex[] y)
public Complex DotProduct(Complex[] x, Complex[] y)
{
if (y == null)
{
@ -177,7 +177,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void AddArrays(Complex[] x, Complex[] y, Complex[] result)
public void AddArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -215,7 +215,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
public void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -253,7 +253,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
public void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -291,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
public void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -332,7 +332,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result)
public void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -373,7 +373,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </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)
{
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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
/// 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)
{
@ -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="beta">The value to scale the <paramref name="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)
{
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -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="order">The order of the square matrix <paramref name="a"/>.</param>
/// <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)
{
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <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>
public virtual void LUInverseFactored(Complex[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{
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="b">On entry the B matrix; on exit the X matrix.</param>
/// <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)
{
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <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)
{
@ -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="columnsB">The number of columns in the B matrix.</param>
/// <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)
{
@ -1106,7 +1106,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="b">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>
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)
{
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1249,7 +1249,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1435,7 +1435,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1507,7 +1507,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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
/// right singular vectors.</param>
/// <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)
{
@ -2294,7 +2294,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -2342,7 +2342,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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="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 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)
{
@ -3229,7 +3229,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </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)
{
@ -3255,7 +3255,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </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)
{

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

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// 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
// 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="result">The result of the addition.</param>
/// <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)
{
@ -93,7 +93,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param>
/// <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)
{
@ -122,7 +122,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary>
/// <param name="x">The values to conjugate.</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)
{
@ -142,7 +142,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual Complex32 DotProduct(Complex32[] x, Complex32[] y)
public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{
if (y == null)
{
@ -178,7 +178,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -216,7 +216,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -254,7 +254,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -292,7 +292,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -333,7 +333,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -372,7 +372,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 virtual double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
public double MatrixNorm(Norm norm, int rows, int columns, Complex32[] matrix)
{
switch (norm)
{
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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
/// 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)
{
@ -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="beta">The value to scale the <paramref name="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)
{
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -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="order">The order of the square matrix <paramref name="a"/>.</param>
/// <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)
{
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <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>
public virtual void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{
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="b">On entry the B matrix; on exit the X matrix.</param>
/// <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)
{
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <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)
{
@ -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="columnsB">The number of columns in the B matrix.</param>
/// <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)
{
@ -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="columnsB">The number of columns in the B matrix.</param>
/// <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)
{
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1249,7 +1249,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1435,7 +1435,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1505,7 +1505,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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
/// right singular vectors.</param>
/// <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)
{
@ -2292,7 +2292,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -2340,7 +2340,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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="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 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)
{
@ -3231,7 +3231,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </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)
{
@ -3257,7 +3257,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary>
/// Assumes that <paramref name="numRows"/> and <paramref name="numCols"/> have already been transposed.
/// </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)
{

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

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// 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
// 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="result">The result of the addition.</param>
/// <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)
{
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param>
/// <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)
{
@ -121,7 +121,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary>
/// <param name="x">The values to conjugate.</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)
{
@ -141,7 +141,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual double DotProduct(double[] x, double[] y)
public double DotProduct(double[] x, double[] y)
{
if (y == null)
{
@ -177,7 +177,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void AddArrays(double[] x, double[] y, double[] result)
public void AddArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -215,7 +215,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void SubtractArrays(double[] x, double[] y, double[] result)
public void SubtractArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -253,7 +253,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
public void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -291,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseDivideArrays(double[] x, double[] y, double[] result)
public void PointWiseDivideArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -332,7 +332,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWisePowerArrays(double[] x, double[] y, double[] result)
public void PointWisePowerArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -373,7 +373,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </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)
{
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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
/// 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)
{
@ -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="beta">The value to scale the <paramref name="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)
{
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -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="order">The order of the square matrix <paramref name="a"/>.</param>
/// <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)
{
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <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>
public virtual void LUInverseFactored(double[] a, int order, int[] ipiv)
public void LUInverseFactored(double[] a, int order, int[] ipiv)
{
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="b">On entry the B matrix; on exit the X matrix.</param>
/// <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)
{
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <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)
{
@ -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="columnsB">The number of columns in the B matrix.</param>
/// <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)
{
@ -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="columnsB">The number of columns in the B matrix.</param>
/// <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)
{
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1248,7 +1248,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1434,7 +1434,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1504,7 +1504,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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
/// right singular vectors.</param>
/// <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)
{
@ -2352,7 +2352,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -2399,7 +2399,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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="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 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)
{

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

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// 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
// 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="result">The result of the addition.</param>
/// <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)
{
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="x">The values to scale.</param>
/// <param name="result">This result of the scaling.</param>
/// <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)
{
@ -121,7 +121,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// </summary>
/// <param name="x">The values to conjugate.</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)
{
@ -141,7 +141,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="y">The vector y.</param>
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
public virtual float DotProduct(float[] x, float[] y)
public float DotProduct(float[] x, float[] y)
{
if (y == null)
{
@ -177,7 +177,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void AddArrays(float[] x, float[] y, float[] result)
public void AddArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -215,7 +215,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void SubtractArrays(float[] x, float[] y, float[] result)
public void SubtractArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -253,7 +253,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
public void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -291,7 +291,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWiseDivideArrays(float[] x, float[] y, float[] result)
public void PointWiseDivideArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -332,7 +332,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public virtual void PointWisePowerArrays(float[] x, float[] y, float[] result)
public void PointWisePowerArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -373,7 +373,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <returns>
/// The requested <see cref="Norm"/> of the matrix.
/// </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)
{
@ -444,7 +444,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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
/// 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)
{
@ -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="beta">The value to scale the <paramref name="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)
{
@ -679,7 +679,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -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="order">The order of the square matrix <paramref name="a"/>.</param>
/// <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)
{
@ -801,7 +801,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <param name="order">The order of the square matrix <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>
public virtual void LUInverseFactored(float[] a, int order, int[] ipiv)
public void LUInverseFactored(float[] a, int order, int[] ipiv)
{
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="b">On entry the B matrix; on exit the X matrix.</param>
/// <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)
{
@ -884,7 +884,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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>
/// <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)
{
@ -983,7 +983,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// the Cholesky factorization.</param>
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <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)
{
@ -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="columnsB">The number of columns in the B matrix.</param>
/// <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)
{
@ -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="columnsB">The number of columns in the B matrix.</param>
/// <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)
{
@ -1187,7 +1187,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1249,7 +1249,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1437,7 +1437,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -1507,7 +1507,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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
/// right singular vectors.</param>
/// <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)
{
@ -2357,7 +2357,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -2405,7 +2405,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <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 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)
{
@ -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="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 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)
{

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

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// 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
// obtaining a copy of this software and associated documentation
@ -34,13 +34,15 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary>
/// The managed linear algebra provider.
/// </summary>
public partial class ManagedLinearAlgebraProvider : ILinearAlgebraProvider
public sealed partial class ManagedLinearAlgebraProvider : ILinearAlgebraProvider
{
public static ManagedLinearAlgebraProvider Instance { get; } = new ManagedLinearAlgebraProvider();
/// <summary>
/// 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.
/// </summary>
public virtual bool IsAvailable()
public bool IsAvailable()
{
return true;
}
@ -48,7 +50,7 @@ namespace MathNet.Numerics.Providers.LinearAlgebra
/// <summary>
/// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider
/// </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.
/// Does not unload the provider itself, it is still usable afterwards.
/// </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>
/// The managed sparse solver provider
/// </summary>
internal class ManagedSparseSolverProvider : ISparseSolverProvider
public sealed class ManagedSparseSolverProvider : ISparseSolverProvider
{
public static ManagedSparseSolverProvider Instance { get; } = new ManagedSparseSolverProvider();
/// <summary>
/// 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.

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 = CreateManaged();
public static void UseManaged() => Provider = ManagedSparseSolverProvider.Instance;
public static void UseNativeMKL() => Provider = MklProbe.Create();
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>
/// Use the best provider available.
/// </summary>

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

@ -29,6 +29,7 @@
using System;
using System.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex;
@ -39,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary>
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>
/// Computes the dot product of x and y.
/// </summary>
@ -47,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex DotProduct(Complex[] x, Complex[] y)
public Complex DotProduct(Complex[] x, Complex[] y)
{
if (y == null)
{
@ -67,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -76,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -114,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
public void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{
if (x == null)
{
@ -134,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -146,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(Complex[] data, int order, int[] ipiv)
public void LUFactor(Complex[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(Complex[] a, int order)
public void LUInverse(Complex[] a, int order)
{
if (a == null)
{
@ -266,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(Complex[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -335,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -378,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(Complex[] a, int order)
public void CholeskyFactor(Complex[] a, int order)
{
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>
[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)
{
@ -442,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -467,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Solves A*X=B for X using the singular value decomposition of A.
/// </summary>
@ -476,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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 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)
{
@ -513,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -527,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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
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));
}
/// <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.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
{
@ -38,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary>
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>
/// Computes the dot product of x and y.
/// </summary>
@ -46,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex32 DotProduct(Complex32[] x, Complex32[] y)
public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{
if (y == null)
{
@ -66,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -75,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -113,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
public void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
{
if (x == null)
{
@ -133,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -145,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(Complex32[] data, int order, int[] ipiv)
public void LUFactor(Complex32[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(Complex32[] a, int order)
public void LUInverse(Complex32[] a, int order)
{
if (a == null)
{
@ -265,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -334,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -377,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(Complex32[] a, int order)
public void CholeskyFactor(Complex32[] a, int order)
{
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>
[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)
{
@ -441,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -466,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Solves A*X=B for X using the singular value decomposition of A.
/// </summary>
@ -475,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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 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)
{
@ -512,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -526,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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
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));
}
/// <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.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
{
@ -38,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary>
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>
/// Computes the dot product of x and y.
/// </summary>
@ -46,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override double DotProduct(double[] x, double[] y)
public double DotProduct(double[] x, double[] y)
{
if (y == null)
{
@ -66,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -75,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -113,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(double alpha, double[] x, double[] result)
public void ScaleArray(double alpha, double[] x, double[] result)
{
if (x == null)
{
@ -133,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -145,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(double[] data, int order, int[] ipiv)
public void LUFactor(double[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(double[] a, int order)
public void LUInverse(double[] a, int order)
{
if (a == null)
{
@ -265,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(double[] a, int order, int[] ipiv)
public void LUInverseFactored(double[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -334,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -377,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(double[] a, int order)
public void CholeskyFactor(double[] a, int order)
{
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>
[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)
{
@ -441,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -466,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Solves A*X=B for X using the singular value decomposition of A.
/// </summary>
@ -475,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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 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)
{
@ -512,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -526,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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
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));
}
/// <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.Security;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.Providers.LinearAlgebra;
using Complex = System.Numerics.Complex;
namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
{
@ -38,6 +40,21 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// </summary>
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>
/// Computes the dot product of x and y.
/// </summary>
@ -46,7 +63,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override float DotProduct(float[] x, float[] y)
public float DotProduct(float[] x, float[] y)
{
if (y == null)
{
@ -66,6 +83,196 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -75,7 +282,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -113,7 +320,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(float alpha, float[] x, float[] result)
public void ScaleArray(float alpha, float[] x, float[] result)
{
if (x == null)
{
@ -133,6 +340,24 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -145,7 +370,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(float[] data, int order, int[] ipiv)
public void LUFactor(float[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(float[] a, int order)
public void LUInverse(float[] a, int order)
{
if (a == null)
{
@ -265,7 +490,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(float[] a, int order, int[] ipiv)
public void LUInverseFactored(float[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -334,7 +559,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -377,7 +602,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(float[] a, int order)
public void CholeskyFactor(float[] a, int order)
{
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>
[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)
{
@ -441,7 +666,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -466,6 +691,75 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Solves A*X=B for X using the singular value decomposition of A.
/// </summary>
@ -475,7 +769,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// <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 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)
{
@ -512,6 +806,22 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -526,7 +836,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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
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));
}
/// <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>
/// NVidia's CUDA Toolkit linear algebra provider.
/// </summary>
internal partial class CudaLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable
internal sealed partial class CudaLinearAlgebraProvider : ILinearAlgebraProvider, IDisposable
{
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.
/// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary>
public override bool IsAvailable()
public bool IsAvailable()
{
return CudaProvider.IsAvailable(hintPath: _hintPath);
}
@ -62,7 +62,7 @@ namespace MathNet.Numerics.Providers.CUDA.LinearAlgebra
/// Initialize and verify that the provided is indeed available.
/// If calling this method fails, consider to fall back to alternatives like the managed provider.
/// </summary>
public override void InitializeVerify()
public void InitializeVerify()
{
int revision = CudaProvider.Load(hintPath: _hintPath);
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.
/// Does not unload the provider itself, it is still usable afterwards.
/// </summary>
public override void FreeResources()
public void 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
{
internal class MklFourierTransformProvider : IFourierTransformProvider, IDisposable
internal sealed class MklFourierTransformProvider : IFourierTransformProvider, IDisposable
{
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.
/// </summary>
[SecuritySafeCritical]
public virtual void FreeResources()
public void FreeResources()
{
Kernel kernel = Interlocked.Exchange(ref _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.
/// </returns>
[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)
{
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex DotProduct(Complex[] x, Complex[] y)
public Complex DotProduct(Complex[] x, Complex[] y)
{
if (y == null)
{
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
public void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{
if (x == null)
{
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(Complex[] data, int order, int[] ipiv)
public void LUFactor(Complex[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(Complex[] a, int order)
public void LUInverse(Complex[] a, int order)
{
if (a == null)
{
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(Complex[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -465,7 +483,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(Complex[] a, int order)
public void CholeskyFactor(Complex[] a, int order)
{
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>
[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)
{
@ -549,7 +567,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -592,7 +610,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -640,7 +658,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
public void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
public void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -879,6 +897,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -893,7 +927,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -958,7 +992,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void AddArrays(Complex[] x, Complex[] y, Complex[] result)
public void AddArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -993,7 +1027,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
public void SubtractArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -1028,7 +1062,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
public void PointWiseMultiplyArrays(Complex[] x, Complex[] y, Complex[] result)
{
if (y == null)
{
@ -1063,13 +1097,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// 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)
{
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.");
}
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);
}
@ -1103,7 +1142,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
public void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
{
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="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 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)
{

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.
/// </returns>
[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)
{
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex32 DotProduct(Complex32[] x, Complex32[] y)
public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{
if (y == null)
{
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
public void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
{
if (x == null)
{
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(Complex32[] data, int order, int[] ipiv)
public void LUFactor(Complex32[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(Complex32[] a, int order)
public void LUInverse(Complex32[] a, int order)
{
if (a == null)
{
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -460,7 +478,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(Complex32[] a, int order)
public void CholeskyFactor(Complex32[] a, int order)
{
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>
[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)
{
@ -544,7 +562,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -587,7 +605,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -635,7 +653,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
public void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
public void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -874,6 +892,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -888,7 +922,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -953,7 +987,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void AddArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -988,7 +1022,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void SubtractArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -1023,7 +1057,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void PointWiseMultiplyArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -1058,7 +1092,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
public void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
{
if (y == null)
{
@ -1093,13 +1127,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// 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)
{
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.");
}
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);
}
@ -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="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 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)
{

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.
/// </returns>
[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)
{
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override double DotProduct(double[] x, double[] y)
public double DotProduct(double[] x, double[] y)
{
if (y == null)
{
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(double alpha, double[] x, double[] result)
public void ScaleArray(double alpha, double[] x, double[] result)
{
if (x == null)
{
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(double[] data, int order, int[] ipiv)
public void LUFactor(double[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(double[] a, int order)
public void LUInverse(double[] a, int order)
{
if (a == null)
{
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(double[] a, int order, int[] ipiv)
public void LUInverseFactored(double[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -460,7 +478,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(double[] a, int order)
public void CholeskyFactor(double[] a, int order)
{
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>
[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)
{
@ -549,7 +567,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -592,7 +610,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -640,7 +658,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
public void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
public void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -879,6 +897,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -893,7 +927,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -958,7 +992,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void AddArrays(double[] x, double[] y, double[] result)
public void AddArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -993,7 +1027,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void SubtractArrays(double[] x, double[] y, double[] result)
public void SubtractArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -1028,7 +1062,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
public void PointWiseMultiplyArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -1063,7 +1097,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseDivideArrays(double[] x, double[] y, double[] result)
public void PointWiseDivideArrays(double[] x, double[] y, double[] result)
{
if (y == null)
{
@ -1098,13 +1132,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// 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)
{
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.");
}
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);
}
@ -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="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 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)
{

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.
/// </returns>
[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)
{
@ -84,7 +84,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override float DotProduct(float[] x, float[] y)
public float DotProduct(float[] x, float[] y)
{
if (y == null)
{
@ -113,7 +113,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +151,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(float alpha, float[] x, float[] result)
public void ScaleArray(float alpha, float[] x, float[] result)
{
if (x == null)
{
@ -171,6 +171,24 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Multiples two matrices. <c>result = x * y</c>
/// </summary>
@ -183,7 +201,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <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
/// 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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(float[] data, int order, int[] ipiv)
public void LUFactor(float[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(float[] a, int order)
public void LUInverse(float[] a, int order)
{
if (a == null)
{
@ -323,7 +341,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(float[] a, int order, int[] ipiv)
public void LUInverseFactored(float[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +430,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -460,7 +478,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(float[] a, int order)
public void CholeskyFactor(float[] a, int order)
{
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>
[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)
{
@ -544,7 +562,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -587,7 +605,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -635,7 +653,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
public void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
public void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -874,6 +892,22 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -888,7 +922,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -953,7 +987,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void AddArrays(float[] x, float[] y, float[] result)
public void AddArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -988,7 +1022,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void SubtractArrays(float[] x, float[] y, float[] result)
public void SubtractArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -1023,7 +1057,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
public void PointWiseMultiplyArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -1058,7 +1092,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// routine.</remarks>
public override void PointWiseDivideArrays(float[] x, float[] y, float[] result)
public void PointWiseDivideArrays(float[] x, float[] y, float[] result)
{
if (y == null)
{
@ -1093,13 +1127,8 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <remarks>There is no equivalent BLAS routine, but many libraries
/// provide optimized (parallel and/or vectorized) versions of this
/// 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)
{
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.");
}
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);
}
@ -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="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 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)
{

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

@ -28,6 +28,7 @@
// </copyright>
using System;
using System.Numerics;
using System.Security;
using MathNet.Numerics.Providers.LinearAlgebra;
@ -47,7 +48,7 @@ namespace MathNet.Numerics.Providers.MKL.LinearAlgebra
/// <summary>
/// Intel's Math Kernel Library (MKL) linear algebra provider.
/// </summary>
internal partial class MklLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable
internal sealed partial class MklLinearAlgebraProvider : ILinearAlgebraProvider, IDisposable
{
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.
/// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary>
public override bool IsAvailable()
public bool IsAvailable()
{
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.
/// </summary>
[SecuritySafeCritical]
public override void InitializeVerify()
public void InitializeVerify()
{
int revision = MklProvider.Load(_hintPath, _consistency, _precision, _accuracy);
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.
/// Does not unload the provider itself, it is still usable afterwards.
/// </summary>
public override void FreeResources()
public void FreeResources()
{
MklProvider.FreeResources();
}

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

@ -6,7 +6,7 @@ namespace MathNet.Numerics.Providers.MKL.SparseSolver
/// <summary>
/// Intel's Math Kernel Library (MKL) sparse solver provider.
/// </summary>
internal partial class MklSparseSolverProvider : ISparseSolverProvider, IDisposable
internal sealed partial class MklSparseSolverProvider : ISparseSolverProvider, IDisposable
{
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.
/// </returns>
[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)
{
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the dot product of x and y.
/// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex DotProduct(Complex[] x, Complex[] y)
public Complex DotProduct(Complex[] x, Complex[] y)
{
if (y == null)
{
@ -104,6 +122,194 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -113,7 +319,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +357,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
public void ScaleArray(Complex alpha, Complex[] x, Complex[] result)
{
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>
/// <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>
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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(Complex[] data, int order, int[] ipiv)
public void LUFactor(Complex[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(Complex[] a, int order)
public void LUInverse(Complex[] a, int order)
{
if (a == null)
{
@ -323,7 +529,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(Complex[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +618,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -465,7 +671,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(Complex[] a, int order)
public void CholeskyFactor(Complex[] a, int order)
{
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>
[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)
{
@ -549,7 +755,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -592,7 +798,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -640,7 +846,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
public void ThinQRFactor(Complex[] q, int rowsA, int columnsA, Complex[] r, Complex[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
public void QRSolve(Complex[] a, int rows, int columns, Complex[] b, int columnsB, Complex[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -879,6 +1085,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -893,7 +1115,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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="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 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)
{

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.
/// </returns>
[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)
{
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the dot product of x and y.
/// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override Complex32 DotProduct(Complex32[] x, Complex32[] y)
public Complex32 DotProduct(Complex32[] x, Complex32[] y)
{
if (y == null)
{
@ -104,6 +122,196 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -113,7 +321,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +359,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
public void ScaleArray(Complex32 alpha, Complex32[] x, Complex32[] result)
{
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>
/// <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>
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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(Complex32[] data, int order, int[] ipiv)
public void LUFactor(Complex32[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(Complex32[] a, int order)
public void LUInverse(Complex32[] a, int order)
{
if (a == null)
{
@ -323,7 +531,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
public void LUInverseFactored(Complex32[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +620,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -460,7 +668,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(Complex32[] a, int order)
public void CholeskyFactor(Complex32[] a, int order)
{
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>
[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)
{
@ -544,7 +752,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -587,7 +795,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -635,7 +843,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
public void ThinQRFactor(Complex32[] q, int rowsA, int columnsA, Complex32[] r, Complex32[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
public void QRSolve(Complex32[] a, int rows, int columns, Complex32[] b, int columnsB, Complex32[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -874,6 +1082,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -888,7 +1112,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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="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 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)
{

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.
/// </returns>
[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)
{
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the dot product of x and y.
/// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override double DotProduct(double[] x, double[] y)
public double DotProduct(double[] x, double[] y)
{
if (y == null)
{
@ -104,6 +122,196 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -113,7 +321,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +359,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(double alpha, double[] x, double[] result)
public void ScaleArray(double alpha, double[] x, double[] result)
{
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>
/// <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>
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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(double[] data, int order, int[] ipiv)
public void LUFactor(double[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(double[] a, int order)
public void LUInverse(double[] a, int order)
{
if (a == null)
{
@ -323,7 +531,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(double[] a, int order, int[] ipiv)
public void LUInverseFactored(double[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +620,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -460,7 +668,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(double[] a, int order)
public void CholeskyFactor(double[] a, int order)
{
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>
[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)
{
@ -549,7 +757,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -592,7 +800,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -640,7 +848,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
public void ThinQRFactor(double[] q, int rowsA, int columnsA, double[] r, double[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
public void QRSolve(double[] a, int rows, int columns, double[] b, int columnsB, double[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -879,6 +1087,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -893,7 +1117,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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="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 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)
{

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.
/// </returns>
[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)
{
@ -76,6 +76,24 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the dot product of x and y.
/// </summary>
@ -84,7 +102,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <returns>The dot product of x and y.</returns>
/// <remarks>This is equivalent to the DOT BLAS routine.</remarks>
[SecuritySafeCritical]
public override float DotProduct(float[] x, float[] y)
public float DotProduct(float[] x, float[] y)
{
if (y == null)
{
@ -104,6 +122,196 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Adds a scaled vector to another: <c>result = y + alpha*x</c>.
/// </summary>
@ -113,7 +321,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">The result of the addition.</param>
/// <remarks>This is similar to the AXPY BLAS routine.</remarks>
[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)
{
@ -151,7 +359,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="result">This result of the scaling.</param>
/// <remarks>This is similar to the SCAL BLAS routine.</remarks>
[SecuritySafeCritical]
public override void ScaleArray(float alpha, float[] x, float[] result)
public void ScaleArray(float alpha, float[] x, float[] result)
{
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>
/// <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>
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);
}
@ -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="c">The c matrix.</param>
[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)
{
@ -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>
/// <remarks>This is equivalent to the GETRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUFactor(float[] data, int order, int[] ipiv)
public void LUFactor(float[] data, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRI LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void LUInverse(float[] a, int order)
public void LUInverse(float[] a, int order)
{
if (a == null)
{
@ -323,7 +531,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="ipiv">The pivot indices of <paramref name="a"/>.</param>
/// <remarks>This is equivalent to the GETRI LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void LUInverseFactored(float[] a, int order, int[] ipiv)
public void LUInverseFactored(float[] a, int order, int[] ipiv)
{
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>
/// <remarks>This is equivalent to the GETRF and GETRS LAPACK routines.</remarks>
[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)
{
@ -412,7 +620,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="b">On entry the B matrix; on exit the X matrix.</param>
/// <remarks>This is equivalent to the GETRS LAPACK routine.</remarks>
[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)
{
@ -460,7 +668,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="order">The number of rows or columns in the matrix.</param>
/// <remarks>This is equivalent to the POTRF LAPACK routine.</remarks>
[SecuritySafeCritical]
public override void CholeskyFactor(float[] a, int order)
public void CholeskyFactor(float[] a, int order)
{
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>
[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)
{
@ -544,7 +752,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <param name="columnsB">The number of columns in the B matrix.</param>
/// <remarks>This is equivalent to the POTRS LAPACK routine.</remarks>
[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)
{
@ -587,7 +795,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void 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)
{
@ -635,7 +843,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// to be used by the QR solve routine.</param>
/// <remarks>This is similar to the GEQRF and ORGQR LAPACK routines.</remarks>
[SecuritySafeCritical]
public override void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
public void ThinQRFactor(float[] q, int rowsA, int columnsA, float[] r, float[] tau)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[SecuritySafeCritical]
public override void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
public void QRSolve(float[] a, int rows, int columns, float[] b, int columnsB, float[] x, QRMethod method = QRMethod.Full)
{
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>
/// <remarks>Rows must be greater or equal to columns.</remarks>
[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)
{
@ -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.
// 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="columnsB">The number of columns of B.</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)
{
@ -874,6 +1082,22 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
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>
/// Computes the singular value decomposition of A.
/// </summary>
@ -888,7 +1112,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// right singular vectors.</param>
/// <remarks>This is equivalent to the GESVD LAPACK routine.</remarks>
[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)
{
@ -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="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 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)
{

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

@ -53,7 +53,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// <summary>
/// OpenBLAS linear algebra provider.
/// </summary>
internal partial class OpenBlasLinearAlgebraProvider : ManagedLinearAlgebraProvider, IDisposable
internal sealed partial class OpenBlasLinearAlgebraProvider : ILinearAlgebraProvider, IDisposable
{
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.
/// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary>
public override bool IsAvailable()
public bool IsAvailable()
{
return OpenBlasProvider.IsAvailable(hintPath: _hintPath);
}
@ -78,7 +78,7 @@ namespace MathNet.Numerics.Providers.OpenBLAS.LinearAlgebra
/// Initialize and verify that the provided is indeed available.
/// If not, fall back to alternatives like the managed provider
/// </summary>
public override void InitializeVerify()
public void InitializeVerify()
{
int revision = OpenBlasProvider.Load(hintPath: _hintPath);
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.
/// Does not unload the provider itself, it is still usable afterwards.
/// </summary>
public override void FreeResources()
public void FreeResources()
{
OpenBlasProvider.FreeResources();
}

Loading…
Cancel
Save