Browse Source

LA: optimize diagonal-scalar division #146

provider
Christoph Ruegg 13 years ago
parent
commit
269f7f371e
  1. 159
      src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
  2. 159
      src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
  3. 160
      src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
  4. 2
      src/Numerics/LinearAlgebra/Double/Matrix.cs
  5. 4
      src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
  6. 160
      src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs
  7. 2
      src/Numerics/LinearAlgebra/Single/Matrix.cs

159
src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,13 +28,14 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Complex
{
@ -279,51 +280,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Complex[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Array.Copy(source, _data, source.Length);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<Complex> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Array.Copy(denseSource.Values, _data, denseSource.Values.Length);
}
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
@ -351,11 +307,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
else
{
if (!ReferenceEquals(this, result))
{
CopyTo(diagResult);
}
Control.LinearAlgebraProvider.ScaleArray(scalar, _data, diagResult._data);
}
}
@ -700,6 +651,61 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
/// <summary>
/// Divides each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="divisor">The scalar to divide the matrix with.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivide(Complex divisor, Matrix<Complex> result)
{
if (divisor == Complex.One)
{
CopyTo(result);
return;
}
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
Control.LinearAlgebraProvider.ScaleArray(1.0/divisor, _data, diagResult._data);
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, _data[i]/divisor);
}
}
/// <summary>
/// Divides a scalar by each element of the matrix and stores the result in the result matrix.
/// </summary>
/// <param name="dividend">The scalar to add.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivideByThis(Complex dividend, Matrix<Complex> result)
{
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
var resultData = diagResult._data;
CommonParallel.For(0, _data.Length, 4096, (a, b) =>
{
for (int i = a; i < b; i++)
{
resultData[i] = dividend/_data[i];
}
});
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, dividend/_data[i]);
}
}
/// <summary>
/// Computes the determinant of this matrix.
/// </summary>
@ -725,6 +731,51 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return new DenseVector(_data).Clone();
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Complex[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Array.Copy(source, _data, source.Length);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<Complex> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Array.Copy(denseSource.Values, _data, denseSource.Values.Length);
}
/// <summary>Calculates the induced L1 norm of this matrix.</summary>
/// <returns>The maximum absolute column sum of the matrix.</returns>
public override double L1Norm()

159
src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,13 +28,14 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Complex32
{
@ -274,51 +275,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Complex32[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Array.Copy(source, _data, source.Length);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<Complex32> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Array.Copy(denseSource.Values, _data, denseSource.Values.Length);
}
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
@ -345,11 +301,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
else
{
if (!ReferenceEquals(this, result))
{
CopyTo(diagResult);
}
Control.LinearAlgebraProvider.ScaleArray(scalar, _data, diagResult._data);
}
}
@ -694,6 +645,61 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
/// <summary>
/// Divides each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="divisor">The scalar to divide the matrix with.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivide(Complex32 divisor, Matrix<Complex32> result)
{
if (divisor == Complex32.One)
{
CopyTo(result);
return;
}
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
Control.LinearAlgebraProvider.ScaleArray(1.0f/divisor, _data, diagResult._data);
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, _data[i]/divisor);
}
}
/// <summary>
/// Divides a scalar by each element of the matrix and stores the result in the result matrix.
/// </summary>
/// <param name="dividend">The scalar to add.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivideByThis(Complex32 dividend, Matrix<Complex32> result)
{
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
var resultData = diagResult._data;
CommonParallel.For(0, _data.Length, 4096, (a, b) =>
{
for (int i = a; i < b; i++)
{
resultData[i] = dividend/_data[i];
}
});
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, dividend/_data[i]);
}
}
/// <summary>
/// Computes the determinant of this matrix.
/// </summary>
@ -719,6 +725,51 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return new DenseVector(_data).Clone();
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Complex32[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Array.Copy(source, _data, source.Length);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<Complex32> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Array.Copy(denseSource.Values, _data, denseSource.Values.Length);
}
/// <summary>Calculates the induced L1 norm of this matrix.</summary>
/// <returns>The maximum absolute column sum of the matrix.</returns>
public override double L1Norm()

160
src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,14 +28,14 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Double
{
@ -253,51 +253,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(double[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Buffer.BlockCopy(source, 0, _data, 0, source.Length * Constants.SizeOfDouble);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<double> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Buffer.BlockCopy(denseSource.Values, 0, _data, 0, denseSource.Values.Length * Constants.SizeOfDouble);
}
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
@ -325,11 +280,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
if (!ReferenceEquals(this, result))
{
CopyTo(diagResult);
}
Control.LinearAlgebraProvider.ScaleArray(scalar, _data, diagResult._data);
}
}
@ -544,6 +494,61 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
/// <summary>
/// Divides each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="divisor">The scalar to divide the matrix with.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivide(double divisor, Matrix<double> result)
{
if (divisor == 1.0)
{
CopyTo(result);
return;
}
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
Control.LinearAlgebraProvider.ScaleArray(1.0/divisor, _data, diagResult._data);
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, _data[i]/divisor);
}
}
/// <summary>
/// Divides a scalar by each element of the matrix and stores the result in the result matrix.
/// </summary>
/// <param name="dividend">The scalar to add.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivideByThis(double dividend, Matrix<double> result)
{
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
var resultData = diagResult._data;
CommonParallel.For(0, _data.Length, 4096, (a, b) =>
{
for (int i = a; i < b; i++)
{
resultData[i] = dividend/_data[i];
}
});
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, dividend/_data[i]);
}
}
/// <summary>
/// Computes the determinant of this matrix.
/// </summary>
@ -569,6 +574,51 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return new DenseVector(_data).Clone();
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(double[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Buffer.BlockCopy(source, 0, _data, 0, source.Length * Constants.SizeOfDouble);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<double> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Buffer.BlockCopy(denseSource.Values, 0, _data, 0, denseSource.Values.Length * Constants.SizeOfDouble);
}
/// <summary>Calculates the induced L1 norm of this matrix.</summary>
/// <returns>The maximum absolute column sum of the matrix.</returns>
public override double L1Norm()

2
src/Numerics/LinearAlgebra/Double/Matrix.cs

@ -439,7 +439,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="rightSide">The vector to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoConjugateTransposeThisAndMultiply(Vector<double> rightSide, Vector<double> result)
protected override sealed void DoConjugateTransposeThisAndMultiply(Vector<double> rightSide, Vector<double> result)
{
DoTransposeThisAndMultiply(rightSide, result);
}

4
src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs

@ -745,7 +745,7 @@ namespace MathNet.Numerics.LinearAlgebra
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.ColumnCount</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.RowCount x other.RowCount.</exception>
public virtual void TransposeAndMultiply(Matrix<T> other, Matrix<T> result)
public void TransposeAndMultiply(Matrix<T> other, Matrix<T> result)
{
if (ColumnCount != other.ColumnCount || result.RowCount != RowCount || result.ColumnCount != other.RowCount)
{
@ -884,7 +884,7 @@ namespace MathNet.Numerics.LinearAlgebra
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.ColumnCount</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.RowCount x other.RowCount.</exception>
public virtual void ConjugateTransposeAndMultiply(Matrix<T> other, Matrix<T> result)
public void ConjugateTransposeAndMultiply(Matrix<T> other, Matrix<T> result)
{
if (ColumnCount != other.ColumnCount || result.RowCount != RowCount || result.ColumnCount != other.RowCount)
{

160
src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,14 +28,14 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.LinearAlgebra.Single
{
@ -253,51 +253,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(float[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Buffer.BlockCopy(source, 0, _data, 0, source.Length * Constants.SizeOfFloat);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<float> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Buffer.BlockCopy(denseSource.Values, 0, _data, 0, denseSource.Values.Length * Constants.SizeOfFloat);
}
/// <summary>
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
@ -325,11 +280,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
else
{
if (!ReferenceEquals(this, result))
{
CopyTo(diagResult);
}
Control.LinearAlgebraProvider.ScaleArray(scalar, _data, diagResult._data);
}
}
@ -544,6 +494,61 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
}
/// <summary>
/// Divides each element of the matrix by a scalar and places results into the result matrix.
/// </summary>
/// <param name="divisor">The scalar to divide the matrix with.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivide(float divisor, Matrix<float> result)
{
if (divisor == 1.0f)
{
CopyTo(result);
return;
}
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
Control.LinearAlgebraProvider.ScaleArray(1.0f/divisor, _data, diagResult._data);
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, _data[i]/divisor);
}
}
/// <summary>
/// Divides a scalar by each element of the matrix and stores the result in the result matrix.
/// </summary>
/// <param name="dividend">The scalar to add.</param>
/// <param name="result">The matrix to store the result of the division.</param>
protected override void DoDivideByThis(float dividend, Matrix<float> result)
{
var diagResult = result as DiagonalMatrix;
if (diagResult != null)
{
var resultData = diagResult._data;
CommonParallel.For(0, _data.Length, 4096, (a, b) =>
{
for (int i = a; i < b; i++)
{
resultData[i] = dividend/_data[i];
}
});
return;
}
result.Clear();
for (int i = 0; i < _data.Length; i++)
{
result.At(i, i, dividend/_data[i]);
}
}
/// <summary>
/// Computes the determinant of this matrix.
/// </summary>
@ -569,6 +574,51 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return new DenseVector(_data).Clone();
}
/// <summary>
/// Copies the values of the given array to the diagonal.
/// </summary>
/// <param name="source">The array to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(float[] source)
{
if (source.Length != _data.Length)
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
Buffer.BlockCopy(source, 0, _data, 0, source.Length * Constants.SizeOfFloat);
}
/// <summary>
/// Copies the values of the given <see cref="Vector{T}"/> to the diagonal.
/// </summary>
/// <param name="source">The vector to copy the values from. The length of the vector should be
/// Min(Rows, Columns).</param>
/// <exception cref="ArgumentException">If the length of <paramref name="source"/> does not
/// equal Min(Rows, Columns).</exception>
/// <remarks>For non-square matrices, the elements of <paramref name="source"/> are copied to
/// this[i,i].</remarks>
public override void SetDiagonal(Vector<float> source)
{
var denseSource = source as DenseVector;
if (denseSource == null)
{
base.SetDiagonal(source);
return;
}
if (_data.Length != denseSource.Values.Length)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
Buffer.BlockCopy(denseSource.Values, 0, _data, 0, denseSource.Values.Length * Constants.SizeOfFloat);
}
/// <summary>Calculates the induced L1 norm of this matrix.</summary>
/// <returns>The maximum absolute column sum of the matrix.</returns>
public override double L1Norm()

2
src/Numerics/LinearAlgebra/Single/Matrix.cs

@ -439,7 +439,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </summary>
/// <param name="rightSide">The vector to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoConjugateTransposeThisAndMultiply(Vector<float> rightSide, Vector<float> result)
protected override sealed void DoConjugateTransposeThisAndMultiply(Vector<float> rightSide, Vector<float> result)
{
DoTransposeThisAndMultiply(rightSide, result);
}

Loading…
Cancel
Save