Browse Source

LA: dense-diagonal TransposeAndMultiply

optimization-3
Christoph Ruegg 13 years ago
parent
commit
19873cb304
  1. 33
      src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
  2. 33
      src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
  3. 30
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  4. 33
      src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
  5. 20
      src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs
  6. 21
      src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs
  7. 20
      src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs
  8. 20
      src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs

33
src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs

@ -684,14 +684,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeAndMultiply(Matrix<Complex> other, Matrix<Complex> result)
{
var denseOther = other as DenseMatrix;
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoTransposeAndMultiply(other, result);
}
else
if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@ -705,7 +700,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
denseOther._columnCount,
0.0,
denseResult._values);
return;
}
var diagonalOther = other.Storage as DiagonalMatrixStorage<Complex>;
if (diagonalOther != null)
{
var diagonal = diagonalOther.Data;
var d = Math.Min(ColumnCount, other.RowCount);
if (d < other.RowCount)
{
result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < RowCount; i++)
{
result.At(i, j, _values[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
/// <summary>

33
src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs

@ -679,14 +679,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeAndMultiply(Matrix<Complex32> other, Matrix<Complex32> result)
{
var denseOther = other as DenseMatrix;
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoTransposeAndMultiply(other, result);
}
else
if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@ -700,7 +695,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
denseOther._columnCount,
0.0f,
denseResult._values);
return;
}
var diagonalOther = other.Storage as DiagonalMatrixStorage<Complex32>;
if (diagonalOther != null)
{
var diagonal = diagonalOther.Data;
var d = Math.Min(ColumnCount, other.RowCount);
if (d < other.RowCount)
{
result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < RowCount; i++)
{
result.At(i, j, _values[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
/// <summary>

30
src/Numerics/LinearAlgebra/Double/DenseMatrix.cs

@ -661,11 +661,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoTransposeAndMultiply(other, result);
}
else
if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@ -679,7 +675,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double
denseOther._columnCount,
0.0,
denseResult._values);
return;
}
var diagonalOther = other.Storage as DiagonalMatrixStorage<double>;
if (diagonalOther != null)
{
var diagonal = diagonalOther.Data;
var d = Math.Min(ColumnCount, other.RowCount);
if (d < other.RowCount)
{
result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < RowCount; i++)
{
result.At(i, j, _values[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
/// <summary>

33
src/Numerics/LinearAlgebra/Single/DenseMatrix.cs

@ -659,14 +659,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <param name="result">The result of the multiplication.</param>
protected override void DoTransposeAndMultiply(Matrix<float> other, Matrix<float> result)
{
var denseOther = other as DenseMatrix;
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
if (denseOther == null || denseResult == null)
{
base.DoTransposeAndMultiply(other, result);
}
else
if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@ -680,7 +675,31 @@ namespace MathNet.Numerics.LinearAlgebra.Single
denseOther._columnCount,
0.0f,
denseResult._values);
return;
}
var diagonalOther = other.Storage as DiagonalMatrixStorage<float>;
if (diagonalOther != null)
{
var diagonal = diagonalOther.Data;
var d = Math.Min(ColumnCount, other.RowCount);
if (d < other.RowCount)
{
result.ClearSubMatrix(0, RowCount, ColumnCount, other.RowCount - ColumnCount);
}
int index = 0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < RowCount; i++)
{
result.At(i, j, _values[index]*diagonal[j]);
index++;
}
}
return;
}
base.DoTransposeAndMultiply(other, result);
}
/// <summary>

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

@ -387,7 +387,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
}
[Test]
public void DenseDiagonalMatrixMultiplication()
public void DenseDiagonalMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
@ -403,5 +403,23 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
Assert.IsTrue((wide*Matrix<Complex>.Build.Diagonal(8, 10, 2d)).Equals(wide.Multiply(2d).Append(Matrix<Complex>.Build.Dense(3, 2))));
Assert.IsTrue((wide*Matrix<Complex>.Build.Diagonal(8, 2, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DenseDiagonalMatrixTransposeAndMultiply()
{
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(tall.TransposeAndMultiply(Matrix<Complex>.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d)));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<Complex>.Build.Diagonal(5, 3, 2d)).Equals(tall.Multiply(2d).Append(Matrix<Complex>.Build.Dense(8, 2))));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<Complex>.Build.Diagonal(2, 3, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2)));
var wide = Matrix<Complex>.Build.Random(3, 8, dist);
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<Complex>.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d)));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<Complex>.Build.Diagonal(10, 8, 2d)).Equals(wide.Multiply(2d).Append(Matrix<Complex>.Build.Dense(3, 2))));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<Complex>.Build.Diagonal(2, 8, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2)));
}
}
}

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

@ -381,8 +381,9 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
var matrix = TestMatrices["Square3x3"];
Assert.IsTrue(matrix.IsSymmetric);
}
[Test]
public void DenseDiagonalMatrixMultiplication()
public void DenseDiagonalMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
@ -398,5 +399,23 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
Assert.IsTrue((wide*Matrix<Complex32>.Build.Diagonal(8, 10, 2f)).Equals(wide.Multiply(2f).Append(Matrix<Complex32>.Build.Dense(3, 2))));
Assert.IsTrue((wide*Matrix<Complex32>.Build.Diagonal(8, 2, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DenseDiagonalMatrixTransposeAndMultiply()
{
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(tall.TransposeAndMultiply(Matrix<Complex32>.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f)));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<Complex32>.Build.Diagonal(5, 3, 2f)).Equals(tall.Multiply(2f).Append(Matrix<Complex32>.Build.Dense(8, 2))));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<Complex32>.Build.Diagonal(2, 3, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2)));
var wide = Matrix<Complex32>.Build.Random(3, 8, dist);
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<Complex32>.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f)));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<Complex32>.Build.Diagonal(10, 8, 2f)).Equals(wide.Multiply(2f).Append(Matrix<Complex32>.Build.Dense(3, 2))));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<Complex32>.Build.Diagonal(2, 8, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2)));
}
}
}

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

@ -414,7 +414,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
}
[Test]
public void DenseDiagonalMatrixMultiplication()
public void DenseDiagonalMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
@ -430,5 +430,23 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
Assert.IsTrue((wide*Matrix<double>.Build.Diagonal(8, 10, 2d)).Equals(wide.Multiply(2d).Append(Matrix<double>.Build.Dense(3, 2))));
Assert.IsTrue((wide*Matrix<double>.Build.Diagonal(8, 2, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DenseDiagonalMatrixTransposeAndMultiply()
{
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(tall.TransposeAndMultiply(Matrix<double>.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d)));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<double>.Build.Diagonal(5, 3, 2d)).Equals(tall.Multiply(2d).Append(Matrix<double>.Build.Dense(8, 2))));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<double>.Build.Diagonal(2, 3, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2)));
var wide = Matrix<double>.Build.Random(3, 8, dist);
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<double>.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d)));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<double>.Build.Diagonal(10, 8, 2d)).Equals(wide.Multiply(2d).Append(Matrix<double>.Build.Dense(3, 2))));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<double>.Build.Diagonal(2, 8, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2)));
}
}
}

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

@ -381,7 +381,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
}
[Test]
public void DenseDiagonalMatrixMultiplication()
public void DenseDiagonalMatrixMultiply()
{
var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
@ -397,5 +397,23 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
Assert.IsTrue((wide*Matrix<float>.Build.Diagonal(8, 10, 2f)).Equals(wide.Multiply(2f).Append(Matrix<float>.Build.Dense(3, 2))));
Assert.IsTrue((wide*Matrix<float>.Build.Diagonal(8, 2, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2)));
}
[Test]
public void DenseDiagonalMatrixTransposeAndMultiply()
{
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(tall.TransposeAndMultiply(Matrix<float>.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f)));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<float>.Build.Diagonal(5, 3, 2f)).Equals(tall.Multiply(2f).Append(Matrix<float>.Build.Dense(8, 2))));
Assert.IsTrue(tall.TransposeAndMultiply(Matrix<float>.Build.Diagonal(2, 3, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2)));
var wide = Matrix<float>.Build.Random(3, 8, dist);
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<float>.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f)));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<float>.Build.Diagonal(10, 8, 2f)).Equals(wide.Multiply(2f).Append(Matrix<float>.Build.Dense(3, 2))));
Assert.IsTrue(wide.TransposeAndMultiply(Matrix<float>.Build.Diagonal(2, 8, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2)));
}
}
}

Loading…
Cancel
Save