diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index 5bcc8265..c3af5888 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -61,6 +61,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The matrix's data. readonly Complex[] _data; + internal DenseColumnMajorMatrixStorage Raw + { + get { return _storage; } + } + + internal DenseMatrix(DenseColumnMajorMatrixStorage storage) + : base(storage) + { + _storage = storage; + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -69,13 +83,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// If is less than one. /// public DenseMatrix(int order) - : base(order) + : this(new DenseColumnMajorMatrixStorage(order, order)) { - _storage = new DenseColumnMajorMatrixStorage(order, order); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -88,13 +97,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The number of columns. /// public DenseMatrix(int rows, int columns) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -108,14 +112,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The value which we assign to each element of the matrix. public DenseMatrix(int rows, int columns, Complex value) - : base(rows, columns) + : this(rows, columns) { - _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; @@ -130,13 +128,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The number of columns. /// The one dimensional array to create this matrix from. This array should store the matrix in column-major order. see: http://en.wikipedia.org/wiki/Row-major_order public DenseMatrix(int rows, int columns, Complex[] array) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns, array)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns, array); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -145,14 +138,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The 2D array to create this matrix from. public DenseMatrix(Complex[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _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++) @@ -162,11 +149,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - internal DenseColumnMajorMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets the matrix's data. /// @@ -222,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 35ec6452..de481cf2 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -54,6 +54,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The matrix's data. readonly Complex[] _data; + internal SparseDiagonalMatrixStorage Raw + { + get { return _storage; } + } + + internal DiagonalMatrix(SparseDiagonalMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -61,11 +73,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// If is less than one. /// - public DiagonalMatrix(int order) : base(order) - { - _storage = new SparseDiagonalMatrixStorage(order, order, Complex.Zero); - _data = _storage.Data; - } + public DiagonalMatrix(int order) + : this(new SparseDiagonalMatrixStorage(order, order, Complex.Zero)) + { + } /// /// Initializes a new instance of the class. @@ -76,10 +87,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The number of columns. /// - public DiagonalMatrix(int rows, int columns) : base(rows, columns) + public DiagonalMatrix(int rows, int columns) + : this(new SparseDiagonalMatrixStorage(rows, columns, Complex.Zero)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, Complex.Zero); - _data = _storage.Data; } /// @@ -92,11 +102,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The number of columns. /// /// The value which we assign to each diagonal element of the matrix. - public DiagonalMatrix(int rows, int columns, Complex value) : base(rows, columns) + public DiagonalMatrix(int rows, int columns, Complex value) + : this(rows, columns) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, Complex.Zero); - _data = _storage.Data; - for (var i = 0; i < _data.Length; i++) { _data[i] = value; @@ -110,10 +118,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The number of rows. /// The number of columns. /// The one dimensional array which contain diagonal elements. - public DiagonalMatrix(int rows, int columns, Complex[] diagonalArray) : base(rows, columns) + public DiagonalMatrix(int rows, int columns, Complex[] diagonalArray) + : this(new SparseDiagonalMatrixStorage(rows, columns, Complex.Zero, diagonalArray)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, Complex.Zero, diagonalArray); - _data = _storage.Data; } /// @@ -123,11 +130,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// When contains an off-diagonal element. /// Depending on the implementation, an /// may be thrown if one of the indices is outside the dimensions of the matrix. - public DiagonalMatrix(Complex[,] array) : this(array.GetLength(0), array.GetLength(1)) + public DiagonalMatrix(Complex[,] array) + : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseDiagonalMatrixStorage(array.GetLength(0), array.GetLength(1), Complex.Zero); - _data = _storage.Data; - for (var i = 0; i < RowCount; i++) { for (var j = 0; j < ColumnCount; j++) @@ -144,11 +149,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - internal SparseDiagonalMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets or sets the value at the given row and column, with range checking. /// @@ -806,21 +806,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var diagonalTarget = target as DiagonalMatrix; if (diagonalTarget != null) { - _storage.CopyTo(diagonalTarget.Storage); + _storage.CopyTo(diagonalTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Complex/Matrix.cs b/src/Numerics/LinearAlgebra/Complex/Matrix.cs index 6e6c76f8..4a3aa454 100644 --- a/src/Numerics/LinearAlgebra/Complex/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/Matrix.cs @@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex using Distributions; using Generic; using Properties; + using Storage; /// /// Complex version of the class. @@ -47,18 +48,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The number of columns. /// - protected Matrix(int rows, int columns) : base(rows, columns) - { - } - - /// - /// Initializes a new instance of the Matrix class. - /// - /// - /// The order of the matrix. - /// - protected Matrix(int order) - : base(order) + protected Matrix(MatrixStorage storage) + : base(storage) { } diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index b2eae281..feb5b6d3 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -56,8 +56,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex get { return _storage.ValueCount; } } + internal SparseCompressedRowMatrixStorage Raw + { + get { return _storage; } + } + internal SparseMatrix(SparseCompressedRowMatrixStorage storage) - : base(storage.RowCount, storage.ColumnCount) + : base(storage) { _storage = storage; } @@ -72,9 +77,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The number of columns. /// public SparseMatrix(int rows, int columns) - : base(rows, columns) + : this(new SparseCompressedRowMatrixStorage(rows, columns, Complex.Zero)) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, Complex.Zero); } /// @@ -85,9 +89,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// If is less than one. /// public SparseMatrix(int order) - : base(order, order) + : this(order, order) { - _storage = new SparseCompressedRowMatrixStorage(order, order, Complex.Zero); } /// @@ -101,10 +104,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The value which we assign to each element of the matrix. public SparseMatrix(int rows, int columns, Complex value) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, Complex.Zero); - if (value.IsZero()) { return; @@ -143,10 +144,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// If length is less than * . /// public SparseMatrix(int rows, int columns, Complex[] array) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, Complex.Zero); - if (rows * columns > array.Length) { throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); @@ -166,10 +165,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The 2D array to create this matrix from. public SparseMatrix(Complex[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseCompressedRowMatrixStorage(array.GetLength(0), array.GetLength(1), Complex.Zero); - for (var i = 0; i < _storage.RowCount; i++) { for (var j = 0; j < _storage.ColumnCount; j++) @@ -185,10 +182,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The matrix to copy. public SparseMatrix(Matrix matrix) - : base(matrix.RowCount, matrix.ColumnCount) + : this(matrix.RowCount, matrix.ColumnCount) { - _storage = new SparseCompressedRowMatrixStorage(matrix.RowCount, matrix.ColumnCount, Complex.Zero); - var sparseMatrix = matrix as SparseMatrix; var rows = matrix.RowCount; @@ -206,7 +201,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } else { - var matrixStorage = sparseMatrix.Storage; + var matrixStorage = sparseMatrix.Raw; var valueCount = _storage.ValueCount = matrixStorage.ValueCount; _storage.ColumnIndices = new int[valueCount]; _storage.Values = new Complex[valueCount]; @@ -217,11 +212,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - internal SparseCompressedRowMatrixStorage Storage - { - get { return _storage; } - } - /// /// Creates a SparseMatrix for the given number of rows and columns. /// @@ -700,14 +690,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } @@ -749,7 +739,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var valueCount = _storage.ValueCount; var ret = new SparseMatrix(ColumnCount, RowCount); - var retStorage = ret.Storage; + var retStorage = ret.Raw; retStorage.ColumnIndices = new int[valueCount]; retStorage.Values = new Complex[valueCount]; @@ -781,7 +771,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex public override Complex FrobeniusNorm() { var transpose = (SparseMatrix)Transpose(); - var aat = (this * transpose).Storage; + var aat = (this * transpose).Raw; var norm = 0d; @@ -936,8 +926,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } else { - var resultStorage = resultSparseMatrix.Storage; - var lowerStorage = lowerSparseMatrix.Storage; + var resultStorage = resultSparseMatrix.Raw; + var lowerStorage = lowerSparseMatrix.Raw; if (resultSparseMatrix.RowCount != RowCount + lowerSparseMatrix.RowCount || resultSparseMatrix.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) { @@ -979,7 +969,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex public static SparseMatrix Identity(int order) { var m = new SparseMatrix(order); - var mStorage = m.Storage; + var mStorage = m.Raw; mStorage.ValueCount = order; mStorage.Values = new Complex[order]; @@ -1029,7 +1019,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return base.Equals(other); } - var otherStorage = sparseMatrix.Storage; + var otherStorage = sparseMatrix.Raw; if (_storage.ValueCount != otherStorage.ValueCount) { return false; @@ -1091,7 +1081,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex left = sparseOther; } - var leftStorage = left.Storage; + var leftStorage = left.Raw; for (var i = 0; i < leftStorage.RowCount; i++) { // Get the begin / end index for the current row @@ -1131,7 +1121,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return; } - var otherStorage = sparseOther.Storage; + var otherStorage = sparseOther.Raw; if (ReferenceEquals(this, sparseResult)) { @@ -1231,7 +1221,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex CopyTo(sparseResult); } - CommonParallel.For(0, NonZerosCount, index => sparseResult.Storage.Values[index] *= scalar); + CommonParallel.For(0, NonZerosCount, index => sparseResult.Raw.Values[index] *= scalar); } } @@ -1330,7 +1320,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var values = _storage.Values; var valueCount = _storage.ValueCount; - var otherStorage = otherSparse.Storage; + var otherStorage = otherSparse.Raw; for (var j = 0; j < RowCount; j++) { @@ -1363,7 +1353,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - resultSparse.Storage.At(i, j, sum + result.At(i, j)); + resultSparse.Raw.At(i, j, sum + result.At(i, j)); } } } diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index 3074f342..2a3537a9 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -61,6 +61,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The matrix's data. readonly Complex32[] _data; + internal DenseColumnMajorMatrixStorage Raw + { + get { return _storage; } + } + + internal DenseMatrix(DenseColumnMajorMatrixStorage storage) + : base(storage) + { + _storage = storage; + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -69,13 +83,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// If is less than one. /// public DenseMatrix(int order) - : base(order) + : this(new DenseColumnMajorMatrixStorage(order, order)) { - _storage = new DenseColumnMajorMatrixStorage(order, order); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -88,13 +97,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The number of columns. /// public DenseMatrix(int rows, int columns) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -108,14 +112,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The value which we assign to each element of the matrix. public DenseMatrix(int rows, int columns, Complex32 value) - : base(rows, columns) + : this(rows, columns) { - _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; @@ -130,13 +128,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The number of columns. /// The one dimensional array to create this matrix from. This array should store the matrix in column-major order. see: http://en.wikipedia.org/wiki/Row-major_order public DenseMatrix(int rows, int columns, Complex32[] array) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns, array)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns, array); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -145,14 +138,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The 2D array to create this matrix from. public DenseMatrix(Complex32[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _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++) @@ -162,11 +149,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - internal DenseColumnMajorMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets the matrix's data. /// @@ -222,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index 586eb060..5067f368 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -54,6 +54,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The matrix's data. readonly Complex32[] _data; + internal SparseDiagonalMatrixStorage Raw + { + get { return _storage; } + } + + internal DiagonalMatrix(SparseDiagonalMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -62,10 +74,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// If is less than one. /// public DiagonalMatrix(int order) - : base(order) + : this(new SparseDiagonalMatrixStorage(order, order, Complex32.Zero)) { - _storage = new SparseDiagonalMatrixStorage(order, order, Complex32.Zero); - _data = _storage.Data; } /// @@ -78,10 +88,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The number of columns. /// public DiagonalMatrix(int rows, int columns) - : base(rows, columns) + : this(new SparseDiagonalMatrixStorage(rows, columns, Complex32.Zero)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, Complex32.Zero); - _data = _storage.Data; } /// @@ -95,11 +103,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The value which we assign to each diagonal element of the matrix. public DiagonalMatrix(int rows, int columns, Complex32 value) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, Complex32.Zero); - _data = _storage.Data; - for (var i = 0; i < _data.Length; i++) { _data[i] = value; @@ -114,10 +119,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The number of columns. /// The one dimensional array which contain diagonal elements. public DiagonalMatrix(int rows, int columns, Complex32[] diagonalArray) - : base(rows, columns) + : this(new SparseDiagonalMatrixStorage(rows, columns, Complex32.Zero, diagonalArray)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, Complex32.Zero, diagonalArray); - _data = _storage.Data; } /// @@ -130,9 +133,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public DiagonalMatrix(Complex32[,] array) : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseDiagonalMatrixStorage(array.GetLength(0), array.GetLength(1), Complex32.Zero); - _data = _storage.Data; - for (var i = 0; i < RowCount; i++) { for (var j = 0; j < ColumnCount; j++) @@ -149,11 +149,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - internal SparseDiagonalMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets or sets the value at the given row and column, with range checking. /// @@ -811,21 +806,21 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var diagonalTarget = target as DiagonalMatrix; if (diagonalTarget != null) { - _storage.CopyTo(diagonalTarget.Storage); + _storage.CopyTo(diagonalTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs index a3f1944c..e3d9ce41 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs @@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 using Generic; using Numerics; using Properties; + using Storage; /// /// Complex32 version of the class. @@ -41,24 +42,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Initializes a new instance of the Matrix class. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// - protected Matrix(int rows, int columns) : base(rows, columns) - { - } - - /// - /// Initializes a new instance of the Matrix class. - /// - /// - /// The order of the matrix. - /// - protected Matrix(int order) - : base(order) + protected Matrix(MatrixStorage storage) + : base(storage) { } diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 86b2e01a..4026f892 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -56,8 +56,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 get { return _storage.ValueCount; } } + internal SparseCompressedRowMatrixStorage Raw + { + get { return _storage; } + } + internal SparseMatrix(SparseCompressedRowMatrixStorage storage) - : base(storage.RowCount, storage.ColumnCount) + : base(storage) { _storage = storage; } @@ -72,9 +77,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The number of columns. /// public SparseMatrix(int rows, int columns) - : base(rows, columns) + : this(new SparseCompressedRowMatrixStorage(rows, columns, Complex32.Zero)) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, Complex32.Zero); } /// @@ -85,9 +89,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// If is less than one. /// public SparseMatrix(int order) - : base(order, order) + : this(order, order) { - _storage = new SparseCompressedRowMatrixStorage(order, order, Complex32.Zero); } /// @@ -101,10 +104,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The value which we assign to each element of the matrix. public SparseMatrix(int rows, int columns, Complex32 value) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, Complex32.Zero); - if (value.IsZero()) { return; @@ -143,10 +144,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// If length is less than * . /// public SparseMatrix(int rows, int columns, Complex32[] array) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, Complex32.Zero); - if (rows * columns > array.Length) { throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); @@ -166,10 +165,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The 2D array to create this matrix from. public SparseMatrix(Complex32[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseCompressedRowMatrixStorage(array.GetLength(0), array.GetLength(1), Complex32.Zero); - for (var i = 0; i < _storage.RowCount; i++) { for (var j = 0; j < _storage.ColumnCount; j++) @@ -185,10 +182,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The matrix to copy. public SparseMatrix(Matrix matrix) - : base(matrix.RowCount, matrix.ColumnCount) + : this(matrix.RowCount, matrix.ColumnCount) { - _storage = new SparseCompressedRowMatrixStorage(matrix.RowCount, matrix.ColumnCount, Complex32.Zero); - var sparseMatrix = matrix as SparseMatrix; var rows = matrix.RowCount; @@ -206,7 +201,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } else { - var matrixStorage = sparseMatrix.Storage; + var matrixStorage = sparseMatrix.Raw; var valueCount = _storage.ValueCount = matrixStorage.ValueCount; _storage.ColumnIndices = new int[valueCount]; _storage.Values = new Complex32[valueCount]; @@ -217,11 +212,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - internal SparseCompressedRowMatrixStorage Storage - { - get { return _storage; } - } - /// /// Creates a SparseMatrix for the given number of rows and columns. /// @@ -700,14 +690,14 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } @@ -749,7 +739,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var valueCount = _storage.ValueCount; var ret = new SparseMatrix(ColumnCount, RowCount); - var retStorage = ret.Storage; + var retStorage = ret.Raw; retStorage.ColumnIndices = new int[valueCount]; retStorage.Values = new Complex32[valueCount]; @@ -781,7 +771,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public override Complex32 FrobeniusNorm() { var transpose = (SparseMatrix)Transpose(); - var aat = (this * transpose).Storage; + var aat = (this * transpose).Raw; var norm = 0f; @@ -936,8 +926,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } else { - var resultStorage = resultSparseMatrix.Storage; - var lowerStorage = lowerSparseMatrix.Storage; + var resultStorage = resultSparseMatrix.Raw; + var lowerStorage = lowerSparseMatrix.Raw; if (resultSparseMatrix.RowCount != RowCount + lowerSparseMatrix.RowCount || resultSparseMatrix.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) { @@ -979,7 +969,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public static SparseMatrix Identity(int order) { var m = new SparseMatrix(order); - var mStorage = m.Storage; + var mStorage = m.Raw; mStorage.ValueCount = order; mStorage.Values = new Complex32[order]; @@ -1029,7 +1019,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return base.Equals(other); } - var otherStorage = sparseMatrix.Storage; + var otherStorage = sparseMatrix.Raw; if (_storage.ValueCount != otherStorage.ValueCount) { return false; @@ -1091,7 +1081,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 left = sparseOther; } - var leftStorage = left.Storage; + var leftStorage = left.Raw; for (var i = 0; i < leftStorage.RowCount; i++) { // Get the begin / end index for the current row @@ -1130,7 +1120,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return; } - var otherStorage = sparseOther.Storage; + var otherStorage = sparseOther.Raw; if (ReferenceEquals(this, sparseResult)) { @@ -1230,7 +1220,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 CopyTo(sparseResult); } - CommonParallel.For(0, NonZerosCount, index => sparseResult.Storage.Values[index] *= scalar); + CommonParallel.For(0, NonZerosCount, index => sparseResult.Raw.Values[index] *= scalar); } } @@ -1329,7 +1319,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var values = _storage.Values; var valueCount = _storage.ValueCount; - var otherStorage = otherSparse.Storage; + var otherStorage = otherSparse.Raw; for (var j = 0; j < RowCount; j++) { @@ -1362,7 +1352,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - resultSparse.Storage.At(i, j, sum + result.At(i, j)); + resultSparse.Raw.At(i, j, sum + result.At(i, j)); } } } diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index beb12775..0d6f2d76 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -61,6 +61,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The matrix's data. readonly double[] _data; + internal DenseColumnMajorMatrixStorage Raw + { + get { return _storage; } + } + + internal DenseMatrix(DenseColumnMajorMatrixStorage storage) + : base(storage) + { + _storage = storage; + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -69,13 +83,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// If is less than one. /// public DenseMatrix(int order) - : base(order) + : this(new DenseColumnMajorMatrixStorage(order, order)) { - _storage = new DenseColumnMajorMatrixStorage(order, order); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -88,13 +97,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The number of columns. /// public DenseMatrix(int rows, int columns) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -108,14 +112,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The value which we assign to each element of the matrix. public DenseMatrix(int rows, int columns, double value) - : base(rows, columns) + : this(rows, columns) { - _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; @@ -130,13 +128,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The number of columns. /// The one dimensional array to create this matrix from. This array should store the matrix in column-major order. see: http://en.wikipedia.org/wiki/Row-major_order public DenseMatrix(int rows, int columns, double[] array) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns, array)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns, array); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -145,14 +138,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The 2D array to create this matrix from. public DenseMatrix(double[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _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++) @@ -162,11 +149,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - internal DenseColumnMajorMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets the matrix's data. /// @@ -222,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index 11af89cf..dbf75904 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -53,6 +53,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The matrix's data. readonly double[] _data; + internal SparseDiagonalMatrixStorage Raw + { + get { return _storage; } + } + + internal DiagonalMatrix(SparseDiagonalMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -60,11 +72,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// If is less than one. /// - public DiagonalMatrix(int order) : base(order) - { - _storage = new SparseDiagonalMatrixStorage(order, order, 0d); - _data = _storage.Data; - } + public DiagonalMatrix(int order) + : this(new SparseDiagonalMatrixStorage(order, order, 0d)) + { + } /// /// Initializes a new instance of the class. @@ -75,10 +86,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The number of columns. /// - public DiagonalMatrix(int rows, int columns) : base(rows, columns) + public DiagonalMatrix(int rows, int columns) + : this(new SparseDiagonalMatrixStorage(rows, columns, 0d)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, 0d); - _data = _storage.Data; } /// @@ -91,11 +101,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The number of columns. /// /// The value which we assign to each diagonal element of the matrix. - public DiagonalMatrix(int rows, int columns, double value) : base(rows, columns) + public DiagonalMatrix(int rows, int columns, double value) + : this(rows, columns) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, 0d); - _data = _storage.Data; - for (var i = 0; i < _data.Length; i++) { _data[i] = value; @@ -109,10 +117,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The number of rows. /// The number of columns. /// The one dimensional array which contain diagonal elements. - public DiagonalMatrix(int rows, int columns, double[] diagonalArray) : base(rows, columns) + public DiagonalMatrix(int rows, int columns, double[] diagonalArray) + : this(new SparseDiagonalMatrixStorage(rows, columns, 0d, diagonalArray)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, 0d, diagonalArray); - _data = _storage.Data; } /// @@ -122,11 +129,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// When contains an off-diagonal element. /// Depending on the implementation, an /// may be thrown if one of the indices is outside the dimensions of the matrix. - public DiagonalMatrix(double[,] array) : this(array.GetLength(0), array.GetLength(1)) + public DiagonalMatrix(double[,] array) + : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseDiagonalMatrixStorage(array.GetLength(0), array.GetLength(1), 0d); - _data = _storage.Data; - for (var i = 0; i < RowCount; i++) { for (var j = 0; j < ColumnCount; j++) @@ -143,11 +148,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - internal SparseDiagonalMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets or sets the value at the given row and column, with range checking. /// @@ -800,21 +800,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double var diagonalTarget = target as DiagonalMatrix; if (diagonalTarget != null) { - _storage.CopyTo(diagonalTarget.Storage); + _storage.CopyTo(diagonalTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index c395ca25..4e072807 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs @@ -24,6 +24,8 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra.Storage; + namespace MathNet.Numerics.LinearAlgebra.Double { using System; @@ -40,24 +42,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Initializes a new instance of the Matrix class. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// - protected Matrix(int rows, int columns) : base(rows, columns) - { - } - - /// - /// Initializes a new instance of the Matrix class. - /// - /// - /// The order of the matrix. - /// - protected Matrix(int order) - : base(order) + protected Matrix(MatrixStorage storage) + : base(storage) { } diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 05f1c8d4..28a249e6 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -55,8 +55,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double get { return _storage.ValueCount; } } + internal SparseCompressedRowMatrixStorage Raw + { + get { return _storage; } + } + internal SparseMatrix(SparseCompressedRowMatrixStorage storage) - : base(storage.RowCount, storage.ColumnCount) + : base(storage) { _storage = storage; } @@ -71,9 +76,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The number of columns. /// public SparseMatrix(int rows, int columns) - : base(rows, columns) + : this(new SparseCompressedRowMatrixStorage(rows, columns, 0d)) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, 0d); } /// @@ -84,9 +88,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// If is less than one. /// public SparseMatrix(int order) - : base(order, order) + : this(order, order) { - _storage = new SparseCompressedRowMatrixStorage(order, order, 0d); } /// @@ -100,10 +103,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The value which we assign to each element of the matrix. public SparseMatrix(int rows, int columns, double value) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, 0d); - if (value == 0.0) { return; @@ -142,10 +143,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// If length is less than * . /// public SparseMatrix(int rows, int columns, double[] array) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, 0d); - if (rows * columns > array.Length) { throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); @@ -165,10 +164,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The 2D array to create this matrix from. public SparseMatrix(double[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseCompressedRowMatrixStorage(array.GetLength(0), array.GetLength(1), 0d); - for (var i = 0; i < _storage.RowCount; i++) { for (var j = 0; j < _storage.ColumnCount; j++) @@ -184,10 +181,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The matrix to copy. public SparseMatrix(Matrix matrix) - : base(matrix.RowCount, matrix.ColumnCount) + : this(matrix.RowCount, matrix.ColumnCount) { - _storage = new SparseCompressedRowMatrixStorage(matrix.RowCount, matrix.ColumnCount, 0d); - var sparseMatrix = matrix as SparseMatrix; var rows = matrix.RowCount; @@ -205,7 +200,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } else { - var matrixStorage = sparseMatrix.Storage; + var matrixStorage = sparseMatrix.Raw; var valueCount = _storage.ValueCount = matrixStorage.ValueCount; _storage.ColumnIndices = new int[valueCount]; _storage.Values = new double[valueCount]; @@ -216,11 +211,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - internal SparseCompressedRowMatrixStorage Storage - { - get { return _storage; } - } - /// /// Creates a SparseMatrix for the given number of rows and columns. /// @@ -699,14 +689,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } @@ -748,7 +738,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double var valueCount = _storage.ValueCount; var ret = new SparseMatrix(ColumnCount, RowCount); - var retStorage = ret.Storage; + var retStorage = ret.Raw; retStorage.ColumnIndices = new int[valueCount]; retStorage.Values = new double[valueCount]; @@ -780,7 +770,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double public override double FrobeniusNorm() { var transpose = (SparseMatrix)Transpose(); - var aat = (this * transpose).Storage; + var aat = (this * transpose).Raw; var norm = 0d; @@ -934,8 +924,8 @@ namespace MathNet.Numerics.LinearAlgebra.Double } else { - var resultStorage = resultSparseMatrix.Storage; - var lowerStorage = lowerSparseMatrix.Storage; + var resultStorage = resultSparseMatrix.Raw; + var lowerStorage = lowerSparseMatrix.Raw; if (resultStorage.RowCount != RowCount + lowerStorage.RowCount || resultStorage.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) { @@ -977,7 +967,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double public static SparseMatrix Identity(int order) { var m = new SparseMatrix(order); - var mStorage = m.Storage; + var mStorage = m.Raw; mStorage.ValueCount = order; mStorage.Values = new double[order]; @@ -1027,7 +1017,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double return base.Equals(other); } - var otherStorage = sparseMatrix.Storage; + var otherStorage = sparseMatrix.Raw; if (_storage.ValueCount != otherStorage.ValueCount) { return false; @@ -1089,7 +1079,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double left = sparseOther; } - var leftStorage = left.Storage; + var leftStorage = left.Raw; for (var i = 0; i < leftStorage.RowCount; i++) { // Get the begin / end index for the current row @@ -1129,7 +1119,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double return; } - var otherStorage = sparseOther.Storage; + var otherStorage = sparseOther.Raw; if (ReferenceEquals(this, sparseResult)) { @@ -1229,7 +1219,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double CopyTo(sparseResult); } - CommonParallel.For(0, _storage.ValueCount, index => sparseResult.Storage.Values[index] *= scalar); + CommonParallel.For(0, _storage.ValueCount, index => sparseResult.Raw.Values[index] *= scalar); } } @@ -1328,7 +1318,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double var values = _storage.Values; var valueCount = _storage.ValueCount; - var otherStorage = otherSparse.Storage; + var otherStorage = otherSparse.Raw; for (var j = 0; j < RowCount; j++) { @@ -1361,7 +1351,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - resultSparse.Storage.At(i, j, sum + result.At(i, j)); + resultSparse.Raw.At(i, j, sum + result.At(i, j)); } } } @@ -1457,7 +1447,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double CopyTo(result); } - var resultStorage = sparseResult.Storage; + var resultStorage = sparseResult.Raw; for (var index = 0; index < resultStorage.Values.Length; index++) { resultStorage.Values[index] %= divisor; diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.cs index 7d3121a0..0d9d7695 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -24,6 +24,8 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.LinearAlgebra.Storage; + namespace MathNet.Numerics.LinearAlgebra.Generic { using System; @@ -42,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic [Serializable] public abstract partial class Matrix : #if PORTABLE - IFormattable, IEquatable> + IFormattable, IEquatable> #else IFormattable, IEquatable>, ICloneable #endif @@ -51,64 +53,29 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// Initializes a new instance of the Matrix class. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// - protected Matrix(int rows, int columns) + protected Matrix(MatrixStorage storage) { - if (rows <= 0) - { - throw new ArgumentOutOfRangeException(Resources.MatrixRowsMustBePositive); - } - - if (columns <= 0) - { - throw new ArgumentOutOfRangeException(Resources.MatrixColumnsMustBePositive); - } - - RowCount = rows; - ColumnCount = columns; + Storage = storage; + RowCount = storage.RowCount; + ColumnCount = storage.ColumnCount; } /// - /// Initializes a new instance of the Matrix class. + /// Gets the raw matrix data storage. /// - /// - /// The order of the matrix. - /// - protected Matrix(int order) - { - if (order <= 0) - { - throw new ArgumentOutOfRangeException(Resources.MatrixRowsOrColumnsMustBePositive); - } - - RowCount = order; - ColumnCount = order; - } + public MatrixStorage Storage { get; private set; } /// /// Gets the number of columns. /// /// The number of columns. - public int ColumnCount - { - get; - private set; - } + public int ColumnCount { get; private set; } /// /// Gets the number of rows. /// /// The number of rows. - public int RowCount - { - get; - private set; - } + public int RowCount { get; private set; } /// /// Constructs matrix from a list of column vectors. diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index bb7103f5..e6607d76 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -61,6 +61,20 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The matrix's data. readonly float[] _data; + internal DenseColumnMajorMatrixStorage Raw + { + get { return _storage; } + } + + internal DenseMatrix(DenseColumnMajorMatrixStorage storage) + : base(storage) + { + _storage = storage; + _rowCount = _storage.RowCount; + _columnCount = _storage.ColumnCount; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -69,13 +83,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// If is less than one. /// public DenseMatrix(int order) - : base(order) + : this(new DenseColumnMajorMatrixStorage(order, order)) { - _storage = new DenseColumnMajorMatrixStorage(order, order); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -88,13 +97,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The number of columns. /// public DenseMatrix(int rows, int columns) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -108,14 +112,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The value which we assign to each element of the matrix. public DenseMatrix(int rows, int columns, float value) - : base(rows, columns) + : this(rows, columns) { - _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; @@ -130,13 +128,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The number of columns. /// The one dimensional array to create this matrix from. This array should store the matrix in column-major order. see: http://en.wikipedia.org/wiki/Row-major_order public DenseMatrix(int rows, int columns, float[] array) - : base(rows, columns) + : this(new DenseColumnMajorMatrixStorage(rows, columns, array)) { - _storage = new DenseColumnMajorMatrixStorage(rows, columns, array); - - _rowCount = _storage.RowCount; - _columnCount = _storage.ColumnCount; - _data = _storage.Data; } /// @@ -145,14 +138,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The 2D array to create this matrix from. public DenseMatrix(float[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _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++) @@ -162,11 +149,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } - internal DenseColumnMajorMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets the matrix's data. /// @@ -222,7 +204,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index c602f74b..94934d13 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -53,6 +53,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The matrix's data. readonly float[] _data; + internal SparseDiagonalMatrixStorage Raw + { + get { return _storage; } + } + + internal DiagonalMatrix(SparseDiagonalMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -61,10 +73,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// If is less than one. /// public DiagonalMatrix(int order) - : base(order) + : this(new SparseDiagonalMatrixStorage(order, order, 0f)) { - _storage = new SparseDiagonalMatrixStorage(order, order, 0f); - _data = _storage.Data; } /// @@ -77,10 +87,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The number of columns. /// public DiagonalMatrix(int rows, int columns) - : base(rows, columns) + : this(new SparseDiagonalMatrixStorage(rows, columns, 0f)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, 0f); - _data = _storage.Data; } /// @@ -94,11 +102,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The value which we assign to each diagonal element of the matrix. public DiagonalMatrix(int rows, int columns, float value) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, 0f); - _data = _storage.Data; - for (var i = 0; i < _data.Length; i++) { _data[i] = value; @@ -113,10 +118,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The number of columns. /// The one dimensional array which contain diagonal elements. public DiagonalMatrix(int rows, int columns, float[] diagonalArray) - : base(rows, columns) + : this(new SparseDiagonalMatrixStorage(rows, columns, 0f, diagonalArray)) { - _storage = new SparseDiagonalMatrixStorage(rows, columns, 0f, diagonalArray); - _data = _storage.Data; } /// @@ -129,9 +132,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single public DiagonalMatrix(float[,] array) : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseDiagonalMatrixStorage(array.GetLength(0), array.GetLength(1), 0f); - _data = _storage.Data; - for (var i = 0; i < RowCount; i++) { for (var j = 0; j < ColumnCount; j++) @@ -148,11 +148,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } - internal SparseDiagonalMatrixStorage Storage - { - get { return _storage; } - } - /// /// Gets or sets the value at the given row and column, with range checking. /// @@ -805,21 +800,21 @@ namespace MathNet.Numerics.LinearAlgebra.Single var diagonalTarget = target as DiagonalMatrix; if (diagonalTarget != null) { - _storage.CopyTo(diagonalTarget.Storage); + _storage.CopyTo(diagonalTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } diff --git a/src/Numerics/LinearAlgebra/Single/Matrix.cs b/src/Numerics/LinearAlgebra/Single/Matrix.cs index e2e0211e..608ec3c2 100644 --- a/src/Numerics/LinearAlgebra/Single/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Single/Matrix.cs @@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single using Distributions; using Generic; using Properties; + using Storage; /// /// float version of the class. @@ -40,24 +41,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Initializes a new instance of the Matrix class. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// - protected Matrix(int rows, int columns) : base(rows, columns) - { - } - - /// - /// Initializes a new instance of the Matrix class. - /// - /// - /// The order of the matrix. - /// - protected Matrix(int order) - : base(order) + protected Matrix(MatrixStorage storage) + : base(storage) { } diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index bacd08f7..d9b08890 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -55,8 +55,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single get { return _storage.ValueCount; } } + internal SparseCompressedRowMatrixStorage Raw + { + get { return _storage; } + } + internal SparseMatrix(SparseCompressedRowMatrixStorage storage) - : base(storage.RowCount, storage.ColumnCount) + : base(storage) { _storage = storage; } @@ -71,9 +76,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// The number of columns. /// public SparseMatrix(int rows, int columns) - : base(rows, columns) + : this(new SparseCompressedRowMatrixStorage(rows, columns, 0f)) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, 0f); } /// @@ -84,9 +88,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// If is less than one. /// public SparseMatrix(int order) - : base(order, order) + : this(order, order) { - _storage = new SparseCompressedRowMatrixStorage(order, order, 0f); } /// @@ -100,10 +103,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The value which we assign to each element of the matrix. public SparseMatrix(int rows, int columns, float value) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, 0f); - if (value == 0.0) { return; @@ -142,10 +143,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// If length is less than * . /// public SparseMatrix(int rows, int columns, float[] array) - : base(rows, columns) + : this(rows, columns) { - _storage = new SparseCompressedRowMatrixStorage(rows, columns, 0f); - if (rows * columns > array.Length) { throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); @@ -165,10 +164,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// The 2D array to create this matrix from. public SparseMatrix(float[,] array) - : base(array.GetLength(0), array.GetLength(1)) + : this(array.GetLength(0), array.GetLength(1)) { - _storage = new SparseCompressedRowMatrixStorage(array.GetLength(0), array.GetLength(1), 0f); - for (var i = 0; i < _storage.RowCount; i++) { for (var j = 0; j < _storage.ColumnCount; j++) @@ -186,8 +183,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single public SparseMatrix(Matrix matrix) : this(matrix.RowCount, matrix.ColumnCount) { - _storage = new SparseCompressedRowMatrixStorage(matrix.RowCount, matrix.ColumnCount, 0f); - var sparseMatrix = matrix as SparseMatrix; var rows = matrix.RowCount; @@ -205,7 +200,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single } else { - var matrixStorage = sparseMatrix.Storage; + var matrixStorage = sparseMatrix.Raw; var valueCount = _storage.ValueCount = matrixStorage.ValueCount; _storage.ColumnIndices = new int[valueCount]; _storage.Values = new float[valueCount]; @@ -216,11 +211,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } - internal SparseCompressedRowMatrixStorage Storage - { - get { return _storage; } - } - /// /// Creates a SparseMatrix for the given number of rows and columns. /// @@ -699,14 +689,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single var sparseTarget = target as SparseMatrix; if (sparseTarget != null) { - _storage.CopyTo(sparseTarget.Storage); + _storage.CopyTo(sparseTarget.Raw); return; } var denseTarget = target as DenseMatrix; if (denseTarget != null) { - _storage.CopyTo(denseTarget.Storage); + _storage.CopyTo(denseTarget.Raw); return; } @@ -748,7 +738,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single var valueCount = _storage.ValueCount; var ret = new SparseMatrix(ColumnCount, RowCount); - var retStorage = ret.Storage; + var retStorage = ret.Raw; retStorage.ColumnIndices = new int[valueCount]; retStorage.Values = new float[valueCount]; @@ -780,7 +770,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single public override float FrobeniusNorm() { var transpose = (SparseMatrix)Transpose(); - var aat = (this * transpose).Storage; + var aat = (this * transpose).Raw; var norm = 0f; @@ -934,8 +924,8 @@ namespace MathNet.Numerics.LinearAlgebra.Single } else { - var resultStorage = resultSparseMatrix.Storage; - var lowerStorage = lowerSparseMatrix.Storage; + var resultStorage = resultSparseMatrix.Raw; + var lowerStorage = lowerSparseMatrix.Raw; if (resultStorage.RowCount != RowCount + lowerStorage.RowCount || resultStorage.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) { @@ -977,7 +967,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single public static SparseMatrix Identity(int order) { var m = new SparseMatrix(order); - var mStorage = m.Storage; + var mStorage = m.Raw; mStorage.ValueCount = order; mStorage.Values = new float[order]; @@ -1027,7 +1017,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single return base.Equals(other); } - var otherStorage = sparseMatrix.Storage; + var otherStorage = sparseMatrix.Raw; if (_storage.ValueCount != otherStorage.ValueCount) { return false; @@ -1089,7 +1079,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single left = sparseOther; } - var leftStorage = left.Storage; + var leftStorage = left.Raw; for (var i = 0; i < leftStorage.RowCount; i++) { // Get the begin / end index for the current row @@ -1128,7 +1118,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single return; } - var otherStorage = sparseOther.Storage; + var otherStorage = sparseOther.Raw; if (ReferenceEquals(this, sparseResult)) { @@ -1228,7 +1218,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single CopyTo(sparseResult); } - CommonParallel.For(0, NonZerosCount, index => sparseResult.Storage.Values[index] *= scalar); + CommonParallel.For(0, NonZerosCount, index => sparseResult.Raw.Values[index] *= scalar); } } @@ -1327,7 +1317,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single var values = _storage.Values; var valueCount = _storage.ValueCount; - var otherStorage = otherSparse.Storage; + var otherStorage = otherSparse.Raw; for (var j = 0; j < RowCount; j++) { @@ -1360,7 +1350,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } - resultSparse.Storage.At(i, j, sum + result.At(i, j)); + resultSparse.Raw.At(i, j, sum + result.At(i, j)); } } } @@ -1456,7 +1446,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single CopyTo(result); } - var resultStorage = sparseResult.Storage; + var resultStorage = sparseResult.Raw; for (var index = 0; index < resultStorage.Values.Length; index++) { resultStorage.Values[index] %= divisor; diff --git a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs index 5e4abb41..f6d04d51 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -1,84 +1,31 @@ using System; using MathNet.Numerics.Properties; -using MathNet.Numerics.Threading; namespace MathNet.Numerics.LinearAlgebra.Storage { - internal class DenseColumnMajorMatrixStorage : IMatrixStorage + internal class DenseColumnMajorMatrixStorage : MatrixStorage where T : struct, IEquatable, IFormattable { // [ruegg] public fields are OK here - public readonly int RowCount; - public readonly int ColumnCount; - public readonly T[] Data; internal DenseColumnMajorMatrixStorage(int rows, int columns) + : base(rows, columns) { - RowCount = rows; - ColumnCount = columns; - Data = new T[rows * columns]; } internal DenseColumnMajorMatrixStorage(int rows, int columns, T[] data) + : base(rows, columns) { - RowCount = rows; - ColumnCount = columns; - Data = data; } - /// - /// Gets or sets the value at the given row and column, with range checking. - /// - /// - /// The row of the element. - /// - /// - /// The column of the element. - /// - /// The value to get or set. - /// This method is ranged checked. and - /// to get and set values without range checking. - public T this[int row, int column] - { - get - { - if (row < 0 || row >= RowCount) - { - throw new ArgumentOutOfRangeException("row"); - } - - if (column < 0 || column >= ColumnCount) - { - throw new ArgumentOutOfRangeException("column"); - } - - return At(row, column); - } - - set - { - if (row < 0 || row >= RowCount) - { - throw new ArgumentOutOfRangeException("row"); - } - - if (column < 0 || column >= ColumnCount) - { - throw new ArgumentOutOfRangeException("column"); - } - - At(row, column, value); - } - } - /// /// Retrieves the requested element without range checking. /// - public T At(int row, int column) + public override T At(int row, int column) { return Data[(column * RowCount) + row]; } @@ -86,17 +33,17 @@ namespace MathNet.Numerics.LinearAlgebra.Storage /// /// Sets the element without range checking. /// - public void At(int row, int column, T value) + public override void At(int row, int column, T value) { Data[(column * RowCount) + row] = value; } - public void Clear() + public override void Clear() { Array.Clear(Data, 0, Data.Length); } - public void CopyTo(IMatrixStorage target, bool skipClearing = false) + public void CopyTo(MatrixStorage target, bool skipClearing = false) { var denseTarget = target as DenseColumnMajorMatrixStorage; if (denseTarget != null) @@ -179,15 +126,5 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Copy(Data, j*RowCount + sourceRowIndex, target.Data, jj*target.RowCount + targetRowIndex, rowCount); } } - - int IMatrixStorage.RowCount - { - get { return RowCount; } - } - - int IMatrixStorage.ColumnCount - { - get { return ColumnCount; } - } } } diff --git a/src/Numerics/LinearAlgebra/Storage/IMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/IMatrixStorage.cs deleted file mode 100644 index 081edf68..00000000 --- a/src/Numerics/LinearAlgebra/Storage/IMatrixStorage.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; - -namespace MathNet.Numerics.LinearAlgebra.Storage -{ - public interface IMatrixStorage where T : struct, IEquatable, IFormattable - { - int RowCount { get; } - int ColumnCount { get; } - - /// - /// Gets or sets the value at the given row and column, with range checking. - /// - /// - /// The row of the element. - /// - /// - /// The column of the element. - /// - /// The value to get or set. - /// This method is ranged checked. and - /// to get and set values without range checking. - T this[int row, int column] { get; set; } - - /// - /// Retrieves the requested element without range checking. - /// - /// - /// The row of the element. - /// - /// - /// The column of the element. - /// - /// - /// The requested element. - /// - /// Not range-checked. - T At(int row, int column); - - /// - /// Sets the element without range checking. - /// - /// The row of the element. - /// The column of the element. - /// The value to set the element to. - /// WARNING: This method is not thread safe. Use "lock" with it and be sure to avoid deadlocks. - void At(int row, int column, T value); - - void Clear(); - void CopyTo(IMatrixStorage target, bool skipClearing = false); - } -} diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs new file mode 100644 index 00000000..2d7ac6a7 --- /dev/null +++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs @@ -0,0 +1,100 @@ +using System; +using MathNet.Numerics.Properties; + +namespace MathNet.Numerics.LinearAlgebra.Storage +{ + public abstract class MatrixStorage where T : struct, IEquatable, IFormattable + { + // [ruegg] public fields are OK here + + public readonly int RowCount; + public readonly int ColumnCount; + + protected MatrixStorage(int rowCount, int columnCount) + { + if (rowCount <= 0) + { + throw new ArgumentOutOfRangeException(Resources.MatrixRowsMustBePositive); + } + + if (columnCount <= 0) + { + throw new ArgumentOutOfRangeException(Resources.MatrixColumnsMustBePositive); + } + + RowCount = rowCount; + ColumnCount = columnCount; + } + + /// + /// Gets or sets the value at the given row and column, with range checking. + /// + /// + /// The row of the element. + /// + /// + /// The column of the element. + /// + /// The value to get or set. + /// This method is ranged checked. and + /// to get and set values without range checking. + public T this[int row, int column] + { + get + { + if (row < 0 || row >= RowCount) + { + throw new ArgumentOutOfRangeException("row"); + } + + if (column < 0 || column >= ColumnCount) + { + throw new ArgumentOutOfRangeException("column"); + } + + return At(row, column); + } + + set + { + if (row < 0 || row >= RowCount) + { + throw new ArgumentOutOfRangeException("row"); + } + + if (column < 0 || column >= ColumnCount) + { + throw new ArgumentOutOfRangeException("column"); + } + + At(row, column, value); + } + } + + /// + /// Retrieves the requested element without range checking. + /// + /// + /// The row of the element. + /// + /// + /// The column of the element. + /// + /// + /// The requested element. + /// + /// Not range-checked. + public abstract T At(int row, int column); + + /// + /// Sets the element without range checking. + /// + /// The row of the element. + /// The column of the element. + /// The value to set the element to. + /// WARNING: This method is not thread safe. Use "lock" with it and be sure to avoid deadlocks. + public abstract void At(int row, int column, T value); + + public abstract void Clear(); + } +} diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index b5646c0c..a15a9645 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -3,13 +3,11 @@ using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage { - internal class SparseCompressedRowMatrixStorage : IMatrixStorage + internal class SparseCompressedRowMatrixStorage : MatrixStorage where T : struct, IEquatable, IFormattable { // [ruegg] public fields are OK here - public readonly int RowCount; - public readonly int ColumnCount; readonly T _zero; /// @@ -37,62 +35,15 @@ namespace MathNet.Numerics.LinearAlgebra.Storage public int ValueCount; internal SparseCompressedRowMatrixStorage(int rows, int columns, T zero) + : base(rows, columns) { - RowCount = rows; - ColumnCount = columns; _zero = zero; - RowPointers = new int[rows]; ColumnIndices = new int[0]; Values = new T[0]; ValueCount = 0; } - /// - /// Gets or sets the value at the given row and column, with range checking. - /// - /// - /// The row of the element. - /// - /// - /// The column of the element. - /// - /// The value to get or set. - /// This method is ranged checked. and - /// to get and set values without range checking. - public T this[int row, int column] - { - get - { - if (row < 0 || row >= RowCount) - { - throw new ArgumentOutOfRangeException("row"); - } - - if (column < 0 || column >= ColumnCount) - { - throw new ArgumentOutOfRangeException("column"); - } - - return At(row, column); - } - - set - { - if (row < 0 || row >= RowCount) - { - throw new ArgumentOutOfRangeException("row"); - } - - if (column < 0 || column >= ColumnCount) - { - throw new ArgumentOutOfRangeException("column"); - } - - At(row, column, value); - } - } - /// /// Retrieves the requested element without range checking. /// @@ -106,7 +57,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage /// The requested element. /// /// Not range-checked. - public T At(int row, int column) + public override T At(int row, int column) { var index = FindItem(row, column); return index >= 0 ? Values[index] : _zero; @@ -119,7 +70,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage /// The column of the element. /// The value to set the element to. /// WARNING: This method is not thread safe. Use "lock" with it and be sure to avoid deadlocks. - public void At(int row, int column, T value) + public override void At(int row, int column, T value) { var index = FindItem(row, column); if (index >= 0) @@ -185,7 +136,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } - public void Clear() + public override void Clear() { ValueCount = 0; Array.Clear(RowPointers, 0, RowPointers.Length); @@ -266,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return delta; } - public void CopyTo(IMatrixStorage target, bool skipClearing = false) + public void CopyTo(MatrixStorage target, bool skipClearing = false) { var sparseTarget = target as SparseCompressedRowMatrixStorage; if (sparseTarget != null) @@ -375,15 +326,5 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } } - - int IMatrixStorage.RowCount - { - get { return RowCount; } - } - - int IMatrixStorage.ColumnCount - { - get { return ColumnCount; } - } } } diff --git a/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs index 29c5da2a..4e60bceb 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs @@ -3,84 +3,32 @@ using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage { - internal class SparseDiagonalMatrixStorage : IMatrixStorage + internal class SparseDiagonalMatrixStorage : MatrixStorage where T : struct, IEquatable, IFormattable { // [ruegg] public fields are OK here - public readonly int RowCount; - public readonly int ColumnCount; readonly T _zero; - public readonly T[] Data; internal SparseDiagonalMatrixStorage(int rows, int columns, T zero) + : base(rows, columns) { - RowCount = rows; - ColumnCount = columns; _zero = zero; - Data = new T[Math.Min(rows, columns)]; } internal SparseDiagonalMatrixStorage(int rows, int columns, T zero, T[] data) + : base(rows, columns) { - RowCount = rows; - ColumnCount = columns; _zero = zero; - Data = data; } - /// - /// Gets or sets the value at the given row and column, with range checking. - /// - /// - /// The row of the element. - /// - /// - /// The column of the element. - /// - /// The value to get or set. - /// This method is ranged checked. and - /// to get and set values without range checking. - public T this[int row, int column] - { - get - { - if (row < 0 || row >= RowCount) - { - throw new ArgumentOutOfRangeException("row"); - } - - if (column < 0 || column >= ColumnCount) - { - throw new ArgumentOutOfRangeException("column"); - } - - return At(row, column); - } - - set - { - if (row < 0 || row >= RowCount) - { - throw new ArgumentOutOfRangeException("row"); - } - - if (column < 0 || column >= ColumnCount) - { - throw new ArgumentOutOfRangeException("column"); - } - - At(row, column, value); - } - } - /// /// Retrieves the requested element without range checking. /// - public T At(int row, int column) + public override T At(int row, int column) { return row == column ? Data[row] : _zero; } @@ -88,7 +36,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage /// /// Sets the element without range checking. /// - public void At(int row, int column, T value) + public override void At(int row, int column, T value) { if (row == column) { @@ -100,12 +48,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } - public void Clear() + public override void Clear() { Array.Clear(Data, 0, Data.Length); } - public void CopyTo(IMatrixStorage target, bool skipClearing = false) + public void CopyTo(MatrixStorage target, bool skipClearing = false) { var diagonalTarget = target as SparseDiagonalMatrixStorage; if (diagonalTarget != null) @@ -329,15 +277,5 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } } - - int IMatrixStorage.RowCount - { - get { return RowCount; } - } - - int IMatrixStorage.ColumnCount - { - get { return ColumnCount; } - } } } diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 8652bbb1..2e64b192 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -332,7 +332,7 @@ - + diff --git a/src/Portable/Portable.csproj b/src/Portable/Portable.csproj index 22020468..c994bf26 100644 --- a/src/Portable/Portable.csproj +++ b/src/Portable/Portable.csproj @@ -894,8 +894,8 @@ LinearAlgebra\Storage\DenseColumnMajorMatrixStorage.cs - - LinearAlgebra\Storage\IMatrixStorage.cs + + LinearAlgebra\Storage\MatrixStorage.cs LinearAlgebra\Storage\SparseCompressedRowMatrixStorage.cs diff --git a/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrix.cs b/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrix.cs index 3f5243e6..11d5dc16 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrix.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/UserDefinedMatrix.cs @@ -24,6 +24,9 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra.Storage; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { using System.Numerics; @@ -35,18 +38,55 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// internal class UserDefinedMatrix : Matrix { - /// - /// Values storage - /// - private readonly Complex[,] _data; + class UserDefinedMatrixStorage : MatrixStorage + { + public readonly Complex[,] Data; + + public UserDefinedMatrixStorage(int rowCount, int columnCount) + : base(rowCount, columnCount) + { + Data = new Complex[rowCount, columnCount]; + } + + public UserDefinedMatrixStorage(int rowCount, int columnCount, Complex[,] data) + : base(rowCount, columnCount) + { + Data = data; + } + + public override Complex At(int row, int column) + { + return Data[row, column]; + } + + public override void At(int row, int column, Complex value) + { + Data[row, column] = value; + } + + public override void Clear() + { + Array.Clear(Data, 0, RowCount * ColumnCount); + } + } + + readonly UserDefinedMatrixStorage _storage; + readonly Complex[,] _data; + + private UserDefinedMatrix(UserDefinedMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } /// /// Initializes a new instance of the class. This matrix is square with a given size. /// /// the size of the square matrix. - public UserDefinedMatrix(int order) : base(order, order) + public UserDefinedMatrix(int order) + : this(new UserDefinedMatrixStorage(order, order)) { - _data = new Complex[order, order]; } /// @@ -54,18 +94,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// /// The number of rows. /// The number of columns. - public UserDefinedMatrix(int rows, int columns) : base(rows, columns) + public UserDefinedMatrix(int rows, int columns) + : this(new UserDefinedMatrixStorage(rows, columns)) { - _data = new Complex[rows, columns]; } /// /// Initializes a new instance of the class from a 2D array. /// /// The 2D array to create this matrix from. - public UserDefinedMatrix(Complex[,] data) : base(data.GetLength(0), data.GetLength(1)) + public UserDefinedMatrix(Complex[,] data) + : this(new UserDefinedMatrixStorage(data.GetLength(0), data.GetLength(1), (Complex[,]) data.Clone())) { - _data = (Complex[,])data.Clone(); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs index e523b123..a2b82f8f 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs @@ -24,6 +24,9 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra.Storage; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { using LinearAlgebra.Complex32; @@ -35,18 +38,55 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// internal class UserDefinedMatrix : Matrix { - /// - /// Values storage - /// - private readonly Complex32[,] _data; + class UserDefinedMatrixStorage : MatrixStorage + { + public readonly Complex32[,] Data; + + public UserDefinedMatrixStorage(int rowCount, int columnCount) + : base(rowCount, columnCount) + { + Data = new Complex32[rowCount, columnCount]; + } + + public UserDefinedMatrixStorage(int rowCount, int columnCount, Complex32[,] data) + : base(rowCount, columnCount) + { + Data = data; + } + + public override Complex32 At(int row, int column) + { + return Data[row, column]; + } + + public override void At(int row, int column, Complex32 value) + { + Data[row, column] = value; + } + + public override void Clear() + { + Array.Clear(Data, 0, RowCount * ColumnCount); + } + } + + readonly UserDefinedMatrixStorage _storage; + readonly Complex32[,] _data; + + private UserDefinedMatrix(UserDefinedMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } /// /// Initializes a new instance of the class. This matrix is square with a given size. /// /// the size of the square matrix. - public UserDefinedMatrix(int order) : base(order, order) + public UserDefinedMatrix(int order) + : this(new UserDefinedMatrixStorage(order, order)) { - _data = new Complex32[order, order]; } /// @@ -54,18 +94,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// /// The number of rows. /// The number of columns. - public UserDefinedMatrix(int rows, int columns) : base(rows, columns) + public UserDefinedMatrix(int rows, int columns) + : this(new UserDefinedMatrixStorage(rows, columns)) { - _data = new Complex32[rows, columns]; } /// /// Initializes a new instance of the class from a 2D array. /// /// The 2D array to create this matrix from. - public UserDefinedMatrix(Complex32[,] data) : base(data.GetLength(0), data.GetLength(1)) + public UserDefinedMatrix(Complex32[,] data) + : this(new UserDefinedMatrixStorage(data.GetLength(0), data.GetLength(1), (Complex32[,])data.Clone())) { - _data = (Complex32[,])data.Clone(); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs index 74fd4992..f0e8ee35 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs @@ -24,6 +24,9 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra.Storage; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { using LinearAlgebra.Double; @@ -34,18 +37,55 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// internal class UserDefinedMatrix : Matrix { - /// - /// Values storage - /// - private readonly double[,] _data; + private class UserDefinedMatrixStorage : MatrixStorage + { + public readonly double[,] Data; + + public UserDefinedMatrixStorage(int rowCount, int columnCount) + : base(rowCount, columnCount) + { + Data = new double[rowCount,columnCount]; + } + + public UserDefinedMatrixStorage(int rowCount, int columnCount, double[,] data) + : base(rowCount, columnCount) + { + Data = data; + } + + public override double At(int row, int column) + { + return Data[row, column]; + } + + public override void At(int row, int column, double value) + { + Data[row, column] = value; + } + + public override void Clear() + { + Array.Clear(Data, 0, RowCount * ColumnCount); + } + } + + readonly UserDefinedMatrixStorage _storage; + readonly double[,] _data; + + private UserDefinedMatrix(UserDefinedMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } /// /// Initializes a new instance of the class. This matrix is square with a given size. /// /// the size of the square matrix. - public UserDefinedMatrix(int order) : base(order, order) + public UserDefinedMatrix(int order) + : this(new UserDefinedMatrixStorage(order, order)) { - _data = new double[order, order]; } /// @@ -53,18 +93,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// /// The number of rows. /// The number of columns. - public UserDefinedMatrix(int rows, int columns) : base(rows, columns) + public UserDefinedMatrix(int rows, int columns) + : this(new UserDefinedMatrixStorage(rows, columns)) { - _data = new double[rows, columns]; } /// /// Initializes a new instance of the class from a 2D array. /// /// The 2D array to create this matrix from. - public UserDefinedMatrix(double[,] data) : base(data.GetLength(0), data.GetLength(1)) + public UserDefinedMatrix(double[,] data) + : this(new UserDefinedMatrixStorage(data.GetLength(0), data.GetLength(1), (double[,])data.Clone())) { - _data = (double[,])data.Clone(); } /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs index 8c952436..75e71b9d 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs @@ -24,6 +24,9 @@ // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.LinearAlgebra.Storage; + namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { using LinearAlgebra.Generic; @@ -34,18 +37,55 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// internal class UserDefinedMatrix : Matrix { - /// - /// Values storage - /// - private readonly float[,] _data; + class UserDefinedMatrixStorage : MatrixStorage + { + public readonly float[,] Data; + + public UserDefinedMatrixStorage(int rowCount, int columnCount) + : base(rowCount, columnCount) + { + Data = new float[rowCount, columnCount]; + } + + public UserDefinedMatrixStorage(int rowCount, int columnCount, float[,] data) + : base(rowCount, columnCount) + { + Data = data; + } + + public override float At(int row, int column) + { + return Data[row, column]; + } + + public override void At(int row, int column, float value) + { + Data[row, column] = value; + } + + public override void Clear() + { + Array.Clear(Data, 0, RowCount*ColumnCount); + } + } + + readonly UserDefinedMatrixStorage _storage; + readonly float[,] _data; + + private UserDefinedMatrix(UserDefinedMatrixStorage storage) + : base(storage) + { + _storage = storage; + _data = _storage.Data; + } /// /// Initializes a new instance of the class. This matrix is square with a given size. /// /// the size of the square matrix. - public UserDefinedMatrix(int order) : base(order, order) + public UserDefinedMatrix(int order) + : this(new UserDefinedMatrixStorage(order, order)) { - _data = new float[order, order]; } /// @@ -53,18 +93,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// /// The number of rows. /// The number of columns. - public UserDefinedMatrix(int rows, int columns) : base(rows, columns) + public UserDefinedMatrix(int rows, int columns) + : this(new UserDefinedMatrixStorage(rows, columns)) { - _data = new float[rows, columns]; } /// /// Initializes a new instance of the class from a 2D array. /// /// The 2D array to create this matrix from. - public UserDefinedMatrix(float[,] data) : base(data.GetLength(0), data.GetLength(1)) + public UserDefinedMatrix(float[,] data) + : this(new UserDefinedMatrixStorage(data.GetLength(0), data.GetLength(1), (float[,])data.Clone())) { - _data = (float[,])data.Clone(); } ///