diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
index 7142e826..43adc606 100644
--- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
@@ -407,6 +407,27 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
get { return _values; }
}
+ /// Calculates the induced L1 norm of this matrix.
+ /// The maximum absolute column sum of the matrix.
+ public override double L1Norm()
+ {
+ return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values);
+ }
+
+ /// Calculates the induced infinity norm of this matrix.
+ /// The maximum absolute row sum of the matrix.
+ public override double InfinityNorm()
+ {
+ return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values);
+ }
+
+ /// Calculates the entry-wise Frobenius norm of this matrix.
+ /// The square root of the sum of the squared values.
+ public override double FrobeniusNorm()
+ {
+ return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
+ }
+
///
/// Returns the transpose of this matrix.
///
@@ -422,29 +443,139 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
ret._values[(i * _columnCount) + j] = _values[index + i];
}
}
+ return ret;
+ }
+ ///
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
+ {
+ var ret = new DenseMatrix(_columnCount, _rowCount);
+ for (var j = 0; j < _columnCount; j++)
+ {
+ var index = j * _rowCount;
+ for (var i = 0; i < _rowCount; i++)
+ {
+ ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate();
+ }
+ }
return ret;
}
- /// Calculates the induced L1 norm of this matrix.
- /// The maximum absolute column sum of the matrix.
- public override double L1Norm()
+ ///
+ /// Add a scalar to each element of the matrix and stores the result in the result vector.
+ ///
+ /// The scalar to add.
+ /// The matrix to store the result of the addition.
+ protected override void DoAdd(Complex scalar, Matrix result)
{
- return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values);
+ var denseResult = result as DenseMatrix;
+ if (denseResult == null)
+ {
+ base.DoAdd(scalar, result);
+ return;
+ }
+
+ CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
+ {
+ v[i] = _values[i] + scalar;
+ }
+ });
}
- /// Calculates the induced infinity norm of this matrix.
- /// The maximum absolute row sum of the matrix.
- public override double InfinityNorm()
+ ///
+ /// Adds another matrix to this matrix.
+ ///
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of add
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoAdd(Matrix other, Matrix result)
{
- return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values);
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
+ {
+ Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data);
+ return;
+ }
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) + diagonal[i]);
+ }
+ return;
+ }
+
+ base.DoAdd(other, result);
}
- /// Calculates the entry-wise Frobenius norm of this matrix.
- /// The square root of the sum of the squared values.
- public override double FrobeniusNorm()
+ ///
+ /// Subtracts a scalar from each element of the matrix and stores the result in the result vector.
+ ///
+ /// The scalar to subtract.
+ /// The matrix to store the result of the subtraction.
+ protected override void DoSubtract(Complex scalar, Matrix result)
{
- return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
+ var denseResult = result as DenseMatrix;
+ if (denseResult == null)
+ {
+ base.DoSubtract(scalar, result);
+ return;
+ }
+
+ CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
+ {
+ v[i] = _values[i] - scalar;
+ }
+ });
+ }
+
+ ///
+ /// Subtracts another matrix from this matrix.
+ ///
+ /// The matrix to subtract.
+ /// The matrix to store the result of the subtraction.
+ protected override void DoSubtract(Matrix other, Matrix result)
+ {
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
+ {
+ Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data);
+ return;
+ }
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) - diagonal[i]);
+ }
+ return;
+ }
+
+ base.DoSubtract(other, result);
}
///
@@ -505,12 +636,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
-
- if (denseOther == null || denseResult == null)
- {
- base.DoMultiply(other, result);
- }
- else
+ if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@@ -524,7 +650,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
denseOther._columnCount,
0.0,
denseResult._values);
+ return;
}
+
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ var diagonal = diagonalOther.Data;
+ var d = Math.Min(ColumnCount, other.ColumnCount);
+ if (d < other.ColumnCount)
+ {
+ result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - 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.DoMultiply(other, result);
}
///
@@ -696,113 +846,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
- ///
- /// Add a scalar to each element of the matrix and stores the result in the result vector.
- ///
- /// The scalar to add.
- /// The matrix to store the result of the addition.
- protected override void DoAdd(Complex scalar, Matrix result)
- {
- var denseResult = result as DenseMatrix;
- if (denseResult == null)
- {
- base.DoAdd(scalar, result);
- return;
- }
-
- CommonParallel.For(0, _values.Length, 4096, (a, b) =>
- {
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] + scalar;
- }
- });
- }
-
- ///
- /// Adds another matrix to this matrix.
- ///
- /// The matrix to add to this matrix.
- /// The matrix to store the result of add
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- protected override void DoAdd(Matrix other, Matrix result)
- {
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
- {
- base.DoAdd(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values);
- }
- }
-
- ///
- /// Subtracts a scalar from each element of the matrix and stores the result in the result vector.
- ///
- /// The scalar to subtract.
- /// The matrix to store the result of the subtraction.
- protected override void DoSubtract(Complex scalar, Matrix result)
- {
- var denseResult = result as DenseMatrix;
- if (denseResult == null)
- {
- base.DoSubtract(scalar, result);
- return;
- }
-
- CommonParallel.For(0, _values.Length, 4096, (a, b) =>
- {
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] - scalar;
- }
- });
- }
-
- ///
- /// Subtracts another matrix from this matrix.
- ///
- /// The matrix to subtract.
- /// The matrix to store the result of the subtraction.
- protected override void DoSubtract(Matrix other, Matrix result)
- {
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
- {
- base.DoSubtract(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values);
- }
- }
-
- ///
- /// Returns the conjugate transpose of this matrix.
- ///
- /// The conjugate transpose of this matrix.
- public override Matrix ConjugateTranspose()
- {
- var ret = new DenseMatrix(_columnCount, _rowCount);
- for (var j = 0; j < _columnCount; j++)
- {
- var index = j * _rowCount;
- for (var i = 0; i < _rowCount; i++)
- {
- ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate();
- }
- }
-
- return ret;
- }
-
///
/// Computes the trace of this matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
index d6a3e968..c89e3e5b 100644
--- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
@@ -588,9 +588,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// i == j (i is the row index, and j is the column index).
public override Vector Diagonal()
{
- // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will
- // not influence onto diagonal elements
- return new DenseVector((Complex[])_data.Clone());
+ return new DenseVector(_data).Clone();
}
///
@@ -616,31 +614,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
Multiply(otherDiagonal.Transpose(), result);
}
- ///
- /// Multiplies this matrix with transpose of another matrix and returns the result.
- ///
- /// The matrix to multiply with.
- /// If this.Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix TransposeAndMultiply(Matrix other)
- {
- var otherDiagonal = other as DiagonalMatrix;
- if (otherDiagonal == null)
- {
- return base.TransposeAndMultiply(other);
- }
-
- if (ColumnCount != otherDiagonal.ColumnCount)
- {
- throw DimensionsDontMatch(this, otherDiagonal);
- }
-
- var result = other.CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
- }
-
///
/// Returns the transpose of this matrix.
///
@@ -703,7 +676,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
if (RowCount != ColumnCount)
{
- throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
var inverse = (DiagonalMatrix)Clone();
diff --git a/src/Numerics/LinearAlgebra/Complex/Matrix.cs b/src/Numerics/LinearAlgebra/Complex/Matrix.cs
index 75c1412d..a15cd12c 100644
--- a/src/Numerics/LinearAlgebra/Complex/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/Matrix.cs
@@ -41,6 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
using Complex = Numerics.Complex;
#else
using Complex = System.Numerics.Complex;
+
#endif
///
@@ -48,7 +49,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
///
[Serializable]
public abstract class Matrix : Matrix
- {
+ {
///
/// Initializes a new instance of the Matrix class.
///
@@ -96,7 +97,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public override double FrobeniusNorm()
{
var transpose = ConjugateTranspose();
- var aat = this * transpose;
+ var aat = this*transpose;
var norm = 0d;
for (var i = 0; i < RowCount; i++)
{
@@ -119,7 +120,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
ret.At(j, i, At(i, j).Conjugate());
}
}
-
return ret;
}
@@ -202,7 +202,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, At(i, j) * scalar);
+ result.At(i, j, At(i, j)*scalar);
}
}
}
@@ -213,18 +213,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// The vector to multiply with.
/// The result of the multiplication.
protected override void DoMultiply(Vector rightSide, Vector result)
- {
+ {
for (var i = 0; i < RowCount; i++)
{
var s = Complex.Zero;
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
- s += At(i, j) * rightSide[j];
+ s += At(i, j)*rightSide[j];
}
-
result[i] = s;
}
- }
+ }
///
/// Multiplies this matrix with another matrix and places the results into the result matrix.
@@ -240,9 +239,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
var s = Complex.Zero;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(j, l) * other.At(l, i);
+ s += At(j, l)*other.At(l, i);
}
-
result.At(j, i, s);
}
}
@@ -255,7 +253,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// The matrix to store the result of the division.
protected override void DoDivide(Complex divisor, Matrix result)
{
- DoMultiply(1.0 / divisor, result);
+ DoMultiply(1.0/divisor, result);
}
///
@@ -269,7 +267,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, dividend / At(i, j));
+ result.At(i, j, dividend/At(i, j));
}
}
}
@@ -288,9 +286,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
var s = Complex.Zero;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(i, l) * other.At(j, l);
+ s += At(i, l)*other.At(j, l);
}
-
result.At(i, j, s);
}
}
@@ -310,9 +307,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
var s = Complex.Zero;
for (var l = 0; l < RowCount; l++)
{
- s += At(l, i) * other.At(l, j);
+ s += At(l, i)*other.At(l, j);
}
-
result.At(i, j, s);
}
}
@@ -328,11 +324,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
for (var i = 0; i < ColumnCount; i++)
{
var s = Complex.Zero;
- for (var j = 0; j != RowCount; j++)
+ for (var j = 0; j < RowCount; j++)
{
- s += At(j, i) * rightSide[j];
+ s += At(j, i)*rightSide[j];
}
-
result[i] = s;
}
}
@@ -345,7 +340,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
for (var i = 0; i < RowCount; i++)
{
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, -At(i, j));
}
@@ -360,7 +355,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
for (var i = 0; i < RowCount; i++)
{
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, At(i, j).Conjugate());
}
@@ -378,7 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
for (var i = 0; i < RowCount; i++)
{
- result.At(i, j, At(i, j) * other.At(i, j));
+ result.At(i, j, At(i, j)*other.At(i, j));
}
}
}
@@ -394,7 +389,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
for (var i = 0; i < RowCount; i++)
{
- result.At(i, j, At(i, j) / divisor.At(i, j));
+ result.At(i, j, At(i, j)/divisor.At(i, j));
}
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
index df9a2192..37721c1a 100644
--- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
@@ -402,6 +402,27 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
get { return _values; }
}
+ /// Calculates the induced L1 norm of this matrix.
+ /// The maximum absolute column sum of the matrix.
+ public override double L1Norm()
+ {
+ return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values);
+ }
+
+ /// Calculates the induced infinity norm of this matrix.
+ /// The maximum absolute row sum of the matrix.
+ public override double InfinityNorm()
+ {
+ return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values);
+ }
+
+ /// Calculates the entry-wise Frobenius norm of this matrix.
+ /// The square root of the sum of the squared values.
+ public override double FrobeniusNorm()
+ {
+ return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
+ }
+
///
/// Returns the transpose of this matrix.
///
@@ -417,29 +438,139 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
ret._values[(i * _columnCount) + j] = _values[index + i];
}
}
+ return ret;
+ }
+ ///
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
+ {
+ var ret = new DenseMatrix(_columnCount, _rowCount);
+ for (var j = 0; j < _columnCount; j++)
+ {
+ var index = j * _rowCount;
+ for (var i = 0; i < _rowCount; i++)
+ {
+ ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate();
+ }
+ }
return ret;
}
- /// Calculates the induced L1 norm of this matrix.
- /// The maximum absolute column sum of the matrix.
- public override double L1Norm()
+ ///
+ /// Add a scalar to each element of the matrix and stores the result in the result vector.
+ ///
+ /// The scalar to add.
+ /// The matrix to store the result of the addition.
+ protected override void DoAdd(Complex32 scalar, Matrix result)
{
- return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _values);
+ var denseResult = result as DenseMatrix;
+ if (denseResult == null)
+ {
+ base.DoAdd(scalar, result);
+ return;
+ }
+
+ CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
+ {
+ v[i] = _values[i] + scalar;
+ }
+ });
}
- /// Calculates the induced infinity norm of this matrix.
- /// The maximum absolute row sum of the matrix.
- public override double InfinityNorm()
+ ///
+ /// Adds another matrix to this matrix.
+ ///
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of add
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoAdd(Matrix other, Matrix result)
{
- return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _values);
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
+ {
+ Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data);
+ return;
+ }
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) + diagonal[i]);
+ }
+ return;
+ }
+
+ base.DoAdd(other, result);
}
- /// Calculates the entry-wise Frobenius norm of this matrix.
- /// The square root of the sum of the squared values.
- public override double FrobeniusNorm()
+ ///
+ /// Subtracts a scalar from each element of the matrix and stores the result in the result vector.
+ ///
+ /// The scalar to subtract.
+ /// The matrix to store the result of the subtraction.
+ protected override void DoSubtract(Complex32 scalar, Matrix result)
{
- return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
+ var denseResult = result as DenseMatrix;
+ if (denseResult == null)
+ {
+ base.DoSubtract(scalar, result);
+ return;
+ }
+
+ CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
+ {
+ v[i] = _values[i] - scalar;
+ }
+ });
+ }
+
+ ///
+ /// Subtracts another matrix from this matrix.
+ ///
+ /// The matrix to subtract.
+ /// The matrix to store the result of the subtraction.
+ protected override void DoSubtract(Matrix other, Matrix result)
+ {
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
+ {
+ Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data);
+ return;
+ }
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) - diagonal[i]);
+ }
+ return;
+ }
+
+ base.DoSubtract(other, result);
}
///
@@ -500,12 +631,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
-
- if (denseOther == null || denseResult == null)
- {
- base.DoMultiply(other, result);
- }
- else
+ if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@@ -519,7 +645,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
denseOther._columnCount,
0.0f,
denseResult._values);
+ return;
}
+
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ var diagonal = diagonalOther.Data;
+ var d = Math.Min(ColumnCount, other.ColumnCount);
+ if (d < other.ColumnCount)
+ {
+ result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - 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.DoMultiply(other, result);
}
///
@@ -691,113 +841,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
- ///
- /// Add a scalar to each element of the matrix and stores the result in the result vector.
- ///
- /// The scalar to add.
- /// The matrix to store the result of the addition.
- protected override void DoAdd(Complex32 scalar, Matrix result)
- {
- var denseResult = result as DenseMatrix;
- if (denseResult == null)
- {
- base.DoAdd(scalar, result);
- return;
- }
-
- CommonParallel.For(0, _values.Length, 4096, (a, b) =>
- {
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] + scalar;
- }
- });
- }
-
- ///
- /// Adds another matrix to this matrix.
- ///
- /// The matrix to add to this matrix.
- /// The matrix to store the result of add
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- protected override void DoAdd(Matrix other, Matrix result)
- {
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
- {
- base.DoAdd(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values);
- }
- }
-
- ///
- /// Subtracts a scalar from each element of the matrix and stores the result in the result vector.
- ///
- /// The scalar to subtract.
- /// The matrix to store the result of the subtraction.
- protected override void DoSubtract(Complex32 scalar, Matrix result)
- {
- var denseResult = result as DenseMatrix;
- if (denseResult == null)
- {
- base.DoSubtract(scalar, result);
- return;
- }
-
- CommonParallel.For(0, _values.Length, 4096, (a, b) =>
- {
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] - scalar;
- }
- });
- }
-
- ///
- /// Subtracts another matrix from this matrix.
- ///
- /// The matrix to subtract.
- /// The matrix to store the result of the subtraction.
- protected override void DoSubtract(Matrix other, Matrix result)
- {
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
- {
- base.DoSubtract(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values);
- }
- }
-
- ///
- /// Returns the conjugate transpose of this matrix.
- ///
- /// The conjugate transpose of this matrix.
- public override Matrix ConjugateTranspose()
- {
- var ret = new DenseMatrix(_columnCount, _rowCount);
- for (var j = 0; j < _columnCount; j++)
- {
- var index = j * _rowCount;
- for (var i = 0; i < _rowCount; i++)
- {
- ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate();
- }
- }
-
- return ret;
- }
-
///
/// Computes the trace of this matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
index f1f04d3b..2213a10e 100644
--- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
@@ -583,9 +583,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// i == j (i is the row index, and j is the column index).
public override Vector Diagonal()
{
- // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will
- // not influence onto diagonal elements
- return new DenseVector((Complex32[])_data.Clone());
+ return new DenseVector(_data).Clone();
}
///
@@ -611,31 +609,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
Multiply(otherDiagonal.Transpose(), result);
}
- ///
- /// Multiplies this matrix with transpose of another matrix and returns the result.
- ///
- /// The matrix to multiply with.
- /// If this.Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix TransposeAndMultiply(Matrix other)
- {
- var otherDiagonal = other as DiagonalMatrix;
- if (otherDiagonal == null)
- {
- return base.TransposeAndMultiply(other);
- }
-
- if (ColumnCount != otherDiagonal.ColumnCount)
- {
- throw DimensionsDontMatch(this, otherDiagonal);
- }
-
- var result = other.CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
- }
-
///
/// Returns the transpose of this matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
index ad6a3346..dae6f558 100644
--- a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
@@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
+using System;
using MathNet.Numerics.LinearAlgebra.Complex32.Factorization;
using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.LinearAlgebra.Storage;
using MathNet.Numerics.Properties;
-using System;
namespace MathNet.Numerics.LinearAlgebra.Complex32
{
@@ -91,7 +91,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public override double FrobeniusNorm()
{
var transpose = ConjugateTranspose();
- var aat = this * transpose;
+ var aat = this*transpose;
var norm = 0d;
for (var i = 0; i < RowCount; i++)
{
@@ -196,29 +196,28 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, At(i, j) * scalar);
+ result.At(i, j, At(i, j)*scalar);
}
}
}
- ///
+ ///
/// Multiplies this matrix with a vector and places the results into the result vector.
///
/// The vector to multiply with.
/// The result of the multiplication.
protected override void DoMultiply(Vector rightSide, Vector result)
- {
+ {
for (var i = 0; i < RowCount; i++)
{
var s = Complex32.Zero;
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
- s += At(i, j) * rightSide[j];
+ s += At(i, j)*rightSide[j];
}
-
result[i] = s;
}
- }
+ }
///
/// Divides each element of the matrix by a scalar and places results into the result matrix.
@@ -227,7 +226,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// The matrix to store the result of the division.
protected override void DoDivide(Complex32 divisor, Matrix result)
{
- DoMultiply(1.0f / divisor, result);
+ DoMultiply(1.0f/divisor, result);
}
///
@@ -241,7 +240,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, dividend / At(i, j));
+ result.At(i, j, dividend/At(i, j));
}
}
}
@@ -260,9 +259,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
var s = Complex32.Zero;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(j, l) * other.At(l, i);
+ s += At(j, l)*other.At(l, i);
}
-
result.At(j, i, s);
}
}
@@ -282,9 +280,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
var s = Complex32.Zero;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(i, l) * other.At(j, l);
+ s += At(i, l)*other.At(j, l);
}
-
result.At(i, j, s);
}
}
@@ -304,9 +301,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
var s = Complex32.Zero;
for (var l = 0; l < RowCount; l++)
{
- s += At(l, i) * other.At(l, j);
+ s += At(l, i)*other.At(l, j);
}
-
result.At(i, j, s);
}
}
@@ -322,11 +318,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
for (var i = 0; i < ColumnCount; i++)
{
var s = Complex32.Zero;
- for (var j = 0; j != RowCount; j++)
+ for (var j = 0; j < RowCount; j++)
{
- s += At(j, i) * rightSide[j];
+ s += At(j, i)*rightSide[j];
}
-
result[i] = s;
}
}
@@ -339,7 +334,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
for (var i = 0; i < RowCount; i++)
{
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, -At(i, j));
}
@@ -354,7 +349,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
for (var i = 0; i < RowCount; i++)
{
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, At(i, j).Conjugate());
}
@@ -372,7 +367,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
for (var i = 0; i < RowCount; i++)
{
- result.At(i, j, At(i, j) * other.At(i, j));
+ result.At(i, j, At(i, j)*other.At(i, j));
}
}
}
@@ -388,7 +383,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
for (var i = 0; i < RowCount; i++)
{
- result.At(i, j, At(i, j) / divisor.At(i, j));
+ result.At(i, j, At(i, j)/divisor.At(i, j));
}
}
}
diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
index 30198a63..f9370001 100644
--- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
@@ -399,25 +399,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
get { return _values; }
}
- ///
- /// Returns the transpose of this matrix.
- ///
- /// The transpose of this matrix.
- public override Matrix Transpose()
- {
- var ret = new DenseMatrix(_columnCount, _rowCount);
- for (var j = 0; j < _columnCount; j++)
- {
- var index = j * _rowCount;
- for (var i = 0; i < _rowCount; i++)
- {
- ret._values[(i * _columnCount) + j] = _values[index + i];
- }
- }
-
- return ret;
- }
-
/// Calculates the induced L1 norm of this matrix.
/// The maximum absolute column sum of the matrix.
public override double L1Norm()
@@ -439,6 +420,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
}
+ ///
+ /// Returns the transpose of this matrix.
+ ///
+ /// The transpose of this matrix.
+ public override Matrix Transpose()
+ {
+ var ret = new DenseMatrix(_columnCount, _rowCount);
+ for (var j = 0; j < _columnCount; j++)
+ {
+ var index = j * _rowCount;
+ for (var i = 0; i < _rowCount; i++)
+ {
+ ret._values[(i * _columnCount) + j] = _values[index + i];
+ }
+ }
+
+ return ret;
+ }
+
///
/// Add a scalar to each element of the matrix and stores the result in the result vector.
///
@@ -454,13 +454,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
{
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] + scalar;
- }
- });
+ v[i] = _values[i] + scalar;
+ }
+ });
}
///
@@ -472,16 +472,29 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// If the two matrices don't have the same dimensions.
protected override void DoAdd(Matrix other, Matrix result)
{
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
{
- base.DoAdd(other, result);
+ Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data);
+ return;
}
- else
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
{
- Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values);
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) + diagonal[i]);
+ }
+ return;
}
+
+ base.DoAdd(other, result);
}
///
@@ -499,13 +512,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
{
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] - scalar;
- }
- });
+ v[i] = _values[i] - scalar;
+ }
+ });
}
///
@@ -515,16 +528,29 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The matrix to store the result of the subtraction.
protected override void DoSubtract(Matrix other, Matrix result)
{
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
{
- base.DoSubtract(other, result);
+ Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data);
+ return;
}
- else
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
{
- Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values);
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) - diagonal[i]);
+ }
+ return;
}
+
+ base.DoSubtract(other, result);
}
///
@@ -585,12 +611,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
-
- if (denseOther == null || denseResult == null)
- {
- base.DoMultiply(other, result);
- }
- else
+ if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@@ -604,7 +625,31 @@ namespace MathNet.Numerics.LinearAlgebra.Double
denseOther._columnCount,
0.0,
denseResult._values);
+ return;
}
+
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ var diagonal = diagonalOther.Data;
+ var d = Math.Min(ColumnCount, other.ColumnCount);
+ if (d < other.ColumnCount)
+ {
+ result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - 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.DoMultiply(other, result);
}
///
@@ -614,9 +659,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The result of the multiplication.
protected override void DoTransposeAndMultiply(Matrix other, Matrix 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);
diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
index e489a675..872d85b3 100644
--- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
@@ -577,9 +577,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// i == j (i is the row index, and j is the column index).
public override Vector Diagonal()
{
- // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will
- // not influence onto diagonal elements
- return new DenseVector((double[])_data.Clone());
+ return new DenseVector(_data).Clone();
}
///
@@ -605,31 +603,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
Multiply(otherDiagonal.Transpose(), result);
}
- ///
- /// Multiplies this matrix with transpose of another matrix and returns the result.
- ///
- /// The matrix to multiply with.
- /// If this.Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix TransposeAndMultiply(Matrix other)
- {
- var otherDiagonal = other as DiagonalMatrix;
- if (otherDiagonal == null)
- {
- return base.TransposeAndMultiply(other);
- }
-
- if (ColumnCount != otherDiagonal.ColumnCount)
- {
- throw DimensionsDontMatch(this, otherDiagonal);
- }
-
- var result = other.CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
- }
-
///
/// Returns the transpose of this matrix.
///
@@ -692,7 +665,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
if (RowCount != ColumnCount)
{
- throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
var inverse = (DiagonalMatrix)Clone();
diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs
index ec4eaa25..b70d67f7 100644
--- a/src/Numerics/LinearAlgebra/Double/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs
@@ -41,7 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
[Serializable]
public abstract class Matrix : Matrix
- {
+ {
///
/// Initializes a new instance of the Matrix class.
///
@@ -89,7 +89,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double FrobeniusNorm()
{
var transpose = Transpose();
- var aat = this * transpose;
+ var aat = this*transpose;
var norm = 0d;
for (var i = 0; i < RowCount; i++)
{
@@ -156,7 +156,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
}
-
+
///
/// Subtracts another matrix from this matrix.
///
@@ -186,7 +186,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, At(i, j) * scalar);
+ result.At(i, j, At(i, j)*scalar);
}
}
}
@@ -197,18 +197,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The vector to multiply with.
/// The result of the multiplication.
protected override void DoMultiply(Vector rightSide, Vector result)
- {
- for (var i = 0; i < RowCount; i++)
- {
- var s = 0.0;
- for (var j = 0; j != ColumnCount; j++)
- {
- s += At(i, j) * rightSide[j];
- }
-
- result[i] = s;
- }
- }
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ var s = 0.0;
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ s += At(i, j)*rightSide[j];
+ }
+ result[i] = s;
+ }
+ }
///
/// Divides each element of the matrix by a scalar and places results into the result matrix.
@@ -217,7 +216,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The matrix to store the result of the division.
protected override void DoDivide(double divisor, Matrix result)
{
- DoMultiply(1.0 / divisor, result);
+ DoMultiply(1.0/divisor, result);
}
///
@@ -231,7 +230,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, dividend / At(i, j));
+ result.At(i, j, dividend/At(i, j));
}
}
}
@@ -245,14 +244,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
for (var j = 0; j < RowCount; j++)
{
- for (var i = 0; i != other.ColumnCount; i++)
+ for (var i = 0; i < other.ColumnCount; i++)
{
var s = 0.0;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(j, l) * other.At(l, i);
+ s += At(j, l)*other.At(l, i);
}
-
result.At(j, i, s);
}
}
@@ -272,9 +270,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var s = 0.0;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(i, l) * other.At(j, l);
+ s += At(i, l)*other.At(j, l);
}
-
result.At(i, j, s);
}
}
@@ -294,9 +291,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var s = 0.0;
for (var l = 0; l < RowCount; l++)
{
- s += At(l, i) * other.At(l, j);
+ s += At(l, i)*other.At(l, j);
}
-
result.At(i, j, s);
}
}
@@ -312,11 +308,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
for (var i = 0; i < ColumnCount; i++)
{
var s = 0.0;
- for (var j = 0; j != RowCount; j++)
+ for (var j = 0; j < RowCount; j++)
{
- s += At(j, i) * rightSide[j];
+ s += At(j, i)*rightSide[j];
}
-
result[i] = s;
}
}
@@ -329,7 +324,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
for (var i = 0; i < RowCount; i++)
{
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, -At(i, j));
}
diff --git a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
index 25163d6a..bb5fcebf 100644
--- a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
+++ b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs
@@ -702,7 +702,7 @@ namespace MathNet.Numerics.LinearAlgebra
/// The matrix to multiply with.
/// If this.Columns != other.ColumnCount.
/// The result of the multiplication.
- public virtual Matrix TransposeAndMultiply(Matrix other)
+ public Matrix TransposeAndMultiply(Matrix other)
{
if (ColumnCount != other.ColumnCount)
{
diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
index 8c3417ee..b112612d 100644
--- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
@@ -399,25 +399,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
get { return _values; }
}
- ///
- /// Returns the transpose of this matrix.
- ///
- /// The transpose of this matrix.
- public override Matrix Transpose()
- {
- var ret = new DenseMatrix(_columnCount, _rowCount);
- for (var j = 0; j < _columnCount; j++)
- {
- var index = j * _rowCount;
- for (var i = 0; i < _rowCount; i++)
- {
- ret._values[(i * _columnCount) + j] = _values[index + i];
- }
- }
-
- return ret;
- }
-
/// Calculates the induced L1 norm of this matrix.
/// The maximum absolute column sum of the matrix.
public override double L1Norm()
@@ -439,6 +420,25 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values);
}
+ ///
+ /// Returns the transpose of this matrix.
+ ///
+ /// The transpose of this matrix.
+ public override Matrix Transpose()
+ {
+ var ret = new DenseMatrix(_columnCount, _rowCount);
+ for (var j = 0; j < _columnCount; j++)
+ {
+ var index = j * _rowCount;
+ for (var i = 0; i < _rowCount; i++)
+ {
+ ret._values[(i * _columnCount) + j] = _values[index + i];
+ }
+ }
+
+ return ret;
+ }
+
///
/// Add a scalar to each element of the matrix and stores the result in the result vector.
///
@@ -454,13 +454,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
{
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] + scalar;
- }
- });
+ v[i] = _values[i] + scalar;
+ }
+ });
}
///
@@ -472,16 +472,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// If the two matrices don't have the same dimensions.
protected override void DoAdd(Matrix other, Matrix result)
{
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
{
- base.DoAdd(other, result);
+ Control.LinearAlgebraProvider.AddArrays(_values, denseOther.Data, denseResult.Data);
+ return;
}
- else
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
{
- Control.LinearAlgebraProvider.AddArrays(_values, denseOther._values, denseResult._values);
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) + diagonal[i]);
+ }
+ return;
}
+
+ base.DoAdd(other, result);
}
///
@@ -499,13 +512,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
CommonParallel.For(0, _values.Length, 4096, (a, b) =>
+ {
+ var v = denseResult._values;
+ for (int i = a; i < b; i++)
{
- var v = denseResult._values;
- for (int i = a; i < b; i++)
- {
- v[i] = _values[i] - scalar;
- }
- });
+ v[i] = _values[i] - scalar;
+ }
+ });
}
///
@@ -515,16 +528,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// The matrix to store the result of the subtraction.
protected override void DoSubtract(Matrix other, Matrix result)
{
- var denseOther = other as DenseMatrix;
- var denseResult = result as DenseMatrix;
- if (denseOther == null || denseResult == null)
+ // dense + dense = dense
+ var denseOther = other.Storage as DenseColumnMajorMatrixStorage;
+ var denseResult = result.Storage as DenseColumnMajorMatrixStorage;
+ if (denseOther != null && denseResult != null)
{
- base.DoSubtract(other, result);
+ Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther.Data, denseResult.Data);
+ return;
}
- else
+
+ // dense + diagonal = matrix
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
{
- Control.LinearAlgebraProvider.SubtractArrays(_values, denseOther._values, denseResult._values);
+ CopyTo(result);
+ var diagonal = diagonalOther.Data;
+ for (int i = 0; i < diagonal.Length; i++)
+ {
+ result.At(i, i, result.At(i, i) - diagonal[i]);
+ }
+ return;
}
+
+ base.DoSubtract(other, result);
}
///
@@ -585,12 +611,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{
var denseOther = other as DenseMatrix;
var denseResult = result as DenseMatrix;
-
- if (denseOther == null || denseResult == null)
- {
- base.DoMultiply(other, result);
- }
- else
+ if (denseOther != null && denseResult != null)
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Providers.LinearAlgebra.Transpose.DontTranspose,
@@ -604,7 +625,31 @@ namespace MathNet.Numerics.LinearAlgebra.Single
denseOther._columnCount,
0.0f,
denseResult._values);
+ return;
}
+
+ var diagonalOther = other.Storage as DiagonalMatrixStorage;
+ if (diagonalOther != null)
+ {
+ var diagonal = diagonalOther.Data;
+ var d = Math.Min(ColumnCount, other.ColumnCount);
+ if (d < other.ColumnCount)
+ {
+ result.ClearSubMatrix(0, RowCount, ColumnCount, other.ColumnCount - 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.DoMultiply(other, result);
}
///
diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs
index e388e2b2..42d5b944 100644
--- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs
@@ -577,9 +577,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// i == j (i is the row index, and j is the column index).
public override Vector Diagonal()
{
- // TODO: Should we return reference to array? In current implementation we return copy of array, so changes in DenseVector will
- // not influence onto diagonal elements
- return new DenseVector((float[])_data.Clone());
+ return new DenseVector(_data).Clone();
}
///
@@ -605,31 +603,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
Multiply(otherDiagonal.Transpose(), result);
}
- ///
- /// Multiplies this matrix with transpose of another matrix and returns the result.
- ///
- /// The matrix to multiply with.
- /// If this.Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix TransposeAndMultiply(Matrix other)
- {
- var otherDiagonal = other as DiagonalMatrix;
- if (otherDiagonal == null)
- {
- return base.TransposeAndMultiply(other);
- }
-
- if (ColumnCount != otherDiagonal.ColumnCount)
- {
- throw DimensionsDontMatch(this, otherDiagonal);
- }
-
- var result = other.CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
- }
-
///
/// Returns the transpose of this matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Single/Matrix.cs b/src/Numerics/LinearAlgebra/Single/Matrix.cs
index 761734f0..b8737c0e 100644
--- a/src/Numerics/LinearAlgebra/Single/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Single/Matrix.cs
@@ -41,7 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
///
[Serializable]
public abstract class Matrix : Matrix
- {
+ {
///
/// Initializes a new instance of the Matrix class.
///
@@ -89,7 +89,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public override double FrobeniusNorm()
{
var transpose = Transpose();
- var aat = this * transpose;
+ var aat = this*transpose;
var norm = 0d;
for (var i = 0; i < RowCount; i++)
{
@@ -186,29 +186,28 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, At(i, j) * scalar);
+ result.At(i, j, At(i, j)*scalar);
}
}
}
- ///
+ ///
/// Multiplies this matrix with a vector and places the results into the result vector.
///
/// The vector to multiply with.
/// The result of the multiplication.
protected override void DoMultiply(Vector rightSide, Vector result)
- {
+ {
for (var i = 0; i < RowCount; i++)
{
var s = 0.0f;
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
- s += At(i, j) * rightSide[j];
+ s += At(i, j)*rightSide[j];
}
-
result[i] = s;
}
- }
+ }
///
/// Multiplies this matrix with another matrix and places the results into the result matrix.
@@ -219,14 +218,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{
for (var j = 0; j < RowCount; j++)
{
- for (var i = 0; i != other.ColumnCount; i++)
+ for (var i = 0; i < other.ColumnCount; i++)
{
var s = 0.0f;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(j, l) * other.At(l, i);
+ s += At(j, l)*other.At(l, i);
}
-
result.At(j, i, s);
}
}
@@ -239,7 +237,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// The matrix to store the result of the division.
protected override void DoDivide(float divisor, Matrix result)
{
- DoMultiply(1.0f / divisor, result);
+ DoMultiply(1.0f/divisor, result);
}
///
@@ -253,7 +251,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{
for (var j = 0; j < ColumnCount; j++)
{
- result.At(i, j, dividend / At(i, j));
+ result.At(i, j, dividend/At(i, j));
}
}
}
@@ -272,9 +270,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single
var s = 0.0f;
for (var l = 0; l < ColumnCount; l++)
{
- s += At(i, l) * other.At(j, l);
+ s += At(i, l)*other.At(j, l);
}
-
result.At(i, j, s);
}
}
@@ -294,9 +291,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single
var s = 0.0f;
for (var l = 0; l < RowCount; l++)
{
- s += At(l, i) * other.At(l, j);
+ s += At(l, i)*other.At(l, j);
}
-
result.At(i, j, s);
}
}
@@ -312,11 +308,10 @@ namespace MathNet.Numerics.LinearAlgebra.Single
for (var i = 0; i < ColumnCount; i++)
{
var s = 0.0f;
- for (var j = 0; j != RowCount; j++)
+ for (var j = 0; j < RowCount; j++)
{
- s += At(j, i) * rightSide[j];
+ s += At(j, i)*rightSide[j];
}
-
result[i] = s;
}
}
@@ -332,7 +327,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{
for (var column = 0; column < ColumnCount; column++)
{
- result.At(row, column, At(row, column) % divisor);
+ result.At(row, column, At(row, column)%divisor);
}
}
}
@@ -348,7 +343,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{
for (var column = 0; column < ColumnCount; column++)
{
- result.At(row, column, dividend % At(row, column));
+ result.At(row, column, dividend%At(row, column));
}
}
}
@@ -361,7 +356,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
{
for (var i = 0; i < RowCount; i++)
{
- for (var j = 0; j != ColumnCount; j++)
+ for (var j = 0; j < ColumnCount; j++)
{
result.At(i, j, -At(i, j));
}
diff --git a/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs
index fc265c89..c54dc08c 100644
--- a/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs
@@ -30,8 +30,10 @@
using System;
using System.Collections.Generic;
+using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Complex;
+using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
@@ -383,5 +385,23 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
var matrix = TestMatrices["Square3x3"];
Assert.IsTrue(matrix.IsSymmetric);
}
+
+ [Test]
+ public void DenseDiagonalMatrixMultiplication()
+ {
+ var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
+
+ Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3));
+
+ var tall = Matrix.Build.Random(8, 3, dist);
+ Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d)));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2d)).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2))));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2)));
+
+ var wide = Matrix.Build.Random(3, 8, dist);
+ Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d)));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2d)).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2))));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2)));
+ }
}
}
diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs
index 1e3058e3..2623229d 100644
--- a/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs
@@ -30,8 +30,10 @@
using System;
using System.Collections.Generic;
+using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Complex32;
+using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
@@ -379,5 +381,22 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
var matrix = TestMatrices["Square3x3"];
Assert.IsTrue(matrix.IsSymmetric);
}
+ [Test]
+ public void DenseDiagonalMatrixMultiplication()
+ {
+ var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
+
+ Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3));
+
+ var tall = Matrix.Build.Random(8, 3, dist);
+ Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f)));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2f)).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2))));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2)));
+
+ var wide = Matrix.Build.Random(3, 8, dist);
+ Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f)));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2f)).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2))));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2)));
+ }
}
}
diff --git a/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs
index 171cfe35..cc3e5240 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs
@@ -30,8 +30,10 @@
using System;
using System.Collections.Generic;
+using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
+using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
@@ -410,5 +412,23 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
var test = diagonal*dense;
var test2 = dense*diagonal;
}
+
+ [Test]
+ public void DenseDiagonalMatrixMultiplication()
+ {
+ var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
+
+ Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3));
+
+ var tall = Matrix.Build.Random(8, 3, dist);
+ Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2d)).Equals(tall.Multiply(2d)));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2d)).Equals(tall.Multiply(2d).Append(Matrix.Build.Dense(8, 2))));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2d)).Equals(tall.Multiply(2d).SubMatrix(0, 8, 0, 2)));
+
+ var wide = Matrix.Build.Random(3, 8, dist);
+ Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2d)).Equals(wide.Multiply(2d)));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2d)).Equals(wide.Multiply(2d).Append(Matrix.Build.Dense(3, 2))));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2d)).Equals(wide.Multiply(2d).SubMatrix(0, 3, 0, 2)));
+ }
}
}
diff --git a/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs
index 26ae0809..8773fce1 100644
--- a/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs
@@ -30,8 +30,10 @@
using System;
using System.Collections.Generic;
+using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Single;
+using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
@@ -377,5 +379,23 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
var matrix = TestMatrices["Square3x3"];
Assert.IsTrue(matrix.IsSymmetric);
}
+
+ [Test]
+ public void DenseDiagonalMatrixMultiplication()
+ {
+ var dist = new ContinuousUniform(-1.0, 1.0, new MersenneTwister());
+
+ Assert.IsInstanceOf(Matrix.Build.DiagonalIdentity(3, 3));
+
+ var tall = Matrix.Build.Random(8, 3, dist);
+ Assert.IsTrue((tall*Matrix.Build.DiagonalIdentity(3).Multiply(2f)).Equals(tall.Multiply(2f)));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 5, 2f)).Equals(tall.Multiply(2f).Append(Matrix.Build.Dense(8, 2))));
+ Assert.IsTrue((tall*Matrix.Build.Diagonal(3, 2, 2f)).Equals(tall.Multiply(2f).SubMatrix(0, 8, 0, 2)));
+
+ var wide = Matrix.Build.Random(3, 8, dist);
+ Assert.IsTrue((wide*Matrix.Build.DiagonalIdentity(8).Multiply(2f)).Equals(wide.Multiply(2f)));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 10, 2f)).Equals(wide.Multiply(2f).Append(Matrix.Build.Dense(3, 2))));
+ Assert.IsTrue((wide*Matrix.Build.Diagonal(8, 2, 2f)).Equals(wide.Multiply(2f).SubMatrix(0, 3, 0, 2)));
+ }
}
}