Browse Source

LA Storage: dense matrix storage (perf, deduplication)

la-knuth
Christoph Ruegg 14 years ago
parent
commit
8e8f7704bb
  1. 220
      src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs
  2. 216
      src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs
  3. 215
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  4. 214
      src/Numerics/LinearAlgebra/Single/DenseMatrix.cs
  5. 49
      src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs
  6. 1
      src/Numerics/Numerics.csproj

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

@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
using Algorithms.LinearAlgebra; using Algorithms.LinearAlgebra;
using Generic; using Generic;
using Properties; using Properties;
using Storage;
/// <summary> /// <summary>
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order. /// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
@ -38,19 +39,27 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
[Serializable] [Serializable]
public class DenseMatrix : Matrix public class DenseMatrix : Matrix
{ {
readonly DenseColumnMajorMatrixStorage<Complex> _storage;
/// <summary> /// <summary>
/// Number of rows. /// Number of rows.
/// </summary> /// </summary>
/// <remarks>Using this instead of the RowCount property to speed up calculating /// <remarks>Using this instead of the RowCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _rowCount; readonly int _rowCount;
/// <summary> /// <summary>
/// Number of columns. /// Number of columns.
/// </summary> /// </summary>
/// <remarks>Using this instead of the ColumnCount property to speed up calculating /// <remarks>Using this instead of the ColumnCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _columnCount; readonly int _columnCount;
/// <summary>
/// Gets the matrix's data.
/// </summary>
/// <value>The matrix's data.</value>
readonly Complex[] _data;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size. /// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size.
@ -62,9 +71,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(int order) public DenseMatrix(int order)
: base(order) : base(order)
{ {
_rowCount = order; _storage = new DenseColumnMajorMatrixStorage<Complex>(order, order);
_columnCount = order;
Data = new Complex[order * order]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(int rows, int columns) public DenseMatrix(int rows, int columns)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<Complex>(rows, columns);
_columnCount = columns;
Data = new Complex[rows * columns]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(int rows, int columns, Complex value) public DenseMatrix(int rows, int columns, Complex value)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<Complex>(rows, columns);
_columnCount = columns;
Data = new Complex[rows * columns]; _rowCount = _storage.RowCount;
for (var i = 0; i < Data.Length; i++) _columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _data.Length; i++)
{ {
Data[i] = value; _data[i] = value;
} }
} }
@ -116,9 +132,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(int rows, int columns, Complex[] array) public DenseMatrix(int rows, int columns, Complex[] array)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<Complex>(rows, columns, array);
_columnCount = columns;
Data = array; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -129,14 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(Complex[,] array) public DenseMatrix(Complex[,] array)
: base(array.GetLength(0), array.GetLength(1)) : base(array.GetLength(0), array.GetLength(1))
{ {
_rowCount = array.GetLength(0); _storage = new DenseColumnMajorMatrixStorage<Complex>(array.GetLength(0), array.GetLength(1));
_columnCount = array.GetLength(1);
Data = new Complex[_rowCount * _columnCount]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _rowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
for (var j = 0; j < _columnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
Data[(j * _rowCount) + i] = array[i, j]; _data[(j * _rowCount) + i] = array[i, j];
} }
} }
} }
@ -147,8 +168,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <value>The matrix's data.</value> /// <value>The matrix's data.</value>
public Complex[] Data public Complex[] Data
{ {
get; get { return _data; }
private set;
} }
/// <summary> /// <summary>
@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public override void CopyTo(Matrix<Complex> target) public override void CopyTo(Matrix<Complex> target)
{ {
var denseTarget = target as DenseMatrix; var denseTarget = target as DenseMatrix;
if (denseTarget == null) if (denseTarget != null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
{ {
_storage.CopyTo(denseTarget._storage);
return; return;
} }
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) base.CopyTo(target);
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Array.Copy(Data, 0, denseTarget.Data, 0, Data.Length);
} }
/// <summary> /// <summary>
@ -240,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
set set
@ -255,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
} }
@ -273,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </returns> /// </returns>
public override Complex At(int row, int column) public override Complex At(int row, int column)
{ {
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
/// <summary> /// <summary>
@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </param> /// </param>
public override void At(int row, int column, Complex value) public override void At(int row, int column, Complex value)
{ {
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
/// <summary> /// <summary>
@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </summary> /// </summary>
public override void Clear() public override void Clear()
{ {
Array.Clear(Data, 0, Data.Length); Array.Clear(_data, 0, _data.Length);
} }
/// <summary> /// <summary>
@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix<Complex> Transpose() public override Matrix<Complex> Transpose()
{ {
var ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
var index = j * RowCount; var index = j * _rowCount;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
ret.Data[(i * ColumnCount) + j] = Data[index + i]; ret._data[(i * _columnCount) + j] = _data[index + i];
} }
} }
@ -324,21 +334,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <returns>The L1 norm of the matrix.</returns> /// <returns>The L1 norm of the matrix.</returns>
public override Complex L1Norm() public override Complex L1Norm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the Frobenius norm of this matrix.</summary> /// <summary>Calculates the Frobenius norm of this matrix.</summary>
/// <returns>The Frobenius norm of this matrix.</returns> /// <returns>The Frobenius norm of this matrix.</returns>
public override Complex FrobeniusNorm() public override Complex FrobeniusNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the infinity norm of this matrix.</summary> /// <summary>Calculates the infinity norm of this matrix.</summary>
/// <returns>The infinity norm of this matrix.</returns> /// <returns>The infinity norm of this matrix.</returns>
public override Complex InfinityNorm() public override Complex InfinityNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _data);
} }
#region Static constructors for special matrices. #region Static constructors for special matrices.
@ -356,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
var m = new DenseMatrix(order); var m = new DenseMatrix(order);
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
m.Data[(i * order) + i] = 1.0; m._data[(i * order) + i] = 1.0;
} }
return m; return m;
@ -378,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(scalar, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(scalar, _data, denseResult._data);
} }
} }
@ -402,9 +412,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -430,17 +440,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0, 0.0,
denseResult.Data); denseResult._data);
} }
} }
@ -461,17 +471,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0, 0.0,
denseResult.Data); denseResult._data);
} }
} }
@ -495,9 +505,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -523,17 +533,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0, 0.0,
denseResult.Data); denseResult._data);
} }
} }
@ -551,7 +561,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(-1, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(-1, _data, denseResult._data);
} }
} }
@ -571,7 +581,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -591,7 +601,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseDivideArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseDivideArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -612,7 +622,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.AddArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -631,7 +641,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
} }
else else
{ {
Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.SubtractArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -641,13 +651,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <returns>The conjugate transpose of this matrix.</returns> /// <returns>The conjugate transpose of this matrix.</returns>
public override Matrix<Complex> ConjugateTranspose() public override Matrix<Complex> ConjugateTranspose()
{ {
var ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
var index = j * RowCount; var index = j * _rowCount;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
ret.Data[(i * ColumnCount) + j] = Data[index + i].Conjugate(); ret._data[(i * _columnCount) + j] = _data[index + i].Conjugate();
} }
} }
@ -661,15 +671,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <exception cref="ArgumentException">If the matrix is not square</exception> /// <exception cref="ArgumentException">If the matrix is not square</exception>
public override Complex Trace() public override Complex Trace()
{ {
if (RowCount != ColumnCount) if (_rowCount != _columnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var sum = Complex.Zero; var sum = Complex.Zero;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
sum += Data[(i * RowCount) + i]; sum += _data[(i * _rowCount) + i];
} }
return sum; return sum;
@ -698,7 +708,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -745,7 +755,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -826,7 +836,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentNullException("rightSide"); throw new ArgumentNullException("rightSide");
} }
if (leftSide.ColumnCount != rightSide.RowCount) if (leftSide._columnCount != rightSide._rowCount)
{ {
throw DimensionsDontMatch<ArgumentException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentException>(leftSide, rightSide);
} }

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

@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
using Generic; using Generic;
using Numerics; using Numerics;
using Properties; using Properties;
using Storage;
/// <summary> /// <summary>
/// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order. /// A Matrix class with dense storage. The underlying storage is a one dimensional array in column-major order.
@ -38,6 +39,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
[Serializable] [Serializable]
public class DenseMatrix : Matrix public class DenseMatrix : Matrix
{ {
readonly DenseColumnMajorMatrixStorage<Complex32> _storage;
/// <summary> /// <summary>
/// Number of rows. /// Number of rows.
/// </summary> /// </summary>
@ -52,6 +55,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _columnCount; private readonly int _columnCount;
/// <summary>
/// Gets the matrix's data.
/// </summary>
/// <value>The matrix's data.</value>
readonly Complex32[] _data;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size. /// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size.
/// </summary> /// </summary>
@ -62,9 +71,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(int order) public DenseMatrix(int order)
: base(order) : base(order)
{ {
_rowCount = order; _storage = new DenseColumnMajorMatrixStorage<Complex32>(order, order);
_columnCount = order;
Data = new Complex32[order * order]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(int rows, int columns) public DenseMatrix(int rows, int columns)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<Complex32>(rows, columns);
_columnCount = columns;
Data = new Complex32[rows * columns]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(int rows, int columns, Complex32 value) public DenseMatrix(int rows, int columns, Complex32 value)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<Complex32>(rows, columns);
_columnCount = columns;
Data = new Complex32[rows * columns]; _rowCount = _storage.RowCount;
for (var i = 0; i < Data.Length; i++) _columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _data.Length; i++)
{ {
Data[i] = value; _data[i] = value;
} }
} }
@ -116,9 +132,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(int rows, int columns, Complex32[] array) public DenseMatrix(int rows, int columns, Complex32[] array)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<Complex32>(rows, columns, array);
_columnCount = columns;
Data = array; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -129,14 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(Complex32[,] array) public DenseMatrix(Complex32[,] array)
: base(array.GetLength(0), array.GetLength(1)) : base(array.GetLength(0), array.GetLength(1))
{ {
_rowCount = array.GetLength(0); _storage = new DenseColumnMajorMatrixStorage<Complex32>(array.GetLength(0), array.GetLength(1));
_columnCount = array.GetLength(1);
Data = new Complex32[_rowCount * _columnCount]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _rowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
for (var j = 0; j < _columnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
Data[(j * _rowCount) + i] = array[i, j]; _data[(j * _rowCount) + i] = array[i, j];
} }
} }
} }
@ -147,8 +168,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <value>The matrix's data.</value> /// <value>The matrix's data.</value>
public Complex32[] Data public Complex32[] Data
{ {
get; get { return _data; }
private set;
} }
/// <summary> /// <summary>
@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public override void CopyTo(Matrix<Complex32> target) public override void CopyTo(Matrix<Complex32> target)
{ {
var denseTarget = target as DenseMatrix; var denseTarget = target as DenseMatrix;
if (denseTarget == null) if (denseTarget != null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
{ {
_storage.CopyTo(denseTarget._storage);
return; return;
} }
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) base.CopyTo(target);
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Array.Copy(Data, 0, denseTarget.Data, 0, Data.Length);
} }
/// <summary> /// <summary>
@ -240,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
set set
@ -255,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
} }
@ -273,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </returns> /// </returns>
public override Complex32 At(int row, int column) public override Complex32 At(int row, int column)
{ {
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
/// <summary> /// <summary>
@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </param> /// </param>
public override void At(int row, int column, Complex32 value) public override void At(int row, int column, Complex32 value)
{ {
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
/// <summary> /// <summary>
@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </summary> /// </summary>
public override void Clear() public override void Clear()
{ {
Array.Clear(Data, 0, Data.Length); Array.Clear(_data, 0, _data.Length);
} }
/// <summary> /// <summary>
@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix<Complex32> Transpose() public override Matrix<Complex32> Transpose()
{ {
var ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
var index = j * RowCount; var index = j * _rowCount;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
ret.Data[(i * ColumnCount) + j] = Data[index + i]; ret._data[(i * _columnCount) + j] = _data[index + i];
} }
} }
@ -324,21 +334,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <returns>The L1 norm of the matrix.</returns> /// <returns>The L1 norm of the matrix.</returns>
public override Complex32 L1Norm() public override Complex32 L1Norm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the Frobenius norm of this matrix.</summary> /// <summary>Calculates the Frobenius norm of this matrix.</summary>
/// <returns>The Frobenius norm of this matrix.</returns> /// <returns>The Frobenius norm of this matrix.</returns>
public override Complex32 FrobeniusNorm() public override Complex32 FrobeniusNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the infinity norm of this matrix.</summary> /// <summary>Calculates the infinity norm of this matrix.</summary>
/// <returns>The infinity norm of this matrix.</returns> /// <returns>The infinity norm of this matrix.</returns>
public override Complex32 InfinityNorm() public override Complex32 InfinityNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _data);
} }
#region Static constructors for special matrices. #region Static constructors for special matrices.
@ -356,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
var m = new DenseMatrix(order); var m = new DenseMatrix(order);
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
m.Data[(i * order) + i] = 1.0f; m._data[(i * order) + i] = 1.0f;
} }
return m; return m;
@ -378,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(scalar, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(scalar, _data, denseResult._data);
} }
} }
@ -402,9 +412,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -430,17 +440,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0f, 0.0f,
denseResult.Data); denseResult._data);
} }
} }
@ -461,17 +471,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0f, 0.0f,
denseResult.Data); denseResult._data);
} }
} }
@ -495,9 +505,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -523,17 +533,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0f, 0.0f,
denseResult.Data); denseResult._data);
} }
} }
@ -551,7 +561,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(-1, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(-1, _data, denseResult._data);
} }
} }
@ -571,7 +581,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -591,7 +601,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseDivideArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseDivideArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -612,7 +622,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.AddArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -631,7 +641,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
} }
else else
{ {
Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.SubtractArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -641,13 +651,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <returns>The conjugate transpose of this matrix.</returns> /// <returns>The conjugate transpose of this matrix.</returns>
public override Matrix<Complex32> ConjugateTranspose() public override Matrix<Complex32> ConjugateTranspose()
{ {
var ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
var index = j * RowCount; var index = j * _rowCount;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
ret.Data[(i * ColumnCount) + j] = Data[index + i].Conjugate(); ret._data[(i * _columnCount) + j] = _data[index + i].Conjugate();
} }
} }
@ -661,15 +671,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <exception cref="ArgumentException">If the matrix is not square</exception> /// <exception cref="ArgumentException">If the matrix is not square</exception>
public override Complex32 Trace() public override Complex32 Trace()
{ {
if (RowCount != ColumnCount) if (_rowCount != _columnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var sum = Complex32.Zero; var sum = Complex32.Zero;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
sum += Data[(i * RowCount) + i]; sum += _data[(i * _rowCount) + i];
} }
return sum; return sum;
@ -698,7 +708,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -745,7 +755,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -826,7 +836,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentNullException("rightSide"); throw new ArgumentNullException("rightSide");
} }
if (leftSide.ColumnCount != rightSide.RowCount) if (leftSide._columnCount != rightSide._rowCount)
{ {
throw DimensionsDontMatch<ArgumentException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentException>(leftSide, rightSide);
} }

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

@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
using Algorithms.LinearAlgebra; using Algorithms.LinearAlgebra;
using Generic; using Generic;
using Properties; using Properties;
using Storage;
using Threading; using Threading;
/// <summary> /// <summary>
@ -38,19 +39,27 @@ namespace MathNet.Numerics.LinearAlgebra.Double
[Serializable] [Serializable]
public class DenseMatrix : Matrix public class DenseMatrix : Matrix
{ {
readonly DenseColumnMajorMatrixStorage<double> _storage;
/// <summary> /// <summary>
/// Number of rows. /// Number of rows.
/// </summary> /// </summary>
/// <remarks>Using this instead of the RowCount property to speed up calculating /// <remarks>Using this instead of the RowCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _rowCount; readonly int _rowCount;
/// <summary> /// <summary>
/// Number of columns. /// Number of columns.
/// </summary> /// </summary>
/// <remarks>Using this instead of the ColumnCount property to speed up calculating /// <remarks>Using this instead of the ColumnCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _columnCount; readonly int _columnCount;
/// <summary>
/// Gets the matrix's data.
/// </summary>
/// <value>The matrix's data.</value>
readonly double[] _data;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size. /// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size.
@ -62,9 +71,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int order) public DenseMatrix(int order)
: base(order) : base(order)
{ {
_rowCount = order; _storage = new DenseColumnMajorMatrixStorage<double>(order, order);
_columnCount = order;
Data = new double[order * order]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns) public DenseMatrix(int rows, int columns)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<double>(rows, columns);
_columnCount = columns;
Data = new double[rows * columns]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns, double value) public DenseMatrix(int rows, int columns, double value)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<double>(rows, columns);
_columnCount = columns;
Data = new double[rows * columns]; _rowCount = _storage.RowCount;
for (var i = 0; i < Data.Length; i++) _columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _data.Length; i++)
{ {
Data[i] = value; _data[i] = value;
} }
} }
@ -116,9 +132,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns, double[] array) public DenseMatrix(int rows, int columns, double[] array)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<double>(rows, columns, array);
_columnCount = columns;
Data = array; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -129,15 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(double[,] array) public DenseMatrix(double[,] array)
: base(array.GetLength(0), array.GetLength(1)) : base(array.GetLength(0), array.GetLength(1))
{ {
_rowCount = array.GetLength(0); _storage = new DenseColumnMajorMatrixStorage<double>(array.GetLength(0), array.GetLength(1));
_columnCount = array.GetLength(1);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
Data = new double[_rowCount * _columnCount];
for (var i = 0; i < _rowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
for (var j = 0; j < _columnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
Data[(j * _rowCount) + i] = array[i, j]; _data[(j * _rowCount) + i] = array[i, j];
} }
} }
} }
@ -148,8 +168,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <value>The matrix's data.</value> /// <value>The matrix's data.</value>
public double[] Data public double[] Data
{ {
get; get { return _data; }
private set;
} }
/// <summary> /// <summary>
@ -196,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override void CopyTo(Matrix<double> target) public override void CopyTo(Matrix<double> target)
{ {
var denseTarget = target as DenseMatrix; var denseTarget = target as DenseMatrix;
if (denseTarget == null) if (denseTarget != null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
{ {
_storage.CopyTo(denseTarget._storage);
return; return;
} }
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) base.CopyTo(target);
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Buffer.BlockCopy(Data, 0, denseTarget.Data, 0, Data.Length * Constants.SizeOfDouble);
} }
/// <summary> /// <summary>
@ -241,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
set set
@ -256,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
} }
@ -274,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
public override double At(int row, int column) public override double At(int row, int column)
{ {
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
/// <summary> /// <summary>
@ -291,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </param> /// </param>
public override void At(int row, int column, double value) public override void At(int row, int column, double value)
{ {
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
/// <summary> /// <summary>
@ -299,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary> /// </summary>
public override void Clear() public override void Clear()
{ {
Array.Clear(Data, 0, Data.Length); Array.Clear(_data, 0, _data.Length);
} }
/// <summary> /// <summary>
@ -308,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix<double> Transpose() public override Matrix<double> Transpose()
{ {
var ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
var index = j * RowCount; var index = j * _rowCount;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
ret.Data[(i * ColumnCount) + j] = Data[index + i]; ret._data[(i * _columnCount) + j] = _data[index + i];
} }
} }
@ -325,21 +334,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The L1 norm of the matrix.</returns> /// <returns>The L1 norm of the matrix.</returns>
public override double L1Norm() public override double L1Norm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the Frobenius norm of this matrix.</summary> /// <summary>Calculates the Frobenius norm of this matrix.</summary>
/// <returns>The Frobenius norm of this matrix.</returns> /// <returns>The Frobenius norm of this matrix.</returns>
public override double FrobeniusNorm() public override double FrobeniusNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the infinity norm of this matrix.</summary> /// <summary>Calculates the infinity norm of this matrix.</summary>
/// <returns>The infinity norm of this matrix.</returns> /// <returns>The infinity norm of this matrix.</returns>
public override double InfinityNorm() public override double InfinityNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _data);
} }
#region Static constructors for special matrices. #region Static constructors for special matrices.
@ -357,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var m = new DenseMatrix(order); var m = new DenseMatrix(order);
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
m.Data[(i * order) + i] = 1.0; m._data[(i * order) + i] = 1.0;
} }
return m; return m;
@ -382,7 +391,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.AddArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -401,7 +410,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.SubtractArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -419,7 +428,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(scalar, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(scalar, _data, denseResult._data);
} }
} }
@ -443,9 +452,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -471,17 +480,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0, 0.0,
denseResult.Data); denseResult._data);
} }
} }
@ -502,17 +511,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0, 0.0,
denseResult.Data); denseResult._data);
} }
} }
@ -536,9 +545,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -564,17 +573,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0, 1.0,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0, 0.0,
denseResult.Data); denseResult._data);
} }
} }
@ -592,7 +601,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(-1, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(-1, _data, denseResult._data);
} }
} }
@ -612,7 +621,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -632,7 +641,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseDivideArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseDivideArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -657,9 +666,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
CommonParallel.For( CommonParallel.For(
0, 0,
Data.Length, _data.Length,
index => denseResult.Data[index] %= divisor); index => denseResult._data[index] %= divisor);
} }
} }
@ -670,15 +679,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If the matrix is not square</exception> /// <exception cref="ArgumentException">If the matrix is not square</exception>
public override double Trace() public override double Trace()
{ {
if (RowCount != ColumnCount) if (_rowCount != _columnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var sum = 0.0; var sum = 0.0;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
sum += Data[(i * RowCount) + i]; sum += _data[(i * _rowCount) + i];
} }
return sum; return sum;
@ -707,7 +716,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -754,7 +763,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -835,7 +844,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("rightSide"); throw new ArgumentNullException("rightSide");
} }
if (leftSide.ColumnCount != rightSide.RowCount) if (leftSide._columnCount != rightSide._rowCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }

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

@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
using Algorithms.LinearAlgebra; using Algorithms.LinearAlgebra;
using Generic; using Generic;
using Properties; using Properties;
using Storage;
using Threading; using Threading;
/// <summary> /// <summary>
@ -38,19 +39,27 @@ namespace MathNet.Numerics.LinearAlgebra.Single
[Serializable] [Serializable]
public class DenseMatrix : Matrix public class DenseMatrix : Matrix
{ {
readonly DenseColumnMajorMatrixStorage<float> _storage;
/// <summary> /// <summary>
/// Number of rows. /// Number of rows.
/// </summary> /// </summary>
/// <remarks>Using this instead of the RowCount property to speed up calculating /// <remarks>Using this instead of the RowCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _rowCount; readonly int _rowCount;
/// <summary> /// <summary>
/// Number of columns. /// Number of columns.
/// </summary> /// </summary>
/// <remarks>Using this instead of the ColumnCount property to speed up calculating /// <remarks>Using this instead of the ColumnCount property to speed up calculating
/// a matrix index in the data array.</remarks> /// a matrix index in the data array.</remarks>
private readonly int _columnCount; readonly int _columnCount;
/// <summary>
/// Gets the matrix's data.
/// </summary>
/// <value>The matrix's data.</value>
readonly float[] _data;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size. /// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size.
@ -62,9 +71,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(int order) public DenseMatrix(int order)
: base(order) : base(order)
{ {
_rowCount = order; _storage = new DenseColumnMajorMatrixStorage<float>(order, order);
_columnCount = order;
Data = new float[order * order]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(int rows, int columns) public DenseMatrix(int rows, int columns)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<float>(rows, columns);
_columnCount = columns;
Data = new float[rows * columns]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(int rows, int columns, float value) public DenseMatrix(int rows, int columns, float value)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<float>(rows, columns);
_columnCount = columns;
Data = new float[rows * columns]; _rowCount = _storage.RowCount;
for (var i = 0; i < Data.Length; i++) _columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _data.Length; i++)
{ {
Data[i] = value; _data[i] = value;
} }
} }
@ -116,9 +132,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(int rows, int columns, float[] array) public DenseMatrix(int rows, int columns, float[] array)
: base(rows, columns) : base(rows, columns)
{ {
_rowCount = rows; _storage = new DenseColumnMajorMatrixStorage<float>(rows, columns, array);
_columnCount = columns;
Data = array; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
} }
/// <summary> /// <summary>
@ -129,14 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(float[,] array) public DenseMatrix(float[,] array)
: base(array.GetLength(0), array.GetLength(1)) : base(array.GetLength(0), array.GetLength(1))
{ {
_rowCount = array.GetLength(0); _storage = new DenseColumnMajorMatrixStorage<float>(array.GetLength(0), array.GetLength(1));
_columnCount = array.GetLength(1);
Data = new float[_rowCount * _columnCount]; _rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _rowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
for (var j = 0; j < _columnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
Data[(j * _rowCount) + i] = array[i, j]; _data[(j * _rowCount) + i] = array[i, j];
} }
} }
} }
@ -147,8 +168,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <value>The matrix's data.</value> /// <value>The matrix's data.</value>
public float[] Data public float[] Data
{ {
get; get { return _data; }
private set;
} }
/// <summary> /// <summary>
@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public override void CopyTo(Matrix<float> target) public override void CopyTo(Matrix<float> target)
{ {
var denseTarget = target as DenseMatrix; var denseTarget = target as DenseMatrix;
if (denseTarget == null) if (denseTarget != null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
{ {
_storage.CopyTo(denseTarget._storage);
return; return;
} }
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) base.CopyTo(target);
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Buffer.BlockCopy(Data, 0, denseTarget.Data, 0, Data.Length * Constants.SizeOfFloat);
} }
/// <summary> /// <summary>
@ -240,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
set set
@ -255,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentOutOfRangeException("column"); throw new ArgumentOutOfRangeException("column");
} }
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
} }
@ -273,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </returns> /// </returns>
public override float At(int row, int column) public override float At(int row, int column)
{ {
return Data[(column * _rowCount) + row]; return _data[(column * _rowCount) + row];
} }
/// <summary> /// <summary>
@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </param> /// </param>
public override void At(int row, int column, float value) public override void At(int row, int column, float value)
{ {
Data[(column * _rowCount) + row] = value; _data[(column * _rowCount) + row] = value;
} }
/// <summary> /// <summary>
@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </summary> /// </summary>
public override void Clear() public override void Clear()
{ {
Array.Clear(Data, 0, Data.Length); Array.Clear(_data, 0, _data.Length);
} }
/// <summary> /// <summary>
@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <returns>The transpose of this matrix.</returns> /// <returns>The transpose of this matrix.</returns>
public override Matrix<float> Transpose() public override Matrix<float> Transpose()
{ {
var ret = new DenseMatrix(ColumnCount, RowCount); var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < ColumnCount; j++) for (var j = 0; j < _columnCount; j++)
{ {
var index = j * RowCount; var index = j * _rowCount;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
ret.Data[(i * ColumnCount) + j] = Data[index + i]; ret._data[(i * _columnCount) + j] = _data[index + i];
} }
} }
@ -324,21 +334,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <returns>The L1 norm of the matrix.</returns> /// <returns>The L1 norm of the matrix.</returns>
public override float L1Norm() public override float L1Norm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the Frobenius norm of this matrix.</summary> /// <summary>Calculates the Frobenius norm of this matrix.</summary>
/// <returns>The Frobenius norm of this matrix.</returns> /// <returns>The Frobenius norm of this matrix.</returns>
public override float FrobeniusNorm() public override float FrobeniusNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data);
} }
/// <summary>Calculates the infinity norm of this matrix.</summary> /// <summary>Calculates the infinity norm of this matrix.</summary>
/// <returns>The infinity norm of this matrix.</returns> /// <returns>The infinity norm of this matrix.</returns>
public override float InfinityNorm() public override float InfinityNorm()
{ {
return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, RowCount, ColumnCount, Data); return Control.LinearAlgebraProvider.MatrixNorm(Norm.InfinityNorm, _rowCount, _columnCount, _data);
} }
#region Static constructors for special matrices. #region Static constructors for special matrices.
@ -356,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
var m = new DenseMatrix(order); var m = new DenseMatrix(order);
for (var i = 0; i < order; i++) for (var i = 0; i < order; i++)
{ {
m.Data[(i * order) + i] = 1.0f; m._data[(i * order) + i] = 1.0f;
} }
return m; return m;
@ -381,7 +391,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
Control.LinearAlgebraProvider.AddArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.AddArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -400,7 +410,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
Control.LinearAlgebraProvider.SubtractArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.SubtractArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -418,7 +428,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(scalar, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(scalar, _data, denseResult._data);
} }
} }
@ -442,9 +452,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -470,17 +480,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0f, 0.0f,
denseResult.Data); denseResult._data);
} }
} }
@ -501,17 +511,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0f, 0.0f,
denseResult.Data); denseResult._data);
} }
} }
@ -535,9 +545,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseRight.Data, denseRight.Data,
denseRight.Count, denseRight.Count,
1, 1,
@ -563,17 +573,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
else else
{ {
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate( Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose, Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose, Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f, 1.0f,
Data, _data,
RowCount, _rowCount,
ColumnCount, _columnCount,
denseOther.Data, denseOther._data,
denseOther.RowCount, denseOther._rowCount,
denseOther.ColumnCount, denseOther._columnCount,
0.0f, 0.0f,
denseResult.Data); denseResult._data);
} }
} }
@ -591,7 +601,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
Control.LinearAlgebraProvider.ScaleArray(-1, Data, denseResult.Data); Control.LinearAlgebraProvider.ScaleArray(-1, _data, denseResult._data);
} }
} }
@ -611,7 +621,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseMultiplyArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseMultiplyArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -631,7 +641,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
} }
else else
{ {
Control.LinearAlgebraProvider.PointWiseDivideArrays(Data, denseOther.Data, denseResult.Data); Control.LinearAlgebraProvider.PointWiseDivideArrays(_data, denseOther._data, denseResult._data);
} }
} }
@ -657,8 +667,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single
CommonParallel.For( CommonParallel.For(
0, 0,
Data.Length, _data.Length,
index => denseResult.Data[index] %= divisor); index => denseResult._data[index] %= divisor);
} }
} }
@ -669,15 +679,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <exception cref="ArgumentException">If the matrix is not square</exception> /// <exception cref="ArgumentException">If the matrix is not square</exception>
public override float Trace() public override float Trace()
{ {
if (RowCount != ColumnCount) if (_rowCount != _columnCount)
{ {
throw new ArgumentException(Resources.ArgumentMatrixSquare); throw new ArgumentException(Resources.ArgumentMatrixSquare);
} }
var sum = 0.0f; var sum = 0.0f;
for (var i = 0; i < RowCount; i++) for (var i = 0; i < _rowCount; i++)
{ {
sum += Data[(i * RowCount) + i]; sum += _data[(i * _rowCount) + i];
} }
return sum; return sum;
@ -706,7 +716,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -753,7 +763,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentNullException("leftSide"); throw new ArgumentNullException("leftSide");
} }
if (leftSide.RowCount != rightSide.RowCount || leftSide.ColumnCount != rightSide.ColumnCount) if (leftSide._rowCount != rightSide._rowCount || leftSide._columnCount != rightSide._columnCount)
{ {
throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentOutOfRangeException>(leftSide, rightSide);
} }
@ -834,7 +844,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentNullException("rightSide"); throw new ArgumentNullException("rightSide");
} }
if (leftSide.ColumnCount != rightSide.RowCount) if (leftSide._columnCount != rightSide._rowCount)
{ {
throw DimensionsDontMatch<ArgumentException>(leftSide, rightSide); throw DimensionsDontMatch<ArgumentException>(leftSide, rightSide);
} }

49
src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs

@ -0,0 +1,49 @@
using System;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
internal class DenseColumnMajorMatrixStorage<T>
where T : struct, IEquatable<T>, IFormattable
{
public int RowCount { get; private set; }
public int ColumnCount { get; private set; }
public T[] Data { get; private set; }
internal DenseColumnMajorMatrixStorage(int rows, int columns)
{
RowCount = rows;
ColumnCount = columns;
Data = new T[rows * columns];
}
internal DenseColumnMajorMatrixStorage(int rows, int columns, T[] data)
{
RowCount = rows;
ColumnCount = columns;
Data = data;
}
public void CopyTo(DenseColumnMajorMatrixStorage<T> target)
{
if (ReferenceEquals(this, target))
{
return;
}
if (target == null)
{
throw new ArgumentNullException("target");
}
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
{
var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount);
throw new ArgumentException(message, "target");
}
//Buffer.BlockCopy(Data, 0, target.Data, 0, Data.Length * System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)));
Array.Copy(Data, 0, target.Data, 0, Data.Length);
}
}
}

1
src/Numerics/Numerics.csproj

@ -330,6 +330,7 @@
<Compile Include="LinearAlgebra\Generic\Matrix.cs" /> <Compile Include="LinearAlgebra\Generic\Matrix.cs" />
<Compile Include="LinearAlgebra\Generic\Vector.cs" /> <Compile Include="LinearAlgebra\Generic\Vector.cs" />
<Compile Include="LinearAlgebra\Single\Vector.cs" /> <Compile Include="LinearAlgebra\Single\Vector.cs" />
<Compile Include="LinearAlgebra\Storage\DenseColumnMajorMatrixStorage.cs" />
<Compile Include="Permutation.cs" /> <Compile Include="Permutation.cs" />
<Compile Include="Distributions\Continuous\Beta.cs" /> <Compile Include="Distributions\Continuous\Beta.cs" />
<Compile Include="Distributions\Continuous\ContinuousUniform.cs" /> <Compile Include="Distributions\Continuous\ContinuousUniform.cs" />

Loading…
Cancel
Save