diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
index 825b2877..a2cf4afa 100644
--- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
@@ -1152,43 +1152,52 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// If the two matrices don't have the same dimensions.
protected override void DoAdd(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ base.DoAdd(other, result);
+ return;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- result.At(i, _columnIndices[j], resVal);
- }
- }
+ if (ReferenceEquals(this, other))
+ {
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
}
+
+ Control.LinearAlgebraProvider.ScaleArray(2.0, _nonZeroValues, _nonZeroValues);
+ return;
+ }
+
+ SparseMatrix left;
+
+ if (ReferenceEquals(sparseOther, sparseResult))
+ {
+ left = this;
+ }
+ else if (ReferenceEquals(this, sparseResult))
+ {
+ left = sparseOther;
}
else
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ CopyTo(sparseResult);
+ left = sparseOther;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
- }
+ for (var i = 0; i < left.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = left._rowIndex[i];
+ var endIndex = i < left._rowIndex.Length - 1 ? left._rowIndex[i + 1] : left.NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var columnIndex = left._columnIndices[j];
+ var resVal = left._nonZeroValues[j] + result.At(i, columnIndex);
+ result.At(i, columnIndex, resVal);
}
}
}
@@ -1202,30 +1211,46 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// If the two matrices don't have the same dimensions.
protected override void DoSubtract(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
+ {
+ base.DoSubtract(other, result);
+ return;
+ }
+
+ if (ReferenceEquals(this, other))
{
- for (var i = 0; i < other.RowCount; i++)
+ result.Clear();
+ return;
+ }
+
+ if (ReferenceEquals(this, sparseResult))
+ {
+ for (var i = 0; i < sparseOther.RowCount; i++)
{
// Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ var startIndex = sparseOther._rowIndex[i];
+ var endIndex = i < sparseOther._rowIndex.Length - 1 ? sparseOther._rowIndex[i + 1] : sparseOther.NonZerosCount;
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- result.At(i, _columnIndices[j], resVal);
- }
+ var columnIndex = sparseOther._columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) - sparseOther._nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
else
{
- for (var i = 0; i < other.RowCount; i++)
+ if (!ReferenceEquals(sparseOther, sparseResult))
+ {
+ sparseOther.CopyTo(sparseResult);
+ }
+
+ sparseResult.Negate(sparseResult);
+
+ for (var i = 0; i < RowCount; i++)
{
// Get the begin / end index for the current row
var startIndex = _rowIndex[i];
@@ -1233,11 +1258,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
+ var columnIndex = _columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) + _nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
index 1e6d03c6..f5c3c4c0 100644
--- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
@@ -1152,43 +1152,52 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// If the two matrices don't have the same dimensions.
protected override void DoAdd(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ base.DoAdd(other, result);
+ return;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- result.At(i, _columnIndices[j], resVal);
- }
- }
+ if (ReferenceEquals(this, other))
+ {
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
}
+
+ Control.LinearAlgebraProvider.ScaleArray(2.0f, _nonZeroValues, _nonZeroValues);
+ return;
+ }
+
+ SparseMatrix left;
+
+ if (ReferenceEquals(sparseOther, sparseResult))
+ {
+ left = this;
+ }
+ else if (ReferenceEquals(this, sparseResult))
+ {
+ left = sparseOther;
}
else
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ CopyTo(sparseResult);
+ left = sparseOther;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
- }
+ for (var i = 0; i < left.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = left._rowIndex[i];
+ var endIndex = i < left._rowIndex.Length - 1 ? left._rowIndex[i + 1] : left.NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var columnIndex = left._columnIndices[j];
+ var resVal = left._nonZeroValues[j] + result.At(i, columnIndex);
+ result.At(i, columnIndex, resVal);
}
}
}
@@ -1202,30 +1211,46 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// If the two matrices don't have the same dimensions.
protected override void DoSubtract(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
+ {
+ base.DoSubtract(other, result);
+ return;
+ }
+
+ if (ReferenceEquals(this, other))
{
- for (var i = 0; i < other.RowCount; i++)
+ result.Clear();
+ return;
+ }
+
+ if (ReferenceEquals(this, sparseResult))
+ {
+ for (var i = 0; i < sparseOther.RowCount; i++)
{
// Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ var startIndex = sparseOther._rowIndex[i];
+ var endIndex = i < sparseOther._rowIndex.Length - 1 ? sparseOther._rowIndex[i + 1] : sparseOther.NonZerosCount;
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- result.At(i, _columnIndices[j], resVal);
- }
+ var columnIndex = sparseOther._columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) - sparseOther._nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
else
{
- for (var i = 0; i < other.RowCount; i++)
+ if (!ReferenceEquals(sparseOther, sparseResult))
+ {
+ sparseOther.CopyTo(sparseResult);
+ }
+
+ sparseResult.Negate(sparseResult);
+
+ for (var i = 0; i < RowCount; i++)
{
// Get the begin / end index for the current row
var startIndex = _rowIndex[i];
@@ -1233,11 +1258,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
+ var columnIndex = _columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) + _nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
index 43a10b57..1a1def63 100644
--- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
@@ -1163,43 +1163,52 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// If the two matrices don't have the same dimensions.
protected override void DoAdd(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ base.DoAdd(other, result);
+ return;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- result.At(i, _columnIndices[j], resVal);
- }
- }
+ if (ReferenceEquals(this, other))
+ {
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
}
+
+ Control.LinearAlgebraProvider.ScaleArray(2.0, _nonZeroValues, _nonZeroValues);
+ return;
+ }
+
+ SparseMatrix left;
+
+ if (ReferenceEquals(sparseOther, sparseResult))
+ {
+ left = this;
+ }
+ else if (ReferenceEquals(this, sparseResult))
+ {
+ left = sparseOther;
}
else
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ CopyTo(sparseResult);
+ left = sparseOther;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
- }
+ for (var i = 0; i < left.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = left._rowIndex[i];
+ var endIndex = i < left._rowIndex.Length - 1 ? left._rowIndex[i + 1] : left.NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var columnIndex = left._columnIndices[j];
+ var resVal = left._nonZeroValues[j] + result.At(i, columnIndex);
+ result.At(i, columnIndex, resVal);
}
}
}
@@ -1213,30 +1222,46 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// If the two matrices don't have the same dimensions.
protected override void DoSubtract(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
+ {
+ base.DoSubtract(other, result);
+ return;
+ }
+
+ if (ReferenceEquals(this, other))
{
- for (var i = 0; i < other.RowCount; i++)
+ result.Clear();
+ return;
+ }
+
+ if (ReferenceEquals(this, sparseResult))
+ {
+ for (var i = 0; i < sparseOther.RowCount; i++)
{
// Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ var startIndex = sparseOther._rowIndex[i];
+ var endIndex = i < sparseOther._rowIndex.Length - 1 ? sparseOther._rowIndex[i + 1] : sparseOther.NonZerosCount;
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- result.At(i, _columnIndices[j], resVal);
- }
+ var columnIndex = sparseOther._columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) - sparseOther._nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
else
{
- for (var i = 0; i < other.RowCount; i++)
+ if (!ReferenceEquals(sparseOther, sparseResult))
+ {
+ sparseOther.CopyTo(sparseResult);
+ }
+
+ sparseResult.Negate(sparseResult);
+
+ for (var i = 0; i < RowCount; i++)
{
// Get the begin / end index for the current row
var startIndex = _rowIndex[i];
@@ -1244,11 +1269,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
+ var columnIndex = _columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) + _nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
index c0ab7de3..9525ced1 100644
--- a/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
+++ b/src/Numerics/LinearAlgebra/Generic/Matrix.Arithmetic.cs
@@ -66,7 +66,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateMatrix(RowCount, ColumnCount);
- Add(other, result);
+ DoAdd(other, result);
return result;
}
@@ -177,7 +177,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateMatrix(RowCount, ColumnCount);
- Multiply(scalar, result);
+ DoMultiply(scalar, result);
return result;
}
@@ -238,7 +238,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
var result = CreateMatrix(RowCount, ColumnCount);
- Divide(scalar, result);
+ DoDivide(scalar, result);
return result;
}
@@ -577,7 +577,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
public virtual Matrix Negate()
{
var result = CreateMatrix(RowCount, ColumnCount);
- Negate(result);
+ DoNegate(result);
return result;
}
diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs
index f2efa00c..945bf895 100644
--- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs
@@ -1146,43 +1146,52 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// If the two matrices don't have the same dimensions.
protected override void DoAdd(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ base.DoAdd(other, result);
+ return;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- result.At(i, _columnIndices[j], resVal);
- }
- }
+ if (ReferenceEquals(this, other))
+ {
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
}
+
+ Control.LinearAlgebraProvider.ScaleArray(2.0f, _nonZeroValues, _nonZeroValues);
+ return;
+ }
+
+ SparseMatrix left;
+
+ if (ReferenceEquals(sparseOther, sparseResult))
+ {
+ left = this;
+ }
+ else if (ReferenceEquals(this, sparseResult))
+ {
+ left = sparseOther;
}
else
{
- for (var i = 0; i < other.RowCount; i++)
- {
- // Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ CopyTo(sparseResult);
+ left = sparseOther;
+ }
- for (var j = startIndex; j < endIndex; j++)
- {
- var resVal = _nonZeroValues[j] + other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
- }
+ for (var i = 0; i < left.RowCount; i++)
+ {
+ // Get the begin / end index for the current row
+ var startIndex = left._rowIndex[i];
+ var endIndex = i < left._rowIndex.Length - 1 ? left._rowIndex[i + 1] : left.NonZerosCount;
+
+ for (var j = startIndex; j < endIndex; j++)
+ {
+ var columnIndex = left._columnIndices[j];
+ var resVal = left._nonZeroValues[j] + result.At(i, columnIndex);
+ result.At(i, columnIndex, resVal);
}
}
}
@@ -1196,30 +1205,46 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// If the two matrices don't have the same dimensions.
protected override void DoSubtract(Matrix other, Matrix result)
{
- result.Clear();
-
+ var sparseOther = other as SparseMatrix;
var sparseResult = result as SparseMatrix;
- if (sparseResult == null)
+ if (sparseOther == null || sparseResult == null)
+ {
+ base.DoSubtract(other, result);
+ return;
+ }
+
+ if (ReferenceEquals(this, other))
+ {
+ result.Clear();
+ return;
+ }
+
+ if (ReferenceEquals(this, sparseResult))
{
- for (var i = 0; i < other.RowCount; i++)
+ for (var i = 0; i < sparseOther.RowCount; i++)
{
// Get the begin / end index for the current row
- var startIndex = _rowIndex[i];
- var endIndex = i < _rowIndex.Length - 1 ? _rowIndex[i + 1] : NonZerosCount;
+ var startIndex = sparseOther._rowIndex[i];
+ var endIndex = i < sparseOther._rowIndex.Length - 1 ? sparseOther._rowIndex[i + 1] : sparseOther.NonZerosCount;
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- result.At(i, _columnIndices[j], resVal);
- }
+ var columnIndex = sparseOther._columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) - sparseOther._nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
else
{
- for (var i = 0; i < other.RowCount; i++)
+ if (!ReferenceEquals(sparseOther, sparseResult))
+ {
+ sparseOther.CopyTo(sparseResult);
+ }
+
+ sparseResult.Negate(sparseResult);
+
+ for (var i = 0; i < RowCount; i++)
{
// Get the begin / end index for the current row
var startIndex = _rowIndex[i];
@@ -1227,16 +1252,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single
for (var j = startIndex; j < endIndex; j++)
{
- var resVal = _nonZeroValues[j] - other.At(i, _columnIndices[j]);
- if (resVal != 0.0f)
- {
- sparseResult.SetValueAt(i, _columnIndices[j], resVal);
- }
+ var columnIndex = _columnIndices[j];
+ var resVal = sparseResult.At(i, columnIndex) + _nonZeroValues[j];
+ result.At(i, columnIndex, resVal);
}
}
}
}
-
+
///
/// Multiplies each element of the matrix by a scalar and places results into the result matrix.
///
diff --git a/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs
index 610026a2..886e7022 100644
--- a/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Complex/SparseMatrixTests.cs
@@ -209,5 +209,93 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex
Assert.AreEqual(matrix.NonZerosCount, nonzero);
}
+
+ ///
+ /// Test whether order matters when adding sparse matrices.
+ ///
+ [Test]
+ public void CanAddSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ var sum1 = m1 + m2;
+ var sum2 = m2 + m1;
+ Assert.IsTrue(sum1.Equals(m2));
+ Assert.IsTrue(sum1.Equals(sum2));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Add(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ sparseResult.Add(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ m1.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ sparseResult.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(2 * sum1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Add(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ denseResult = new DenseMatrix(new Complex[,] { { 0, 1, 1 } });
+ denseResult.Add(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ var m3 = new DenseMatrix(new Complex[,] { { 0, 1, 1 } });
+ var sum3 = m1 + m3;
+ var sum4 = m3 + m1;
+ Assert.IsTrue(sum3.Equals(m3));
+ Assert.IsTrue(sum3.Equals(sum4));
+ }
+
+ ///
+ /// Test whether order matters when subtracting sparse matrices.
+ ///
+ [Test]
+ public void CanSubtractSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ var diff1 = m1 - m2;
+ var diff2 = m2 - m1;
+ Assert.IsTrue(diff1.Equals(m2.Negate()));
+ Assert.IsTrue(diff1.Equals(diff2.Negate()));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Subtract(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff2));
+
+ sparseResult = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ m1.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new Complex[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(0 * diff1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Subtract(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff1));
+
+ denseResult = new DenseMatrix(new Complex[,] { { 0, 1, 1 } });
+ denseResult.Subtract(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff2));
+
+ var m3 = new DenseMatrix(new Complex[,] { { 0, 1, 1 } });
+ var diff3 = m1 - m3;
+ var diff4 = m3 - m1;
+ Assert.IsTrue(diff3.Equals(m3.Negate()));
+ Assert.IsTrue(diff3.Equals(diff4.Negate()));
+ }
}
}
diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs
index d204b878..62c63a73 100644
--- a/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Complex32/SparseMatrixTests.cs
@@ -209,5 +209,93 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
Assert.AreEqual(matrix.NonZerosCount, nonzero);
}
+
+ ///
+ /// Test whether order matters when adding sparse matrices.
+ ///
+ [Test]
+ public void CanAddSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ var sum1 = m1 + m2;
+ var sum2 = m2 + m1;
+ Assert.IsTrue(sum1.Equals(m2));
+ Assert.IsTrue(sum1.Equals(sum2));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Add(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ sparseResult.Add(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ m1.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ sparseResult.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(2 * sum1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Add(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ denseResult = new DenseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ denseResult.Add(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ var m3 = new DenseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ var sum3 = m1 + m3;
+ var sum4 = m3 + m1;
+ Assert.IsTrue(sum3.Equals(m3));
+ Assert.IsTrue(sum3.Equals(sum4));
+ }
+
+ ///
+ /// Test whether order matters when subtracting sparse matrices.
+ ///
+ [Test]
+ public void CanSubtractSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ var diff1 = m1 - m2;
+ var diff2 = m2 - m1;
+ Assert.IsTrue(diff1.Equals(m2.Negate()));
+ Assert.IsTrue(diff1.Equals(diff2.Negate()));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Subtract(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff2));
+
+ sparseResult = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ m1.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(0 * diff1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Subtract(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff1));
+
+ denseResult = new DenseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ denseResult.Subtract(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff2));
+
+ var m3 = new DenseMatrix(new Complex32[,] { { 0, 1, 1 } });
+ var diff3 = m1 - m3;
+ var diff4 = m3 - m1;
+ Assert.IsTrue(diff3.Equals(m3.Negate()));
+ Assert.IsTrue(diff3.Equals(diff4.Negate()));
+ }
}
}
diff --git a/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs
index 027446e4..bb7bd52a 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/SparseMatrixTests.cs
@@ -208,5 +208,93 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
Assert.AreEqual(matrix.NonZerosCount, nonzero);
}
+
+ ///
+ /// Test whether order matters when adding sparse matrices.
+ ///
+ [Test]
+ public void CanAddSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ var sum1 = m1 + m2;
+ var sum2 = m2 + m1;
+ Assert.IsTrue(sum1.Equals(m2));
+ Assert.IsTrue(sum1.Equals(sum2));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Add(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ sparseResult.Add(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ m1.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ sparseResult.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(2 * sum1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Add(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ denseResult = new DenseMatrix(new double[,] { { 0, 1, 1 } });
+ denseResult.Add(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ var m3 = new DenseMatrix(new double[,] { { 0, 1, 1 } });
+ var sum3 = m1 + m3;
+ var sum4 = m3 + m1;
+ Assert.IsTrue(sum3.Equals(m3));
+ Assert.IsTrue(sum3.Equals(sum4));
+ }
+
+ ///
+ /// Test whether order matters when subtracting sparse matrices.
+ ///
+ [Test]
+ public void CanSubtractSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ var diff1 = m1 - m2;
+ var diff2 = m2 - m1;
+ Assert.IsTrue(diff1.Equals(m2.Negate()));
+ Assert.IsTrue(diff1.Equals(diff2.Negate()));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Subtract(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff2));
+
+ sparseResult = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ m1.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new double[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(0 * diff1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Subtract(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff1));
+
+ denseResult = new DenseMatrix(new double[,] { { 0, 1, 1 } });
+ denseResult.Subtract(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff2));
+
+ var m3 = new DenseMatrix(new double[,] { { 0, 1, 1 } });
+ var diff3 = m1 - m3;
+ var diff4 = m3 - m1;
+ Assert.IsTrue(diff3.Equals(m3.Negate()));
+ Assert.IsTrue(diff3.Equals(diff4.Negate()));
+ }
}
}
diff --git a/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs
index 09b10117..54b14d6d 100644
--- a/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Single/SparseMatrixTests.cs
@@ -208,5 +208,93 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single
Assert.AreEqual(matrix.NonZerosCount, nonzero);
}
+
+ ///
+ /// Test whether order matters when adding sparse matrices.
+ ///
+ [Test]
+ public void CanAddSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ var sum1 = m1 + m2;
+ var sum2 = m2 + m1;
+ Assert.IsTrue(sum1.Equals(m2));
+ Assert.IsTrue(sum1.Equals(sum2));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Add(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ sparseResult.Add(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ m1.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(sum1));
+
+ sparseResult = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ sparseResult.Add(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(2 * sum1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Add(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ denseResult = new DenseMatrix(new float[,] { { 0, 1, 1 } });
+ denseResult.Add(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(sum1));
+
+ var m3 = new DenseMatrix(new float[,] { { 0, 1, 1 } });
+ var sum3 = m1 + m3;
+ var sum4 = m3 + m1;
+ Assert.IsTrue(sum3.Equals(m3));
+ Assert.IsTrue(sum3.Equals(sum4));
+ }
+
+ ///
+ /// Test whether order matters when subtracting sparse matrices.
+ ///
+ [Test]
+ public void CanSubtractSparseMatricesBothWays()
+ {
+ var m1 = new SparseMatrix(1, 3);
+ var m2 = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ var diff1 = m1 - m2;
+ var diff2 = m2 - m1;
+ Assert.IsTrue(diff1.Equals(m2.Negate()));
+ Assert.IsTrue(diff1.Equals(diff2.Negate()));
+
+ var sparseResult = new SparseMatrix(1, 3);
+ sparseResult.Subtract(m2, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(m1, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff2));
+
+ sparseResult = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ m1.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(diff1));
+
+ sparseResult = new SparseMatrix(new float[,] { { 0, 1, 1 } });
+ sparseResult.Subtract(sparseResult, sparseResult);
+ Assert.IsTrue(sparseResult.Equals(0 * diff1));
+
+ var denseResult = new DenseMatrix(1, 3);
+ denseResult.Subtract(m2, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff1));
+
+ denseResult = new DenseMatrix(new float[,] { { 0, 1, 1 } });
+ denseResult.Subtract(m1, denseResult);
+ Assert.IsTrue(denseResult.Equals(diff2));
+
+ var m3 = new DenseMatrix(new float[,] { { 0, 1, 1 } });
+ var diff3 = m1 - m3;
+ var diff4 = m3 - m1;
+ Assert.IsTrue(diff3.Equals(m3.Negate()));
+ Assert.IsTrue(diff3.Equals(diff4.Negate()));
+ }
}
}