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 Generic;
using Properties;
using Storage;
/// <summary>
/// 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]
public class DenseMatrix : Matrix
{
readonly DenseColumnMajorMatrixStorage<Complex> _storage;
/// <summary>
/// Number of rows.
/// </summary>
/// <remarks>Using this instead of the RowCount property to speed up calculating
/// a matrix index in the data array.</remarks>
private readonly int _rowCount;
readonly int _rowCount;
/// <summary>
/// Number of columns.
/// </summary>
/// <remarks>Using this instead of the ColumnCount property to speed up calculating
/// 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>
/// 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)
: base(order)
{
_rowCount = order;
_columnCount = order;
Data = new Complex[order * order];
_storage = new DenseColumnMajorMatrixStorage<Complex>(order, order);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(int rows, int columns)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new Complex[rows * columns];
_storage = new DenseColumnMajorMatrixStorage<Complex>(rows, columns);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(int rows, int columns, Complex value)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new Complex[rows * columns];
for (var i = 0; i < Data.Length; i++)
_storage = new DenseColumnMajorMatrixStorage<Complex>(rows, columns);
_rowCount = _storage.RowCount;
_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)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = array;
_storage = new DenseColumnMajorMatrixStorage<Complex>(rows, columns, array);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -129,14 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public DenseMatrix(Complex[,] array)
: base(array.GetLength(0), array.GetLength(1))
{
_rowCount = array.GetLength(0);
_columnCount = array.GetLength(1);
Data = new Complex[_rowCount * _columnCount];
_storage = new DenseColumnMajorMatrixStorage<Complex>(array.GetLength(0), array.GetLength(1));
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _rowCount; i++)
{
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>
public Complex[] Data
{
get;
private set;
get { return _data; }
}
/// <summary>
@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public override void CopyTo(Matrix<Complex> target)
{
var denseTarget = target as DenseMatrix;
if (denseTarget == null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
if (denseTarget != null)
{
_storage.CopyTo(denseTarget._storage);
return;
}
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Array.Copy(Data, 0, denseTarget.Data, 0, Data.Length);
base.CopyTo(target);
}
/// <summary>
@ -240,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentOutOfRangeException("column");
}
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
set
@ -255,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentOutOfRangeException("column");
}
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
}
@ -273,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </returns>
public override Complex At(int row, int column)
{
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
/// <summary>
@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </param>
public override void At(int row, int column, Complex value)
{
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
/// <summary>
@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// </summary>
public override void Clear()
{
Array.Clear(Data, 0, Data.Length);
Array.Clear(_data, 0, _data.Length);
}
/// <summary>
@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <returns>The transpose of this matrix.</returns>
public override Matrix<Complex> Transpose()
{
var ret = new DenseMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < _columnCount; j++)
{
var index = j * RowCount;
for (var i = 0; i < RowCount; i++)
var index = j * _rowCount;
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>
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>
/// <returns>The Frobenius norm of this matrix.</returns>
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>
/// <returns>The infinity norm of this matrix.</returns>
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.
@ -356,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
var m = new DenseMatrix(order);
for (var i = 0; i < order; i++)
{
m.Data[(i * order) + i] = 1.0;
m._data[(i * order) + i] = 1.0;
}
return m;
@ -378,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
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,
1.0,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -430,17 +440,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0,
denseResult._data);
}
}
@ -461,17 +471,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose,
1.0,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0,
denseResult._data);
}
}
@ -495,9 +505,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -523,17 +533,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
else
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
Data,
RowCount,
ColumnCount,
denseOther.Data,
denseOther.RowCount,
denseOther.ColumnCount,
0.0,
denseResult.Data);
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0,
denseResult._data);
}
}
@ -551,7 +561,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
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
{
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
{
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
{
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
{
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>
public override Matrix<Complex> ConjugateTranspose()
{
var ret = new DenseMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < _columnCount; j++)
{
var index = j * RowCount;
for (var i = 0; i < RowCount; i++)
var index = j * _rowCount;
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>
public override Complex Trace()
{
if (RowCount != ColumnCount)
if (_rowCount != _columnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
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;
@ -698,7 +708,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
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);
}
@ -745,7 +755,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
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);
}
@ -826,7 +836,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
throw new ArgumentNullException("rightSide");
}
if (leftSide.ColumnCount != rightSide.RowCount)
if (leftSide._columnCount != rightSide._rowCount)
{
throw DimensionsDontMatch<ArgumentException>(leftSide, rightSide);
}

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

@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
using Generic;
using Numerics;
using Properties;
using Storage;
/// <summary>
/// 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]
public class DenseMatrix : Matrix
{
readonly DenseColumnMajorMatrixStorage<Complex32> _storage;
/// <summary>
/// Number of rows.
/// </summary>
@ -52,6 +55,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// a matrix index in the data array.</remarks>
private readonly int _columnCount;
/// <summary>
/// Gets the matrix's data.
/// </summary>
/// <value>The matrix's data.</value>
readonly Complex32[] _data;
/// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class. This matrix is square with a given size.
/// </summary>
@ -62,9 +71,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(int order)
: base(order)
{
_rowCount = order;
_columnCount = order;
Data = new Complex32[order * order];
_storage = new DenseColumnMajorMatrixStorage<Complex32>(order, order);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(int rows, int columns)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new Complex32[rows * columns];
_storage = new DenseColumnMajorMatrixStorage<Complex32>(rows, columns);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(int rows, int columns, Complex32 value)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new Complex32[rows * columns];
for (var i = 0; i < Data.Length; i++)
_storage = new DenseColumnMajorMatrixStorage<Complex32>(rows, columns);
_rowCount = _storage.RowCount;
_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)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = array;
_storage = new DenseColumnMajorMatrixStorage<Complex32>(rows, columns, array);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -129,14 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public DenseMatrix(Complex32[,] array)
: base(array.GetLength(0), array.GetLength(1))
{
_rowCount = array.GetLength(0);
_columnCount = array.GetLength(1);
Data = new Complex32[_rowCount * _columnCount];
_storage = new DenseColumnMajorMatrixStorage<Complex32>(array.GetLength(0), array.GetLength(1));
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _rowCount; i++)
{
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>
public Complex32[] Data
{
get;
private set;
get { return _data; }
}
/// <summary>
@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public override void CopyTo(Matrix<Complex32> target)
{
var denseTarget = target as DenseMatrix;
if (denseTarget == null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
if (denseTarget != null)
{
_storage.CopyTo(denseTarget._storage);
return;
}
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Array.Copy(Data, 0, denseTarget.Data, 0, Data.Length);
base.CopyTo(target);
}
/// <summary>
@ -240,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentOutOfRangeException("column");
}
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
set
@ -255,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentOutOfRangeException("column");
}
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
}
@ -273,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </returns>
public override Complex32 At(int row, int column)
{
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
/// <summary>
@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </param>
public override void At(int row, int column, Complex32 value)
{
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
/// <summary>
@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// </summary>
public override void Clear()
{
Array.Clear(Data, 0, Data.Length);
Array.Clear(_data, 0, _data.Length);
}
/// <summary>
@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <returns>The transpose of this matrix.</returns>
public override Matrix<Complex32> Transpose()
{
var ret = new DenseMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < _columnCount; j++)
{
var index = j * RowCount;
for (var i = 0; i < RowCount; i++)
var index = j * _rowCount;
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>
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>
/// <returns>The Frobenius norm of this matrix.</returns>
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>
/// <returns>The infinity norm of this matrix.</returns>
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.
@ -356,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
var m = new DenseMatrix(order);
for (var i = 0; i < order; i++)
{
m.Data[(i * order) + i] = 1.0f;
m._data[(i * order) + i] = 1.0f;
}
return m;
@ -378,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
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,
1.0f,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -430,17 +440,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0f,
denseResult._data);
}
}
@ -461,17 +471,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose,
1.0f,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0f,
denseResult._data);
}
}
@ -495,9 +505,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -523,17 +533,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
else
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
Data,
RowCount,
ColumnCount,
denseOther.Data,
denseOther.RowCount,
denseOther.ColumnCount,
0.0f,
denseResult.Data);
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0f,
denseResult._data);
}
}
@ -551,7 +561,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
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
{
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
{
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
{
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
{
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>
public override Matrix<Complex32> ConjugateTranspose()
{
var ret = new DenseMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < _columnCount; j++)
{
var index = j * RowCount;
for (var i = 0; i < RowCount; i++)
var index = j * _rowCount;
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>
public override Complex32 Trace()
{
if (RowCount != ColumnCount)
if (_rowCount != _columnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
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;
@ -698,7 +708,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
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);
}
@ -745,7 +755,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
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);
}
@ -826,7 +836,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
throw new ArgumentNullException("rightSide");
}
if (leftSide.ColumnCount != rightSide.RowCount)
if (leftSide._columnCount != rightSide._rowCount)
{
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 Generic;
using Properties;
using Storage;
using Threading;
/// <summary>
@ -38,19 +39,27 @@ namespace MathNet.Numerics.LinearAlgebra.Double
[Serializable]
public class DenseMatrix : Matrix
{
readonly DenseColumnMajorMatrixStorage<double> _storage;
/// <summary>
/// Number of rows.
/// </summary>
/// <remarks>Using this instead of the RowCount property to speed up calculating
/// a matrix index in the data array.</remarks>
private readonly int _rowCount;
readonly int _rowCount;
/// <summary>
/// Number of columns.
/// </summary>
/// <remarks>Using this instead of the ColumnCount property to speed up calculating
/// 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>
/// 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)
: base(order)
{
_rowCount = order;
_columnCount = order;
Data = new double[order * order];
_storage = new DenseColumnMajorMatrixStorage<double>(order, order);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new double[rows * columns];
_storage = new DenseColumnMajorMatrixStorage<double>(rows, columns);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(int rows, int columns, double value)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new double[rows * columns];
for (var i = 0; i < Data.Length; i++)
_storage = new DenseColumnMajorMatrixStorage<double>(rows, columns);
_rowCount = _storage.RowCount;
_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)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = array;
_storage = new DenseColumnMajorMatrixStorage<double>(rows, columns, array);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -129,15 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public DenseMatrix(double[,] array)
: base(array.GetLength(0), array.GetLength(1))
{
_rowCount = array.GetLength(0);
_columnCount = array.GetLength(1);
_storage = new DenseColumnMajorMatrixStorage<double>(array.GetLength(0), 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 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>
public double[] Data
{
get;
private set;
get { return _data; }
}
/// <summary>
@ -196,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override void CopyTo(Matrix<double> target)
{
var denseTarget = target as DenseMatrix;
if (denseTarget == null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
if (denseTarget != null)
{
_storage.CopyTo(denseTarget._storage);
return;
}
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Buffer.BlockCopy(Data, 0, denseTarget.Data, 0, Data.Length * Constants.SizeOfDouble);
base.CopyTo(target);
}
/// <summary>
@ -241,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("column");
}
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
set
@ -256,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("column");
}
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
}
@ -274,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns>
public override double At(int row, int column)
{
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
/// <summary>
@ -291,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </param>
public override void At(int row, int column, double value)
{
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
/// <summary>
@ -299,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
public override void Clear()
{
Array.Clear(Data, 0, Data.Length);
Array.Clear(_data, 0, _data.Length);
}
/// <summary>
@ -308,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>The transpose of this matrix.</returns>
public override Matrix<double> Transpose()
{
var ret = new DenseMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < _columnCount; j++)
{
var index = j * RowCount;
for (var i = 0; i < RowCount; i++)
var index = j * _rowCount;
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>
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>
/// <returns>The Frobenius norm of this matrix.</returns>
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>
/// <returns>The infinity norm of this matrix.</returns>
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.
@ -357,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var m = new DenseMatrix(order);
for (var i = 0; i < order; i++)
{
m.Data[(i * order) + i] = 1.0;
m._data[(i * order) + i] = 1.0;
}
return m;
@ -382,7 +391,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
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
{
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
{
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,
1.0,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -471,17 +480,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0,
denseResult._data);
}
}
@ -502,17 +511,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose,
1.0,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0,
denseResult._data);
}
}
@ -536,9 +545,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -564,17 +573,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
else
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
Data,
RowCount,
ColumnCount,
denseOther.Data,
denseOther.RowCount,
denseOther.ColumnCount,
0.0,
denseResult.Data);
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0,
denseResult._data);
}
}
@ -592,7 +601,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
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
{
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
{
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(
0,
Data.Length,
index => denseResult.Data[index] %= divisor);
0,
_data.Length,
index => denseResult._data[index] %= divisor);
}
}
@ -670,15 +679,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <exception cref="ArgumentException">If the matrix is not square</exception>
public override double Trace()
{
if (RowCount != ColumnCount)
if (_rowCount != _columnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
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;
@ -707,7 +716,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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);
}
@ -754,7 +763,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
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);
}
@ -835,7 +844,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentNullException("rightSide");
}
if (leftSide.ColumnCount != rightSide.RowCount)
if (leftSide._columnCount != rightSide._rowCount)
{
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 Generic;
using Properties;
using Storage;
using Threading;
/// <summary>
@ -38,19 +39,27 @@ namespace MathNet.Numerics.LinearAlgebra.Single
[Serializable]
public class DenseMatrix : Matrix
{
readonly DenseColumnMajorMatrixStorage<float> _storage;
/// <summary>
/// Number of rows.
/// </summary>
/// <remarks>Using this instead of the RowCount property to speed up calculating
/// a matrix index in the data array.</remarks>
private readonly int _rowCount;
readonly int _rowCount;
/// <summary>
/// Number of columns.
/// </summary>
/// <remarks>Using this instead of the ColumnCount property to speed up calculating
/// 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>
/// 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)
: base(order)
{
_rowCount = order;
_columnCount = order;
Data = new float[order * order];
_storage = new DenseColumnMajorMatrixStorage<float>(order, order);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -79,9 +90,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(int rows, int columns)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new float[rows * columns];
_storage = new DenseColumnMajorMatrixStorage<float>(rows, columns);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -97,12 +110,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(int rows, int columns, float value)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = new float[rows * columns];
for (var i = 0; i < Data.Length; i++)
_storage = new DenseColumnMajorMatrixStorage<float>(rows, columns);
_rowCount = _storage.RowCount;
_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)
: base(rows, columns)
{
_rowCount = rows;
_columnCount = columns;
Data = array;
_storage = new DenseColumnMajorMatrixStorage<float>(rows, columns, array);
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
}
/// <summary>
@ -129,14 +147,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public DenseMatrix(float[,] array)
: base(array.GetLength(0), array.GetLength(1))
{
_rowCount = array.GetLength(0);
_columnCount = array.GetLength(1);
Data = new float[_rowCount * _columnCount];
_storage = new DenseColumnMajorMatrixStorage<float>(array.GetLength(0), array.GetLength(1));
_rowCount = _storage.RowCount;
_columnCount = _storage.ColumnCount;
_data = _storage.Data;
for (var i = 0; i < _rowCount; i++)
{
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>
public float[] Data
{
get;
private set;
get { return _data; }
}
/// <summary>
@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single
public override void CopyTo(Matrix<float> target)
{
var denseTarget = target as DenseMatrix;
if (denseTarget == null)
{
base.CopyTo(target);
return;
}
if (ReferenceEquals(this, target))
if (denseTarget != null)
{
_storage.CopyTo(denseTarget._storage);
return;
}
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
{
throw DimensionsDontMatch<ArgumentException>(this, target, "target");
}
Buffer.BlockCopy(Data, 0, denseTarget.Data, 0, Data.Length * Constants.SizeOfFloat);
base.CopyTo(target);
}
/// <summary>
@ -240,7 +250,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentOutOfRangeException("column");
}
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
set
@ -255,7 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentOutOfRangeException("column");
}
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
}
@ -273,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </returns>
public override float At(int row, int column)
{
return Data[(column * _rowCount) + row];
return _data[(column * _rowCount) + row];
}
/// <summary>
@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </param>
public override void At(int row, int column, float value)
{
Data[(column * _rowCount) + row] = value;
_data[(column * _rowCount) + row] = value;
}
/// <summary>
@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// </summary>
public override void Clear()
{
Array.Clear(Data, 0, Data.Length);
Array.Clear(_data, 0, _data.Length);
}
/// <summary>
@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <returns>The transpose of this matrix.</returns>
public override Matrix<float> Transpose()
{
var ret = new DenseMatrix(ColumnCount, RowCount);
for (var j = 0; j < ColumnCount; j++)
var ret = new DenseMatrix(_columnCount, _rowCount);
for (var j = 0; j < _columnCount; j++)
{
var index = j * RowCount;
for (var i = 0; i < RowCount; i++)
var index = j * _rowCount;
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>
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>
/// <returns>The Frobenius norm of this matrix.</returns>
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>
/// <returns>The infinity norm of this matrix.</returns>
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.
@ -356,7 +366,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
var m = new DenseMatrix(order);
for (var i = 0; i < order; i++)
{
m.Data[(i * order) + i] = 1.0f;
m._data[(i * order) + i] = 1.0f;
}
return m;
@ -381,7 +391,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
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
{
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
{
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,
1.0f,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -470,17 +480,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0f,
denseResult._data);
}
}
@ -501,17 +511,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
else
{
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);
Algorithms.LinearAlgebra.Transpose.DontTranspose,
Algorithms.LinearAlgebra.Transpose.Transpose,
1.0f,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0f,
denseResult._data);
}
}
@ -535,9 +545,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
Data,
RowCount,
ColumnCount,
_data,
_rowCount,
_columnCount,
denseRight.Data,
denseRight.Count,
1,
@ -563,17 +573,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single
else
{
Control.LinearAlgebraProvider.MatrixMultiplyWithUpdate(
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
Data,
RowCount,
ColumnCount,
denseOther.Data,
denseOther.RowCount,
denseOther.ColumnCount,
0.0f,
denseResult.Data);
Algorithms.LinearAlgebra.Transpose.Transpose,
Algorithms.LinearAlgebra.Transpose.DontTranspose,
1.0f,
_data,
_rowCount,
_columnCount,
denseOther._data,
denseOther._rowCount,
denseOther._columnCount,
0.0f,
denseResult._data);
}
}
@ -591,7 +601,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
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
{
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
{
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(
0,
Data.Length,
index => denseResult.Data[index] %= divisor);
_data.Length,
index => denseResult._data[index] %= divisor);
}
}
@ -669,15 +679,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <exception cref="ArgumentException">If the matrix is not square</exception>
public override float Trace()
{
if (RowCount != ColumnCount)
if (_rowCount != _columnCount)
{
throw new ArgumentException(Resources.ArgumentMatrixSquare);
}
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;
@ -706,7 +716,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
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);
}
@ -753,7 +763,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
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);
}
@ -834,7 +844,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
throw new ArgumentNullException("rightSide");
}
if (leftSide.ColumnCount != rightSide.RowCount)
if (leftSide._columnCount != rightSide._rowCount)
{
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\Vector.cs" />
<Compile Include="LinearAlgebra\Single\Vector.cs" />
<Compile Include="LinearAlgebra\Storage\DenseColumnMajorMatrixStorage.cs" />
<Compile Include="Permutation.cs" />
<Compile Include="Distributions\Continuous\Beta.cs" />
<Compile Include="Distributions\Continuous\ContinuousUniform.cs" />

Loading…
Cancel
Save