Browse Source

LA: diagonal-dense Multiply TransoseAndMultiply TransposeThisAndMultiply

pull/184/head
Christoph Ruegg 13 years ago
parent
commit
aadb8a4bb5
  1. 242
      src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
  2. 244
      src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
  3. 237
      src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
  4. 36
      src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
  5. 237
      src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs
  6. 51
      src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs
  7. 51
      src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs
  8. 51
      src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs
  9. 51
      src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs

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

@ -194,39 +194,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
i => new Complex(distribution.Sample(), distribution.Sample())));
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<Complex> Add(Matrix<Complex> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<Complex> result;
if (other is DiagonalMatrix)
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
else
{
result = new DenseMatrix(RowCount, ColumnCount);
}
Add(other, result);
return result;
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
@ -249,39 +216,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<Complex> Subtract(Matrix<Complex> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<Complex> result;
if (other is DiagonalMatrix)
{
result = new DenseMatrix(RowCount, ColumnCount);
}
else
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
Subtract(other, result);
return result;
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
@ -398,72 +332,44 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void Multiply(Matrix<Complex> other, Matrix<Complex> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (result == null)
{
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
}
if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, result);
}
var m = other as DiagonalMatrix;
var r = result as DiagonalMatrix;
if (m == null || r == null)
{
base.Multiply(other, result);
}
else
{
var thisDataCopy = new Complex[r._data.Length];
var otherDataCopy = new Complex[r._data.Length];
Array.Copy(_data, thisDataCopy, (r._data.Length > _data.Length) ? _data.Length : r._data.Length);
Array.Copy(m._data, otherDataCopy, (r._data.Length > m._data.Length) ? m._data.Length : r._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data);
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix<Complex> Multiply(Matrix<Complex> other)
protected override void DoMultiply(Matrix<Complex> other, Matrix<Complex> result)
{
if (other == null)
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
throw new ArgumentNullException("other");
var thisDataCopy = new Complex[diagonalResult._data.Length];
var otherDataCopy = new Complex[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
if (ColumnCount != other.RowCount)
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<Complex>;
if (denseOther != null)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
var result = other.CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result;
base.DoMultiply(other, result);
}
/// <summary>
@ -596,22 +502,88 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix<Complex> other, Matrix<Complex> result)
protected override void DoTransposeAndMultiply(Matrix<Complex> other, Matrix<Complex> result)
{
var otherDiagonal = other as DiagonalMatrix;
var resultDiagonal = result as DiagonalMatrix;
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
var thisDataCopy = new Complex[diagonalResult._data.Length];
var otherDataCopy = new Complex[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<Complex>;
if (denseOther != null)
{
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.ColumnCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < denseOther.RowCount; i++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
if (otherDiagonal == null || resultDiagonal == null)
/// <summary>
/// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeThisAndMultiply(Matrix<Complex> other, Matrix<Complex> result)
{
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
base.TransposeAndMultiply(other, result);
var thisDataCopy = new Complex[diagonalResult._data.Length];
var otherDataCopy = new Complex[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<Complex>;
if (denseOther != null)
{
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, ColumnCount);
if (d < ColumnCount)
{
result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
Multiply(otherDiagonal.Transpose(), result);
base.DoTransposeThisAndMultiply(other, result);
}
/// <summary>

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

@ -189,39 +189,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
i => new Complex32((float) distribution.Sample(), (float) distribution.Sample())));
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<Complex32> Add(Matrix<Complex32> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<Complex32> result;
if (other is DiagonalMatrix)
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
else
{
result = new DenseMatrix(RowCount, ColumnCount);
}
Add(other, result);
return result;
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
@ -244,39 +211,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<Complex32> Subtract(Matrix<Complex32> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<Complex32> result;
if (other is DiagonalMatrix)
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
else
{
result = new DenseMatrix(RowCount, ColumnCount);
}
Subtract(other, result);
return result;
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
@ -356,8 +290,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </summary>
/// <param name="scalar">The scalar to multiply the matrix with.</param>
/// <param name="result">The matrix to store the result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the same as this matrix.</exception>
protected override void DoMultiply(Complex32 scalar, Matrix<Complex32> result)
{
if (scalar.IsZero())
@ -393,72 +325,44 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void Multiply(Matrix<Complex32> other, Matrix<Complex32> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (result == null)
{
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
}
if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
}
var m = other as DiagonalMatrix;
var r = result as DiagonalMatrix;
if (m == null || r == null)
{
base.Multiply(other, result);
}
else
{
var thisDataCopy = new Complex32[r._data.Length];
var otherDataCopy = new Complex32[r._data.Length];
Array.Copy(_data, thisDataCopy, (r._data.Length > _data.Length) ? _data.Length : r._data.Length);
Array.Copy(m._data, otherDataCopy, (r._data.Length > m._data.Length) ? m._data.Length : r._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data);
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix<Complex32> Multiply(Matrix<Complex32> other)
protected override void DoMultiply(Matrix<Complex32> other, Matrix<Complex32> result)
{
if (other == null)
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
throw new ArgumentNullException("other");
var thisDataCopy = new Complex32[diagonalResult._data.Length];
var otherDataCopy = new Complex32[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
if (ColumnCount != other.RowCount)
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<Complex32>;
if (denseOther != null)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
var result = other.CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result;
base.DoMultiply(other, result);
}
/// <summary>
@ -591,22 +495,88 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix<Complex32> other, Matrix<Complex32> result)
protected override void DoTransposeAndMultiply(Matrix<Complex32> other, Matrix<Complex32> result)
{
var otherDiagonal = other as DiagonalMatrix;
var resultDiagonal = result as DiagonalMatrix;
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
var thisDataCopy = new Complex32[diagonalResult._data.Length];
var otherDataCopy = new Complex32[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
if (otherDiagonal == null || resultDiagonal == null)
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<Complex32>;
if (denseOther != null)
{
base.TransposeAndMultiply(other, result);
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.ColumnCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < denseOther.RowCount; i++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
/// <summary>
/// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeThisAndMultiply(Matrix<Complex32> other, Matrix<Complex32> result)
{
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
var thisDataCopy = new Complex32[diagonalResult._data.Length];
var otherDataCopy = new Complex32[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<Complex32>;
if (denseOther != null)
{
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, ColumnCount);
if (d < ColumnCount)
{
result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
Multiply(otherDiagonal.Transpose(), result);
base.DoTransposeThisAndMultiply(other, result);
}
/// <summary>

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

@ -188,39 +188,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
i => distribution.Sample()));
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<double> Add(Matrix<double> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<double> result;
if (other is DiagonalMatrix)
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
else
{
result = new DenseMatrix(RowCount, ColumnCount);
}
Add(other, result);
return result;
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
@ -243,39 +210,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<double> Subtract(Matrix<double> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<double> result;
if (other is DiagonalMatrix)
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
else
{
result = new DenseMatrix(RowCount, ColumnCount);
}
Subtract(other, result);
return result;
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
@ -392,67 +326,44 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void Multiply(Matrix<double> other, Matrix<double> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (result == null)
{
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount || result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, other, result);
}
var m = other as DiagonalMatrix;
var r = result as DiagonalMatrix;
if (m == null || r == null)
{
base.Multiply(other, result);
}
else
{
var thisDataCopy = new double[r._data.Length];
var otherDataCopy = new double[r._data.Length];
Buffer.BlockCopy(_data, 0, thisDataCopy, 0, (r._data.Length > _data.Length) ? _data.Length * Constants.SizeOfDouble : r._data.Length * Constants.SizeOfDouble);
Buffer.BlockCopy(m._data, 0, otherDataCopy, 0, (r._data.Length > m._data.Length) ? m._data.Length * Constants.SizeOfDouble : r._data.Length * Constants.SizeOfDouble);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data);
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix<double> Multiply(Matrix<double> other)
protected override void DoMultiply(Matrix<double> other, Matrix<double> result)
{
if (other == null)
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
throw new ArgumentNullException("other");
var thisDataCopy = new double[diagonalResult._data.Length];
var otherDataCopy = new double[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
if (ColumnCount != other.RowCount)
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<double>;
if (denseOther != null)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
var result = other.CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result;
base.DoMultiply(other, result);
}
/// <summary>
@ -585,22 +496,88 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix<double> other, Matrix<double> result)
protected override void DoTransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
var thisDataCopy = new double[diagonalResult._data.Length];
var otherDataCopy = new double[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<double>;
if (denseOther != null)
{
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.ColumnCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < denseOther.RowCount; i++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
/// <summary>
/// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeThisAndMultiply(Matrix<double> other, Matrix<double> result)
{
var otherDiagonal = other as DiagonalMatrix;
var resultDiagonal = result as DiagonalMatrix;
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
var thisDataCopy = new double[diagonalResult._data.Length];
var otherDataCopy = new double[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
if (otherDiagonal == null || resultDiagonal == null)
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<double>;
if (denseOther != null)
{
base.TransposeAndMultiply(other, result);
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, ColumnCount);
if (d < ColumnCount)
{
result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
Multiply(otherDiagonal.Transpose(), result);
base.DoTransposeThisAndMultiply(other, result);
}
/// <summary>

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

@ -204,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra
return Clone();
}
var result = CreateMatrix(RowCount, ColumnCount);
var result = Build.SameType(this, RowCount, ColumnCount);
DoAdd(scalar, result);
return result;
}
@ -237,14 +237,14 @@ namespace MathNet.Numerics.LinearAlgebra
/// <param name="other">The matrix to add to this matrix.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual Matrix<T> Add(Matrix<T> other)
public Matrix<T> Add(Matrix<T> other)
{
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other);
}
var result = CreateMatrix(RowCount, ColumnCount);
var result = Build.SameType(this, other, RowCount, ColumnCount);
DoAdd(other, result);
return result;
}
@ -282,7 +282,7 @@ namespace MathNet.Numerics.LinearAlgebra
return Clone();
}
var result = CreateMatrix(RowCount, ColumnCount);
var result = Build.SameType(this, RowCount, ColumnCount);
DoSubtract(scalar, result);
return result;
}
@ -316,7 +316,7 @@ namespace MathNet.Numerics.LinearAlgebra
/// <returns>A new matrix containing the subtraction of the scalar and this matrix.</returns>
public Matrix<T> SubtractFrom(T scalar)
{
var result = CreateMatrix(RowCount, ColumnCount);
var result = Build.SameType(this, RowCount, ColumnCount);
DoSubtractFrom(scalar, result);
return result;
}
@ -343,14 +343,14 @@ namespace MathNet.Numerics.LinearAlgebra
/// <param name="other">The matrix to subtract.</param>
/// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public virtual Matrix<T> Subtract(Matrix<T> other)
public Matrix<T> Subtract(Matrix<T> other)
{
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other);
}
var result = CreateMatrix(RowCount, ColumnCount);
var result = Build.SameType(this, other, RowCount, ColumnCount);
DoSubtract(other, result);
return result;
}
@ -633,7 +633,7 @@ namespace MathNet.Numerics.LinearAlgebra
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public virtual void Multiply(Matrix<T> other, Matrix<T> result)
public void Multiply(Matrix<T> other, Matrix<T> result)
{
if (ColumnCount != other.RowCount || result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
@ -642,7 +642,7 @@ namespace MathNet.Numerics.LinearAlgebra
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount);
var tmp = Build.SameType(result, result.RowCount, result.ColumnCount);
DoMultiply(other, tmp);
tmp.CopyTo(result);
}
@ -658,14 +658,14 @@ namespace MathNet.Numerics.LinearAlgebra
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <returns>The result of the multiplication.</returns>
public virtual Matrix<T> Multiply(Matrix<T> other)
public Matrix<T> Multiply(Matrix<T> other)
{
if (ColumnCount != other.RowCount)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
}
var result = CreateMatrix(RowCount, other.ColumnCount);
var result = Build.SameType(this, other, RowCount, other.ColumnCount);
DoMultiply(other, result);
return result;
}
@ -686,7 +686,7 @@ namespace MathNet.Numerics.LinearAlgebra
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount);
var tmp = Build.SameType(result, result.RowCount, result.ColumnCount);
DoTransposeAndMultiply(other, tmp);
tmp.CopyTo(result);
}
@ -709,7 +709,7 @@ namespace MathNet.Numerics.LinearAlgebra
throw DimensionsDontMatch<ArgumentException>(this, other);
}
var result = CreateMatrix(RowCount, other.RowCount);
var result = Build.SameType(this, other, RowCount, other.RowCount);
DoTransposeAndMultiply(other, result);
return result;
}
@ -727,9 +727,9 @@ namespace MathNet.Numerics.LinearAlgebra
throw DimensionsDontMatch<ArgumentException>(this, rightSide, "rightSide");
}
var ret = CreateVector(ColumnCount);
DoTransposeThisAndMultiply(rightSide, ret);
return ret;
var result = CreateVector(ColumnCount);
DoTransposeThisAndMultiply(rightSide, result);
return result;
}
/// <summary>
@ -779,7 +779,7 @@ namespace MathNet.Numerics.LinearAlgebra
if (ReferenceEquals(this, result) || ReferenceEquals(other, result))
{
var tmp = result.CreateMatrix(result.RowCount, result.ColumnCount);
var tmp = Build.SameType(result, result.RowCount, result.ColumnCount);
DoTransposeThisAndMultiply(other, tmp);
tmp.CopyTo(result);
}
@ -802,7 +802,7 @@ namespace MathNet.Numerics.LinearAlgebra
throw DimensionsDontMatch<ArgumentException>(this, other);
}
var result = CreateMatrix(ColumnCount, other.ColumnCount);
var result = Build.SameType(this, other, ColumnCount, other.ColumnCount);
DoTransposeThisAndMultiply(other, result);
return result;
}

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

@ -188,39 +188,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
i => (float) distribution.Sample()));
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
/// <param name="other">The matrix to add to this matrix.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<float> Add(Matrix<float> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<float> result;
if (other is DiagonalMatrix)
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
else
{
result = new DenseMatrix(RowCount, ColumnCount);
}
Add(other, result);
return result;
}
/// <summary>
/// Adds another matrix to this matrix.
/// </summary>
@ -243,39 +210,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
/// <param name="other">The matrix to subtract.</param>
/// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null"/>.</exception>
/// <exception cref="ArgumentOutOfRangeException">If the two matrices don't have the same dimensions.</exception>
public override Matrix<float> Subtract(Matrix<float> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
throw DimensionsDontMatch<ArgumentOutOfRangeException>(this, other, "other");
}
Matrix<float> result;
if (other is DiagonalMatrix)
{
result = new DiagonalMatrix(RowCount, ColumnCount);
}
else
{
result = new DenseMatrix(RowCount, ColumnCount);
}
Subtract(other, result);
return result;
}
/// <summary>
/// Subtracts another matrix from this matrix.
/// </summary>
@ -392,67 +326,44 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void Multiply(Matrix<float> other, Matrix<float> result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (result == null)
{
throw new ArgumentNullException("result");
}
if (ColumnCount != other.RowCount || result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, other, result);
}
var m = other as DiagonalMatrix;
var r = result as DiagonalMatrix;
if (m == null || r == null)
{
base.Multiply(other, result);
}
else
{
var thisDataCopy = new float[r._data.Length];
var otherDataCopy = new float[r._data.Length];
Buffer.BlockCopy(_data, 0, thisDataCopy, 0, (r._data.Length > _data.Length) ? _data.Length * Constants.SizeOfFloat : r._data.Length * Constants.SizeOfFloat);
Buffer.BlockCopy(m._data, 0, otherDataCopy, 0, (r._data.Length > m._data.Length) ? m._data.Length * Constants.SizeOfFloat : r._data.Length * Constants.SizeOfFloat);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, r._data);
}
}
/// <summary>
/// Multiplies this matrix with another matrix and returns the result.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <returns>The result of multiplication.</returns>
public override Matrix<float> Multiply(Matrix<float> other)
protected override void DoMultiply(Matrix<float> other, Matrix<float> result)
{
if (other == null)
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
throw new ArgumentNullException("other");
var thisDataCopy = new float[diagonalResult._data.Length];
var otherDataCopy = new float[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
if (ColumnCount != other.RowCount)
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<float>;
if (denseOther != null)
{
throw DimensionsDontMatch<ArgumentException>(this, other);
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.RowCount, RowCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
var result = other.CreateMatrix(RowCount, other.ColumnCount);
Multiply(other, result);
return result;
base.DoMultiply(other, result);
}
/// <summary>
@ -585,22 +496,88 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the other matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentNullException">If the result matrix is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If <strong>this.Columns != other.Rows</strong>.</exception>
/// <exception cref="ArgumentException">If the result matrix's dimensions are not the this.Rows x other.Columns.</exception>
public override void TransposeAndMultiply(Matrix<float> other, Matrix<float> result)
protected override void DoTransposeAndMultiply(Matrix<float> other, Matrix<float> result)
{
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
var thisDataCopy = new float[diagonalResult._data.Length];
var otherDataCopy = new float[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<float>;
if (denseOther != null)
{
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.ColumnCount, RowCount);
if (d < RowCount)
{
result.ClearSubMatrix(denseOther.ColumnCount, RowCount - denseOther.ColumnCount, 0, denseOther.RowCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < denseOther.RowCount; i++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
/// <summary>
/// Multiplies the transpose of this matrix with another matrix and places the results into the result matrix.
/// </summary>
/// <param name="other">The matrix to multiply with.</param>
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeThisAndMultiply(Matrix<float> other, Matrix<float> result)
{
var otherDiagonal = other as DiagonalMatrix;
var resultDiagonal = result as DiagonalMatrix;
var diagonalOther = other as DiagonalMatrix;
var diagonalResult = result as DiagonalMatrix;
if (diagonalOther != null && diagonalResult != null)
{
var thisDataCopy = new float[diagonalResult._data.Length];
var otherDataCopy = new float[diagonalResult._data.Length];
Array.Copy(_data, thisDataCopy, (diagonalResult._data.Length > _data.Length) ? _data.Length : diagonalResult._data.Length);
Array.Copy(diagonalOther._data, otherDataCopy, (diagonalResult._data.Length > diagonalOther._data.Length) ? diagonalOther._data.Length : diagonalResult._data.Length);
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(thisDataCopy, otherDataCopy, diagonalResult._data);
return;
}
if (otherDiagonal == null || resultDiagonal == null)
var denseOther = other.Storage as DenseColumnMajorMatrixStorage<float>;
if (denseOther != null)
{
base.TransposeAndMultiply(other, result);
var dense = denseOther.Data;
var diagonal = _data;
var d = Math.Min(denseOther.RowCount, ColumnCount);
if (d < ColumnCount)
{
result.ClearSubMatrix(denseOther.RowCount, ColumnCount - denseOther.RowCount, 0, denseOther.ColumnCount);
}
int index = 0;
for (int i = 0; i < denseOther.ColumnCount; i++)
{
for (int j = 0; j < d; j++)
{
result.At(j, i, dense[index]*diagonal[j]);
index++;
}
index += (denseOther.RowCount - d);
}
return;
}
Multiply(otherDiagonal.Transpose(), result);
base.DoTransposeThisAndMultiply(other, result);
}
/// <summary>

51
src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs

@ -436,5 +436,56 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<Complex>.Build.Diagonal(8, 10, 2d)).Equals(tall.Transpose().Multiply(2d).Append(Matrix<Complex>.Build.Dense(3, 2))));
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<Complex>.Build.Diagonal(8, 2, 2d)).Equals(tall.Transpose().Multiply(2d).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DiagonalDenseMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<Complex>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<Complex>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<Complex>.Build.DiagonalIdentity(3).Multiply(2d)*wide).Equals(wide.Multiply(2d)));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(5, 3, 2d)*wide).Equals(wide.Multiply(2d).Stack(Matrix<Complex>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(2, 3, 2d)*wide).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<Complex>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<Complex>.Build.DiagonalIdentity(8).Multiply(2d)*tall).Equals(tall.Multiply(2d)));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(10, 8, 2d)*tall).Equals(tall.Multiply(2d).Stack(Matrix<Complex>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(2, 8, 2d)*tall).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3)));
}
[Test]
public void DiagonalDenseMatrixTransposeAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<Complex>.Build.DiagonalIdentity(3, 3));
var tall = Matrix<Complex>.Build.Random(8, 3, dist);
Assert.IsTrue(Matrix<Complex>.Build.DiagonalIdentity(3).Multiply(2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Transpose()));
Assert.IsTrue(Matrix<Complex>.Build.Diagonal(5, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Append(Matrix<Complex>.Build.Dense(8, 2)).Transpose()));
Assert.IsTrue(Matrix<Complex>.Build.Diagonal(2, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2).Transpose()));
var wide = Matrix<Complex>.Build.Random(3, 8, dist);
Assert.IsTrue(Matrix<Complex>.Build.DiagonalIdentity(8).Multiply(2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Transpose()));
Assert.IsTrue(Matrix<Complex>.Build.Diagonal(10, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Append(Matrix<Complex>.Build.Dense(3, 2)).Transpose()));
Assert.IsTrue(Matrix<Complex>.Build.Diagonal(2, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2).Transpose()));
}
[Test]
public void DiagonalDenseMatrixTransposeThisAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<Complex>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<Complex>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<Complex>.Build.DiagonalIdentity(3).Multiply(2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d)));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(3, 5, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).Stack(Matrix<Complex>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(3, 2, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<Complex>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<Complex>.Build.DiagonalIdentity(8).Multiply(2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d)));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(8, 10, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).Stack(Matrix<Complex>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<Complex>.Build.Diagonal(8, 2, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3)));
}
}
}

51
src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs

@ -432,5 +432,56 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<Complex32>.Build.Diagonal(8, 10, 2f)).Equals(tall.Transpose().Multiply(2f).Append(Matrix<Complex32>.Build.Dense(3, 2))));
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<Complex32>.Build.Diagonal(8, 2, 2f)).Equals(tall.Transpose().Multiply(2f).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DiagonalDenseMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<Complex32>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<Complex32>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<Complex32>.Build.DiagonalIdentity(3).Multiply(2f)*wide).Equals(wide.Multiply(2f)));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(5, 3, 2f)*wide).Equals(wide.Multiply(2f).Stack(Matrix<Complex32>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(2, 3, 2f)*wide).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<Complex32>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<Complex32>.Build.DiagonalIdentity(8).Multiply(2f)*tall).Equals(tall.Multiply(2f)));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(10, 8, 2f)*tall).Equals(tall.Multiply(2f).Stack(Matrix<Complex32>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(2, 8, 2f)*tall).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3)));
}
[Test]
public void DiagonalDenseMatrixTransposeAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<Complex32>.Build.DiagonalIdentity(3, 3));
var tall = Matrix<Complex32>.Build.Random(8, 3, dist);
Assert.IsTrue(Matrix<Complex32>.Build.DiagonalIdentity(3).Multiply(2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Transpose()));
Assert.IsTrue(Matrix<Complex32>.Build.Diagonal(5, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Append(Matrix<Complex32>.Build.Dense(8, 2)).Transpose()));
Assert.IsTrue(Matrix<Complex32>.Build.Diagonal(2, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2).Transpose()));
var wide = Matrix<Complex32>.Build.Random(3, 8, dist);
Assert.IsTrue(Matrix<Complex32>.Build.DiagonalIdentity(8).Multiply(2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Transpose()));
Assert.IsTrue(Matrix<Complex32>.Build.Diagonal(10, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Append(Matrix<Complex32>.Build.Dense(3, 2)).Transpose()));
Assert.IsTrue(Matrix<Complex32>.Build.Diagonal(2, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2).Transpose()));
}
[Test]
public void DiagonalDenseMatrixTransposeThisAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<Complex32>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<Complex32>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<Complex32>.Build.DiagonalIdentity(3).Multiply(2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f)));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(3, 5, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).Stack(Matrix<Complex32>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(3, 2, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<Complex32>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<Complex32>.Build.DiagonalIdentity(8).Multiply(2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f)));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(8, 10, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).Stack(Matrix<Complex32>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<Complex32>.Build.Diagonal(8, 2, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3)));
}
}
}

51
src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs

@ -463,5 +463,56 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<double>.Build.Diagonal(8, 10, 2d)).Equals(tall.Transpose().Multiply(2d).Append(Matrix<double>.Build.Dense(3, 2))));
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<double>.Build.Diagonal(8, 2, 2d)).Equals(tall.Transpose().Multiply(2d).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DiagonalDenseMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<double>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<double>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<double>.Build.DiagonalIdentity(3).Multiply(2d)*wide).Equals(wide.Multiply(2d)));
Assert.IsTrue((Matrix<double>.Build.Diagonal(5, 3, 2d)*wide).Equals(wide.Multiply(2d).Stack(Matrix<double>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<double>.Build.Diagonal(2, 3, 2d)*wide).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<double>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<double>.Build.DiagonalIdentity(8).Multiply(2d)*tall).Equals(tall.Multiply(2d)));
Assert.IsTrue((Matrix<double>.Build.Diagonal(10, 8, 2d)*tall).Equals(tall.Multiply(2d).Stack(Matrix<double>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<double>.Build.Diagonal(2, 8, 2d)*tall).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3)));
}
[Test]
public void DiagonalDenseMatrixTransposeAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<double>.Build.DiagonalIdentity(3, 3));
var tall = Matrix<double>.Build.Random(8, 3, dist);
Assert.IsTrue(Matrix<double>.Build.DiagonalIdentity(3).Multiply(2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Transpose()));
Assert.IsTrue(Matrix<double>.Build.Diagonal(5, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).Append(Matrix<double>.Build.Dense(8, 2)).Transpose()));
Assert.IsTrue(Matrix<double>.Build.Diagonal(2, 3, 2d).TransposeAndMultiply(tall).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2).Transpose()));
var wide = Matrix<double>.Build.Random(3, 8, dist);
Assert.IsTrue(Matrix<double>.Build.DiagonalIdentity(8).Multiply(2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Transpose()));
Assert.IsTrue(Matrix<double>.Build.Diagonal(10, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).Append(Matrix<double>.Build.Dense(3, 2)).Transpose()));
Assert.IsTrue(Matrix<double>.Build.Diagonal(2, 8, 2d).TransposeAndMultiply(wide).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2).Transpose()));
}
[Test]
public void DiagonalDenseMatrixTransposeThisAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<double>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<double>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<double>.Build.DiagonalIdentity(3).Multiply(2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d)));
Assert.IsTrue((Matrix<double>.Build.Diagonal(3, 5, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).Stack(Matrix<double>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<double>.Build.Diagonal(3, 2, 2d).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2d).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<double>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<double>.Build.DiagonalIdentity(8).Multiply(2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d)));
Assert.IsTrue((Matrix<double>.Build.Diagonal(8, 10, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).Stack(Matrix<double>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<double>.Build.Diagonal(8, 2, 2d).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2d).SubMatrix(0, 2, 0, 3)));
}
}
}

51
src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs

@ -430,5 +430,56 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<float>.Build.Diagonal(8, 10, 2f)).Equals(tall.Transpose().Multiply(2f).Append(Matrix<float>.Build.Dense(3, 2))));
Assert.IsTrue(tall.TransposeThisAndMultiply(Matrix<float>.Build.Diagonal(8, 2, 2f)).Equals(tall.Transpose().Multiply(2f).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DiagonalDenseMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<float>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<float>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<float>.Build.DiagonalIdentity(3).Multiply(2f)*wide).Equals(wide.Multiply(2f)));
Assert.IsTrue((Matrix<float>.Build.Diagonal(5, 3, 2f)*wide).Equals(wide.Multiply(2f).Stack(Matrix<float>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<float>.Build.Diagonal(2, 3, 2f)*wide).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<float>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<float>.Build.DiagonalIdentity(8).Multiply(2f)*tall).Equals(tall.Multiply(2f)));
Assert.IsTrue((Matrix<float>.Build.Diagonal(10, 8, 2f)*tall).Equals(tall.Multiply(2f).Stack(Matrix<float>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<float>.Build.Diagonal(2, 8, 2f)*tall).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3)));
}
[Test]
public void DiagonalDenseMatrixTransposeAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<float>.Build.DiagonalIdentity(3, 3));
var tall = Matrix<float>.Build.Random(8, 3, dist);
Assert.IsTrue(Matrix<float>.Build.DiagonalIdentity(3).Multiply(2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Transpose()));
Assert.IsTrue(Matrix<float>.Build.Diagonal(5, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).Append(Matrix<float>.Build.Dense(8, 2)).Transpose()));
Assert.IsTrue(Matrix<float>.Build.Diagonal(2, 3, 2f).TransposeAndMultiply(tall).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2).Transpose()));
var wide = Matrix<float>.Build.Random(3, 8, dist);
Assert.IsTrue(Matrix<float>.Build.DiagonalIdentity(8).Multiply(2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Transpose()));
Assert.IsTrue(Matrix<float>.Build.Diagonal(10, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).Append(Matrix<float>.Build.Dense(3, 2)).Transpose()));
Assert.IsTrue(Matrix<float>.Build.Diagonal(2, 8, 2f).TransposeAndMultiply(wide).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2).Transpose()));
}
[Test]
public void DiagonalDenseMatrixTransposeThisAndMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
Assert.IsInstanceOf<DiagonalMatrix>(Matrix<float>.Build.DiagonalIdentity(3, 3));
var wide = Matrix<float>.Build.Random(3, 8, dist);
Assert.IsTrue((Matrix<float>.Build.DiagonalIdentity(3).Multiply(2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f)));
Assert.IsTrue((Matrix<float>.Build.Diagonal(3, 5, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).Stack(Matrix<float>.Build.Dense(2, 8))));
Assert.IsTrue((Matrix<float>.Build.Diagonal(3, 2, 2f).TransposeThisAndMultiply(wide)).Equals(wide.Multiply(2f).SubMatrix(0, 2, 0, 8)));
var tall = Matrix<float>.Build.Random(8, 3, dist);
Assert.IsTrue((Matrix<float>.Build.DiagonalIdentity(8).Multiply(2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f)));
Assert.IsTrue((Matrix<float>.Build.Diagonal(8, 10, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).Stack(Matrix<float>.Build.Dense(2, 3))));
Assert.IsTrue((Matrix<float>.Build.Diagonal(8, 2, 2f).TransposeThisAndMultiply(tall)).Equals(tall.Multiply(2f).SubMatrix(0, 2, 0, 3)));
}
}
}

Loading…
Cancel
Save