diff --git a/src/MathNet.Numerics.5.1.ReSharper b/src/MathNet.Numerics.5.1.ReSharper
index 37a21618..778ad35b 100644
--- a/src/MathNet.Numerics.5.1.ReSharper
+++ b/src/MathNet.Numerics.5.1.ReSharper
@@ -23,7 +23,9 @@ indices
<
>
Frobenius
-Pointwise
+Pointwise
+multipcation
+kronecker
diff --git a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs
index e96d496e..f519d19e 100644
--- a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs
+++ b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProviderOfT.cs
@@ -145,7 +145,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
///
/// Does a point wise multiplication of two arrays z = x * y. This can be used
- /// to multiple elements of vectors or matrices.
+ /// to multiply elements of vectors or matrices.
///
/// The array x.
/// The array y.
@@ -155,6 +155,18 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
/// routine.
void PointWiseMultiplyArrays(T[] x, T[] y, T[] result);
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ void PointWiseDivideArrays(T[] x, T[] y, T[] result);
+
///
/// Computes the requested of the matrix.
///
diff --git a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs
index 4a0ddef7..979b362c 100644
--- a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs
+++ b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs
@@ -229,6 +229,42 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
CommonParallel.For(0, y.Length, index => { result[index] = x[index] * y[index]; });
}
+
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public void PointWiseDivideArrays(double[] x, double[] y, double[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (y.Length != x.Length || y.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ CommonParallel.For(0, y.Length, index => { result[index] = x[index] / y[index]; });
+ }
+
///
/// Computes the requested of the matrix.
///
@@ -2982,6 +3018,41 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
CommonParallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
}
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public void PointWiseDivideArrays(float[] x, float[] y, float[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (y.Length != x.Length || y.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ CommonParallel.For(0, y.Length, index => { result[index] = x[index] / y[index]; });
+ }
+
///
/// Computes the requested of the matrix.
///
@@ -5581,7 +5652,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentNullException("x");
}
- if (alpha == 1.0)
+ if (alpha.IsOne())
{
return;
}
@@ -5721,6 +5792,41 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
CommonParallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
}
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public void PointWiseDivideArrays(Complex[] x, Complex[] y, Complex[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (y.Length != x.Length || y.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ CommonParallel.For(0, y.Length, index => { result[index] = x[index] / y[index]; });
+ }
+
///
/// Computes the requested of the matrix.
///
@@ -5921,7 +6027,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
rowsC = rowsA;
}
- if (alpha == 0.0 && beta == 0.0)
+ if (alpha.IsZero() && beta.IsZero())
{
Array.Clear(c, 0, c.Length);
return;
@@ -5950,9 +6056,9 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
bdata = b;
}
- if (alpha == 1.0)
+ if (alpha.IsOne())
{
- if (beta == 0.0)
+ if (beta.IsZero())
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
@@ -8422,6 +8528,41 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
CommonParallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
}
+ ///
+ /// Does a point wise division of two arrays z = x / y. This can be used
+ /// to divide elements of vectors or matrices.
+ ///
+ /// The array x.
+ /// The array y.
+ /// The result of the point wise division.
+ /// There is no equivalent BLAS routine, but many libraries
+ /// provide optimized (parallel and/or vectorized) versions of this
+ /// routine.
+ public void PointWiseDivideArrays(Complex32[] x, Complex32[] y, Complex32[] result)
+ {
+ if (y == null)
+ {
+ throw new ArgumentNullException("y");
+ }
+
+ if (x == null)
+ {
+ throw new ArgumentNullException("x");
+ }
+
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (y.Length != x.Length || y.Length != result.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ }
+
+ CommonParallel.For(0, y.Length, index => { result[index] = x[index] / y[index]; });
+ }
+
///
/// Computes the requested of the matrix.
///
diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
index c970b583..4648158e 100644
--- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
@@ -28,7 +28,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
using System;
using System.Numerics;
- using Distributions;
using Generic;
using Properties;
using Threading;
@@ -36,7 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
///
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
///
- public class DenseMatrix : Matrix
+ public class DenseMatrix : Matrix
{
///
/// Initializes a new instance of the class. This matrix is square with a given size.
@@ -219,28 +218,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
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.Data[(i * ColumnCount) + j] = Data[index + i].Conjugate();
- }
- }
-
- return ret;
- }
-
/// Calculates the L1 norm.
/// The L1 norm of the matrix.
- public override double L1Norm()
+ public override Complex L1Norm()
{
var norm = 0.0;
for (var j = 0; j < ColumnCount; j++)
@@ -259,10 +239,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Calculates the Frobenius norm of this matrix.
/// The Frobenius norm of this matrix.
- public override double FrobeniusNorm()
+ public override Complex FrobeniusNorm()
{
var transpose = (DenseMatrix)Transpose();
- var aat = this * transpose;
+ var aat = (DenseMatrix)(this * transpose);
var norm = 0.0;
for (var i = 0; i < RowCount; i++)
@@ -276,7 +256,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Calculates the infinity norm of this matrix.
/// The infinity norm of this matrix.
- public override double InfinityNorm()
+ public override Complex InfinityNorm()
{
var norm = 0.0;
for (var i = 0; i < RowCount; i++)
@@ -296,437 +276,303 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
#region Elementary operations
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
/// The matrix to add to this matrix.
- /// If the other matrix is .
+ /// The matrix to store the result of add
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public override void Add(Matrix other)
+ protected override void DoAdd(Matrix other, Matrix result)
{
- var m = other as DenseMatrix;
- if (m == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+ if (denseOther == null || denseResult == null)
{
- base.Add(other);
+ base.DoAdd(other, result);
}
else
{
- Add(m);
+ Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data);
}
}
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Add(DenseMatrix other)
+ /// The matrix to subtract.
+ /// The matrix to store the result of the subtraction.
+ protected override void DoSubtract(Matrix other, Matrix result)
{
- if (other == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+ if (denseOther == null || denseResult == null)
{
- throw new ArgumentNullException("other");
+ base.DoSubtract(other, result);
}
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ else
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data);
}
-
- Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
}
+
+ #endregion
+
+ #region Static constructors for special matrices.
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Initializes a square with all zero's except for ones on the diagonal.
///
- /// The matrix to subtract.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public override void Subtract(Matrix other)
+ /// the size of the square matrix.
+ /// A dense identity matrix.
+ ///
+ /// If is less than one.
+ ///
+ public static DenseMatrix Identity(int order)
{
- var m = other as DenseMatrix;
- if (m == null)
- {
- base.Subtract(other);
- }
- else
+ var m = new DenseMatrix(order);
+ for (var i = 0; i < order; i++)
{
- Subtract(m);
+ m.Data[(i * order) + i] = 1.0;
}
+
+ return m;
}
+ #endregion
+
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
- ///
- /// The to subtract.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Subtract(DenseMatrix other)
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ var ret = new DenseMatrix(ColumnCount, RowCount);
+ for (var j = 0; j < ColumnCount; j++)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ var index = j * RowCount;
+ for (var i = 0; i < RowCount; i++)
+ {
+ ret.Data[(i * ColumnCount) + j] = Data[index + i].Conjugate();
+ }
}
- Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
+ return ret;
}
///
- /// Multiplies each element of this matrix with a complex.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The complex to multiply with.
- public override void Multiply(Complex complex)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(Complex scalar, Matrix result)
{
- Control.LinearAlgebraProvider.ScaleArray(complex, Data);
+ var denseResult = result as DenseMatrix;
+ if (denseResult == null)
+ {
+ base.DoMultiply(scalar, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.ScaleArray(scalar, denseResult.Data);
+ }
}
///
- /// Multiplies this dense matrix with another dense matrix and places the results into the result dense matrix.
+ /// Multiplies this matrix with a vector and places the results into the result vector.
///
- /// The matrix to multiply with.
+ /// The vector to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void Multiply(Matrix other, Matrix result)
+ protected override void DoMultiply(Vector rightSide, Vector result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
+ var denseRight = rightSide as DenseVector;
+ var denseResult = result as DenseVector;
- if (result == null)
+ if (denseRight == null || denseResult == null)
{
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var m = other as DenseMatrix;
- var r = result as DenseMatrix;
-
- if (m == null || r == null)
- {
- base.Multiply(other, result);
+ base.DoMultiply(rightSide, result);
}
else
{
- Control.LinearAlgebraProvider.MatrixMultiply(
- Data,
- RowCount,
- ColumnCount,
- m.Data,
- m.RowCount,
- m.ColumnCount,
- r.Data);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseRight.Data,
+ denseRight.Count,
+ 1,
+ 0.0,
+ denseResult.Data);
}
}
///
- /// Multiplies this matrix with another matrix and returns the result.
+ /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
///
- /// The matrix to multiply with.
- /// If this.Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix Multiply(Matrix other)
+ /// The vector to multiply with.
+ /// The result of the multiplication.
+ protected override void DoLeftMultiply(Vector leftSide, Vector result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
+ var denseLeft = leftSide as DenseVector;
+ var denseResult = result as DenseVector;
- if (ColumnCount != other.RowCount)
+ if (denseLeft == null || denseResult == null)
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ base.DoLeftMultiply(leftSide, result);
}
-
- var m = other as DenseMatrix;
- if (m == null)
+ else
{
- return base.Multiply(other);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0,
+ denseLeft.Data,
+ 1,
+ denseResult.Count,
+ Data,
+ RowCount,
+ ColumnCount,
+ 0.0,
+ denseResult.Data);
}
-
- var result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount);
- Multiply(other, result);
- return result;
}
-
+
///
- /// Multiplies this dense matrix with transpose of another dense matrix and places the results into the result dense matrix.
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void TransposeAndMultiply(Matrix other, Matrix result)
+ protected override void DoMultiply(Matrix other, Matrix result)
{
- var otherDense = other as DenseMatrix;
- var resultDense = result as DenseMatrix;
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
- if (otherDense == null || resultDense == null)
+ if (denseOther == null || denseResult == null)
{
- base.TransposeAndMultiply(other, result);
- return;
+ base.DoMultiply(other, result);
}
-
- if (ColumnCount != otherDense.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if ((resultDense.RowCount != RowCount) || (resultDense.ColumnCount != otherDense.RowCount))
+ else
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseOther.Data,
+ denseOther.RowCount,
+ denseOther.ColumnCount,
+ 0.0,
+ denseResult.Data);
}
-
- Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
- Algorithms.LinearAlgebra.Transpose.DontTranspose,
- Algorithms.LinearAlgebra.Transpose.Transpose,
- 1.0,
- Data,
- RowCount,
- ColumnCount,
- otherDense.Data,
- otherDense.RowCount,
- otherDense.ColumnCount,
- 1.0,
- resultDense.Data);
}
///
- /// Multiplies this matrix with transpose of another matrix and returns the result.
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
///
/// 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)
+ /// The result of the multiplication.
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
{
- var otherDense = other as DenseMatrix;
- if (otherDense == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+
+ if (denseOther == null || denseResult == null)
{
- return base.TransposeAndMultiply(other);
+ base.DoTransposeAndMultiply(other, result);
}
-
- if (ColumnCount != otherDense.ColumnCount)
+ else
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.Transpose,
+ 1.0,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseOther.Data,
+ denseOther.RowCount,
+ denseOther.ColumnCount,
+ 0.0,
+ denseResult.Data);
}
-
- var result = (DenseMatrix)CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
}
///
- /// Multiplies two dense matrices.
+ /// Negate each element of this matrix and place the results into the result matrix.
///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static DenseMatrix operator *(DenseMatrix leftSide, DenseMatrix rightSide)
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
{
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
+ var denseResult = result as DenseMatrix;
- if (rightSide == null)
+ if (denseResult == null)
{
- throw new ArgumentNullException("rightSide");
+ base.DoNegate(result);
}
-
- if (leftSide.ColumnCount != rightSide.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- return (DenseMatrix)leftSide.Multiply(rightSide);
- }
-
- #endregion
-
- #region Static constructors for special matrices.
-
- ///
- /// Initializes a square with all zero's except for ones on the diagonal.
- ///
- /// the size of the square matrix.
- /// A dense identity matrix.
- ///
- /// If is less than one.
- ///
- public static DenseMatrix Identity(int order)
- {
- var m = new DenseMatrix(order);
- for (var i = 0; i < order; i++)
+ else
{
- m[i, i] = Complex.One;
+ Array.Copy(Data, denseResult.Data, Data.Length);
+ Control.LinearAlgebraProvider.ScaleArray(-1, denseResult.Data);
}
-
- return m;
}
- #endregion
-
///
- /// Negate each element of this matrix.
+ /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
///
- /// If the result matrix is .
- /// if the result matrix's dimensions are not the same as this matrix.
- public override void Negate()
+ /// The matrix to pointwise multiply with this one.
+ /// The matrix to store the result of the pointwise multiplication.
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
{
- Multiply(-1);
- }
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
+ if (denseOther == null || denseResult == null)
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
+ base.DoPointwiseMultiply(other, result);
}
-
- if (numberOfColumns < 1)
+ else
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
+ Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, denseOther.Data, denseResult.Data);
}
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < matrix.RowCount; i++)
- {
- matrix[i, j] = new Complex(distribution.Sample(), distribution.Sample());
- }
- });
-
- return matrix;
}
///
- /// Generates matrix with random elements.
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
{
- if (numberOfRows < 1)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+
+ if (denseOther == null || denseResult == null)
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
+ base.DoPointwiseDivide(other, result);
}
-
- if (numberOfColumns < 1)
+ else
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
+ Control.LinearAlgebraProvider.PointWiseDivideArrays(Data, denseOther.Data, denseResult.Data);
}
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < matrix.RowCount; i++)
- {
- matrix[i, j] = new Complex(distribution.Sample(), distribution.Sample());
- }
- });
-
- return matrix;
}
- #region Simple arithmetic of type T
///
- /// Add two values T+T
+ /// Computes the trace of this matrix.
///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override Complex AddT(Complex val1, Complex val2)
+ /// The trace of this matrix
+ /// If the matrix is not square
+ public override Complex Trace()
{
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override Complex SubtractT(Complex val1, Complex val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override Complex MultiplyT(Complex val1, Complex val2)
- {
- return val1 * val2;
- }
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override Complex DivideT(Complex val1, Complex val2)
- {
- return val1 / val2;
- }
+ if (RowCount != ColumnCount)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ }
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(Complex val1)
- {
- return val1.Magnitude;
+ return CommonParallel.Aggregate(0, RowCount, i => Data[(i * RowCount) + i]);
}
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
index ca00ec8a..b174bf02 100644
--- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
@@ -29,7 +29,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
using System;
using System.Linq;
using System.Numerics;
- using Distributions;
using Generic;
using Properties;
using Threading;
@@ -43,7 +42,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// entries are set. The exception to this is when the off diagonal elements are
/// 0.0 or NaN; these settings will cause no change to the diagonal matrix.
///
- public class DiagonalMatrix : Matrix
+ public class DiagonalMatrix : Matrix
{
///
/// Initializes a new instance of the class. This matrix is square with a given size.
@@ -279,92 +278,155 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
#region Elementary operations
+
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
/// The matrix to add to this matrix.
- /// If the other matrix is .
+ /// The result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- /// If is not .
- public override void Add(Matrix other)
+ public override Matrix Add(Matrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
- var m = other as DiagonalMatrix;
- if (m == null)
+ if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ Matrix result;
+ if (other is DiagonalMatrix)
+ {
+ result = new DenseMatrix(RowCount, ColumnCount);
+ }
+ else
{
- throw new ArgumentException(Resources.ArgumentTypeMismatch);
+ result = new DiagonalMatrix(RowCount, ColumnCount);
}
- Add(m);
+ Add(other, result);
+ return result;
}
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
- /// The to add to this matrix.
- /// If the other matrix is .
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Add(DiagonalMatrix other)
+ public override void Add(Matrix other, Matrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("result", Resources.ArgumentMatrixDimensions);
}
- Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
+ var diagOther = other as DiagonalMatrix;
+ var diagResult = result as DiagonalMatrix;
+
+ if (diagOther == null || diagResult == null)
+ {
+ base.Add(other, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.AddArrays(Data, diagOther.Data, diagResult.Data);
+ }
}
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
/// The matrix to subtract.
- /// If the other matrix is .
+ /// The result of the subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- /// If is not .
- public override void Subtract(Matrix other)
+ public override Matrix Subtract(Matrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
- var m = other as DiagonalMatrix;
- if (m == null)
+ if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ Matrix result;
+ if (other is DiagonalMatrix)
{
- throw new ArgumentException(Resources.ArgumentTypeMismatch);
+ result = new DenseMatrix(RowCount, ColumnCount);
+ }
+ else
+ {
+ result = new DiagonalMatrix(RowCount, ColumnCount);
}
- Subtract(m);
+ Subtract(other, result);
+ return result;
}
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to subtract.
- /// If the other matrix is .
+ /// The matrix to subtract.
+ /// The matrix to store the result of the subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Subtract(DiagonalMatrix other)
+ public override void Subtract(Matrix other, Matrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("result", Resources.ArgumentMatrixDimensions);
}
- Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
+ var diagOther = other as DiagonalMatrix;
+ var diagResult = result as DiagonalMatrix;
+
+ if (diagOther == null || diagResult == null)
+ {
+ base.Subtract(other, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.SubtractArrays(Data, diagOther.Data, diagResult.Data);
+ }
}
///
@@ -388,8 +450,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
-
- CommonParallel.For(0, source.Length, index => Data[index] = source[index]);
+
+ Array.Copy(source, Data, source.Length);
}
///
@@ -416,27 +478,45 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
- CommonParallel.For(0, denseSource.Data.Length, index => Data[index] = denseSource.Data[index]);
+ Array.Copy(denseSource.Data, Data, denseSource.Data.Length);
}
///
- /// Multiplies each element of this matrix with a scalar.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The scalar to multiply with.
- public override void Multiply(Complex scalar)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ /// If the result matrix is .
+ /// If the result matrix's dimensions are not the same as this matrix.
+ public override void Multiply(Complex scalar, Matrix result)
{
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (scalar == 0.0)
{
- Clear();
+ result.Clear();
return;
}
if (scalar == 1.0)
{
+ CopyTo(result);
return;
}
- Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
+ var diagResult = result as DiagonalMatrix;
+ if (diagResult == null)
+ {
+ base.Multiply(scalar, result);
+ }
+ else
+ {
+ CopyTo(diagResult);
+ Control.LinearAlgebraProvider.ScaleArray(scalar, diagResult.Data);
+ }
}
///
@@ -481,9 +561,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
var thisDataCopy = new Complex[r.Data.Length];
var otherDataCopy = new Complex[r.Data.Length];
-
- CommonParallel.For(0, (r.Data.Length > Data.Length) ? Data.Length : r.Data.Length, index => thisDataCopy[index] = Data[index]);
- CommonParallel.For(0, (r.Data.Length > m.Data.Length) ? m.Data.Length : r.Data.Length, index => otherDataCopy[index] = m.Data[index]);
+ 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);
}
@@ -694,34 +773,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return result;
}
- ///
- /// Multiplies two diagonal matrices.
- ///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static DiagonalMatrix operator *(DiagonalMatrix leftSide, DiagonalMatrix rightSide)
- {
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
-
- if (rightSide == null)
- {
- throw new ArgumentNullException("rightSide");
- }
-
- if (leftSide.ColumnCount != rightSide.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- return (DiagonalMatrix)leftSide.Multiply(rightSide);
- }
-
#endregion
///
@@ -756,7 +807,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentException(Resources.ArgumentMatrixDimensions, "target");
}
- CommonParallel.For(0, Data.Length, index => diagonalTarget.Data[index] = Data[index]);
+ Array.Copy(Data, diagonalTarget.Data, Data.Length);
}
///
@@ -766,18 +817,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public override Matrix Transpose()
{
var ret = new DiagonalMatrix(ColumnCount, RowCount);
- CommonParallel.For(0, Data.Length, index => ret.Data[index] = Data[index]);
- return ret;
- }
-
- ///
- /// Returns the conjugate transpose of this matrix.
- ///
- /// The conjugate transpose of this matrix.
- public override Matrix ConjugateTranspose()
- {
- var ret = new DiagonalMatrix(ColumnCount, RowCount);
- CommonParallel.For(0, Data.Length, index => ret.Data[index] = Data[index].Conjugate());
+ Array.Copy(Data, ret.Data, Data.Length);
return ret;
}
@@ -895,21 +935,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Calculates the L1 norm.
/// The L1 norm of the matrix.
- public override double L1Norm()
+ public override Complex L1Norm()
{
return Data.Aggregate(double.NegativeInfinity, (current, t) => Math.Max(current, t.Magnitude));
}
/// Calculates the L2 norm.
/// The L2 norm of the matrix.
- public override double L2Norm()
+ public override Complex L2Norm()
{
return Data.Aggregate(double.NegativeInfinity, (current, t) => Math.Max(current, t.Magnitude));
}
/// Calculates the Frobenius norm of this matrix.
/// The Frobenius norm of this matrix.
- public override double FrobeniusNorm()
+ public override Complex FrobeniusNorm()
{
var norm = Data.Sum(t => t.Magnitude * t.Magnitude);
return Math.Sqrt(norm);
@@ -917,21 +957,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Calculates the infinity norm of this matrix.
/// The infinity norm of this matrix.
- public override double InfinityNorm()
+ public override Complex InfinityNorm()
{
return L1Norm();
}
/// Calculates the condition number of this matrix.
/// The condition number of the matrix.
- public override double ConditionNumber()
+ public override Complex ConditionNumber()
{
var maxSv = double.NegativeInfinity;
var minSv = double.PositiveInfinity;
- for (var i = 0; i < Data.Length; i++)
+ foreach (var t in Data)
{
- maxSv = Math.Max(maxSv, Data[i].Magnitude);
- minSv = Math.Min(minSv, Data[i].Magnitude);
+ maxSv = Math.Max(maxSv, t.Magnitude);
+ minSv = Math.Min(minSv, t.Magnitude);
}
return maxSv / minSv;
@@ -1476,50 +1516,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
CommonParallel.For(0, lower.RowCount, i => CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j + ColumnCount, lower.At(i, j))));
}
- ///
- /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
- ///
- /// The matrix to pointwise multiply with this one.
- /// The matrix to store the result of the pointwise multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this matrix and are not the same size.
- /// If this matrix and are not the same size.
- public override void PointwiseMultiply(Matrix other, Matrix result)
- {
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (result == null)
- {
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- if (ColumnCount != result.ColumnCount || RowCount != result.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- var m = other as DiagonalMatrix;
- var r = result as DiagonalMatrix;
-
- if (m == null || r == null)
- {
- base.PointwiseMultiply(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, m.Data, r.Data);
- }
- }
-
///
/// Permute the columns of a matrix according to a permutation.
///
@@ -1564,129 +1560,5 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
#endregion
-
- ///
- /// Negates each element of this matrix.
- ///
- public override void Negate()
- {
- Multiply(-1);
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- var mn = Math.Min(numberOfRows, numberOfColumns);
- CommonParallel.For(0, mn, i => matrix[i, i] = new Complex(distribution.Sample(), distribution.Sample()));
-
- return matrix;
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- var mn = Math.Min(numberOfRows, numberOfColumns);
- CommonParallel.For(0, mn, i => matrix[i, i] = new Complex(distribution.Sample(), distribution.Sample()));
-
- return matrix;
- }
-
- #region Simple arithmetic of type T
- ///
- /// Add two values T+T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override Complex AddT(Complex val1, Complex val2)
- {
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override Complex SubtractT(Complex val1, Complex val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override Complex MultiplyT(Complex val1, Complex val2)
- {
- return val1 * val2;
- }
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override Complex DivideT(Complex val1, Complex val2)
- {
- return val1 / val2;
- }
-
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(Complex val1)
- {
- return val1.Magnitude;
- }
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex/Matrix.cs b/src/Numerics/LinearAlgebra/Complex/Matrix.cs
new file mode 100644
index 00000000..5d0524ac
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Complex/Matrix.cs
@@ -0,0 +1,413 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+// Copyright (c) 2009-2010 Math.NET
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.LinearAlgebra.Complex
+{
+ using System;
+ using System.Numerics;
+ using Distributions;
+ using Generic;
+ using Properties;
+ using Threading;
+
+ ///
+ /// Complex version of the class.
+ ///
+ public abstract class Matrix : Matrix
+ {
+ ///
+ /// Initializes a new instance of the Matrix class.
+ ///
+ ///
+ /// The number of rows.
+ ///
+ ///
+ /// The number of columns.
+ ///
+ protected Matrix(int rows, int columns) : base(rows, columns)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the Matrix class.
+ ///
+ ///
+ /// The order of the matrix.
+ ///
+ protected Matrix(int order)
+ : base(order)
+ {
+ }
+
+ /// Calculates the L1 norm.
+ /// The L1 norm of the matrix.
+ public override Complex L1Norm()
+ {
+ var norm = 0.0;
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ var s = 0.0;
+ for (var i = 0; i < RowCount; i++)
+ {
+ s += At(i, j).Magnitude;
+ }
+
+ norm = Math.Max(norm, s);
+ }
+
+ return norm;
+ }
+
+ ///
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
+ {
+ var ret = CreateMatrix(ColumnCount, RowCount);
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ ret.At(j, i, At(i, j).Conjugate());
+ }
+ }
+
+ return ret;
+ }
+
+ /// Calculates the Frobenius norm of this matrix.
+ /// The Frobenius norm of this matrix.
+ public override Complex FrobeniusNorm()
+ {
+ var transpose = Transpose();
+ var aat = this * transpose;
+
+ var norm = 0.0;
+ for (var i = 0; i < RowCount; i++)
+ {
+ norm += aat.At(i, i).Magnitude;
+ }
+
+ norm = Math.Sqrt(norm);
+
+ return norm;
+ }
+
+ /// Calculates the infinity norm of this matrix.
+ /// The infinity norm of this matrix.
+ public override Complex InfinityNorm()
+ {
+ var norm = 0.0;
+ for (var i = 0; i < RowCount; i++)
+ {
+ var s = 0.0;
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ s += At(i, j).Magnitude;
+ }
+
+ norm = Math.Max(norm, s);
+ }
+
+ return norm;
+ }
+
+ ///
+ /// Adds another matrix to this matrix.
+ ///
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoAdd(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ result.At(i, j, At(i, j) + other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Subtracts another matrix from this matrix.
+ ///
+ /// The matrix to subtract to this matrix.
+ /// The matrix to store the result of subtraction.
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoSubtract(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ result.At(i, j, At(i, j) - other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
+ ///
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(Complex scalar, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ 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)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ var s = new Complex();
+ for (var j = 0; j != ColumnCount; j++)
+ {
+ s += At(i, j) * rightSide[j];
+ }
+
+ result[i] = s;
+ });
+ }
+
+ ///
+ /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
+ ///
+ /// The vector to multiply with.
+ /// The result of the multiplication.
+ protected override void DoLeftMultiply(Vector leftSide, Vector result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ var s = new Complex();
+ for (var i = 0; i != leftSide.Count; i++)
+ {
+ s += leftSide[i] * At(i, j);
+ }
+
+ result[j] = s;
+ });
+ }
+
+ ///
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
+ ///
+ /// The matrix to multiply with.
+ /// The result of the multiplication.
+ protected override void DoMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ for (var i = 0; i != other.ColumnCount; i++)
+ {
+ var s = new Complex();
+ for (var l = 0; l < ColumnCount; l++)
+ {
+ s += At(j, l) * other.At(l, i);
+ }
+
+ result.At(j, i, s);
+ }
+ });
+ }
+
+ ///
+ /// Divides each element of the matrix by a scalar and places results into the result matrix.
+ ///
+ /// The scalar to divide the matrix with.
+ /// The matrix to store the result of the division.
+ protected override void DoDivide(Complex scalar, Matrix result)
+ {
+ DoMultiply(1.0 / scalar, result);
+ }
+
+ ///
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
+ ///
+ /// The matrix to multiply with.
+ /// The result of the multiplication.
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ var s = new Complex();
+ for (var l = 0; l < ColumnCount; l++)
+ {
+ s += At(i, l) * other.At(j, l);
+ }
+
+ result.At(i, j, s);
+ }
+ });
+ }
+
+ ///
+ /// Negate each element of this matrix and place the results into the result matrix.
+ ///
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j != ColumnCount; j++)
+ {
+ result[i, j] = -At(i, j);
+ }
+ });
+ }
+
+ ///
+ /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
+ ///
+ /// The matrix to pointwise multiply with this one.
+ /// The matrix to store the result of the pointwise multiplication.
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ ColumnCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ result.At(i, j, At(i, j) * other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
+ ///
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ ColumnCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ result.At(i, j, At(i, j) / other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Computes the trace of this matrix.
+ ///
+ /// The trace of this matrix
+ /// If the matrix is not square
+ public override Complex Trace()
+ {
+ if (RowCount != ColumnCount)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ }
+
+ return CommonParallel.Aggregate(0, RowCount, i => At(i, i));
+ }
+
+ ///
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected override void DoRandom(Matrix matrix, IContinuousDistribution distribution)
+ {
+ CommonParallel.For(
+ 0,
+ matrix.RowCount,
+ i =>
+ {
+ for (var j = 0; j < matrix.ColumnCount; j++)
+ {
+ matrix.At(i, j, distribution.Sample());
+ }
+ });
+ }
+
+ ///
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected override void DoRandom(Matrix matrix, IDiscreteDistribution distribution)
+ {
+ CommonParallel.For(
+ 0,
+ matrix.RowCount,
+ i =>
+ {
+ for (var j = 0; j < matrix.ColumnCount; j++)
+ {
+ matrix.At(i, j, distribution.Sample());
+ }
+ });
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
index 235e3f07..d20a9c3c 100644
--- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
@@ -32,7 +32,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
{
using System;
using System.Numerics;
- using Distributions;
using Generic;
using Properties;
using Threading;
@@ -41,7 +40,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// A Matrix class with sparse storage. The underlying storage scheme is 3-array compressed-sparse-row (CSR) Format.
/// Wikipedia - CSR.
///
- public class SparseMatrix : Matrix
+ public class SparseMatrix : Matrix
{
///
/// Object for use in "lock"
@@ -113,7 +112,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// The value which we assign to each element of the matrix.
public SparseMatrix(int rows, int columns, Complex value) : this(rows, columns)
{
- if (value == Complex.Zero)
+ if (value == 0.0)
{
return;
}
@@ -613,7 +612,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
if (index >= 0)
{
// Non-zero item found in matrix
- if (value == Complex.Zero)
+ if (value == 0.0)
{
// Delete existing item
DeleteItemByIndex(index, row);
@@ -627,7 +626,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
else
{
// Item not found. Add new value
- if (value == Complex.Zero)
+ if (value == 0.0)
{
return;
}
@@ -790,56 +789,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
sparseTarget._columnIndices = new int[NonZerosCount];
sparseTarget.NonZerosCount = NonZerosCount;
- if (NonZerosCount != 0)
- {
- CommonParallel.For(0, NonZerosCount, index => sparseTarget._nonZeroValues[index] = _nonZeroValues[index]);
- Buffer.BlockCopy(_columnIndices, 0, sparseTarget._columnIndices, 0, NonZerosCount * Constants.SizeOfInt);
- Buffer.BlockCopy(_rowIndex, 0, sparseTarget._rowIndex, 0, RowCount * Constants.SizeOfInt);
- }
+ Array.Copy(_nonZeroValues, sparseTarget._nonZeroValues, NonZerosCount);
+ Array.Copy(_columnIndices, sparseTarget._columnIndices, NonZerosCount);
+ Array.Copy(_rowIndex, sparseTarget._rowIndex, RowCount);
}
}
- ///
- /// Indicates whether the current object is equal to another object of the same type.
- ///
- ///
- /// An object to compare with this object.
- ///
- ///
- /// true if the current object is equal to the parameter; otherwise, false.
- ///
- public override bool Equals(object obj)
- {
- var sparseMatrix = obj as SparseMatrix;
-
- if (sparseMatrix == null)
- {
- return base.Equals(obj);
- }
-
- // Accept if the argument is the same object as this
- if (ReferenceEquals(this, sparseMatrix))
- {
- return true;
- }
-
- if (ColumnCount != sparseMatrix.ColumnCount || RowCount != sparseMatrix.RowCount || NonZerosCount != sparseMatrix.NonZerosCount)
- {
- return false;
- }
-
- // If all else fails, perform element wise comparison.
- for (var index = 0; index < NonZerosCount; index++)
- {
- if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
- {
- return false;
- }
- }
-
- return true;
- }
-
///
/// Returns a hash code for this instance.
///
@@ -853,9 +808,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
for (var i = 0; i < hashNum; i++)
{
#if SILVERLIGHT
- hash ^= Precision.DoubleToInt64Bits(_nonZeroValues[i].GetHashCode());
+ hash ^= Precision.DoubleToInt64Bits(_nonZeroValues[i].Magnitude);
#else
- hash ^= BitConverter.DoubleToInt64Bits(_nonZeroValues[i].GetHashCode());
+ hash ^= BitConverter.DoubleToInt64Bits(_nonZeroValues[i].Magnitude);
#endif
}
@@ -897,47 +852,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return ret;
}
- ///
- /// Returns the conjugate transpose of this matrix.
- ///
- /// The conjugate transpose of this matrix.
- public override Matrix ConjugateTranspose()
- {
- var ret = new SparseMatrix(ColumnCount, RowCount)
- {
- _columnIndices = new int[NonZerosCount],
- _nonZeroValues = new Complex[NonZerosCount]
- };
-
- // Do an 'inverse' CopyTo iterate over the rows
- for (var i = 0; i < _rowIndex.Length; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
-
- // Get the values for the current row
- if (startIndex == endIndex)
- {
- // Begin and end are equal. There are no values in the row, Move to the next row
- continue;
- }
-
- for (var j = startIndex; j < endIndex; j++)
- {
- ret.SetValueAt(_columnIndices[j], i, _nonZeroValues[j].Conjugate());
- }
- }
-
- return ret;
- }
-
/// Calculates the Frobenius norm of this matrix.
/// The Frobenius norm of this matrix.
- public override double FrobeniusNorm()
+ public override Complex FrobeniusNorm()
{
var transpose = (SparseMatrix)Transpose();
- var aat = this * transpose;
+ var aat = (SparseMatrix)(this * transpose);
var norm = 0.0;
@@ -969,7 +889,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// Calculates the infinity norm of this matrix.
/// The infinity norm of this matrix.
- public override double InfinityNorm()
+ public override Complex InfinityNorm()
{
var norm = 0.0;
for (var i = 0; i < _rowIndex.Length; i++)
@@ -1112,200 +1032,231 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
- #region Elementary operations
-
+ #region Static constructors for special matrices.
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Initializes a square with all zero's except for ones on the diagonal.
///
- /// The matrix to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public override void Add(Matrix other)
+ /// the size of the square matrix.
+ /// Identity SparseMatrix
+ ///
+ /// If is less than one.
+ ///
+ public static SparseMatrix Identity(int order)
{
- if (ReferenceEquals(this, other))
- {
- Multiply(2);
- return;
- }
+ var m = new SparseMatrix(order)
+ {
+ NonZerosCount = order,
+ _nonZeroValues = new Complex[order],
+ _columnIndices = new int[order]
+ };
- var m = other as SparseMatrix;
- if (m == null)
- {
- base.Add(other);
- }
- else
+ for (var i = 0; i < order; i++)
{
- Add(m);
+ m._nonZeroValues[i] = 1.0;
+ m._columnIndices[i] = i;
+ m._rowIndex[i] = i;
}
+
+ return m;
}
+ #endregion
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Indicates whether the current object is equal to another object of the same type.
///
- /// The to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Add(SparseMatrix other)
+ ///
+ /// An object to compare with this object.
+ ///
+ ///
+ /// true if the current object is equal to the parameter; otherwise, false.
+ ///
+ public override bool Equals(Matrix other)
{
if (other == null)
{
- throw new ArgumentNullException("other");
+ return false;
}
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ return false;
}
- for (var i = 0; i < other.RowCount; i++)
+ // Accept if the argument is the same object as this.
+ if (ReferenceEquals(this, other))
{
- // Get the begin / end index for the current row
- var startIndex = other._rowIndex[i];
- var endIndex = i < other._rowIndex.Length - 1 ? other._rowIndex[i + 1] : other.NonZerosCount;
+ return true;
+ }
- for (var j = startIndex; j < endIndex; j++)
+ var sparseMatrix = other as SparseMatrix;
+
+ if (sparseMatrix == null)
+ {
+ return base.Equals(other);
+ }
+
+ if (NonZerosCount != sparseMatrix.NonZerosCount)
+ {
+ return false;
+ }
+
+ // If all else fails, perform element wise comparison.
+ for (var index = 0; index < NonZerosCount; index++)
+ {
+ if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
{
- var index = FindItem(i, other._columnIndices[j]);
- if (index >= 0)
- {
- if (_nonZeroValues[index] + other._nonZeroValues[j] == 0.0)
- {
- DeleteItemByIndex(index, i);
- }
- else
- {
- _nonZeroValues[index] += other._nonZeroValues[j];
- }
- }
- else
- {
- SetValueAt(i, other._columnIndices[j], other._nonZeroValues[j]);
- }
+ return false;
}
}
+
+ return true;
}
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
- /// The matrix to subtract.
- /// If the other matrix is .
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public override void Subtract(Matrix other)
+ protected override void DoAdd(Matrix other, Matrix result)
{
- // We are substracting Matrix form itself
- if (ReferenceEquals(this, other))
- {
- Clear();
- return;
- }
+ result.Clear();
- var m = other as SparseMatrix;
- if (m == null)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- base.Subtract(other);
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
else
{
- Subtract(m);
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
}
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to subtract.
- /// If the other matrix is .
+ /// The matrix to subtract to this matrix.
+ /// The matrix to store the result of subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Subtract(SparseMatrix other)
+ protected override void DoSubtract(Matrix other, Matrix result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
- {
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
- }
+ result.Clear();
- for (var i = 0; i < other.RowCount; i++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- // Get the begin / end index for the current row
- var startIndex = other._rowIndex[i];
- var endIndex = i < other._rowIndex.Length - 1 ? other._rowIndex[i + 1] : other.NonZerosCount;
-
- for (var j = startIndex; j < endIndex; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var index = FindItem(i, other._columnIndices[j]);
- if (index >= 0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- if (_nonZeroValues[index] - other._nonZeroValues[j] == 0.0)
+ var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
{
- DeleteItemByIndex(index, i);
- }
- else
- {
- _nonZeroValues[index] -= other._nonZeroValues[j];
+ result.At(i, _columnIndices[j], resVal);
}
}
- else
+ }
+ }
+ else
+ {
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- SetValueAt(i, other._columnIndices[j], -other._nonZeroValues[j]);
+ var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
}
}
}
}
///
- /// Multiplies each element of this matrix with a complex.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The complex to multiply with.
- public override void Multiply(Complex complex)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(Complex scalar, Matrix result)
{
- if (Complex.One.AlmostEqual(complex))
+ if (scalar == 1.0)
{
+ CopyTo(result);
return;
}
- if (Complex.Zero.AlmostEqual(complex))
+ if (scalar == 0.0)
{
- Clear();
+ result.Clear();
return;
}
- Control.LinearAlgebraProvider.ScaleArray(complex, _nonZeroValues);
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
+ {
+ base.DoMultiply(scalar, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.ScaleArray(scalar, sparseResult._nonZeroValues);
+ }
}
///
- /// Multiplies this sparse matrix with another sparse matrix and places the results into the result sparse matrix.
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If Columns != other.Rows.
- /// If the result matrix's dimensions are not the Rows x other.Columns.
- public override void Multiply(Matrix other, Matrix result)
+ protected override void DoMultiply(Matrix other, Matrix result)
{
var otherSparseMatrix = other as SparseMatrix;
var resultSparseMatrix = result as SparseMatrix;
if (otherSparseMatrix == null || resultSparseMatrix == null)
{
- base.Multiply(other, result);
+ base.DoMultiply(other, result);
return;
}
- if (ColumnCount != otherSparseMatrix.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if (resultSparseMatrix.RowCount != RowCount || resultSparseMatrix.ColumnCount != otherSparseMatrix.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
resultSparseMatrix.Clear();
var columnVector = new DenseVector(otherSparseMatrix.RowCount);
for (var row = 0; row < RowCount; row++)
@@ -1332,60 +1283,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
///
- /// Multiplies this matrix with another matrix and returns the result.
- ///
- /// The matrix to multiply with.
- /// If Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix Multiply(Matrix other)
- {
- var matrix = other as SparseMatrix;
- if (matrix == null)
- {
- return base.Multiply(other);
- }
-
- if (ColumnCount != matrix.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var result = (SparseMatrix)CreateMatrix(RowCount, matrix.ColumnCount);
- Multiply(matrix, result);
- return result;
- }
-
- ///
- /// Multiplies this dense matrix with transpose of another dense matrix and places the results into the result dense matrix.
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void TransposeAndMultiply(Matrix other, Matrix result)
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
{
var otherSparse = other as SparseMatrix;
var resultSparse = result as SparseMatrix;
if (otherSparse == null || resultSparse == null)
{
- base.TransposeAndMultiply(other, result);
+ base.DoTransposeAndMultiply(other, result);
return;
}
- if (ColumnCount != otherSparse.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if ((resultSparse.RowCount != RowCount) || (resultSparse.ColumnCount != otherSparse.RowCount))
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
resultSparse.Clear();
for (var j = 0; j < RowCount; j++)
{
@@ -1422,58 +1334,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
}
-
- ///
- /// 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 otherSparse = other as SparseMatrix;
- if (otherSparse == null)
- {
- return base.TransposeAndMultiply(other);
- }
-
- if (ColumnCount != otherSparse.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var result = (SparseMatrix)CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
- }
///
- /// Multiplies two sparse matrices.
+ /// Negate each element of this matrix and place the results into the result matrix.
///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static SparseMatrix operator *(SparseMatrix leftSide, SparseMatrix rightSide)
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
{
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
-
- if (rightSide == null)
- {
- throw new ArgumentNullException("rightSide");
- }
-
- if (leftSide.ColumnCount != rightSide.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- return (SparseMatrix)leftSide.Multiply(rightSide);
+ CopyTo(result);
+ DoMultiply(-1, result);
}
///
@@ -1481,221 +1350,95 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
///
/// The matrix to pointwise multiply with this one.
/// The matrix to store the result of the pointwise multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this matrix and are not the same size.
- /// If this matrix and are not the same size.
- public override void PointwiseMultiply(Matrix other, Matrix result)
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (result == null)
- {
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- if (ColumnCount != result.ColumnCount || RowCount != result.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
result.Clear();
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
- for (var j = startIndex; j < endIndex; j++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
+ {
+ for (var i = 0; i < other.RowCount; i++)
{
- var resVal = _nonZeroValues[j] * other[i, _columnIndices[j]];
- if (resVal != 0.0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- result[i, _columnIndices[j]] = resVal;
+ var resVal = _nonZeroValues[j] * other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
}
}
}
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = (SparseMatrix)CreateMatrix(numberOfRows, numberOfColumns);
- for (var i = 0; i < matrix.RowCount; i++)
+ else
{
- for (var j = 0; j < matrix.ColumnCount; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var value = new Complex(distribution.Sample(), distribution.Sample());
- if (value != 0.0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- matrix.SetValueAt(i, j, value);
+ var resVal = _nonZeroValues[j] * other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
}
}
}
-
- return matrix;
}
///
- /// Generates matrix with random elements.
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
{
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
+ result.Clear();
- var matrix = (SparseMatrix)CreateMatrix(numberOfRows, numberOfColumns);
- for (var i = 0; i < matrix.RowCount; i++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- for (var j = 0; j < matrix.ColumnCount; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var value = new Complex(distribution.Sample(), distribution.Sample());
- if (value != 0.0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- matrix.SetValueAt(i, j, value);
+ var resVal = _nonZeroValues[j] / other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
}
}
}
+ else
+ {
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
- return matrix;
- }
-
- #endregion
-
- #region Static constructors for special matrices.
- ///
- /// Initializes a square with all zero's except for ones on the diagonal.
- ///
- /// the size of the square matrix.
- /// Identity SparseMatrix
- ///
- /// If is less than one.
- ///
- public static SparseMatrix Identity(int order)
- {
- var m = new SparseMatrix(order)
+ for (var j = startIndex; j < endIndex; j++)
{
- NonZerosCount = order,
- _nonZeroValues = new Complex[order],
- _columnIndices = new int[order]
- };
-
- for (var i = 0; i < order; i++)
- {
- m._nonZeroValues[i] = Complex.One;
- m._columnIndices[i] = i;
- m._rowIndex[i] = i;
+ var resVal = _nonZeroValues[j] / other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
-
- return m;
- }
- #endregion
-
- ///
- /// Negates each element of this matrix.
- ///
- public override void Negate()
- {
- Multiply(-1);
- }
-
- #region Simple arithmetic of type T
- ///
- /// Add two values T+T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override Complex AddT(Complex val1, Complex val2)
- {
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override Complex SubtractT(Complex val1, Complex val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override Complex MultiplyT(Complex val1, Complex val2)
- {
- return val1 * val2;
}
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override Complex DivideT(Complex val1, Complex val2)
- {
- return val1 / val2;
- }
-
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(Complex val1)
- {
- return val1.Magnitude;
- }
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex/Vector.cs b/src/Numerics/LinearAlgebra/Complex/Vector.cs
index 809fe1ed..ffe9b52e 100644
--- a/src/Numerics/LinearAlgebra/Complex/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Complex/Vector.cs
@@ -66,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] + scalar);
+ index => result[index] = this[index] + scalar);
}
///
@@ -132,7 +132,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] * scalar);
+ index => result[index] = this[index] * scalar);
}
///
@@ -149,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] / scalar);
+ index => result[index] = this[index] / scalar);
}
///
diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
index 474b1545..bf89b3c5 100644
--- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
@@ -27,7 +27,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32
{
using System;
- using Distributions;
using Generic;
using Numerics;
using Properties;
@@ -36,7 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
///
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
///
- public class DenseMatrix : Matrix
+ public class DenseMatrix : Matrix
{
///
/// Initializes a new instance of the class. This matrix is square with a given size.
@@ -219,33 +218,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
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.Data[(i * ColumnCount) + j] = Data[index + i].Conjugate();
- }
- }
-
- return ret;
- }
-
/// Calculates the L1 norm.
/// The L1 norm of the matrix.
- public override double L1Norm()
+ public override Complex32 L1Norm()
{
- var norm = 0.0;
+ var norm = 0.0f;
for (var j = 0; j < ColumnCount; j++)
{
- var s = 0.0;
+ var s = 0.0f;
for (var i = 0; i < RowCount; i++)
{
s += Data[(j * RowCount) + i].Magnitude;
@@ -259,29 +239,29 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// Calculates the Frobenius norm of this matrix.
/// The Frobenius norm of this matrix.
- public override double FrobeniusNorm()
+ public override Complex32 FrobeniusNorm()
{
var transpose = (DenseMatrix)Transpose();
- var aat = this * transpose;
+ var aat = (DenseMatrix)(this * transpose);
- var norm = 0.0;
+ var norm = 0.0f;
for (var i = 0; i < RowCount; i++)
{
norm += aat.Data[(i * RowCount) + i].Magnitude;
}
- norm = Math.Sqrt(norm);
+ norm = Convert.ToSingle(Math.Sqrt(norm));
return norm;
}
/// Calculates the infinity norm of this matrix.
/// The infinity norm of this matrix.
- public override double InfinityNorm()
+ public override Complex32 InfinityNorm()
{
- var norm = 0.0;
+ var norm = 0.0f;
for (var i = 0; i < RowCount; i++)
{
- var s = 0.0;
+ var s = 0.0f;
for (var j = 0; j < ColumnCount; j++)
{
s += Data[(j * RowCount) + i].Magnitude;
@@ -296,437 +276,303 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
#region Elementary operations
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
/// The matrix to add to this matrix.
- /// If the other matrix is .
+ /// The matrix to store the result of add
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public override void Add(Matrix other)
+ protected override void DoAdd(Matrix other, Matrix result)
{
- var m = other as DenseMatrix;
- if (m == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+ if (denseOther == null || denseResult == null)
{
- base.Add(other);
+ base.DoAdd(other, result);
}
else
{
- Add(m);
+ Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data);
}
}
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Add(DenseMatrix other)
+ /// The matrix to subtract.
+ /// The matrix to store the result of the subtraction.
+ protected override void DoSubtract(Matrix other, Matrix result)
{
- if (other == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+ if (denseOther == null || denseResult == null)
{
- throw new ArgumentNullException("other");
+ base.DoSubtract(other, result);
}
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ else
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data);
}
-
- Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
}
+
+ #endregion
+
+ #region Static constructors for special matrices.
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Initializes a square with all zero's except for ones on the diagonal.
///
- /// The matrix to subtract.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public override void Subtract(Matrix other)
+ /// the size of the square matrix.
+ /// A dense identity matrix.
+ ///
+ /// If is less than one.
+ ///
+ public static DenseMatrix Identity(int order)
{
- var m = other as DenseMatrix;
- if (m == null)
- {
- base.Subtract(other);
- }
- else
+ var m = new DenseMatrix(order);
+ for (var i = 0; i < order; i++)
{
- Subtract(m);
+ m.Data[(i * order) + i] = 1.0f;
}
+
+ return m;
}
+ #endregion
+
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
- ///
- /// The to subtract.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Subtract(DenseMatrix other)
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ var ret = new DenseMatrix(ColumnCount, RowCount);
+ for (var j = 0; j < ColumnCount; j++)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ var index = j * RowCount;
+ for (var i = 0; i < RowCount; i++)
+ {
+ ret.Data[(i * ColumnCount) + j] = Data[index + i].Conjugate();
+ }
}
- Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
+ return ret;
}
///
- /// Multiplies each element of this matrix with a complex.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The complex to multiply with.
- public override void Multiply(Complex32 complex)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(Complex32 scalar, Matrix result)
{
- Control.LinearAlgebraProvider.ScaleArray(complex, Data);
+ var denseResult = result as DenseMatrix;
+ if (denseResult == null)
+ {
+ base.DoMultiply(scalar, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.ScaleArray(scalar, denseResult.Data);
+ }
}
///
- /// Multiplies this dense matrix with another dense matrix and places the results into the result dense matrix.
+ /// Multiplies this matrix with a vector and places the results into the result vector.
///
- /// The matrix to multiply with.
+ /// The vector to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void Multiply(Matrix other, Matrix result)
+ protected override void DoMultiply(Vector rightSide, Vector result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
+ var denseRight = rightSide as DenseVector;
+ var denseResult = result as DenseVector;
- if (result == null)
+ if (denseRight == null || denseResult == null)
{
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var m = other as DenseMatrix;
- var r = result as DenseMatrix;
-
- if (m == null || r == null)
- {
- base.Multiply(other, result);
+ base.DoMultiply(rightSide, result);
}
else
{
- Control.LinearAlgebraProvider.MatrixMultiply(
- Data,
- RowCount,
- ColumnCount,
- m.Data,
- m.RowCount,
- m.ColumnCount,
- r.Data);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0f,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseRight.Data,
+ denseRight.Count,
+ 1,
+ 0.0f,
+ denseResult.Data);
}
}
///
- /// Multiplies this matrix with another matrix and returns the result.
+ /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
///
- /// The matrix to multiply with.
- /// If this.Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix Multiply(Matrix other)
+ /// The vector to multiply with.
+ /// The result of the multiplication.
+ protected override void DoLeftMultiply(Vector leftSide, Vector result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
+ var denseLeft = leftSide as DenseVector;
+ var denseResult = result as DenseVector;
- if (ColumnCount != other.RowCount)
+ if (denseLeft == null || denseResult == null)
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ base.DoLeftMultiply(leftSide, result);
}
-
- var m = other as DenseMatrix;
- if (m == null)
+ else
{
- return base.Multiply(other);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0f,
+ denseLeft.Data,
+ 1,
+ denseResult.Count,
+ Data,
+ RowCount,
+ ColumnCount,
+ 0.0f,
+ denseResult.Data);
}
-
- var result = (DenseMatrix)CreateMatrix(RowCount, other.ColumnCount);
- Multiply(other, result);
- return result;
}
///
- /// Multiplies this dense matrix with transpose of another dense matrix and places the results into the result dense matrix.
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void TransposeAndMultiply(Matrix other, Matrix result)
+ protected override void DoMultiply(Matrix other, Matrix result)
{
- var otherDense = other as DenseMatrix;
- var resultDense = result as DenseMatrix;
-
- if (otherDense == null || resultDense == null)
- {
- base.TransposeAndMultiply(other, result);
- return;
- }
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
- if (ColumnCount != otherDense.ColumnCount)
+ if (denseOther == null || denseResult == null)
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ base.DoMultiply(other, result);
}
-
- if ((resultDense.RowCount != RowCount) || (resultDense.ColumnCount != otherDense.RowCount))
+ else
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0f,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseOther.Data,
+ denseOther.RowCount,
+ denseOther.ColumnCount,
+ 0.0f,
+ denseResult.Data);
}
-
- Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
- Algorithms.LinearAlgebra.Transpose.DontTranspose,
- Algorithms.LinearAlgebra.Transpose.Transpose,
- Complex32.One,
- Data,
- RowCount,
- ColumnCount,
- otherDense.Data,
- otherDense.RowCount,
- otherDense.ColumnCount,
- Complex32.One,
- resultDense.Data);
}
///
- /// Multiplies this matrix with transpose of another matrix and returns the result.
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
///
/// 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)
+ /// The result of the multiplication.
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
{
- var otherDense = other as DenseMatrix;
- if (otherDense == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+
+ if (denseOther == null || denseResult == null)
{
- return base.TransposeAndMultiply(other);
+ base.DoTransposeAndMultiply(other, result);
}
-
- if (ColumnCount != otherDense.ColumnCount)
+ else
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.Transpose,
+ 1.0f,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseOther.Data,
+ denseOther.RowCount,
+ denseOther.ColumnCount,
+ 0.0f,
+ denseResult.Data);
}
-
- var result = (DenseMatrix)CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
}
///
- /// Multiplies two dense matrices.
+ /// Negate each element of this matrix and place the results into the result matrix.
///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static DenseMatrix operator *(DenseMatrix leftSide, DenseMatrix rightSide)
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
{
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
+ var denseResult = result as DenseMatrix;
- if (rightSide == null)
+ if (denseResult == null)
{
- throw new ArgumentNullException("rightSide");
+ base.DoNegate(result);
}
-
- if (leftSide.ColumnCount != rightSide.RowCount)
+ else
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ Array.Copy(Data, denseResult.Data, Data.Length);
+ Control.LinearAlgebraProvider.ScaleArray(-1, denseResult.Data);
}
-
- return (DenseMatrix)leftSide.Multiply(rightSide);
}
- #endregion
-
- #region Static constructors for special matrices.
-
///
- /// Initializes a square with all zero's except for ones on the diagonal.
+ /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
///
- /// the size of the square matrix.
- /// A dense identity matrix.
- ///
- /// If is less than one.
- ///
- public static DenseMatrix Identity(int order)
+ /// The matrix to pointwise multiply with this one.
+ /// The matrix to store the result of the pointwise multiplication.
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
{
- var m = new DenseMatrix(order);
- for (var i = 0; i < order; i++)
- {
- m[i, i] = Complex32.One;
- }
-
- return m;
- }
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
- #endregion
-
- ///
- /// Negate each element of this matrix.
- ///
- /// If the result matrix is .
- /// if the result matrix's dimensions are not the same as this matrix.
- public override void Negate()
- {
- Multiply(-1);
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
+ if (denseOther == null || denseResult == null)
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
+ base.DoPointwiseMultiply(other, result);
}
-
- if (numberOfColumns < 1)
+ else
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
+ Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, denseOther.Data, denseResult.Data);
}
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < matrix.RowCount; i++)
- {
- matrix[i, j] = new Complex32((float)distribution.Sample(), (float)distribution.Sample());
- }
- });
-
- return matrix;
}
///
- /// Generates matrix with random elements.
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
{
- if (numberOfRows < 1)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+
+ if (denseOther == null || denseResult == null)
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
+ base.DoPointwiseDivide(other, result);
}
-
- if (numberOfColumns < 1)
+ else
{
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
+ Control.LinearAlgebraProvider.PointWiseDivideArrays(Data, denseOther.Data, denseResult.Data);
}
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < matrix.RowCount; i++)
- {
- matrix[i, j] = new Complex32(distribution.Sample(), distribution.Sample());
- }
- });
-
- return matrix;
}
- #region Simple arithmetic of type T
///
- /// Add two values T+T
+ /// Computes the trace of this matrix.
///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override Complex32 AddT(Complex32 val1, Complex32 val2)
+ /// The trace of this matrix
+ /// If the matrix is not square
+ public override Complex32 Trace()
{
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override Complex32 SubtractT(Complex32 val1, Complex32 val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override Complex32 MultiplyT(Complex32 val1, Complex32 val2)
- {
- return val1 * val2;
- }
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override Complex32 DivideT(Complex32 val1, Complex32 val2)
- {
- return val1 / val2;
- }
+ if (RowCount != ColumnCount)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ }
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(Complex32 val1)
- {
- return val1.Magnitude;
+ return CommonParallel.Aggregate(0, RowCount, i => Data[(i * RowCount) + i]);
}
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
index e7eca02d..c96f1e3f 100644
--- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
@@ -28,7 +28,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
using System;
using System.Linq;
- using Distributions;
using Generic;
using Numerics;
using Properties;
@@ -43,16 +42,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// entries are set. The exception to this is when the off diagonal elements are
/// 0.0 or NaN; these settings will cause no change to the diagonal matrix.
///
- public class DiagonalMatrix : Matrix
+ public class DiagonalMatrix : Matrix
{
- ///
+ ///
/// Initializes a new instance of the class. This matrix is square with a given size.
///
/// the size of the square matrix.
///
/// If is less than one.
///
- public DiagonalMatrix(int order) : base(order)
+ public DiagonalMatrix(int order)
+ : base(order)
{
Data = new Complex32[order * order];
}
@@ -66,7 +66,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
///
/// The number of columns.
///
- public DiagonalMatrix(int rows, int columns) : base(rows, columns)
+ public DiagonalMatrix(int rows, int columns)
+ : base(rows, columns)
{
Data = new Complex32[Math.Min(rows, columns)];
}
@@ -81,7 +82,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// The number of columns.
///
/// The value which we assign to each element of the matrix.
- public DiagonalMatrix(int rows, int columns, Complex32 value) : base(rows, columns)
+ public DiagonalMatrix(int rows, int columns, Complex32 value)
+ : base(rows, columns)
{
Data = new Complex32[Math.Min(rows, columns)];
for (var i = 0; i < Data.Length; i++)
@@ -97,7 +99,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// The number of rows.
/// The number of columns.
/// The one dimensional array which contain diagonal elements.
- public DiagonalMatrix(int rows, int columns, Complex32[] diagonalArray) : base(rows, columns)
+ public DiagonalMatrix(int rows, int columns, Complex32[] diagonalArray)
+ : base(rows, columns)
{
Data = diagonalArray;
}
@@ -109,7 +112,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// When contains an off-diagonal element.
/// Depending on the implementation, an
/// may be thrown if one of the indices is outside the dimensions of the matrix.
- public DiagonalMatrix(Complex32[,] array) : this(array.GetLength(0), array.GetLength(1))
+ public DiagonalMatrix(Complex32[,] array)
+ : this(array.GetLength(0), array.GetLength(1))
{
var rows = array.GetLength(0);
var columns = array.GetLength(1);
@@ -122,7 +126,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
Data[i] = array[i, j];
}
- else if (((array[i, j].Real != 0.0f) && !float.IsNaN(array[i, j].Real)) || ((array[i, j].Imaginary != 0.0f) && !float.IsNaN(array[i, j].Imaginary)))
+ else if (((array[i, j].Real != 0.0) && !double.IsNaN(array[i, j].Real)) || ((array[i, j].Imaginary != 0.0) && !double.IsNaN(array[i, j].Imaginary)))
{
throw new IndexOutOfRangeException("Cannot set an off-diagonal element in a diagonal matrix.");
}
@@ -156,7 +160,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// may be thrown if one of the indices is outside the dimensions of the matrix.
public override Complex32 At(int row, int column)
{
- return row == column ? Data[row] : Complex32.Zero;
+ return row == column ? Data[row] : 0.0f;
}
///
@@ -180,7 +184,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
Data[row] = value;
}
- else if (((value.Real != 0.0f) && !float.IsNaN(value.Real)) || ((value.Imaginary != 0.0f) && !float.IsNaN(value.Imaginary)))
+ else if (((value.Real != 0.0) && !double.IsNaN(value.Real)) || ((value.Imaginary != 0.0) && !double.IsNaN(value.Imaginary)))
{
throw new IndexOutOfRangeException("Cannot set an off-diagonal element in a diagonal matrix.");
}
@@ -279,92 +283,155 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
#region Elementary operations
+
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
/// The matrix to add to this matrix.
- /// If the other matrix is .
+ /// The result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- /// If is not .
- public override void Add(Matrix other)
+ public override Matrix Add(Matrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
- var m = other as DiagonalMatrix;
- if (m == null)
+ if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentException(Resources.ArgumentTypeMismatch);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
}
- Add(m);
+ Matrix result;
+ if (other is DiagonalMatrix)
+ {
+ result = new DenseMatrix(RowCount, ColumnCount);
+ }
+ else
+ {
+ result = new DiagonalMatrix(RowCount, ColumnCount);
+ }
+
+ Add(other, result);
+ return result;
}
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
- /// The to add to this matrix.
- /// If the other matrix is .
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Add(DiagonalMatrix other)
+ public override void Add(Matrix other, Matrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("result", Resources.ArgumentMatrixDimensions);
}
- Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
+ var diagOther = other as DiagonalMatrix;
+ var diagResult = result as DiagonalMatrix;
+
+ if (diagOther == null || diagResult == null)
+ {
+ base.Add(other, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.AddArrays(Data, diagOther.Data, diagResult.Data);
+ }
}
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
/// The matrix to subtract.
- /// If the other matrix is .
+ /// The result of the subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- /// If is not .
- public override void Subtract(Matrix other)
+ public override Matrix Subtract(Matrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
- var m = other as DiagonalMatrix;
- if (m == null)
+ if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ Matrix result;
+ if (other is DiagonalMatrix)
{
- throw new ArgumentException(Resources.ArgumentTypeMismatch);
+ result = new DenseMatrix(RowCount, ColumnCount);
+ }
+ else
+ {
+ result = new DiagonalMatrix(RowCount, ColumnCount);
}
- Subtract(m);
+ Subtract(other, result);
+ return result;
}
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to subtract.
- /// If the other matrix is .
+ /// The matrix to subtract.
+ /// The matrix to store the result of the subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Subtract(DiagonalMatrix other)
+ public override void Subtract(Matrix other, Matrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
}
- Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
+ if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("result", Resources.ArgumentMatrixDimensions);
+ }
+
+ var diagOther = other as DiagonalMatrix;
+ var diagResult = result as DiagonalMatrix;
+
+ if (diagOther == null || diagResult == null)
+ {
+ base.Subtract(other, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.SubtractArrays(Data, diagOther.Data, diagResult.Data);
+ }
}
///
@@ -389,7 +456,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentException(Resources.ArgumentArraysSameLength, "source");
}
- CommonParallel.For(0, source.Length, index => Data[index] = source[index]);
+ Array.Copy(source, Data, source.Length);
}
///
@@ -416,27 +483,45 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "source");
}
- CommonParallel.For(0, denseSource.Data.Length, index => Data[index] = denseSource.Data[index]);
+ Array.Copy(denseSource.Data, Data, denseSource.Data.Length);
}
///
- /// Multiplies each element of this matrix with a scalar.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The scalar to multiply with.
- public override void Multiply(Complex32 scalar)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ /// If the result matrix is .
+ /// If the result matrix's dimensions are not the same as this matrix.
+ public override void Multiply(Complex32 scalar, Matrix result)
{
- if (scalar == Complex32.Zero)
+ if (result == null)
{
- Clear();
+ throw new ArgumentNullException("result");
+ }
+
+ if (scalar.IsZero())
+ {
+ result.Clear();
return;
}
- if (scalar == Complex32.One)
+ if (scalar.IsOne())
{
+ CopyTo(result);
return;
}
- Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
+ var diagResult = result as DiagonalMatrix;
+ if (diagResult == null)
+ {
+ base.Multiply(scalar, result);
+ }
+ else
+ {
+ CopyTo(diagResult);
+ Control.LinearAlgebraProvider.ScaleArray(scalar, diagResult.Data);
+ }
}
///
@@ -481,9 +566,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
var thisDataCopy = new Complex32[r.Data.Length];
var otherDataCopy = new Complex32[r.Data.Length];
-
- CommonParallel.For(0, (r.Data.Length > Data.Length) ? Data.Length : r.Data.Length, index => thisDataCopy[index] = Data[index]);
- CommonParallel.For(0, (r.Data.Length > m.Data.Length) ? m.Data.Length : r.Data.Length, index => otherDataCopy[index] = m.Data[index]);
+ 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);
}
@@ -694,34 +778,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return result;
}
- ///
- /// Multiplies two diagonal matrices.
- ///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static DiagonalMatrix operator *(DiagonalMatrix leftSide, DiagonalMatrix rightSide)
- {
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
-
- if (rightSide == null)
- {
- throw new ArgumentNullException("rightSide");
- }
-
- if (leftSide.ColumnCount != rightSide.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- return (DiagonalMatrix)leftSide.Multiply(rightSide);
- }
-
#endregion
///
@@ -756,7 +812,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentException(Resources.ArgumentMatrixDimensions, "target");
}
- CommonParallel.For(0, Data.Length, index => diagonalTarget.Data[index] = Data[index]);
+ Array.Copy(Data, diagonalTarget.Data, Data.Length);
}
///
@@ -766,18 +822,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public override Matrix Transpose()
{
var ret = new DiagonalMatrix(ColumnCount, RowCount);
- CommonParallel.For(0, Data.Length, index => ret.Data[index] = Data[index]);
- return ret;
- }
-
- ///
- /// Returns the conjugate transpose of this matrix.
- ///
- /// The conjugate transpose of this matrix.
- public override Matrix ConjugateTranspose()
- {
- var ret = new DiagonalMatrix(ColumnCount, RowCount);
- CommonParallel.For(0, Data.Length, index => ret.Data[index] = Data[index].Conjugate());
+ Array.Copy(Data, ret.Data, Data.Length);
return ret;
}
@@ -895,43 +940,43 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// Calculates the L1 norm.
/// The L1 norm of the matrix.
- public override double L1Norm()
+ public override Complex32 L1Norm()
{
- return Data.Aggregate(double.NegativeInfinity, (current, t) => Math.Max(current, t.Magnitude));
+ return Data.Aggregate(float.NegativeInfinity, (current, t) => Math.Max(current, t.Magnitude));
}
/// Calculates the L2 norm.
/// The L2 norm of the matrix.
- public override double L2Norm()
+ public override Complex32 L2Norm()
{
- return Data.Aggregate(double.NegativeInfinity, (current, t) => Math.Max(current, t.Magnitude));
+ return Data.Aggregate(float.NegativeInfinity, (current, t) => Math.Max(current, t.Magnitude));
}
/// Calculates the Frobenius norm of this matrix.
/// The Frobenius norm of this matrix.
- public override double FrobeniusNorm()
+ public override Complex32 FrobeniusNorm()
{
var norm = Data.Sum(t => t.Magnitude * t.Magnitude);
- return Math.Sqrt(norm);
+ return Convert.ToSingle(Math.Sqrt(norm));
}
/// Calculates the infinity norm of this matrix.
/// The infinity norm of this matrix.
- public override double InfinityNorm()
+ public override Complex32 InfinityNorm()
{
return L1Norm();
}
/// Calculates the condition number of this matrix.
/// The condition number of the matrix.
- public override double ConditionNumber()
+ public override Complex32 ConditionNumber()
{
- var maxSv = double.NegativeInfinity;
- var minSv = double.PositiveInfinity;
- for (var i = 0; i < Data.Length; i++)
+ var maxSv = float.NegativeInfinity;
+ var minSv = float.PositiveInfinity;
+ foreach (var t in Data)
{
- maxSv = Math.Max(maxSv, Data[i].Magnitude);
- minSv = Math.Min(minSv, Data[i].Magnitude);
+ maxSv = Math.Max(maxSv, t.Magnitude);
+ minSv = Math.Min(minSv, t.Magnitude);
}
return maxSv / minSv;
@@ -945,15 +990,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
if (RowCount != ColumnCount)
{
- throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
var inverse = (DiagonalMatrix)Clone();
for (var i = 0; i < Data.Length; i++)
{
- if (Data[i] != Complex32.Zero)
+ if (Data[i] != 0.0f)
{
- inverse.Data[i] = Complex32.One / Data[i];
+ inverse.Data[i] = 1.0f / Data[i];
}
else
{
@@ -1476,50 +1521,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
CommonParallel.For(0, lower.RowCount, i => CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j + ColumnCount, lower.At(i, j))));
}
- ///
- /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
- ///
- /// The matrix to pointwise multiply with this one.
- /// The matrix to store the result of the pointwise multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this matrix and are not the same size.
- /// If this matrix and are not the same size.
- public override void PointwiseMultiply(Matrix other, Matrix result)
- {
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (result == null)
- {
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- if (ColumnCount != result.ColumnCount || RowCount != result.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- var m = other as DiagonalMatrix;
- var r = result as DiagonalMatrix;
-
- if (m == null || r == null)
- {
- base.PointwiseMultiply(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, m.Data, r.Data);
- }
- }
-
///
/// Permute the columns of a matrix according to a permutation.
///
@@ -1557,136 +1558,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
var m = new DiagonalMatrix(order);
for (var i = 0; i < order; i++)
{
- m.Data[i] = Complex32.One;
+ m.Data[i] = 1.0f;
}
return m;
}
#endregion
-
- ///
- /// Negates each element of this matrix.
- ///
- public override void Negate()
- {
- Multiply(-1);
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- var mn = Math.Min(numberOfRows, numberOfColumns);
- CommonParallel.For(0, mn, i => matrix[i, i] = new Complex32((float)distribution.Sample(), (float)distribution.Sample()));
-
- return matrix;
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- var mn = Math.Min(numberOfRows, numberOfColumns);
- CommonParallel.For(0, mn, i => matrix[i, i] = new Complex32(distribution.Sample(), distribution.Sample()));
-
- return matrix;
- }
-
- #region Simple arithmetic of type T
- ///
- /// Add two values T+T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override Complex32 AddT(Complex32 val1, Complex32 val2)
- {
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override Complex32 SubtractT(Complex32 val1, Complex32 val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override Complex32 MultiplyT(Complex32 val1, Complex32 val2)
- {
- return val1 * val2;
- }
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override Complex32 DivideT(Complex32 val1, Complex32 val2)
- {
- return val1 / val2;
- }
-
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(Complex32 val1)
- {
- return val1.Magnitude;
- }
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
new file mode 100644
index 00000000..407d3c05
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs
@@ -0,0 +1,413 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+// Copyright (c) 2009-2010 Math.NET
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.LinearAlgebra.Complex32
+{
+ using System;
+ using Distributions;
+ using Generic;
+ using Numerics;
+ using Properties;
+ using Threading;
+
+ ///
+ /// Complex32 version of the class.
+ ///
+ public abstract class Matrix : Matrix
+ {
+ ///
+ /// Initializes a new instance of the Matrix class.
+ ///
+ ///
+ /// The number of rows.
+ ///
+ ///
+ /// The number of columns.
+ ///
+ protected Matrix(int rows, int columns) : base(rows, columns)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the Matrix class.
+ ///
+ ///
+ /// The order of the matrix.
+ ///
+ protected Matrix(int order)
+ : base(order)
+ {
+ }
+
+ /// Calculates the L1 norm.
+ /// The L1 norm of the matrix.
+ public override Complex32 L1Norm()
+ {
+ var norm = 0.0f;
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ var s = 0.0f;
+ for (var i = 0; i < RowCount; i++)
+ {
+ s += At(i, j).Magnitude;
+ }
+
+ norm = Math.Max(norm, s);
+ }
+
+ return norm;
+ }
+
+ ///
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
+ {
+ var ret = CreateMatrix(ColumnCount, RowCount);
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ ret.At(j, i, At(i, j).Conjugate());
+ }
+ }
+
+ return ret;
+ }
+
+ /// Calculates the Frobenius norm of this matrix.
+ /// The Frobenius norm of this matrix.
+ public override Complex32 FrobeniusNorm()
+ {
+ var transpose = Transpose();
+ var aat = this * transpose;
+
+ var norm = 0.0f;
+ for (var i = 0; i < RowCount; i++)
+ {
+ norm += aat.At(i, i).Magnitude;
+ }
+
+ norm = Convert.ToSingle(Math.Sqrt(norm));
+
+ return norm;
+ }
+
+ /// Calculates the infinity norm of this matrix.
+ /// The infinity norm of this matrix.
+ public override Complex32 InfinityNorm()
+ {
+ var norm = 0.0f;
+ for (var i = 0; i < RowCount; i++)
+ {
+ var s = 0.0f;
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ s += At(i, j).Magnitude;
+ }
+
+ norm = Math.Max(norm, s);
+ }
+
+ return norm;
+ }
+
+ ///
+ /// Adds another matrix to this matrix.
+ ///
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoAdd(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ result.At(i, j, At(i, j) + other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Subtracts another matrix from this matrix.
+ ///
+ /// The matrix to subtract to this matrix.
+ /// The matrix to store the result of subtraction.
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoSubtract(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ result.At(i, j, At(i, j) - other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
+ ///
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(Complex32 scalar, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ 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)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ var s = new Complex32();
+ 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.
+ ///
+ /// The scalar to divide the matrix with.
+ /// The matrix to store the result of the division.
+ protected override void DoDivide(Complex32 scalar, Matrix result)
+ {
+ DoMultiply(1.0f / scalar, result);
+ }
+
+ ///
+ /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
+ ///
+ /// The vector to multiply with.
+ /// The result of the multiplication.
+ protected override void DoLeftMultiply(Vector leftSide, Vector result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ var s = new Complex32();
+ for (var i = 0; i != leftSide.Count; i++)
+ {
+ s += leftSide[i] * At(i, j);
+ }
+
+ result[j] = s;
+ });
+ }
+
+ ///
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
+ ///
+ /// The matrix to multiply with.
+ /// The result of the multiplication.
+ protected override void DoMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ for (var i = 0; i != other.ColumnCount; i++)
+ {
+ var s = new Complex32();
+ for (var l = 0; l < ColumnCount; l++)
+ {
+ s += At(j, l) * other.At(l, i);
+ }
+
+ result.At(j, i, s);
+ }
+ });
+ }
+
+ ///
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
+ ///
+ /// The matrix to multiply with.
+ /// The result of the multiplication.
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ var s = new Complex32();
+ for (var l = 0; l < ColumnCount; l++)
+ {
+ s += At(i, l) * other.At(j, l);
+ }
+
+ result.At(i, j, s);
+ }
+ });
+ }
+
+ ///
+ /// Negate each element of this matrix and place the results into the result matrix.
+ ///
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j != ColumnCount; j++)
+ {
+ result[i, j] = -At(i, j);
+ }
+ });
+ }
+
+ ///
+ /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
+ ///
+ /// The matrix to pointwise multiply with this one.
+ /// The matrix to store the result of the pointwise multiplication.
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ ColumnCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ result.At(i, j, At(i, j) * other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
+ ///
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ ColumnCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ result.At(i, j, At(i, j) / other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Computes the trace of this matrix.
+ ///
+ /// The trace of this matrix
+ /// If the matrix is not square
+ public override Complex32 Trace()
+ {
+ if (RowCount != ColumnCount)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ }
+
+ return CommonParallel.Aggregate(0, RowCount, i => At(i, i));
+ }
+
+ ///
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected override void DoRandom(Matrix matrix, IContinuousDistribution distribution)
+ {
+ CommonParallel.For(
+ 0,
+ matrix.RowCount,
+ i =>
+ {
+ for (var j = 0; j < matrix.ColumnCount; j++)
+ {
+ matrix.At(i, j, Convert.ToSingle(distribution.Sample()));
+ }
+ });
+ }
+
+ ///
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected override void DoRandom(Matrix matrix, IDiscreteDistribution distribution)
+ {
+ CommonParallel.For(
+ 0,
+ matrix.RowCount,
+ i =>
+ {
+ for (var j = 0; j < matrix.ColumnCount; j++)
+ {
+ matrix.At(i, j, distribution.Sample());
+ }
+ });
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
index e68ebb93..3eaf2538 100644
--- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
@@ -31,7 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Complex32
{
using System;
- using Distributions;
using Generic;
using Numerics;
using Properties;
@@ -41,7 +40,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// A Matrix class with sparse storage. The underlying storage scheme is 3-array compressed-sparse-row (CSR) Format.
/// Wikipedia - CSR.
///
- public class SparseMatrix : Matrix
+ public class SparseMatrix : Matrix
{
///
/// Object for use in "lock"
@@ -113,7 +112,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// The value which we assign to each element of the matrix.
public SparseMatrix(int rows, int columns, Complex32 value) : this(rows, columns)
{
- if (value == Complex32.Zero)
+ if (value == 0.0f)
{
return;
}
@@ -551,7 +550,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
for (var i = 0; i < RowCount; i++)
{
var index = FindItem(i, j);
- ret[(j * RowCount) + i] = index >= 0 ? _nonZeroValues[index] : Complex32.Zero;
+ ret[(j * RowCount) + i] = index >= 0 ? _nonZeroValues[index] : 0.0f;
}
}
@@ -575,7 +574,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
lock (_lockObject)
{
var index = FindItem(row, column);
- return index >= 0 ? _nonZeroValues[index] : Complex32.Zero;
+ return index >= 0 ? _nonZeroValues[index] : 0.0f;
}
}
@@ -613,7 +612,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
if (index >= 0)
{
// Non-zero item found in matrix
- if (value == Complex32.Zero)
+ if (value == 0.0f)
{
// Delete existing item
DeleteItemByIndex(index, row);
@@ -627,7 +626,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
else
{
// Item not found. Add new value
- if (value == Complex32.Zero)
+ if (value == 0.0f)
{
return;
}
@@ -790,56 +789,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
sparseTarget._columnIndices = new int[NonZerosCount];
sparseTarget.NonZerosCount = NonZerosCount;
- if (NonZerosCount != 0)
- {
- CommonParallel.For(0, NonZerosCount, index => sparseTarget._nonZeroValues[index] = _nonZeroValues[index]);
- Buffer.BlockCopy(_columnIndices, 0, sparseTarget._columnIndices, 0, NonZerosCount * Constants.SizeOfInt);
- Buffer.BlockCopy(_rowIndex, 0, sparseTarget._rowIndex, 0, RowCount * Constants.SizeOfInt);
- }
+ Array.Copy(_nonZeroValues, sparseTarget._nonZeroValues, NonZerosCount);
+ Array.Copy(_columnIndices, sparseTarget._columnIndices, NonZerosCount);
+ Array.Copy(_rowIndex, sparseTarget._rowIndex, RowCount);
}
}
- ///
- /// Indicates whether the current object is equal to another object of the same type.
- ///
- ///
- /// An object to compare with this object.
- ///
- ///
- /// true if the current object is equal to the parameter; otherwise, false.
- ///
- public override bool Equals(object obj)
- {
- var sparseMatrix = obj as SparseMatrix;
-
- if (sparseMatrix == null)
- {
- return base.Equals(obj);
- }
-
- // Accept if the argument is the same object as this
- if (ReferenceEquals(this, sparseMatrix))
- {
- return true;
- }
-
- if (ColumnCount != sparseMatrix.ColumnCount || RowCount != sparseMatrix.RowCount || NonZerosCount != sparseMatrix.NonZerosCount)
- {
- return false;
- }
-
- // If all else fails, perform element wise comparison.
- for (var index = 0; index < NonZerosCount; index++)
- {
- if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
- {
- return false;
- }
- }
-
- return true;
- }
-
///
/// Returns a hash code for this instance.
///
@@ -853,9 +808,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
for (var i = 0; i < hashNum; i++)
{
#if SILVERLIGHT
- hash ^= Precision.DoubleToInt64Bits(_nonZeroValues[i].GetHashCode());
+ hash ^= Precision.DoubleToInt64Bits(_nonZeroValues[i].Magnitude);
#else
- hash ^= BitConverter.DoubleToInt64Bits(_nonZeroValues[i].GetHashCode());
+ hash ^= BitConverter.DoubleToInt64Bits(_nonZeroValues[i].Magnitude);
#endif
}
@@ -897,49 +852,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return ret;
}
- ///
- /// Returns the conjugate transpose of this matrix.
- ///
- /// The conjugate transpose of this matrix.
- public override Matrix ConjugateTranspose()
- {
- var ret = new SparseMatrix(ColumnCount, RowCount)
- {
- _columnIndices = new int[NonZerosCount],
- _nonZeroValues = new Complex32[NonZerosCount]
- };
-
- // Do an 'inverse' CopyTo iterate over the rows
- for (var i = 0; i < _rowIndex.Length; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
-
- // Get the values for the current row
- if (startIndex == endIndex)
- {
- // Begin and end are equal. There are no values in the row, Move to the next row
- continue;
- }
-
- for (var j = startIndex; j < endIndex; j++)
- {
- ret.SetValueAt(_columnIndices[j], i, _nonZeroValues[j].Conjugate());
- }
- }
-
- return ret;
- }
-
/// Calculates the Frobenius norm of this matrix.
/// The Frobenius norm of this matrix.
- public override double FrobeniusNorm()
+ public override Complex32 FrobeniusNorm()
{
var transpose = (SparseMatrix)Transpose();
- var aat = this * transpose;
+ var aat = (SparseMatrix)(this * transpose);
- var norm = 0.0;
+ var norm = 0.0f;
for (var i = 0; i < aat._rowIndex.Length; i++)
{
@@ -963,15 +883,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
- norm = Math.Sqrt(norm);
+ norm = Convert.ToSingle(Math.Sqrt(norm));
return norm;
}
/// Calculates the infinity norm of this matrix.
/// The infinity norm of this matrix.
- public override double InfinityNorm()
+ public override Complex32 InfinityNorm()
{
- var norm = 0.0;
+ var norm = 0.0f;
for (var i = 0; i < _rowIndex.Length; i++)
{
// Get the begin / end index for the current row
@@ -985,7 +905,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
continue;
}
- var s = 0.0;
+ var s = 0.0f;
for (var j = startIndex; j < endIndex; j++)
{
s += _nonZeroValues[j].Magnitude;
@@ -1060,7 +980,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
{
// Copy code from At(row, column) to avoid unnecessary lock
var index = FindItem(rowIndex, i);
- result[j] = index >= 0 ? _nonZeroValues[index] : Complex32.Zero;
+ result[j] = index >= 0 ? _nonZeroValues[index] : 0.0f;
}
}
}
@@ -1112,200 +1032,231 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
- #region Elementary operations
-
+ #region Static constructors for special matrices.
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Initializes a square with all zero's except for ones on the diagonal.
///
- /// The matrix to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public override void Add(Matrix other)
+ /// the size of the square matrix.
+ /// Identity SparseMatrix
+ ///
+ /// If is less than one.
+ ///
+ public static SparseMatrix Identity(int order)
{
- if (ReferenceEquals(this, other))
- {
- Multiply(2);
- return;
- }
+ var m = new SparseMatrix(order)
+ {
+ NonZerosCount = order,
+ _nonZeroValues = new Complex32[order],
+ _columnIndices = new int[order]
+ };
- var m = other as SparseMatrix;
- if (m == null)
- {
- base.Add(other);
- }
- else
+ for (var i = 0; i < order; i++)
{
- Add(m);
+ m._nonZeroValues[i] = 1.0f;
+ m._columnIndices[i] = i;
+ m._rowIndex[i] = i;
}
+
+ return m;
}
+ #endregion
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Indicates whether the current object is equal to another object of the same type.
///
- /// The to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Add(SparseMatrix other)
+ ///
+ /// An object to compare with this object.
+ ///
+ ///
+ /// true if the current object is equal to the parameter; otherwise, false.
+ ///
+ public override bool Equals(Matrix other)
{
if (other == null)
{
- throw new ArgumentNullException("other");
+ return false;
}
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ return false;
}
- for (var i = 0; i < other.RowCount; i++)
+ // Accept if the argument is the same object as this.
+ if (ReferenceEquals(this, other))
{
- // Get the begin / end index for the current row
- var startIndex = other._rowIndex[i];
- var endIndex = i < other._rowIndex.Length - 1 ? other._rowIndex[i + 1] : other.NonZerosCount;
+ return true;
+ }
- for (var j = startIndex; j < endIndex; j++)
+ var sparseMatrix = other as SparseMatrix;
+
+ if (sparseMatrix == null)
+ {
+ return base.Equals(other);
+ }
+
+ if (NonZerosCount != sparseMatrix.NonZerosCount)
+ {
+ return false;
+ }
+
+ // If all else fails, perform element wise comparison.
+ for (var index = 0; index < NonZerosCount; index++)
+ {
+ if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
{
- var index = FindItem(i, other._columnIndices[j]);
- if (index >= 0)
- {
- if (_nonZeroValues[index] + other._nonZeroValues[j] == Complex32.Zero)
- {
- DeleteItemByIndex(index, i);
- }
- else
- {
- _nonZeroValues[index] += other._nonZeroValues[j];
- }
- }
- else
- {
- SetValueAt(i, other._columnIndices[j], other._nonZeroValues[j]);
- }
+ return false;
}
}
+
+ return true;
}
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
- /// The matrix to subtract.
- /// If the other matrix is .
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public override void Subtract(Matrix other)
+ protected override void DoAdd(Matrix other, Matrix result)
{
- // We are substracting Matrix form itself
- if (ReferenceEquals(this, other))
- {
- Clear();
- return;
- }
+ result.Clear();
- var m = other as SparseMatrix;
- if (m == null)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- base.Subtract(other);
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
else
{
- Subtract(m);
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
}
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to subtract.
- /// If the other matrix is .
+ /// The matrix to subtract to this matrix.
+ /// The matrix to store the result of subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Subtract(SparseMatrix other)
+ protected override void DoSubtract(Matrix other, Matrix result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
- {
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
- }
+ result.Clear();
- for (var i = 0; i < other.RowCount; i++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- // Get the begin / end index for the current row
- var startIndex = other._rowIndex[i];
- var endIndex = i < other._rowIndex.Length - 1 ? other._rowIndex[i + 1] : other.NonZerosCount;
-
- for (var j = startIndex; j < endIndex; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var index = FindItem(i, other._columnIndices[j]);
- if (index >= 0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- if (_nonZeroValues[index] - other._nonZeroValues[j] == Complex32.Zero)
+ var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
{
- DeleteItemByIndex(index, i);
- }
- else
- {
- _nonZeroValues[index] -= other._nonZeroValues[j];
+ result.At(i, _columnIndices[j], resVal);
}
}
- else
+ }
+ }
+ else
+ {
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- SetValueAt(i, other._columnIndices[j], -other._nonZeroValues[j]);
+ var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
}
}
}
}
///
- /// Multiplies each element of this matrix with a complex.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The complex to multiply with.
- public override void Multiply(Complex32 complex)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(Complex32 scalar, Matrix result)
{
- if (Complex32.One.AlmostEqual(complex))
+ if (scalar == 1.0f)
{
+ CopyTo(result);
return;
}
- if (Complex32.Zero.AlmostEqual(complex))
+ if (scalar == 0.0f)
{
- Clear();
+ result.Clear();
return;
}
- Control.LinearAlgebraProvider.ScaleArray(complex, _nonZeroValues);
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
+ {
+ base.DoMultiply(scalar, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.ScaleArray(scalar, sparseResult._nonZeroValues);
+ }
}
///
- /// Multiplies this sparse matrix with another sparse matrix and places the results into the result sparse matrix.
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If Columns != other.Rows.
- /// If the result matrix's dimensions are not the Rows x other.Columns.
- public override void Multiply(Matrix other, Matrix result)
+ protected override void DoMultiply(Matrix other, Matrix result)
{
var otherSparseMatrix = other as SparseMatrix;
var resultSparseMatrix = result as SparseMatrix;
if (otherSparseMatrix == null || resultSparseMatrix == null)
{
- base.Multiply(other, result);
+ base.DoMultiply(other, result);
return;
}
- if (ColumnCount != otherSparseMatrix.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if (resultSparseMatrix.RowCount != RowCount || resultSparseMatrix.ColumnCount != otherSparseMatrix.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
resultSparseMatrix.Clear();
var columnVector = new DenseVector(otherSparseMatrix.RowCount);
for (var row = 0; row < RowCount; row++)
@@ -1332,60 +1283,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
///
- /// Multiplies this matrix with another matrix and returns the result.
- ///
- /// The matrix to multiply with.
- /// If Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix Multiply(Matrix other)
- {
- var matrix = other as SparseMatrix;
- if (matrix == null)
- {
- return base.Multiply(other);
- }
-
- if (ColumnCount != matrix.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var result = (SparseMatrix)CreateMatrix(RowCount, matrix.ColumnCount);
- Multiply(matrix, result);
- return result;
- }
-
- ///
- /// Multiplies this dense matrix with transpose of another dense matrix and places the results into the result dense matrix.
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void TransposeAndMultiply(Matrix other, Matrix result)
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
{
var otherSparse = other as SparseMatrix;
var resultSparse = result as SparseMatrix;
if (otherSparse == null || resultSparse == null)
{
- base.TransposeAndMultiply(other, result);
+ base.DoTransposeAndMultiply(other, result);
return;
}
- if (ColumnCount != otherSparse.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if ((resultSparse.RowCount != RowCount) || (resultSparse.ColumnCount != otherSparse.RowCount))
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
resultSparse.Clear();
for (var j = 0; j < RowCount; j++)
{
@@ -1415,65 +1327,22 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
index =>
{
var ind = FindItem(i1, otherSparse._columnIndices[index]);
- return ind >= 0 ? otherSparse._nonZeroValues[index] * _nonZeroValues[ind] : Complex32.Zero;
+ return ind >= 0 ? otherSparse._nonZeroValues[index] * _nonZeroValues[ind] : 0.0f;
});
resultSparse.SetValueAt(i, j, sum + result.At(i, j));
}
}
}
-
- ///
- /// 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 otherSparse = other as SparseMatrix;
- if (otherSparse == null)
- {
- return base.TransposeAndMultiply(other);
- }
-
- if (ColumnCount != otherSparse.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var result = (SparseMatrix)CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
- }
///
- /// Multiplies two sparse matrices.
+ /// Negate each element of this matrix and place the results into the result matrix.
///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static SparseMatrix operator *(SparseMatrix leftSide, SparseMatrix rightSide)
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
{
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
-
- if (rightSide == null)
- {
- throw new ArgumentNullException("rightSide");
- }
-
- if (leftSide.ColumnCount != rightSide.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- return (SparseMatrix)leftSide.Multiply(rightSide);
+ CopyTo(result);
+ DoMultiply(-1, result);
}
///
@@ -1481,221 +1350,95 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
///
/// The matrix to pointwise multiply with this one.
/// The matrix to store the result of the pointwise multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this matrix and are not the same size.
- /// If this matrix and are not the same size.
- public override void PointwiseMultiply(Matrix other, Matrix result)
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (result == null)
- {
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- if (ColumnCount != result.ColumnCount || RowCount != result.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
result.Clear();
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
- for (var j = startIndex; j < endIndex; j++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
+ {
+ for (var i = 0; i < other.RowCount; i++)
{
- var resVal = _nonZeroValues[j] * other[i, _columnIndices[j]];
- if (resVal != Complex32.Zero)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- result[i, _columnIndices[j]] = resVal;
+ var resVal = _nonZeroValues[j] * other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
}
}
}
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = (SparseMatrix)CreateMatrix(numberOfRows, numberOfColumns);
- for (var i = 0; i < matrix.RowCount; i++)
+ else
{
- for (var j = 0; j < matrix.ColumnCount; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var value = new Complex32((float)distribution.Sample(), (float)distribution.Sample());
- if (value != Complex32.Zero)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- matrix.SetValueAt(i, j, value);
+ var resVal = _nonZeroValues[j] * other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
}
}
}
-
- return matrix;
}
///
- /// Generates matrix with random elements.
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
{
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
+ result.Clear();
- var matrix = (SparseMatrix)CreateMatrix(numberOfRows, numberOfColumns);
- for (var i = 0; i < matrix.RowCount; i++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- for (var j = 0; j < matrix.ColumnCount; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var value = new Complex32(distribution.Sample(), distribution.Sample());
- if (value != Complex32.Zero)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- matrix.SetValueAt(i, j, value);
+ var resVal = _nonZeroValues[j] / other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
}
}
}
+ else
+ {
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
- return matrix;
- }
-
- #endregion
-
- #region Static constructors for special matrices.
- ///
- /// Initializes a square with all zero's except for ones on the diagonal.
- ///
- /// the size of the square matrix.
- /// Identity SparseMatrix
- ///
- /// If is less than one.
- ///
- public static SparseMatrix Identity(int order)
- {
- var m = new SparseMatrix(order)
+ for (var j = startIndex; j < endIndex; j++)
{
- NonZerosCount = order,
- _nonZeroValues = new Complex32[order],
- _columnIndices = new int[order]
- };
-
- for (var i = 0; i < order; i++)
- {
- m._nonZeroValues[i] = Complex32.One;
- m._columnIndices[i] = i;
- m._rowIndex[i] = i;
+ var resVal = _nonZeroValues[j] / other.At(i, _columnIndices[j]);
+ if (resVal != 0.0f)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
-
- return m;
- }
- #endregion
-
- ///
- /// Negates each element of this matrix.
- ///
- public override void Negate()
- {
- Multiply(-1);
- }
-
- #region Simple arithmetic of type T
- ///
- /// Add two values T+T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override Complex32 AddT(Complex32 val1, Complex32 val2)
- {
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override Complex32 SubtractT(Complex32 val1, Complex32 val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override Complex32 MultiplyT(Complex32 val1, Complex32 val2)
- {
- return val1 * val2;
}
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override Complex32 DivideT(Complex32 val1, Complex32 val2)
- {
- return val1 / val2;
- }
-
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(Complex32 val1)
- {
- return val1.Magnitude;
- }
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex32/Vector.cs b/src/Numerics/LinearAlgebra/Complex32/Vector.cs
index b6610cbc..8c0bf51c 100644
--- a/src/Numerics/LinearAlgebra/Complex32/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/Vector.cs
@@ -66,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] + scalar);
+ index => result[index] = this[index] + scalar);
}
///
@@ -132,7 +132,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] * scalar);
+ index => result[index] = this[index] * scalar);
}
///
@@ -149,7 +149,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] / scalar);
+ index => result[index] = this[index] / scalar);
}
///
diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
index 7d9792bd..a5c15d38 100644
--- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
@@ -27,7 +27,6 @@
namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
- using Distributions;
using Generic;
using Properties;
using Threading;
@@ -242,7 +241,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double FrobeniusNorm()
{
var transpose = (DenseMatrix)Transpose();
- var aat = (DenseMatrix) (this * transpose);
+ var aat = (DenseMatrix)(this * transpose);
var norm = 0.0;
for (var i = 0; i < RowCount; i++)
@@ -332,7 +331,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var m = new DenseMatrix(order);
for (var i = 0; i < order; i++)
{
- m[i, i] = 1.0;
+ m.Data[(i * order) + i] = 1.0;
}
return m;
@@ -340,82 +339,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
#endregion
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < matrix.RowCount; i++)
- {
- matrix[i, j] = distribution.Sample();
- }
- });
-
- return matrix;
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < matrix.RowCount; i++)
- {
- matrix[i, j] = distribution.Sample();
- }
- });
-
- return matrix;
- }
-
///
/// Returns the conjugate transpose of this matrix.
///
@@ -425,20 +348,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return Transpose();
}
- /* Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
- Algorithms.LinearAlgebra.Transpose.DontTranspose,
- Algorithms.LinearAlgebra.Transpose.Transpose,
- 1.0,
- Data,
- RowCount,
- ColumnCount,
- otherDense.Data,
- otherDense.RowCount,
- otherDense.ColumnCount,
- 1.0,
- resultDense.Data);
- */
-
///
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
@@ -453,10 +362,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
- Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
+ Control.LinearAlgebraProvider.ScaleArray(scalar, denseResult.Data);
}
}
-
+
///
/// Multiplies this matrix with a vector and places the results into the result vector.
///
@@ -464,19 +373,28 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The result of the multiplication.
protected override void DoMultiply(Vector rightSide, Vector result)
{
- CommonParallel.For(
- 0,
- RowCount,
- i =>
- {
- var s = 0.0;
- for (var j = 0; j != ColumnCount; j++)
- {
- s += At(i, j) * rightSide[j];
- }
-
- result[i] = s;
- });
+ var denseRight = rightSide as DenseVector;
+ var denseResult = result as DenseVector;
+
+ if (denseRight == null || denseResult == null)
+ {
+ base.DoMultiply(rightSide, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseRight.Data,
+ denseRight.Count,
+ 1,
+ 0.0,
+ denseResult.Data);
+ }
}
///
@@ -486,19 +404,28 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// The result of the multiplication.
protected override void DoLeftMultiply(Vector leftSide, Vector result)
{
- CommonParallel.For(
- 0,
- RowCount,
- j =>
- {
- var s = 0.0;
- for (var i = 0; i != leftSide.Count; i++)
- {
- s += leftSide[i] * At(i, j);
- }
-
- result[j] = s;
- });
+ var denseLeft = leftSide as DenseVector;
+ var denseResult = result as DenseVector;
+
+ if (denseLeft == null || denseResult == null)
+ {
+ base.DoLeftMultiply(leftSide, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0,
+ denseLeft.Data,
+ 1,
+ denseResult.Count,
+ Data,
+ RowCount,
+ ColumnCount,
+ 0.0,
+ denseResult.Data);
+ }
}
///
@@ -517,41 +444,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
- CommonParallel.For(
- 0,
- RowCount,
- j =>
- {
- for (var i = 0; i != other.ColumnCount; i++)
- {
- var s = 0.0;
- for (var l = 0; l < ColumnCount; l++)
- {
- s += Data[(j * RowCount) + l] * denseOther.Data[(i * RowCount) + l];
- }
-
- result.At(j, i, s);
- }
- });
-
- CommonParallel.For(
- 0,
- RowCount,
- j =>
- {
- for (var i = 0; i < RowCount; i++)
- {
- var s = 0.0;
- for (var l = 0; l < ColumnCount; l++)
- {
- s += Data[(j * RowCount) + l] * denseOther.Data[(l * RowCount) + j];
- }
-
- denseResult.Data[(j * RowCount) + i] *= s;
- }
- });
- }
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseOther.Data,
+ denseOther.RowCount,
+ denseOther.ColumnCount,
+ 0.0,
+ denseResult.Data);
}
+ }
///
/// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
@@ -569,22 +475,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
- CommonParallel.For(
- 0,
- RowCount,
- j =>
- {
- for (var i = 0; i < RowCount; i++)
- {
- var s = 0.0;
- for (var l = 0; l < ColumnCount; l++)
- {
- s += Data[(j * RowCount) + l] * denseOther.Data[(l * RowCount) + j];
- }
-
- denseResult.Data[(j * RowCount) + i] *= s;
- }
- });
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.Transpose,
+ 1.0,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseOther.Data,
+ denseOther.RowCount,
+ denseOther.ColumnCount,
+ 0.0,
+ denseResult.Data);
}
}
@@ -602,17 +504,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
- CommonParallel.For(
- 0,
- RowCount,
- i =>
- {
- for (var j = 0; j != ColumnCount; j++)
- {
- var index = (j * RowCount) + i;
- denseResult.Data[index] =- Data[index];
- }
- });
+ Buffer.BlockCopy(Data, 0, denseResult.Data, 0, Data.Length * Constants.SizeOfDouble);
+ Control.LinearAlgebraProvider.ScaleArray(-1, denseResult.Data);
}
}
@@ -632,18 +525,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < RowCount; i++)
- {
- var index = (j * RowCount) + i;
- denseResult.Data[index] = Data[index] * denseOther.Data[index];
-
- }
- });
+ Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, denseOther.Data, denseResult.Data);
}
}
@@ -663,17 +545,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
- CommonParallel.For(
- 0,
- ColumnCount,
- j =>
- {
- for (var i = 0; i < RowCount; i++)
- {
- var index = (j * RowCount) + i;
- denseResult.Data[index] = Data[index] / denseOther.Data[index];
- }
- });
+ Control.LinearAlgebraProvider.PointWiseDivideArrays(Data, denseOther.Data, denseResult.Data);
}
}
diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
index 1c50acca..22746c54 100644
--- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
@@ -28,8 +28,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
using System.Linq;
- using System.Text;
- using Distributions;
using Generic;
using Properties;
using Threading;
@@ -43,7 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// entries are set. The exception to this is when the off diagonal elements are
/// 0.0 or NaN; these settings will cause no change to the diagonal matrix.
///
- public class DiagonalMatrix : Matrix
+ public class DiagonalMatrix : Matrix
{
///
/// Initializes a new instance of the class. This matrix is square with a given size.
@@ -279,92 +277,155 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
#region Elementary operations
+
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
/// The matrix to add to this matrix.
- /// If the other matrix is .
+ /// The result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- /// If is not .
- public override void Add(Matrix other)
+ public override Matrix Add(Matrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
- var m = other as DiagonalMatrix;
- if (m == null)
+ if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentException(Resources.ArgumentTypeMismatch);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
}
- Add(m);
+ Matrix result;
+ if (other is DiagonalMatrix)
+ {
+ result = new DenseMatrix(RowCount, ColumnCount);
+ }
+ else
+ {
+ result = new DiagonalMatrix(RowCount, ColumnCount);
+ }
+
+ Add(other, result);
+ return result;
}
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
- /// The to add to this matrix.
- /// If the other matrix is .
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Add(DiagonalMatrix other)
+ public override void Add(Matrix other, Matrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
}
- Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
+ if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("result", Resources.ArgumentMatrixDimensions);
+ }
+
+ var diagOther = other as DiagonalMatrix;
+ var diagResult = result as DiagonalMatrix;
+
+ if (diagOther == null || diagResult == null)
+ {
+ base.Add(other, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.AddArrays(Data, diagOther.Data, diagResult.Data);
+ }
}
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
/// The matrix to subtract.
- /// If the other matrix is .
+ /// The result of the subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- /// If is not .
- public override void Subtract(Matrix other)
+ public override Matrix Subtract(Matrix other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
- var m = other as DiagonalMatrix;
- if (m == null)
+ if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ Matrix result;
+ if (other is DiagonalMatrix)
+ {
+ result = new DenseMatrix(RowCount, ColumnCount);
+ }
+ else
{
- throw new ArgumentException(Resources.ArgumentTypeMismatch);
+ result = new DiagonalMatrix(RowCount, ColumnCount);
}
- Subtract(m);
+ Subtract(other, result);
+ return result;
}
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to subtract.
- /// If the other matrix is .
+ /// The matrix to subtract.
+ /// The matrix to store the result of the subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Subtract(DiagonalMatrix other)
+ public override void Subtract(Matrix other, Matrix result)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ throw new ArgumentOutOfRangeException("other", Resources.ArgumentMatrixDimensions);
+ }
+
+ if (result.RowCount != RowCount || result.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("result", Resources.ArgumentMatrixDimensions);
}
- Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
+ var diagOther = other as DiagonalMatrix;
+ var diagResult = result as DiagonalMatrix;
+
+ if (diagOther == null || diagResult == null)
+ {
+ base.Subtract(other, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.SubtractArrays(Data, diagOther.Data, diagResult.Data);
+ }
}
///
@@ -420,23 +481,41 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
///
- /// Multiplies each element of this matrix with a scalar.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The scalar to multiply with.
- public override void Multiply(double scalar)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ /// If the result matrix is .
+ /// If the result matrix's dimensions are not the same as this matrix.
+ public override void Multiply(double scalar, Matrix result)
{
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
if (scalar == 0.0)
{
- Clear();
+ result.Clear();
return;
}
if (scalar == 1.0)
{
+ CopyTo(result);
return;
}
- Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
+ var diagResult = result as DiagonalMatrix;
+ if (diagResult == null)
+ {
+ base.Multiply(scalar, result);
+ }
+ else
+ {
+ CopyTo(diagResult);
+ Control.LinearAlgebraProvider.ScaleArray(scalar, diagResult.Data);
+ }
}
///
@@ -693,34 +772,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return result;
}
- ///
- /// Multiplies two diagonal matrices.
- ///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static DiagonalMatrix operator *(DiagonalMatrix leftSide, DiagonalMatrix rightSide)
- {
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
-
- if (rightSide == null)
- {
- throw new ArgumentNullException("rightSide");
- }
-
- if (leftSide.ColumnCount != rightSide.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- return (DiagonalMatrix)leftSide.Multiply(rightSide);
- }
-
#endregion
///
@@ -1464,50 +1515,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(0, lower.RowCount, i => CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j + ColumnCount, lower.At(i, j))));
}
- ///
- /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
- ///
- /// The matrix to pointwise multiply with this one.
- /// The matrix to store the result of the pointwise multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this matrix and are not the same size.
- /// If this matrix and are not the same size.
- public override void PointwiseMultiply(Matrix other, Matrix result)
- {
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (result == null)
- {
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- if (ColumnCount != result.ColumnCount || RowCount != result.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- var m = other as DiagonalMatrix;
- var r = result as DiagonalMatrix;
-
- if (m == null || r == null)
- {
- base.PointwiseMultiply(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, m.Data, r.Data);
- }
- }
-
///
/// Permute the columns of a matrix according to a permutation.
///
@@ -1529,6 +1536,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
throw new InvalidOperationException("Permutations in diagonal matrix are not allowed");
}
+
#region Static constructors for special matrices.
///
@@ -1551,165 +1559,5 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
#endregion
-
- ///
- /// Negates each element of this matrix.
- ///
- public override void Negate()
- {
- Multiply(-1);
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- var mn = Math.Min(numberOfRows, numberOfColumns);
- CommonParallel.For(0, mn, i => matrix[i, i] = distribution.Sample());
-
- return matrix;
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = CreateMatrix(numberOfRows, numberOfColumns);
- var mn = Math.Min(numberOfRows, numberOfColumns);
- CommonParallel.For(0, mn, i => matrix[i, i] = distribution.Sample());
-
- return matrix;
- }
-
- ///
- /// Returns a that represents this instance.
- ///
- ///
- /// The format to use.
- ///
- ///
- /// The format provider to use.
- ///
- ///
- /// A that represents this instance.
- ///
- public override string ToString(string format, IFormatProvider formatProvider)
- {
- var stringBuilder = new StringBuilder();
- for (var row = 0; row < RowCount; row++)
- {
- for (var column = 0; column < ColumnCount; column++)
- {
- stringBuilder.Append(At(row, column).ToString(format, formatProvider));
- if (column != ColumnCount - 1)
- {
- stringBuilder.Append(formatProvider.GetTextInfo().ListSeparator);
- }
- }
-
- if (row != RowCount - 1)
- {
- stringBuilder.Append(Environment.NewLine);
- }
- }
-
- return stringBuilder.ToString();
- }
-
- #region Simple arithmetic of type T
- ///
- /// Add two values T+T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override double AddT(double val1, double val2)
- {
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override double SubtractT(double val1, double val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override double MultiplyT(double val1, double val2)
- {
- return val1 * val2;
- }
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override double DivideT(double val1, double val2)
- {
- return val1 / val2;
- }
-
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(double val1)
- {
- return Math.Abs(val1);
- }
-
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs
new file mode 100644
index 00000000..e28d42bf
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs
@@ -0,0 +1,403 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+// Copyright (c) 2009-2010 Math.NET
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.LinearAlgebra.Double
+{
+ using System;
+ using Distributions;
+ using Generic;
+ using Properties;
+ using Threading;
+
+ ///
+ /// double version of the class.
+ ///
+ public abstract class Matrix : Matrix
+ {
+ ///
+ /// Initializes a new instance of the Matrix class.
+ ///
+ ///
+ /// The number of rows.
+ ///
+ ///
+ /// The number of columns.
+ ///
+ protected Matrix(int rows, int columns) : base(rows, columns)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the Matrix class.
+ ///
+ ///
+ /// The order of the matrix.
+ ///
+ protected Matrix(int order)
+ : base(order)
+ {
+ }
+
+ /// Calculates the L1 norm.
+ /// The L1 norm of the matrix.
+ public override double L1Norm()
+ {
+ var norm = 0.0;
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ var s = 0.0;
+ for (var i = 0; i < RowCount; i++)
+ {
+ s += Math.Abs(At(i, j));
+ }
+
+ norm = Math.Max(norm, s);
+ }
+
+ return norm;
+ }
+
+ ///
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
+ {
+ return Transpose();
+ }
+
+ /// Calculates the Frobenius norm of this matrix.
+ /// The Frobenius norm of this matrix.
+ public override double FrobeniusNorm()
+ {
+ var transpose = Transpose();
+ var aat = this * transpose;
+
+ var norm = 0.0;
+ for (var i = 0; i < RowCount; i++)
+ {
+ norm += Math.Abs(aat.At(i, i));
+ }
+
+ norm = Math.Sqrt(norm);
+
+ return norm;
+ }
+
+ /// Calculates the infinity norm of this matrix.
+ /// The infinity norm of this matrix.
+ public override double InfinityNorm()
+ {
+ var norm = 0.0;
+ for (var i = 0; i < RowCount; i++)
+ {
+ var s = 0.0;
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ s += Math.Abs(At(i, j));
+ }
+
+ norm = Math.Max(norm, s);
+ }
+
+ return norm;
+ }
+
+ ///
+ /// Adds another matrix to this matrix.
+ ///
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoAdd(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ result.At(i, j, At(i, j) + other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Subtracts another matrix from this matrix.
+ ///
+ /// The matrix to subtract to this matrix.
+ /// The matrix to store the result of subtraction.
+ /// If the other matrix is .
+ /// If the two matrices don't have the same dimensions.
+ protected override void DoSubtract(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ result.At(i, j, At(i, j) - other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
+ ///
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(double scalar, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j < ColumnCount; j++)
+ {
+ 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)
+ {
+ CommonParallel.For(
+ 0,
+ 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.
+ ///
+ /// The scalar to divide the matrix with.
+ /// The matrix to store the result of the division.
+ protected override void DoDivide(double scalar, Matrix result)
+ {
+ DoMultiply(1.0 / scalar, result);
+ }
+
+ ///
+ /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
+ ///
+ /// The vector to multiply with.
+ /// The result of the multiplication.
+ protected override void DoLeftMultiply(Vector leftSide, Vector result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ var s = 0.0;
+ for (var i = 0; i != leftSide.Count; i++)
+ {
+ s += leftSide[i] * At(i, j);
+ }
+
+ result[j] = s;
+ });
+ }
+
+ ///
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
+ ///
+ /// The matrix to multiply with.
+ /// The result of the multiplication.
+ protected override void DoMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ 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);
+ }
+
+ result.At(j, i, s);
+ }
+ });
+ }
+
+ ///
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
+ ///
+ /// The matrix to multiply with.
+ /// The result of the multiplication.
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ var s = 0.0;
+ for (var l = 0; l < ColumnCount; l++)
+ {
+ s += At(i, l) * other.At(j, l);
+ }
+
+ result.At(i, j, s);
+ }
+ });
+ }
+
+ ///
+ /// Negate each element of this matrix and place the results into the result matrix.
+ ///
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ RowCount,
+ i =>
+ {
+ for (var j = 0; j != ColumnCount; j++)
+ {
+ result[i, j] = -At(i, j);
+ }
+ });
+ }
+
+ ///
+ /// Pointwise multiplies this matrix with another matrix and stores the result into the result matrix.
+ ///
+ /// The matrix to pointwise multiply with this one.
+ /// The matrix to store the result of the pointwise multiplication.
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ ColumnCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ result.At(i, j, At(i, j) * other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
+ ///
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
+ {
+ CommonParallel.For(
+ 0,
+ ColumnCount,
+ j =>
+ {
+ for (var i = 0; i < RowCount; i++)
+ {
+ result.At(i, j, At(i, j) / other.At(i, j));
+ }
+ });
+ }
+
+ ///
+ /// Computes the trace of this matrix.
+ ///
+ /// The trace of this matrix
+ /// If the matrix is not square
+ public override double Trace()
+ {
+ if (RowCount != ColumnCount)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixSquare);
+ }
+
+ return CommonParallel.Aggregate(0, RowCount, i => At(i, i));
+ }
+
+ ///
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected override void DoRandom(Matrix matrix, IContinuousDistribution distribution)
+ {
+ CommonParallel.For(
+ 0,
+ matrix.RowCount,
+ i =>
+ {
+ for (var j = 0; j < matrix.ColumnCount; j++)
+ {
+ matrix.At(i, j, distribution.Sample());
+ }
+ });
+ }
+
+ ///
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected override void DoRandom(Matrix matrix, IDiscreteDistribution distribution)
+ {
+ CommonParallel.For(
+ 0,
+ matrix.RowCount,
+ i =>
+ {
+ for (var j = 0; j < matrix.ColumnCount; j++)
+ {
+ matrix.At(i, j, distribution.Sample());
+ }
+ });
+ }
+ }
+}
diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
index f6d65578..61e832de 100644
--- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
@@ -31,8 +31,6 @@
namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
- using System.Text;
- using Distributions;
using Generic;
using Properties;
using Threading;
@@ -41,7 +39,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// A Matrix class with sparse storage. The underlying storage scheme is 3-array compressed-sparse-row (CSR) Format.
/// Wikipedia - CSR.
///
- public class SparseMatrix : Matrix
+ public class SparseMatrix : Matrix
{
///
/// Object for use in "lock"
@@ -858,7 +856,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double FrobeniusNorm()
{
var transpose = (SparseMatrix)Transpose();
- var aat = this * transpose;
+ var aat = (SparseMatrix)(this * transpose);
var norm = 0.0;
@@ -1033,200 +1031,231 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
- #region Elementary operations
-
+ #region Static constructors for special matrices.
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Initializes a square with all zero's except for ones on the diagonal.
///
- /// The matrix to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public override void Add(Matrix other)
+ /// the size of the square matrix.
+ /// Identity SparseMatrix
+ ///
+ /// If is less than one.
+ ///
+ public static SparseMatrix Identity(int order)
{
- if (ReferenceEquals(this, other))
- {
- Multiply(2);
- return;
- }
+ var m = new SparseMatrix(order)
+ {
+ NonZerosCount = order,
+ _nonZeroValues = new double[order],
+ _columnIndices = new int[order]
+ };
- var m = other as SparseMatrix;
- if (m == null)
- {
- base.Add(other);
- }
- else
+ for (var i = 0; i < order; i++)
{
- Add(m);
+ m._nonZeroValues[i] = 1.0;
+ m._columnIndices[i] = i;
+ m._rowIndex[i] = i;
}
+
+ return m;
}
+ #endregion
///
- /// Adds another to this matrix. The result will be written into this matrix.
+ /// Indicates whether the current object is equal to another object of the same type.
///
- /// The to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Add(SparseMatrix other)
+ ///
+ /// An object to compare with this object.
+ ///
+ ///
+ /// true if the current object is equal to the parameter; otherwise, false.
+ ///
+ public override bool Equals(Matrix other)
{
if (other == null)
{
- throw new ArgumentNullException("other");
+ return false;
}
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ return false;
+ }
+
+ // Accept if the argument is the same object as this.
+ if (ReferenceEquals(this, other))
+ {
+ return true;
}
- for (var i = 0; i < other.RowCount; i++)
+ var sparseMatrix = other as SparseMatrix;
+
+ if (sparseMatrix == null)
{
- // Get the begin / end index for the current row
- var startIndex = other._rowIndex[i];
- var endIndex = i < other._rowIndex.Length - 1 ? other._rowIndex[i + 1] : other.NonZerosCount;
+ return base.Equals(other);
+ }
- for (var j = startIndex; j < endIndex; j++)
+ if (NonZerosCount != sparseMatrix.NonZerosCount)
+ {
+ return false;
+ }
+
+ // If all else fails, perform element wise comparison.
+ for (var index = 0; index < NonZerosCount; index++)
+ {
+ if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
{
- var index = FindItem(i, other._columnIndices[j]);
- if (index >= 0)
- {
- if (_nonZeroValues[index] + other._nonZeroValues[j] == 0.0)
- {
- DeleteItemByIndex(index, i);
- }
- else
- {
- _nonZeroValues[index] += other._nonZeroValues[j];
- }
- }
- else
- {
- SetValueAt(i, other._columnIndices[j], other._nonZeroValues[j]);
- }
+ return false;
}
}
+
+ return true;
}
///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
- /// The matrix to subtract.
- /// If the other matrix is .
+ /// The matrix to add to this matrix.
+ /// The matrix to store the result of the addition.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public override void Subtract(Matrix other)
+ protected override void DoAdd(Matrix other, Matrix result)
{
- // We are substracting Matrix form itself
- if (ReferenceEquals(this, other))
- {
- Clear();
- return;
- }
+ result.Clear();
- var m = other as SparseMatrix;
- if (m == null)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- base.Subtract(other);
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
else
{
- Subtract(m);
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
+ }
+ }
}
}
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
- /// The to subtract.
- /// If the other matrix is .
+ /// The matrix to subtract to this matrix.
+ /// The matrix to store the result of subtraction.
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public void Subtract(SparseMatrix other)
+ protected override void DoSubtract(Matrix other, Matrix result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
- {
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
- }
+ result.Clear();
- for (var i = 0; i < other.RowCount; i++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- // Get the begin / end index for the current row
- var startIndex = other._rowIndex[i];
- var endIndex = i < other._rowIndex.Length - 1 ? other._rowIndex[i + 1] : other.NonZerosCount;
-
- for (var j = startIndex; j < endIndex; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var index = FindItem(i, other._columnIndices[j]);
- if (index >= 0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- if (_nonZeroValues[index] - other._nonZeroValues[j] == 0.0)
- {
- DeleteItemByIndex(index, i);
- }
- else
+ var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
{
- _nonZeroValues[index] -= other._nonZeroValues[j];
+ result.At(i, _columnIndices[j], resVal);
}
}
- else
+ }
+ }
+ else
+ {
+ for (var i = 0; i < other.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- SetValueAt(i, other._columnIndices[j], -other._nonZeroValues[j]);
+ var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
}
}
}
}
///
- /// Multiplies each element of this matrix with a scalar.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The scalar to multiply with.
- public override void Multiply(double scalar)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(double scalar, Matrix result)
{
- if (1.0.AlmostEqualInDecimalPlaces(scalar, 15))
+ if (scalar == 1.0)
{
+ CopyTo(result);
return;
}
- if (0.0.AlmostEqualInDecimalPlaces(scalar, 15))
+ if (scalar == 0.0)
{
- Clear();
+ result.Clear();
return;
}
- Control.LinearAlgebraProvider.ScaleArray(scalar, _nonZeroValues);
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
+ {
+ base.DoMultiply(scalar, result);
+ }
+ else
+ {
+ Control.LinearAlgebraProvider.ScaleArray(scalar, sparseResult._nonZeroValues);
+ }
}
///
- /// Multiplies this sparse matrix with another sparse matrix and places the results into the result sparse matrix.
+ /// Multiplies this matrix with another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If Columns != other.Rows.
- /// If the result matrix's dimensions are not the Rows x other.Columns.
- public override void Multiply(Matrix other, Matrix result)
+ protected override void DoMultiply(Matrix other, Matrix result)
{
var otherSparseMatrix = other as SparseMatrix;
var resultSparseMatrix = result as SparseMatrix;
if (otherSparseMatrix == null || resultSparseMatrix == null)
{
- base.Multiply(other, result);
+ base.DoMultiply(other, result);
return;
}
- if (ColumnCount != otherSparseMatrix.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if (resultSparseMatrix.RowCount != RowCount || resultSparseMatrix.ColumnCount != otherSparseMatrix.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
resultSparseMatrix.Clear();
var columnVector = new DenseVector(otherSparseMatrix.RowCount);
for (var row = 0; row < RowCount; row++)
@@ -1253,60 +1282,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
///
- /// Multiplies this matrix with another matrix and returns the result.
- ///
- /// The matrix to multiply with.
- /// If Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix Multiply(Matrix other)
- {
- var matrix = other as SparseMatrix;
- if (matrix == null)
- {
- return base.Multiply(other);
- }
-
- if (ColumnCount != matrix.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var result = (SparseMatrix)CreateMatrix(RowCount, matrix.ColumnCount);
- Multiply(matrix, result);
- return result;
- }
-
- ///
- /// Multiplies this dense matrix with transpose of another dense matrix and places the results into the result dense matrix.
+ /// Multiplies this matrix with transpose of another matrix and places the results into the result matrix.
///
/// The matrix to multiply with.
/// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void TransposeAndMultiply(Matrix other, Matrix result)
+ protected override void DoTransposeAndMultiply(Matrix other, Matrix result)
{
var otherSparse = other as SparseMatrix;
var resultSparse = result as SparseMatrix;
if (otherSparse == null || resultSparse == null)
{
- base.TransposeAndMultiply(other, result);
+ base.DoTransposeAndMultiply(other, result);
return;
}
- if (ColumnCount != otherSparse.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if ((resultSparse.RowCount != RowCount) || (resultSparse.ColumnCount != otherSparse.RowCount))
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
resultSparse.Clear();
for (var j = 0; j < RowCount; j++)
{
@@ -1343,58 +1333,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
}
-
- ///
- /// 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 otherSparse = other as SparseMatrix;
- if (otherSparse == null)
- {
- return base.TransposeAndMultiply(other);
- }
-
- if (ColumnCount != otherSparse.ColumnCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- var result = (SparseMatrix)CreateMatrix(RowCount, other.RowCount);
- TransposeAndMultiply(other, result);
- return result;
- }
///
- /// Multiplies two sparse matrices.
+ /// Negate each element of this matrix and place the results into the result matrix.
///
- /// The left matrix to multiply.
- /// The right matrix to multiply.
- /// The result of multiplication.
- /// If or is .
- /// If the dimensions of or don't conform.
- public static SparseMatrix operator *(SparseMatrix leftSide, SparseMatrix rightSide)
+ /// The result of the negation.
+ protected override void DoNegate(Matrix result)
{
- if (leftSide == null)
- {
- throw new ArgumentNullException("leftSide");
- }
-
- if (rightSide == null)
- {
- throw new ArgumentNullException("rightSide");
- }
-
- if (leftSide.ColumnCount != rightSide.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- return (SparseMatrix)leftSide.Multiply(rightSide);
+ CopyTo(result);
+ DoMultiply(-1, result);
}
///
@@ -1402,307 +1349,95 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
/// The matrix to pointwise multiply with this one.
/// The matrix to store the result of the pointwise multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this matrix and are not the same size.
- /// If this matrix and are not the same size.
- public override void PointwiseMultiply(Matrix other, Matrix result)
+ protected override void DoPointwiseMultiply(Matrix other, Matrix result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (result == null)
- {
- throw new ArgumentNullException("result");
- }
-
- if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
- if (ColumnCount != result.ColumnCount || RowCount != result.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions, "result");
- }
-
result.Clear();
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
- for (var j = startIndex; j < endIndex; j++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
+ {
+ for (var i = 0; i < other.RowCount; i++)
{
- var resVal = _nonZeroValues[j] * other[i, _columnIndices[j]];
- if (resVal != 0.0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- result[i, _columnIndices[j]] = resVal;
+ var resVal = _nonZeroValues[j] * other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
}
}
}
- }
-
- ///
- /// Generates matrix with random elements.
- ///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
- {
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
-
- var matrix = (SparseMatrix)CreateMatrix(numberOfRows, numberOfColumns);
- for (var i = 0; i < matrix.RowCount; i++)
+ else
{
- for (var j = 0; j < matrix.ColumnCount; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var value = distribution.Sample();
- if (value != 0.0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- matrix.SetValueAt(i, j, value);
+ var resVal = _nonZeroValues[j] * other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
}
}
}
-
- return matrix;
}
///
- /// Generates matrix with random elements.
+ /// Pointwise divide this matrix by another matrix and stores the result into the result matrix.
///
- /// Number of rows.
- /// Number of columns.
- /// Continuous Random Distribution or Source
- ///
- /// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
- ///
- /// If the parameter is not positive.
- /// If the parameter is not positive.
- public override Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
+ /// The matrix to pointwise divide this one by.
+ /// The matrix to store the result of the pointwise division.
+ protected override void DoPointwiseDivide(Matrix other, Matrix result)
{
- if (numberOfRows < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
- }
-
- if (numberOfColumns < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
- }
+ result.Clear();
- var matrix = (SparseMatrix)CreateMatrix(numberOfRows, numberOfColumns);
- for (var i = 0; i < matrix.RowCount; i++)
+ var sparseResult = result as SparseMatrix;
+ if (sparseResult == null)
{
- for (var j = 0; j < matrix.ColumnCount; j++)
+ for (var i = 0; i < other.RowCount; i++)
{
- var value = distribution.Sample();
- if (value != 0.0)
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
{
- matrix.SetValueAt(i, j, value);
+ var resVal = _nonZeroValues[j] / other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ result.At(i, _columnIndices[j], resVal);
+ }
}
}
}
-
- return matrix;
- }
-
- #endregion
-
- #region Static constructors for special matrices.
- ///
- /// Initializes a square with all zero's except for ones on the diagonal.
- ///
- /// the size of the square matrix.
- /// Identity SparseMatrix
- ///
- /// If is less than one.
- ///
- public static SparseMatrix Identity(int order)
- {
- var m = new SparseMatrix(order)
- {
- NonZerosCount = order,
- _nonZeroValues = new double[order],
- _columnIndices = new int[order]
- };
-
- for (var i = 0; i < order; i++)
- {
- m._nonZeroValues[i] = 1.0;
- m._columnIndices[i] = i;
- m._rowIndex[i] = i;
- }
-
- return m;
- }
- #endregion
-
- ///
- /// Negates each element of this matrix.
- ///
- public override void Negate()
- {
- Multiply(-1);
- }
-
- ///
- /// Indicates whether the current object is equal to another object of the same type.
- ///
- ///
- /// An object to compare with this object.
- ///
- ///
- /// true if the current object is equal to the parameter; otherwise, false.
- ///
- public override bool Equals(Matrix other)
- {
- if (other == null)
- {
- return false;
- }
-
- if (ColumnCount != other.ColumnCount || RowCount != other.RowCount)
- {
- return false;
- }
-
- // Accept if the argument is the same object as this.
- if (ReferenceEquals(this, other))
- {
- return true;
- }
-
- var sparseMatrix = other as SparseMatrix;
-
- if (sparseMatrix == null)
- {
- return base.Equals(other);
- }
-
- if (NonZerosCount != sparseMatrix.NonZerosCount)
- {
- return false;
- }
-
- // If all else fails, perform element wise comparison.
- for (var index = 0; index < NonZerosCount; index++)
+ else
{
- if (!_nonZeroValues[index].AlmostEqual(sparseMatrix._nonZeroValues[index]) || _columnIndices[index] != sparseMatrix._columnIndices[index])
+ for (var i = 0; i < other.RowCount; i++)
{
- return false;
- }
- }
-
- return true;
- }
+ // Get the begin / end index for the current row
+ var startIndex = _rowIndex[i];
+ var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
- ///
- /// Returns a that represents this instance.
- ///
- ///
- /// The format to use.
- ///
- ///
- /// The format provider to use.
- ///
- ///
- /// A that represents this instance.
- ///
- public override string ToString(string format, IFormatProvider formatProvider)
- {
- var stringBuilder = new StringBuilder();
- for (var row = 0; row < RowCount; row++)
- {
- for (var column = 0; column < ColumnCount; column++)
- {
- stringBuilder.Append(At(row, column).ToString(format, formatProvider));
- if (column != ColumnCount - 1)
+ for (var j = startIndex; j < endIndex; j++)
{
- stringBuilder.Append(formatProvider.GetTextInfo().ListSeparator);
+ var resVal = _nonZeroValues[j] / other.At(i, _columnIndices[j]);
+ if (resVal != 0.0)
+ {
+ sparseResult.SetValueAt(i, _columnIndices[j], resVal);
+ }
}
}
-
- if (row != RowCount - 1)
- {
- stringBuilder.Append(Environment.NewLine);
- }
}
-
- return stringBuilder.ToString();
- }
-
- #region Simple arithmetic of type T
- ///
- /// Add two values T+T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of addition
- protected sealed override double AddT(double val1, double val2)
- {
- return val1 + val2;
- }
-
- ///
- /// Subtract two values T-T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of subtract
- protected sealed override double SubtractT(double val1, double val2)
- {
- return val1 - val2;
- }
-
- ///
- /// Multiply two values T*T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of multiplication
- protected sealed override double MultiplyT(double val1, double val2)
- {
- return val1 * val2;
- }
-
- ///
- /// Divide two values T/T
- ///
- /// Left operand value
- /// Right operand value
- /// Result of divide
- protected sealed override double DivideT(double val1, double val2)
- {
- return val1 / val2;
- }
-
- ///
- /// Take absolute value
- ///
- /// Source alue
- /// True if one; otherwise false
- protected sealed override double AbsoluteT(double val1)
- {
- return Math.Abs(val1);
}
- #endregion
}
}
diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs
index e45abccf..1de2b78a 100644
--- a/src/Numerics/LinearAlgebra/Double/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Double/Vector.cs
@@ -65,7 +65,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] + scalar);
+ index => result[index] = this[index] + scalar);
}
///
@@ -131,7 +131,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] * scalar);
+ index => result[index] = this[index] * scalar);
}
///
@@ -148,7 +148,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
CommonParallel.For(
0,
Count,
- index => result[index] = result[index] / scalar);
+ index => result[index] = this[index] / scalar);
}
///
diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
index e819a872..e6b7adf1 100644
--- a/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
+++ b/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
@@ -207,10 +207,90 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
{
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "result");
}
+
+ if (scalar.Equals(One))
+ {
+ CopyTo(result);
+ return;
+ }
+
+ if (scalar.Equals(Zero))
+ {
+ result.Clear();
+ return;
+ }
+ CopyTo(result);
DoMultiply(scalar, result);
}
+ ///
+ /// Divides each element of this matrix with a scalar.
+ ///
+ /// The scalar to divide with.
+ /// The result of the division.
+ public virtual Matrix Divide(T scalar)
+ {
+ if (scalar.Equals(One))
+ {
+ return Clone();
+ }
+
+ if (scalar.Equals(0.0))
+ {
+ throw new DivideByZeroException();
+ }
+
+ var result = CreateMatrix(RowCount, ColumnCount);
+ Divide(scalar, result);
+ return result;
+ }
+
+ ///
+ /// Divides each element of the matrix by a scalar and places results into the result matrix.
+ ///
+ /// The scalar to divide the matrix with.
+ /// The matrix to store the result of the division.
+ /// If the result matrix is .
+ /// If the result matrix's dimensions are not the same as this matrix.
+ public virtual void Divide(T scalar, Matrix result)
+ {
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (result.RowCount != RowCount)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "result");
+ }
+
+ if (result.ColumnCount != ColumnCount)
+ {
+ throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "result");
+ }
+
+ if (scalar.Equals(One))
+ {
+ CopyTo(result);
+ return;
+ }
+
+ if (scalar.Equals(0.0))
+ {
+ throw new DivideByZeroException();
+ }
+
+ DoDivide(scalar, result);
+ }
+
+ ///
+ /// Divides each element of the matrix by a scalar and places results into the result matrix.
+ ///
+ /// The scalar to divide the matrix with.
+ /// The matrix to store the result of the division.
+ protected abstract void DoDivide(T scalar, Matrix result);
+
///
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
@@ -560,9 +640,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
- var ret = leftSide.Clone();
- ret.Add(rightSide);
- return ret;
+ return leftSide.Add(rightSide);
}
///
@@ -609,9 +687,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
- var ret = leftSide.Clone();
- ret.Subtract(rightSide);
- return ret;
+ return leftSide.Subtract(rightSide);
}
///
@@ -627,9 +703,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentNullException("rightSide");
}
- var ret = rightSide.Clone();
- ret.Negate();
- return ret;
+ return rightSide.Negate();
}
///
@@ -646,9 +720,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentNullException("leftSide");
}
- var ret = leftSide.Clone();
- ret.Multiply(rightSide);
- return ret;
+ return leftSide.Multiply(rightSide);
}
///
@@ -665,9 +737,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentNullException("rightSide");
}
- var ret = rightSide.Clone();
- ret.Multiply(leftSide);
- return ret;
+ return rightSide.Multiply(leftSide);
}
///
@@ -866,20 +936,42 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
protected abstract void DoPointwiseDivide(Matrix other, Matrix result);
///
- /// Generates matrix with random elements.
+ /// Generates a matrix with random elements.
///
/// Number of rows.
/// Number of columns.
- /// Continuous Random Distribution or Source
+ /// Continuous Random Distribution to generate elements from.
///
/// An numberOfRows-by-numberOfColumns matrix with elements distributed according to the provided distribution.
///
/// If the parameter is not positive.
/// If the parameter is not positive.
- public abstract Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution);
+ public virtual Matrix Random(int numberOfRows, int numberOfColumns, IContinuousDistribution distribution)
+ {
+ if (numberOfRows < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
+ }
+
+ if (numberOfColumns < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
+ }
+
+ var matrix = CreateMatrix(numberOfRows, numberOfColumns);
+ DoRandom(matrix, distribution);
+ return matrix;
+ }
///
- /// Generates matrix with random elements.
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected abstract void DoRandom(Matrix matrix, IContinuousDistribution distribution);
+
+ ///
+ /// Generates a matrix with random elements.
///
/// Number of rows.
/// Number of columns.
@@ -889,7 +981,29 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
///
/// If the parameter is not positive.
/// If the parameter is not positive.
- public abstract Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution);
+ public virtual Matrix Random(int numberOfRows, int numberOfColumns, IDiscreteDistribution distribution)
+ {
+ if (numberOfRows < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfRows");
+ }
+
+ if (numberOfColumns < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "numberOfColumns");
+ }
+
+ var matrix = CreateMatrix(numberOfRows, numberOfColumns);
+ DoRandom(matrix, distribution);
+ return matrix;
+ }
+
+ ///
+ /// Populates a matrix with random elements.
+ ///
+ /// The matrix to populate.
+ /// Continuous Random Distribution to generate elements from.
+ protected abstract void DoRandom(Matrix matrix, IDiscreteDistribution distribution);
///
/// Computes the trace of this matrix.
@@ -910,9 +1024,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// Calculates the condition number of this matrix.
/// The condition number of the matrix.
/// The condition number is calculated using singular value decomposition.
- public virtual double ConditionNumber()
+ public virtual T ConditionNumber()
{
- return Svd.Create(this, false).ConditionNumber;
+ throw new NotImplementedException();
+ //return Svd.Create(this, false).ConditionNumber;
}
/// Computes the determinant of this matrix.
diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
index 4fab2249..6ff55030 100644
--- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
@@ -27,7 +27,6 @@
namespace MathNet.Numerics.LinearAlgebra.Single
{
using System;
- using Distributions;
using Generic;
using Properties;
using Threading;
@@ -35,7 +34,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
///
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
///
- public class DenseMatrix : Matrix
+ public class DenseMatrix : Matrix
{
///
/// Initializes a new instance of the class. This matrix is square with a given size.
@@ -220,12 +219,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// Calculates the L1 norm.
/// The L1 norm of the matrix.
- public override double L1Norm()
+ public override float L1Norm()
{
- var norm = 0.0;
+ var norm = 0.0f;
for (var j = 0; j < ColumnCount; j++)
{
- var s = 0.0;
+ var s = 0.0f;
for (var i = 0; i < RowCount; i++)
{
s += Math.Abs(Data[(j * RowCount) + i]);
@@ -239,29 +238,29 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// Calculates the Frobenius norm of this matrix.
/// The Frobenius norm of this matrix.
- public override double FrobeniusNorm()
+ public override float FrobeniusNorm()
{
var transpose = (DenseMatrix)Transpose();
- var aat = this * transpose;
+ var aat = (DenseMatrix)(this * transpose);
- var norm = 0.0;
+ var norm = 0.0f;
for (var i = 0; i < RowCount; i++)
{
norm += Math.Abs(aat.Data[(i * RowCount) + i]);
}
- norm = Math.Sqrt(norm);
+ norm = Convert.ToSingle(Math.Sqrt(norm));
return norm;
}
/// Calculates the infinity norm of this matrix.
/// The infinity norm of this matrix.
- public override double InfinityNorm()
+ public override float InfinityNorm()
{
- var norm = 0.0;
+ var norm = 0.0f;
for (var i = 0; i < RowCount; i++)
{
- var s = 0.0;
+ var s = 0.0f;
for (var j = 0; j < ColumnCount; j++)
{
s += Math.Abs(Data[(j * RowCount) + i]);
@@ -276,435 +275,293 @@ namespace MathNet.Numerics.LinearAlgebra.Single
#region Elementary operations
///
- /// Adds another matrix to this matrix. The result will be written into this matrix.
+ /// Adds another matrix to this matrix.
///
/// The matrix to add to this matrix.
- /// If the other matrix is .
+ /// The matrix to store the result of add
+ /// If the other matrix is .
/// If the two matrices don't have the same dimensions.
- public override void Add(Matrix other)
+ protected override void DoAdd(Matrix other, Matrix result)
{
- var m = other as DenseMatrix;
- if (m == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+ if (denseOther == null || denseResult == null)
{
- base.Add(other);
+ base.DoAdd(other, result);
}
else
{
- Add(m);
+ Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data);
}
}
///
- /// Adds another to this matrix. The result will be written into this matrix.
- ///
- /// The to add to this matrix.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Add(DenseMatrix other)
- {
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
- {
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
- }
-
- Control.LinearAlgebraProvider.AddArrays(Data, other.Data, Data);
- }
-
- ///
- /// Subtracts another matrix from this matrix. The result will be written into this matrix.
+ /// Subtracts another matrix from this matrix.
///
/// The matrix to subtract.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public override void Subtract(Matrix other)
+ /// The matrix to store the result of the subtraction.
+ protected override void DoSubtract(Matrix other, Matrix result)
{
- var m = other as DenseMatrix;
- if (m == null)
+ var denseOther = other as DenseMatrix;
+ var denseResult = result as DenseMatrix;
+ if (denseOther == null || denseResult == null)
{
- base.Subtract(other);
+ base.DoSubtract(other, result);
}
else
{
- Subtract(m);
+ Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data);
}
}
+
+ #endregion
+
+ #region Static constructors for special matrices.
///
- /// Subtracts another from this matrix. The result will be written into this matrix.
+ /// Initializes a square with all zero's except for ones on the diagonal.
///
- /// The to subtract.
- /// If the other matrix is .
- /// If the two matrices don't have the same dimensions.
- public void Subtract(DenseMatrix other)
+ /// the size of the square matrix.
+ /// A dense identity matrix.
+ ///
+ /// If is less than one.
+ ///
+ public static DenseMatrix Identity(int order)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (other.RowCount != RowCount || other.ColumnCount != ColumnCount)
+ var m = new DenseMatrix(order);
+ for (var i = 0; i < order; i++)
{
- throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
+ m.Data[(i * order) + i] = 1.0f;
}
- Control.LinearAlgebraProvider.SubtractArrays(Data, other.Data, Data);
+ return m;
}
+ #endregion
+
///
- /// Multiplies each element of this matrix with a scalar.
- ///
- /// The scalar to multiply with.
- public override void Multiply(float scalar)
+ /// Returns the conjugate transpose of this matrix.
+ ///
+ /// The conjugate transpose of this matrix.
+ public override Matrix ConjugateTranspose()
{
- Control.LinearAlgebraProvider.ScaleArray(scalar, Data);
+ return Transpose();
}
///
- /// Multiplies this dense matrix with another dense matrix and places the results into the result dense matrix.
+ /// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
- /// The matrix to multiply with.
- /// The result of the multiplication.
- /// If the other matrix is .
- /// If the result matrix is .
- /// If this.Columns != other.Rows.
- /// If the result matrix's dimensions are not the this.Rows x other.Columns.
- public override void Multiply(Matrix other, Matrix result)
+ /// The scalar to multiply the matrix with.
+ /// The matrix to store the result of the multiplication.
+ protected override void DoMultiply(float scalar, Matrix result)
{
- if (other == null)
- {
- throw new ArgumentNullException("other");
- }
-
- if (result == null)
+ var denseResult = result as DenseMatrix;
+ if (denseResult == null)
{
- throw new ArgumentNullException("result");
+ base.DoMultiply(scalar, result);
}
-
- if (ColumnCount != other.RowCount)
- {
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
- }
-
- if (result.RowCount != RowCount || result.ColumnCount != other.ColumnCount)
+ else
{
- throw new ArgumentException(Resources.ArgumentMatrixDimensions);
+ Control.LinearAlgebraProvider.ScaleArray(scalar, denseResult.Data);
}
+ }
- var m = other as DenseMatrix;
- var r = result as DenseMatrix;
+ ///
+ /// 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)
+ {
+ var denseRight = rightSide as DenseVector;
+ var denseResult = result as DenseVector;
- if (m == null || r == null)
+ if (denseRight == null || denseResult == null)
{
- base.Multiply(other, result);
+ base.DoMultiply(rightSide, result);
}
else
{
- Control.LinearAlgebraProvider.MatrixMultiply(
- Data,
- RowCount,
- ColumnCount,
- m.Data,
- m.RowCount,
- m.ColumnCount,
- r.Data);
+ Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ Algorithms.LinearAlgebra.Transpose.DontTranspose,
+ 1.0f,
+ Data,
+ RowCount,
+ ColumnCount,
+ denseRight.Data,
+ denseRight.Count,
+ 1,
+ 0.0f,
+ denseResult.Data);
}
}
///
- /// Multiplies this matrix with another matrix and returns the result.
+ /// Left multiply a matrix with a vector ( = vector * matrix ) and place the result in the result vector.
///
- /// The matrix to multiply with.
- /// If this.Columns != other.Rows.
- /// If the other matrix is .
- /// The result of multiplication.
- public override Matrix Multiply(Matrix other)
+ /// The vector to multiply with.
+ /// The result of the multiplication.
+ protected override void DoLeftMultiply(Vector leftSide, Vector