diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index 60015996..02318a69 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex using Algorithms.LinearAlgebra; using Generic; using Properties; + using Storage; /// /// 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 _storage; + /// /// Number of rows. /// /// Using this instead of the RowCount property to speed up calculating /// a matrix index in the data array. - private readonly int _rowCount; + readonly int _rowCount; /// /// Number of columns. /// /// Using this instead of the ColumnCount property to speed up calculating /// a matrix index in the data array. - private readonly int _columnCount; + readonly int _columnCount; + + /// + /// Gets the matrix's data. + /// + /// The matrix's data. + readonly Complex[] _data; /// /// Initializes a new instance of the 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(order, order); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(rows, columns); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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(rows, columns, array); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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 /// The matrix's data. public Complex[] Data { - get; - private set; + get { return _data; } } /// @@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex public override void CopyTo(Matrix 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(this, target, "target"); - } - - Array.Copy(Data, 0, denseTarget.Data, 0, Data.Length); + base.CopyTo(target); } /// @@ -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 /// public override Complex At(int row, int column) { - return Data[(column * _rowCount) + row]; + return _data[(column * _rowCount) + row]; } /// @@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// public override void At(int row, int column, Complex value) { - Data[(column * _rowCount) + row] = value; + _data[(column * _rowCount) + row] = value; } /// @@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// public override void Clear() { - Array.Clear(Data, 0, Data.Length); + Array.Clear(_data, 0, _data.Length); } /// @@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The transpose of this matrix. public override Matrix 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 /// The L1 norm of the matrix. public override Complex L1Norm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data); } /// Calculates the Frobenius norm of this matrix. /// The Frobenius norm of this matrix. public override Complex FrobeniusNorm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data); } /// Calculates the infinity norm of this matrix. /// The infinity norm of this matrix. 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 /// The conjugate transpose of this matrix. public override Matrix 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 /// If the matrix is not square 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(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(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(leftSide, rightSide); } diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index a19dc67a..3f644992 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 using Generic; using Numerics; using Properties; + using Storage; /// /// 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 _storage; + /// /// Number of rows. /// @@ -52,6 +55,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// a matrix index in the data array. private readonly int _columnCount; + /// + /// Gets the matrix's data. + /// + /// The matrix's data. + readonly Complex32[] _data; + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -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(order, order); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(rows, columns); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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(rows, columns, array); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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 /// The matrix's data. public Complex32[] Data { - get; - private set; + get { return _data; } } /// @@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public override void CopyTo(Matrix 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(this, target, "target"); - } - - Array.Copy(Data, 0, denseTarget.Data, 0, Data.Length); + base.CopyTo(target); } /// @@ -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 /// public override Complex32 At(int row, int column) { - return Data[(column * _rowCount) + row]; + return _data[(column * _rowCount) + row]; } /// @@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// public override void At(int row, int column, Complex32 value) { - Data[(column * _rowCount) + row] = value; + _data[(column * _rowCount) + row] = value; } /// @@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// public override void Clear() { - Array.Clear(Data, 0, Data.Length); + Array.Clear(_data, 0, _data.Length); } /// @@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The transpose of this matrix. public override Matrix 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 /// The L1 norm of the matrix. public override Complex32 L1Norm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data); } /// Calculates the Frobenius norm of this matrix. /// The Frobenius norm of this matrix. public override Complex32 FrobeniusNorm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data); } /// Calculates the infinity norm of this matrix. /// The infinity norm of this matrix. 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 /// The conjugate transpose of this matrix. public override Matrix 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 /// If the matrix is not square 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(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(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(leftSide, rightSide); } diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index 4697f324..d120ed15 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/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; /// @@ -38,19 +39,27 @@ namespace MathNet.Numerics.LinearAlgebra.Double [Serializable] public class DenseMatrix : Matrix { + readonly DenseColumnMajorMatrixStorage _storage; + /// /// Number of rows. /// /// Using this instead of the RowCount property to speed up calculating /// a matrix index in the data array. - private readonly int _rowCount; + readonly int _rowCount; /// /// Number of columns. /// /// Using this instead of the ColumnCount property to speed up calculating /// a matrix index in the data array. - private readonly int _columnCount; + readonly int _columnCount; + + /// + /// Gets the matrix's data. + /// + /// The matrix's data. + readonly double[] _data; /// /// Initializes a new instance of the 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(order, order); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(rows, columns); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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(rows, columns, array); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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 /// The matrix's data. public double[] Data { - get; - private set; + get { return _data; } } /// @@ -196,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double public override void CopyTo(Matrix 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(this, target, "target"); - } - - Buffer.BlockCopy(Data, 0, denseTarget.Data, 0, Data.Length * Constants.SizeOfDouble); + base.CopyTo(target); } /// @@ -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 /// public override double At(int row, int column) { - return Data[(column * _rowCount) + row]; + return _data[(column * _rowCount) + row]; } /// @@ -291,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public override void At(int row, int column, double value) { - Data[(column * _rowCount) + row] = value; + _data[(column * _rowCount) + row] = value; } /// @@ -299,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public override void Clear() { - Array.Clear(Data, 0, Data.Length); + Array.Clear(_data, 0, _data.Length); } /// @@ -308,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The transpose of this matrix. public override Matrix 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 /// The L1 norm of the matrix. public override double L1Norm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data); } /// Calculates the Frobenius norm of this matrix. /// The Frobenius norm of this matrix. public override double FrobeniusNorm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data); } /// Calculates the infinity norm of this matrix. /// The infinity norm of this matrix. 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 /// If the matrix is not square 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(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(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(leftSide, rightSide); } diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 494f69f1..227844f1 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/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; /// @@ -38,19 +39,27 @@ namespace MathNet.Numerics.LinearAlgebra.Single [Serializable] public class DenseMatrix : Matrix { + readonly DenseColumnMajorMatrixStorage _storage; + /// /// Number of rows. /// /// Using this instead of the RowCount property to speed up calculating /// a matrix index in the data array. - private readonly int _rowCount; + readonly int _rowCount; /// /// Number of columns. /// /// Using this instead of the ColumnCount property to speed up calculating /// a matrix index in the data array. - private readonly int _columnCount; + readonly int _columnCount; + + /// + /// Gets the matrix's data. + /// + /// The matrix's data. + readonly float[] _data; /// /// Initializes a new instance of the 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(order, order); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(rows, columns); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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(rows, columns, array); + + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; } /// @@ -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(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 /// The matrix's data. public float[] Data { - get; - private set; + get { return _data; } } /// @@ -195,23 +215,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single public override void CopyTo(Matrix 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(this, target, "target"); - } - - Buffer.BlockCopy(Data, 0, denseTarget.Data, 0, Data.Length * Constants.SizeOfFloat); + base.CopyTo(target); } /// @@ -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 /// public override float At(int row, int column) { - return Data[(column * _rowCount) + row]; + return _data[(column * _rowCount) + row]; } /// @@ -290,7 +300,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// public override void At(int row, int column, float value) { - Data[(column * _rowCount) + row] = value; + _data[(column * _rowCount) + row] = value; } /// @@ -298,7 +308,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// public override void Clear() { - Array.Clear(Data, 0, Data.Length); + Array.Clear(_data, 0, _data.Length); } /// @@ -307,13 +317,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The transpose of this matrix. public override Matrix 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 /// The L1 norm of the matrix. public override float L1Norm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.OneNorm, _rowCount, _columnCount, _data); } /// Calculates the Frobenius norm of this matrix. /// The Frobenius norm of this matrix. public override float FrobeniusNorm() { - return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, RowCount, ColumnCount, Data); + return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _data); } /// Calculates the infinity norm of this matrix. /// The infinity norm of this matrix. 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 /// If the matrix is not square 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(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(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(leftSide, rightSide); } diff --git a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs new file mode 100644 index 00000000..b211dfce --- /dev/null +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -0,0 +1,49 @@ +using System; +using MathNet.Numerics.Properties; + +namespace MathNet.Numerics.LinearAlgebra.Storage +{ + internal class DenseColumnMajorMatrixStorage + where T : struct, IEquatable, 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 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); + } + } +} diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 36a3c06e..bf7bfd7d 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -330,6 +330,7 @@ +