From f8012bca554578d757051c6e27196ab59e09ed04 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Mon, 24 Oct 2016 20:40:43 +0200 Subject: [PATCH] LA: bind matrix dot-power with matrix exponent to provider --- .../LinearAlgebra/Complex/DenseMatrix.cs | 26 ++++++++++-- .../LinearAlgebra/Complex32/DenseMatrix.cs | 26 ++++++++++-- .../LinearAlgebra/Double/DenseMatrix.cs | 26 ++++++++++-- .../LinearAlgebra/Single/DenseMatrix.cs | 20 +++++++++ .../LinearAlgebra/ILinearAlgebraProvider.cs | 12 ++++++ .../ManagedLinearAlgebraProvider.Complex.cs | 41 +++++++++++++++++++ .../ManagedLinearAlgebraProvider.Complex32.cs | 41 +++++++++++++++++++ .../ManagedLinearAlgebraProvider.Double.cs | 41 +++++++++++++++++++ .../ManagedLinearAlgebraProvider.Single.cs | 41 +++++++++++++++++++ 9 files changed, 265 insertions(+), 9 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index ca8da014..1dd3f723 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -974,16 +974,36 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The matrix to store the result of the pointwise division. protected override void DoPointwiseDivide(Matrix divisor, Matrix result) { - var denseOther = divisor as DenseMatrix; + var denseDivisor = divisor as DenseMatrix; var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) + if (denseDivisor == null || denseResult == null) { base.DoPointwiseDivide(divisor, result); } else { - Control.LinearAlgebraProvider.PointWiseDivideArrays(_values, denseOther._values, denseResult._values); + Control.LinearAlgebraProvider.PointWiseDivideArrays(_values, denseDivisor._values, denseResult._values); + } + } + + /// + /// Pointwise raise this matrix to an exponent and store the result into the result matrix. + /// + /// The exponent to raise this matrix values to. + /// The vector to store the result of the pointwise power. + protected override void DoPointwisePower(Matrix exponent, Matrix result) + { + var denseExponent = exponent as DenseMatrix; + var denseResult = result as DenseMatrix; + + if (denseExponent == null || denseResult == null) + { + base.DoPointwisePower(exponent, result); + } + else + { + Control.LinearAlgebraProvider.PointWisePowerArrays(_values, denseExponent._values, denseResult._values); } } diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index 1a406a33..c7f49435 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -971,16 +971,36 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The matrix to store the result of the pointwise division. protected override void DoPointwiseDivide(Matrix divisor, Matrix result) { - var denseOther = divisor as DenseMatrix; + var denseDivisor = divisor as DenseMatrix; var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) + if (denseDivisor == null || denseResult == null) { base.DoPointwiseDivide(divisor, result); } else { - Control.LinearAlgebraProvider.PointWiseDivideArrays(_values, denseOther._values, denseResult._values); + Control.LinearAlgebraProvider.PointWiseDivideArrays(_values, denseDivisor._values, denseResult._values); + } + } + + /// + /// Pointwise raise this matrix to an exponent and store the result into the result matrix. + /// + /// The exponent to raise this matrix values to. + /// The vector to store the result of the pointwise power. + protected override void DoPointwisePower(Matrix exponent, Matrix result) + { + var denseExponent = exponent as DenseMatrix; + var denseResult = result as DenseMatrix; + + if (denseExponent == null || denseResult == null) + { + base.DoPointwisePower(exponent, result); + } + else + { + Control.LinearAlgebraProvider.PointWisePowerArrays(_values, denseExponent._values, denseResult._values); } } diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index 54fab3fa..f14e8c9b 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -817,16 +817,36 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The matrix to store the result of the pointwise division. protected override void DoPointwiseDivide(Matrix divisor, Matrix result) { - var denseOther = divisor as DenseMatrix; + var denseDivisor = divisor as DenseMatrix; var denseResult = result as DenseMatrix; - if (denseOther == null || denseResult == null) + if (denseDivisor == null || denseResult == null) { base.DoPointwiseDivide(divisor, result); } else { - Control.LinearAlgebraProvider.PointWiseDivideArrays(_values, denseOther._values, denseResult._values); + Control.LinearAlgebraProvider.PointWiseDivideArrays(_values, denseDivisor._values, denseResult._values); + } + } + + /// + /// Pointwise raise this matrix to an exponent and store the result into the result matrix. + /// + /// The exponent to raise this matrix values to. + /// The vector to store the result of the pointwise power. + protected override void DoPointwisePower(Matrix exponent, Matrix result) + { + var denseExponent = exponent as DenseMatrix; + var denseResult = result as DenseMatrix; + + if (denseExponent == null || denseResult == null) + { + base.DoPointwisePower(exponent, result); + } + else + { + Control.LinearAlgebraProvider.PointWisePowerArrays(_values, denseExponent._values, denseResult._values); } } diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 44336ce0..9fd3a3b7 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -830,6 +830,26 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } + /// + /// Pointwise raise this matrix to an exponent and store the result into the result matrix. + /// + /// The exponent to raise this matrix values to. + /// The vector to store the result of the pointwise power. + protected override void DoPointwisePower(Matrix exponent, Matrix result) + { + var denseExponent = exponent as DenseMatrix; + var denseResult = result as DenseMatrix; + + if (denseExponent == null || denseResult == null) + { + base.DoPointwisePower(exponent, result); + } + else + { + Control.LinearAlgebraProvider.PointWisePowerArrays(_values, denseExponent._values, denseResult._values); + } + } + /// /// Computes the canonical modulus, where the result has the sign of the divisor, /// for the given divisor each element of the matrix. diff --git a/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs b/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs index 1717dbee..a246c3b7 100644 --- a/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs +++ b/src/Numerics/Providers/LinearAlgebra/ILinearAlgebraProvider.cs @@ -204,6 +204,18 @@ namespace MathNet.Numerics.Providers.LinearAlgebra /// routine. void PointWiseDivideArrays(T[] x, T[] y, T[] result); + /// + /// Does a point wise power of two arrays z = x ^ y. This can be used + /// to raise elements of vectors or matrices to the powers of another vector or matrix. + /// + /// The array x. + /// The array y. + /// The result of the point wise power. + /// There is no equivalent BLAS routine, but many libraries + /// provide optimized (parallel and/or vectorized) versions of this + /// routine. + void PointWisePowerArrays(T[] x, T[] y, T[] result); + /// /// Computes the requested of the matrix. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs index 8ebc6ba8..f9107c06 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs @@ -353,6 +353,47 @@ namespace MathNet.Numerics.Providers.LinearAlgebra }); } + /// + /// Does a point wise power of two arrays z = x ^ y. This can be used + /// to raise elements of vectors or matrices to the powers of another vector or matrix. + /// + /// The array x. + /// The array y. + /// The result of the point wise power. + /// There is no equivalent BLAS routine, but many libraries + /// provide optimized (parallel and/or vectorized) versions of this + /// routine. + public virtual void PointWisePowerArrays(Complex[] x, Complex[] y, Complex[] result) + { + if (y == null) + { + throw new ArgumentNullException("y"); + } + + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (y.Length != x.Length || y.Length != result.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + CommonParallel.For(0, y.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = Complex.Pow(x[i], y[i]); + } + }); + } + /// /// Computes the requested of the matrix. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs index 9ddc97de..aebc2fa8 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs @@ -351,6 +351,47 @@ namespace MathNet.Numerics.Providers.LinearAlgebra }); } + /// + /// Does a point wise power of two arrays z = x ^ y. This can be used + /// to raise elements of vectors or matrices to the powers of another vector or matrix. + /// + /// The array x. + /// The array y. + /// The result of the point wise power. + /// There is no equivalent BLAS routine, but many libraries + /// provide optimized (parallel and/or vectorized) versions of this + /// routine. + public virtual void PointWisePowerArrays(Complex32[] x, Complex32[] y, Complex32[] result) + { + if (y == null) + { + throw new ArgumentNullException("y"); + } + + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (y.Length != x.Length || y.Length != result.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + CommonParallel.For(0, y.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = Complex32.Pow(x[i], y[i]); + } + }); + } + /// /// Computes the requested of the matrix. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs index b8456706..84325cd2 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs @@ -345,6 +345,47 @@ namespace MathNet.Numerics.Providers.LinearAlgebra }); } + /// + /// Does a point wise power of two arrays z = x ^ y. This can be used + /// to raise elements of vectors or matrices to the powers of another vector or matrix. + /// + /// The array x. + /// The array y. + /// The result of the point wise power. + /// There is no equivalent BLAS routine, but many libraries + /// provide optimized (parallel and/or vectorized) versions of this + /// routine. + public virtual void PointWisePowerArrays(double[] x, double[] y, double[] result) + { + if (y == null) + { + throw new ArgumentNullException("y"); + } + + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (y.Length != x.Length || y.Length != result.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + CommonParallel.For(0, y.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = Math.Pow(x[i], y[i]); + } + }); + } + /// /// Computes the requested of the matrix. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs index a877f72b..a6919d35 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs @@ -345,6 +345,47 @@ namespace MathNet.Numerics.Providers.LinearAlgebra }); } + /// + /// Does a point wise power of two arrays z = x ^ y. This can be used + /// to raise elements of vectors or matrices to the powers of another vector or matrix. + /// + /// The array x. + /// The array y. + /// The result of the point wise power. + /// There is no equivalent BLAS routine, but many libraries + /// provide optimized (parallel and/or vectorized) versions of this + /// routine. + public virtual void PointWisePowerArrays(float[] x, float[] y, float[] result) + { + if (y == null) + { + throw new ArgumentNullException("y"); + } + + if (x == null) + { + throw new ArgumentNullException("x"); + } + + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (y.Length != x.Length || y.Length != result.Length) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength); + } + + CommonParallel.For(0, y.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + result[i] = (float)Math.Pow(x[i], y[i]); + } + }); + } + /// /// Computes the requested of the matrix. ///