diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 2f5c499e..fdab532d 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -665,13 +665,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex index = ~index; // Check if the storage needs to be increased - if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < (RowCount * ColumnCount))) + if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < ((long)RowCount * ColumnCount))) { // Value array is completely full so we increase the size // Determine the increase in size. We will not grow beyond the size of the matrix - var size = Math.Min(_nonZeroValues.Length + GrowthSize(), RowCount * ColumnCount); - Array.Resize(ref _nonZeroValues, size); - Array.Resize(ref _columnIndices, size); + var size = Math.Min(_nonZeroValues.Length + GrowthSize(), (long)RowCount * ColumnCount); + if (size > int.MaxValue) + { + throw new NotSupportedException(Resources.TooManyElements); + } + + Array.Resize(ref _nonZeroValues, (int)size); + Array.Resize(ref _columnIndices, (int)size); } // Move all values (with an position larger than index) in the value array to the next position diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 6c594fc7..7444a165 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -666,13 +666,18 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 index = ~index; // Check if the storage needs to be increased - if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < (RowCount * ColumnCount))) + if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < ((long)RowCount * ColumnCount))) { // Value array is completely full so we increase the size // Determine the increase in size. We will not grow beyond the size of the matrix - var size = Math.Min(_nonZeroValues.Length + GrowthSize(), RowCount * ColumnCount); - Array.Resize(ref _nonZeroValues, size); - Array.Resize(ref _columnIndices, size); + var size = Math.Min(_nonZeroValues.Length + GrowthSize(), (long)RowCount * ColumnCount); + if (size > int.MaxValue) + { + throw new NotSupportedException(Resources.TooManyElements); + } + + Array.Resize(ref _nonZeroValues, (int)size); + Array.Resize(ref _columnIndices, (int)size); } // Move all values (with an position larger than index) in the value array to the next position diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index d06829e3..2abb2231 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -677,13 +677,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double index = ~index; // Check if the storage needs to be increased - if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < (RowCount * ColumnCount))) + if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < ((long)RowCount * ColumnCount))) { // Value array is completely full so we increase the size // Determine the increase in size. We will not grow beyond the size of the matrix - var size = Math.Min(_nonZeroValues.Length + GrowthSize(), RowCount * ColumnCount); - Array.Resize(ref _nonZeroValues, size); - Array.Resize(ref _columnIndices, size); + var size = Math.Min(_nonZeroValues.Length + GrowthSize(), (long)RowCount * ColumnCount); + if (size > int.MaxValue) + { + throw new NotSupportedException(Resources.TooManyElements); + } + + Array.Resize(ref _nonZeroValues, (int)size); + Array.Resize(ref _columnIndices, (int)size); } // Move all values (with an position larger than index) in the value array to the next position diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index 4edf02e1..fae0fb6f 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -660,13 +660,18 @@ namespace MathNet.Numerics.LinearAlgebra.Single index = ~index; // Check if the storage needs to be increased - if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < (RowCount * ColumnCount))) + if ((NonZerosCount == _nonZeroValues.Length) && (NonZerosCount < ((long)RowCount * ColumnCount))) { // Value array is completely full so we increase the size // Determine the increase in size. We will not grow beyond the size of the matrix - var size = Math.Min(_nonZeroValues.Length + GrowthSize(), RowCount * ColumnCount); - Array.Resize(ref _nonZeroValues, size); - Array.Resize(ref _columnIndices, size); + var size = Math.Min(_nonZeroValues.Length + GrowthSize(), (long)RowCount * ColumnCount); + if (size > int.MaxValue) + { + throw new NotSupportedException(Resources.TooManyElements); + } + + Array.Resize(ref _nonZeroValues, (int)size); + Array.Resize(ref _columnIndices, (int)size); } // Move all values (with an position larger than index) in the value array to the next position diff --git a/src/Numerics/Properties/Resources.Designer.cs b/src/Numerics/Properties/Resources.Designer.cs index 373ba4d3..afac0b4e 100644 --- a/src/Numerics/Properties/Resources.Designer.cs +++ b/src/Numerics/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.1 +// Runtime Version:4.0.30319.225 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -753,6 +753,15 @@ namespace MathNet.Numerics.Properties { } } + /// + /// Looks up a localized string similar to We only support sparse matrix with less than int.MaxValue elements.. + /// + internal static string TooManyElements { + get { + return ResourceManager.GetString("TooManyElements", resourceCulture); + } + } + /// /// Looks up a localized string similar to The moment of the distribution is undefined.. /// diff --git a/src/Numerics/Properties/Resources.resx b/src/Numerics/Properties/Resources.resx index 4f40d7d6..969bb57e 100644 --- a/src/Numerics/Properties/Resources.resx +++ b/src/Numerics/Properties/Resources.resx @@ -357,4 +357,7 @@ The number of rows must greater than or equal to the number of columns. + + We only support sparse matrix with less than int.MaxValue elements. + \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs index 886e7022..2183d7e4 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs @@ -297,5 +297,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex Assert.IsTrue(diff3.Equals(m3.Negate())); Assert.IsTrue(diff3.Equals(diff4.Negate())); } + + /// + /// Test whether we can create a large sparse matrix + /// + [Test] + public void CanCreateLargeMatrix() + { + const int order = 1000000; + var matrix = new SparseMatrix(order); + Assert.AreEqual(order, matrix.RowCount); + Assert.AreEqual(order, matrix.ColumnCount); + Assert.DoesNotThrow(() => matrix[0, 0] = 1); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs index 62c63a73..c1dbf407 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs @@ -297,5 +297,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 Assert.IsTrue(diff3.Equals(m3.Negate())); Assert.IsTrue(diff3.Equals(diff4.Negate())); } + + /// + /// Test whether we can create a large sparse matrix + /// + [Test] + public void CanCreateLargeMatrix() + { + const int order = 1000000; + var matrix = new SparseMatrix(order); + Assert.AreEqual(order, matrix.RowCount); + Assert.AreEqual(order, matrix.ColumnCount); + Assert.DoesNotThrow(() => matrix[0, 0] = 1); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs index bb7bd52a..15c741cf 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs @@ -296,5 +296,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.IsTrue(diff3.Equals(m3.Negate())); Assert.IsTrue(diff3.Equals(diff4.Negate())); } + + /// + /// Test whether we can create a large sparse matrix + /// + [Test] + public void CanCreateLargeMatrix() + { + const int order = 1000000; + var matrix = new SparseMatrix(order); + Assert.AreEqual(order, matrix.RowCount); + Assert.AreEqual(order, matrix.ColumnCount); + Assert.DoesNotThrow(() => matrix[0, 0] = 1); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs index 54b14d6d..baad4a95 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs @@ -296,5 +296,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single Assert.IsTrue(diff3.Equals(m3.Negate())); Assert.IsTrue(diff3.Equals(diff4.Negate())); } + + /// + /// Test whether we can create a large sparse matrix + /// + [Test] + public void CanCreateLargeMatrix() + { + const int order = 1000000; + var matrix = new SparseMatrix(order); + Assert.AreEqual(order, matrix.RowCount); + Assert.AreEqual(order, matrix.ColumnCount); + Assert.DoesNotThrow(() => matrix[0, 0] = 1); + } } }