Browse Source

LA: use enums for zero and existing data behavior instead of booleans (readability, errors)

provider
Christoph Ruegg 13 years ago
parent
commit
1681a5208f
  1. 18
      src/FSharp/LinearAlgebra.Matrix.fs
  2. 16
      src/FSharp/LinearAlgebra.Vector.fs
  3. 10
      src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
  4. 8
      src/Numerics/LinearAlgebra/Complex/Matrix.cs
  5. 4
      src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
  6. 6
      src/Numerics/LinearAlgebra/Complex/Vector.cs
  7. 10
      src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
  8. 8
      src/Numerics/LinearAlgebra/Complex32/Matrix.cs
  9. 4
      src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
  10. 6
      src/Numerics/LinearAlgebra/Complex32/Vector.cs
  11. 10
      src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
  12. 6
      src/Numerics/LinearAlgebra/Double/Matrix.cs
  13. 4
      src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
  14. 6
      src/Numerics/LinearAlgebra/Double/Vector.cs
  15. 58
      src/Numerics/LinearAlgebra/Matrix.cs
  16. 61
      src/Numerics/LinearAlgebra/Options.cs
  17. 10
      src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs
  18. 6
      src/Numerics/LinearAlgebra/Single/Matrix.cs
  19. 4
      src/Numerics/LinearAlgebra/Single/SparseMatrix.cs
  20. 6
      src/Numerics/LinearAlgebra/Single/Vector.cs
  21. 28
      src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs
  22. 22
      src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs
  23. 82
      src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs
  24. 66
      src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
  25. 76
      src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs
  26. 48
      src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs
  27. 54
      src/Numerics/LinearAlgebra/Storage/VectorStorage.cs
  28. 34
      src/Numerics/LinearAlgebra/Vector.cs
  29. 1
      src/Numerics/Numerics.csproj
  30. 66
      src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Map.cs

18
src/FSharp/LinearAlgebra.Matrix.fs

@ -207,18 +207,18 @@ module Matrix =
/// In-place map of every matrix element using a function. /// In-place map of every matrix element using a function.
let inline mapInPlace f (A: #Matrix<_>) = A.MapInplace((fun x -> f x), true) let inline mapInPlace f (A: #Matrix<_>) = A.MapInplace((fun x -> f x), Zeros.Include)
/// In-place map of every matrix element using a function. /// In-place map of every matrix element using a function.
/// Zero-values may be skipped (relevant mostly for sparse matrices). /// Zero-values may be skipped (relevant mostly for sparse matrices).
let inline mapSkipZerosInPlace f (A: #Matrix<_>) = A.MapInplace((fun x -> f x), false) let inline mapSkipZerosInPlace f (A: #Matrix<_>) = A.MapInplace((fun x -> f x), Zeros.AllowSkip)
/// In-place map of every matrix element using a position dependent function. /// In-place map of every matrix element using a position dependent function.
let inline mapiInPlace f (A: #Matrix<_>) = A.MapIndexedInplace((fun i j x -> f i j x), true) let inline mapiInPlace f (A: #Matrix<_>) = A.MapIndexedInplace((fun i j x -> f i j x), Zeros.Include)
/// In-place map of every matrix element using a position dependent function. /// In-place map of every matrix element using a position dependent function.
/// Zero-values may be skipped (relevant mostly for sparse matrices). /// Zero-values may be skipped (relevant mostly for sparse matrices).
let inline mapiSkipZerosInPlace f (A: #Matrix<_>) = A.MapIndexedInplace((fun i j x -> f i j x), false) let inline mapiSkipZerosInPlace f (A: #Matrix<_>) = A.MapIndexedInplace((fun i j x -> f i j x), Zeros.AllowSkip)
/// In-place map every matrix column using the given position dependent function. /// In-place map every matrix column using the given position dependent function.
let inline mapColsInPlace (f: int -> Vector<'a> -> Vector<'a>) (A: #Matrix<_>) = let inline mapColsInPlace (f: int -> Vector<'a> -> Vector<'a>) (A: #Matrix<_>) =
@ -232,18 +232,18 @@ module Matrix =
/// Map every matrix element using the given function. /// Map every matrix element using the given function.
let inline map f (A: #Matrix<_>) = A.Map((fun x -> f x), true) let inline map f (A: #Matrix<_>) = A.Map((fun x -> f x), Zeros.Include)
/// Map every matrix element using the given function. /// Map every matrix element using the given function.
/// Zero-values may be skipped (relevant mostly for sparse matrices). /// Zero-values may be skipped (relevant mostly for sparse matrices).
let inline mapSkipZeros f (A: #Matrix<_>) = A.Map((fun x -> f x), false) let inline mapSkipZeros f (A: #Matrix<_>) = A.Map((fun x -> f x), Zeros.AllowSkip)
/// Map every matrix element using the given position dependent function. /// Map every matrix element using the given position dependent function.
let inline mapi f (A: #Matrix<_>) = A.MapIndexed((fun i j x -> f i j x), true) let inline mapi f (A: #Matrix<_>) = A.MapIndexed((fun i j x -> f i j x), Zeros.Include)
/// Map every matrix element using the given position dependent function. /// Map every matrix element using the given position dependent function.
/// Zero-values may be skipped (relevant mostly for sparse matrices). /// Zero-values may be skipped (relevant mostly for sparse matrices).
let inline mapiSkipZeros f (A: #Matrix<_>) = A.MapIndexed((fun i j x -> f i j x), false) let inline mapiSkipZeros f (A: #Matrix<_>) = A.MapIndexed((fun i j x -> f i j x), Zeros.AllowSkip)
/// Map every matrix column using the given position dependent function. /// Map every matrix column using the given position dependent function.
let inline mapCols (f: int -> Vector<'a> -> Vector<'a>) (A: #Matrix<_>) = let inline mapCols (f: int -> Vector<'a> -> Vector<'a>) (A: #Matrix<_>) =
@ -285,7 +285,7 @@ module Matrix =
/// In-place assignment. /// In-place assignment.
let inline inplaceAssign f (A: #Matrix<_>) = let inline inplaceAssign f (A: #Matrix<_>) =
A.MapIndexedInplace((fun i j x -> f i j), true) A.MapIndexedInplace((fun i j x -> f i j), Zeros.Include)
/// Fold all columns into one row vector. /// Fold all columns into one row vector.
let inline foldByCol f acc (A: #Matrix<'T>) = let inline foldByCol f acc (A: #Matrix<'T>) =

16
src/FSharp/LinearAlgebra.Vector.fs

@ -132,33 +132,33 @@ module Vector =
/// In-place mutation by applying a function to every element of the vector. /// In-place mutation by applying a function to every element of the vector.
let inline mapInPlace f (v: #Vector<_>) = v.MapInplace((fun x -> f x), true) let inline mapInPlace f (v: #Vector<_>) = v.MapInplace((fun x -> f x), Zeros.Include)
/// In-place mutation by applying a function to every element of the vector. /// In-place mutation by applying a function to every element of the vector.
let inline mapiInPlace f (v: #Vector<_>) = v.MapIndexedInplace((fun i x -> f i x), true) let inline mapiInPlace f (v: #Vector<_>) = v.MapIndexedInplace((fun i x -> f i x), Zeros.Include)
/// In-place mutation by applying a function to every element of the vector. /// In-place mutation by applying a function to every element of the vector.
/// Zero-values may be skipped (relevant mostly for sparse vectors). /// Zero-values may be skipped (relevant mostly for sparse vectors).
let inline mapSkipZerosInPlace f (v: #Vector<_>) = v.MapInplace((fun x -> f x), false) let inline mapSkipZerosInPlace f (v: #Vector<_>) = v.MapInplace((fun x -> f x), Zeros.AllowSkip)
/// In-place mutation by applying a function to every element of the vector. /// In-place mutation by applying a function to every element of the vector.
/// Zero-values may be skipped (relevant mostly for sparse vectors). /// Zero-values may be skipped (relevant mostly for sparse vectors).
let inline mapiSkipZerosInPlace f (v: #Vector<_>) = v.MapIndexedInplace((fun i x -> f i x), false) let inline mapiSkipZerosInPlace f (v: #Vector<_>) = v.MapIndexedInplace((fun i x -> f i x), Zeros.AllowSkip)
/// Maps a vector to a new vector by applying a function to every element. /// Maps a vector to a new vector by applying a function to every element.
let inline map f (v: #Vector<_>) = v.Map((fun x -> f x), true) let inline map f (v: #Vector<_>) = v.Map((fun x -> f x), Zeros.Include)
/// Maps a vector to a new vector by applying a function to every element. /// Maps a vector to a new vector by applying a function to every element.
/// Zero-values may be skipped (relevant mostly for sparse vectors). /// Zero-values may be skipped (relevant mostly for sparse vectors).
let inline mapSkipZeros f (v: #Vector<_>) = v.Map((fun x -> f x), false) let inline mapSkipZeros f (v: #Vector<_>) = v.Map((fun x -> f x), Zeros.AllowSkip)
/// Maps a vector to a new vector by applying a function to every element. /// Maps a vector to a new vector by applying a function to every element.
let inline mapi f (v: #Vector<_>) = v.MapIndexed((fun i x -> f i x), true) let inline mapi f (v: #Vector<_>) = v.MapIndexed((fun i x -> f i x), Zeros.Include)
/// Maps a vector to a new vector by applying a function to every element. /// Maps a vector to a new vector by applying a function to every element.
/// Zero-values may be skipped (relevant mostly for sparse vectors). /// Zero-values may be skipped (relevant mostly for sparse vectors).
let inline mapiSkipZeros f (v: #Vector<_>) = v.MapIndexed((fun i x -> f i x), false) let inline mapiSkipZeros f (v: #Vector<_>) = v.MapIndexed((fun i x -> f i x), Zeros.AllowSkip)

10
src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs

@ -437,12 +437,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -580,12 +580,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -931,7 +931,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
? (Matrix<Complex>)new DiagonalMatrix(rowCount, columnCount) ? (Matrix<Complex>)new DiagonalMatrix(rowCount, columnCount)
: new SparseMatrix(rowCount, columnCount); : new SparseMatrix(rowCount, columnCount);
Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, skipClearing: true); Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, ExistingData.AssumeZeros);
return target; return target;
} }

8
src/Numerics/LinearAlgebra/Complex/Matrix.cs

@ -113,7 +113,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
public override sealed Matrix<Complex> ConjugateTranspose() public override sealed Matrix<Complex> ConjugateTranspose()
{ {
var ret = Transpose(); var ret = Transpose();
ret.MapInplace(c => c.Conjugate(), forceMapZeros: false); ret.MapInplace(c => c.Conjugate(), Zeros.AllowSkip);
return ret; return ret;
} }
@ -455,7 +455,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(Complex exponent, Matrix<Complex> result) protected override void DoPointwisePower(Complex exponent, Matrix<Complex> result)
{ {
Map(x => x.Power(exponent), result, forceMapZeros: false); Map(x => x.Power(exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -530,7 +530,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseExp(Matrix<Complex> result) protected override void DoPointwiseExp(Matrix<Complex> result)
{ {
Map(Complex.Exp, result, forceMapZeros: true); Map(Complex.Exp, result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -539,7 +539,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseLog(Matrix<Complex> result) protected override void DoPointwiseLog(Matrix<Complex> result)
{ {
Map(Complex.Log, result, forceMapZeros: true); Map(Complex.Log, result, Zeros.Include);
} }
/// <summary> /// <summary>

4
src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs

@ -901,12 +901,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
var diagonal = diagonalOther.Data; var diagonal = diagonalOther.Data;
if (other.ColumnCount == other.RowCount) if (other.ColumnCount == other.RowCount)
{ {
Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], false, false); Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Storage.Clear(); result.Storage.Clear();
Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, false, true); Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
return; return;
} }

6
src/Numerics/LinearAlgebra/Complex/Vector.cs

@ -197,7 +197,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(Complex exponent, Vector<Complex> result) protected override void DoPointwisePower(Complex exponent, Vector<Complex> result)
{ {
Map(x => x.Power(exponent), result, forceMapZeros: false); Map(x => x.Power(exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -228,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseExp(Vector<Complex> result) protected override void DoPointwiseExp(Vector<Complex> result)
{ {
Map(Complex.Exp, result, forceMapZeros: true); Map(Complex.Exp, result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -237,7 +237,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseLog(Vector<Complex> result) protected override void DoPointwiseLog(Vector<Complex> result)
{ {
Map(Complex.Log, result, forceMapZeros: true); Map(Complex.Log, result, Zeros.Include);
} }
/// <summary> /// <summary>

10
src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs

@ -431,12 +431,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -574,12 +574,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -925,7 +925,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
? (Matrix<Complex32>)new DiagonalMatrix(rowCount, columnCount) ? (Matrix<Complex32>)new DiagonalMatrix(rowCount, columnCount)
: new SparseMatrix(rowCount, columnCount); : new SparseMatrix(rowCount, columnCount);
Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, skipClearing: true); Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, ExistingData.AssumeZeros);
return target; return target;
} }

8
src/Numerics/LinearAlgebra/Complex32/Matrix.cs

@ -107,7 +107,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
public override sealed Matrix<Complex32> ConjugateTranspose() public override sealed Matrix<Complex32> ConjugateTranspose()
{ {
var ret = Transpose(); var ret = Transpose();
ret.MapInplace(c => c.Conjugate(), forceMapZeros: false); ret.MapInplace(c => c.Conjugate(), Zeros.AllowSkip);
return ret; return ret;
} }
@ -449,7 +449,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(Complex32 exponent, Matrix<Complex32> result) protected override void DoPointwisePower(Complex32 exponent, Matrix<Complex32> result)
{ {
Map(x => x.Power(exponent), result, forceMapZeros: false); Map(x => x.Power(exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -524,7 +524,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseExp(Matrix<Complex32> result) protected override void DoPointwiseExp(Matrix<Complex32> result)
{ {
Map(Complex32.Exp, result, forceMapZeros: true); Map(Complex32.Exp, result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -533,7 +533,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseLog(Matrix<Complex32> result) protected override void DoPointwiseLog(Matrix<Complex32> result)
{ {
Map(Complex32.Log, result, forceMapZeros: true); Map(Complex32.Log, result, Zeros.Include);
} }
/// <summary> /// <summary>

4
src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs

@ -895,12 +895,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
var diagonal = diagonalOther.Data; var diagonal = diagonalOther.Data;
if (other.ColumnCount == other.RowCount) if (other.ColumnCount == other.RowCount)
{ {
Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], false, false); Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Storage.Clear(); result.Storage.Clear();
Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, false, true); Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
return; return;
} }

6
src/Numerics/LinearAlgebra/Complex32/Vector.cs

@ -192,7 +192,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(Complex32 exponent, Vector<Complex32> result) protected override void DoPointwisePower(Complex32 exponent, Vector<Complex32> result)
{ {
Map(x => x.Power(exponent), result, forceMapZeros: false); Map(x => x.Power(exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -223,7 +223,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseExp(Vector<Complex32> result) protected override void DoPointwiseExp(Vector<Complex32> result)
{ {
Map(Complex32.Exp, result, forceMapZeros: true); Map(Complex32.Exp, result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -232,7 +232,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseLog(Vector<Complex32> result) protected override void DoPointwiseLog(Vector<Complex32> result)
{ {
Map(Complex32.Log, result, forceMapZeros: true); Map(Complex32.Log, result, Zeros.Include);
} }
/// <summary> /// <summary>

10
src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs

@ -411,12 +411,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -508,12 +508,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -775,7 +775,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
? (Matrix<double>)new DiagonalMatrix(rowCount, columnCount) ? (Matrix<double>)new DiagonalMatrix(rowCount, columnCount)
: new SparseMatrix(rowCount, columnCount); : new SparseMatrix(rowCount, columnCount);
Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, skipClearing: true); Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, ExistingData.AssumeZeros);
return target; return target;
} }

6
src/Numerics/LinearAlgebra/Double/Matrix.cs

@ -482,7 +482,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(double exponent, Matrix<double> result) protected override void DoPointwisePower(double exponent, Matrix<double> result)
{ {
Map(x => Math.Pow(x, exponent), result, forceMapZeros: false); Map(x => Math.Pow(x, exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -525,7 +525,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseExp(Matrix<double> result) protected override void DoPointwiseExp(Matrix<double> result)
{ {
Map(Math.Exp, result, forceMapZeros: true); Map(Math.Exp, result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -534,7 +534,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseLog(Matrix<double> result) protected override void DoPointwiseLog(Matrix<double> result)
{ {
Map(Math.Log, result, forceMapZeros: true); Map(Math.Log, result, Zeros.Include);
} }
/// <summary> /// <summary>

4
src/Numerics/LinearAlgebra/Double/SparseMatrix.cs

@ -896,12 +896,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var diagonal = diagonalOther.Data; var diagonal = diagonalOther.Data;
if (other.ColumnCount == other.RowCount) if (other.ColumnCount == other.RowCount)
{ {
Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], false, false); Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Storage.Clear(); result.Storage.Clear();
Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, false, true); Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
return; return;
} }

6
src/Numerics/LinearAlgebra/Double/Vector.cs

@ -190,7 +190,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(double exponent, Vector<double> result) protected override void DoPointwisePower(double exponent, Vector<double> result)
{ {
Map(x => Math.Pow(x, exponent), result, forceMapZeros: false); Map(x => Math.Pow(x, exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -227,7 +227,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseExp(Vector<double> result) protected override void DoPointwiseExp(Vector<double> result)
{ {
Map(Math.Exp, result, forceMapZeros: true); Map(Math.Exp, result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -236,7 +236,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseLog(Vector<double> result) protected override void DoPointwiseLog(Vector<double> result)
{ {
Map(Math.Log, result, forceMapZeros: true); Map(Math.Log, result, Zeros.Include);
} }
/// <summary> /// <summary>

58
src/Numerics/LinearAlgebra/Matrix.cs

@ -205,7 +205,7 @@ namespace MathNet.Numerics.LinearAlgebra
public Matrix<T> Clone() public Matrix<T> Clone()
{ {
var result = Build.SameAs(this); var result = Build.SameAs(this);
Storage.CopyToUnchecked(result.Storage, skipClearing: true); Storage.CopyToUnchecked(result.Storage, ExistingData.AssumeZeros);
return result; return result;
} }
@ -509,7 +509,7 @@ namespace MathNet.Numerics.LinearAlgebra
public virtual Matrix<T> SubMatrix(int rowIndex, int rowCount, int columnIndex, int columnCount) public virtual Matrix<T> SubMatrix(int rowIndex, int rowCount, int columnIndex, int columnCount)
{ {
var result = Build.SameAs(this, rowCount, columnCount); var result = Build.SameAs(this, rowCount, columnCount);
Storage.CopySubMatrixTo(result.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, ExistingData.AssumeZeros);
return result; return result;
} }
@ -649,9 +649,9 @@ namespace MathNet.Numerics.LinearAlgebra
} }
var result = Build.SameAs(this, RowCount, ColumnCount + 1, fullyMutable: true); var result = Build.SameAs(this, RowCount, ColumnCount + 1, fullyMutable: true);
Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, columnIndex, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, columnIndex, ExistingData.AssumeZeros);
result.SetColumn(columnIndex, column); result.SetColumn(columnIndex, column);
Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, columnIndex, columnIndex + 1, ColumnCount - columnIndex, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, columnIndex, columnIndex + 1, ColumnCount - columnIndex, ExistingData.AssumeZeros);
return result; return result;
} }
@ -669,8 +669,8 @@ namespace MathNet.Numerics.LinearAlgebra
} }
var result = Build.SameAs(this, RowCount, ColumnCount - 1, fullyMutable: true); var result = Build.SameAs(this, RowCount, ColumnCount - 1, fullyMutable: true);
Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, columnIndex, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, columnIndex, ExistingData.AssumeZeros);
Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, columnIndex + 1, columnIndex, ColumnCount - columnIndex - 1, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, columnIndex + 1, columnIndex, ColumnCount - columnIndex - 1, ExistingData.AssumeZeros);
return result; return result;
} }
@ -765,9 +765,9 @@ namespace MathNet.Numerics.LinearAlgebra
} }
var result = Build.SameAs(this, RowCount + 1, ColumnCount, fullyMutable: true); var result = Build.SameAs(this, RowCount + 1, ColumnCount, fullyMutable: true);
Storage.CopySubMatrixTo(result.Storage, 0, 0, rowIndex, 0, 0, ColumnCount, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, rowIndex, 0, 0, ColumnCount, ExistingData.AssumeZeros);
result.SetRow(rowIndex, row); result.SetRow(rowIndex, row);
Storage.CopySubMatrixTo(result.Storage, rowIndex, rowIndex+1, RowCount - rowIndex, 0, 0, ColumnCount, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, rowIndex, rowIndex+1, RowCount - rowIndex, 0, 0, ColumnCount, ExistingData.AssumeZeros);
return result; return result;
} }
@ -785,8 +785,8 @@ namespace MathNet.Numerics.LinearAlgebra
} }
var result = Build.SameAs(this, RowCount - 1, ColumnCount, fullyMutable: true); var result = Build.SameAs(this, RowCount - 1, ColumnCount, fullyMutable: true);
Storage.CopySubMatrixTo(result.Storage, 0, 0, rowIndex, 0, 0, ColumnCount, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, rowIndex, 0, 0, ColumnCount, ExistingData.AssumeZeros);
Storage.CopySubMatrixTo(result.Storage, rowIndex + 1, rowIndex, RowCount - rowIndex - 1, 0, 0, ColumnCount, skipClearing: true); Storage.CopySubMatrixTo(result.Storage, rowIndex + 1, rowIndex, RowCount - rowIndex - 1, 0, 0, ColumnCount, ExistingData.AssumeZeros);
return result; return result;
} }
@ -983,7 +983,7 @@ namespace MathNet.Numerics.LinearAlgebra
public Matrix<T> Transpose() public Matrix<T> Transpose()
{ {
var result = Build.SameAs(this, ColumnCount, RowCount); var result = Build.SameAs(this, ColumnCount, RowCount);
Storage.TransposeToUnchecked(result.Storage, skipClearing:true); Storage.TransposeToUnchecked(result.Storage, ExistingData.AssumeZeros);
return result; return result;
} }
@ -1071,8 +1071,8 @@ namespace MathNet.Numerics.LinearAlgebra
} }
var result = Build.SameAs(this, right, RowCount, ColumnCount + right.ColumnCount, fullyMutable: true); var result = Build.SameAs(this, right, RowCount, ColumnCount + right.ColumnCount, fullyMutable: true);
Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, skipClearing: true); Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, ExistingData.AssumeZeros);
right.Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, right.RowCount, 0, ColumnCount, right.ColumnCount, skipClearing: true); right.Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, right.RowCount, 0, ColumnCount, right.ColumnCount, ExistingData.AssumeZeros);
return result; return result;
} }
@ -1131,8 +1131,8 @@ namespace MathNet.Numerics.LinearAlgebra
} }
var result = Build.SameAs(this, lower, RowCount + lower.RowCount, ColumnCount, fullyMutable: true); var result = Build.SameAs(this, lower, RowCount + lower.RowCount, ColumnCount, fullyMutable: true);
Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, skipClearing: true); Storage.CopySubMatrixToUnchecked(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, ExistingData.AssumeZeros);
lower.Storage.CopySubMatrixToUnchecked(result.Storage, 0, RowCount, lower.RowCount, 0, 0, lower.ColumnCount, skipClearing: true); lower.Storage.CopySubMatrixToUnchecked(result.Storage, 0, RowCount, lower.RowCount, 0, 0, lower.ColumnCount, ExistingData.AssumeZeros);
return result; return result;
} }
@ -1465,9 +1465,9 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse matrices). /// on the actual data storage implementation (relevant mostly for sparse matrices).
/// </summary> /// </summary>
public void MapInplace(Func<T, T> f, bool forceMapZeros = false) public void MapInplace(Func<T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
Storage.MapInplace(f, forceMapZeros); Storage.MapInplace(f, zeros);
} }
/// <summary> /// <summary>
@ -1476,9 +1476,9 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse matrices). /// on the actual data storage implementation (relevant mostly for sparse matrices).
/// </summary> /// </summary>
public void MapIndexedInplace(Func<int, int, T, T> f, bool forceMapZeros = false) public void MapIndexedInplace(Func<int, int, T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
Storage.MapIndexedInplace(f, forceMapZeros); Storage.MapIndexedInplace(f, zeros);
} }
/// <summary> /// <summary>
@ -1486,10 +1486,10 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse matrices). /// on the actual data storage implementation (relevant mostly for sparse matrices).
/// </summary> /// </summary>
public void Map<TU>(Func<T, TU> f, Matrix<TU> result, bool forceMapZeros = false) public void Map<TU>(Func<T, TU> f, Matrix<TU> result, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
Storage.MapTo(result.Storage, f, forceMapZeros, skipClearing: forceMapZeros); Storage.MapTo(result.Storage, f, zeros, zeros == Zeros.Include ? ExistingData.AssumeZeros : ExistingData.Clear);
} }
/// <summary> /// <summary>
@ -1498,10 +1498,10 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse matrices). /// on the actual data storage implementation (relevant mostly for sparse matrices).
/// </summary> /// </summary>
public void MapIndexed<TU>(Func<int, int, T, TU> f, Matrix<TU> result, bool forceMapZeros = false) public void MapIndexed<TU>(Func<int, int, T, TU> f, Matrix<TU> result, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
Storage.MapIndexedTo(result.Storage, f, forceMapZeros, skipClearing: forceMapZeros); Storage.MapIndexedTo(result.Storage, f, zeros, zeros == Zeros.Include ? ExistingData.AssumeZeros : ExistingData.Clear);
} }
/// <summary> /// <summary>
@ -1509,11 +1509,11 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse matrices). /// on the actual data storage implementation (relevant mostly for sparse matrices).
/// </summary> /// </summary>
public Matrix<TU> Map<TU>(Func<T, TU> f, bool forceMapZeros = false) public Matrix<TU> Map<TU>(Func<T, TU> f, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
var result = Matrix<TU>.Build.SameAs(this, RowCount, ColumnCount, fullyMutable: forceMapZeros); var result = Matrix<TU>.Build.SameAs(this, RowCount, ColumnCount, fullyMutable: zeros == Zeros.Include);
Storage.MapToUnchecked(result.Storage, f, forceMapZeros, skipClearing: true); Storage.MapToUnchecked(result.Storage, f, zeros, ExistingData.AssumeZeros);
return result; return result;
} }
@ -1523,11 +1523,11 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse matrices). /// on the actual data storage implementation (relevant mostly for sparse matrices).
/// </summary> /// </summary>
public Matrix<TU> MapIndexed<TU>(Func<int, int, T, TU> f, bool forceMapZeros = false) public Matrix<TU> MapIndexed<TU>(Func<int, int, T, TU> f, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
var result = Matrix<TU>.Build.SameAs(this, RowCount, ColumnCount, fullyMutable: forceMapZeros); var result = Matrix<TU>.Build.SameAs(this, RowCount, ColumnCount, fullyMutable: zeros == Zeros.Include);
Storage.MapIndexedToUnchecked(result.Storage, f, forceMapZeros, skipClearing: true); Storage.MapIndexedToUnchecked(result.Storage, f, zeros, ExistingData.AssumeZeros);
return result; return result;
} }
} }

61
src/Numerics/LinearAlgebra/Options.cs

@ -0,0 +1,61 @@
// <copyright file="Options.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.LinearAlgebra
{
public enum ExistingData
{
/// <summary>
/// Existing data may not be all zeros, so clearing may be necessary
/// if not all of it will be overwritten anyway.
/// </summary>
Clear = 0,
/// <summary>
/// If existing data is assumed to be all zeros already,
/// clearing it may be skipped if applicable.
/// </summary>
AssumeZeros = 1
}
public enum Zeros
{
/// <summary>
/// Allow skipping zero entries (without enforcing skipping them).
/// When enumerating sparse matrices this can significantly speed up operations.
/// </summary>
AllowSkip = 0,
/// <summary>
/// Force applying the operation to all fields even if they are zero.
/// </summary>
Include = 1
}
}

10
src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs

@ -411,12 +411,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -508,12 +508,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single
if (ColumnCount == RowCount) if (ColumnCount == RowCount)
{ {
other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], false, false); other.Storage.MapIndexedTo(result.Storage, (i, j, x) => x*_data[i], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Clear(); result.Clear();
other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, false, true); other.Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*_data[i], 0, 0, other.RowCount, 0, 0, other.ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
} }
@ -775,7 +775,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
? (Matrix<float>)new DiagonalMatrix(rowCount, columnCount) ? (Matrix<float>)new DiagonalMatrix(rowCount, columnCount)
: new SparseMatrix(rowCount, columnCount); : new SparseMatrix(rowCount, columnCount);
Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, skipClearing: true); Storage.CopySubMatrixTo(target.Storage, rowIndex, 0, rowCount, columnIndex, 0, columnCount, ExistingData.AssumeZeros);
return target; return target;
} }

6
src/Numerics/LinearAlgebra/Single/Matrix.cs

@ -482,7 +482,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(float exponent, Matrix<float> result) protected override void DoPointwisePower(float exponent, Matrix<float> result)
{ {
Map(x => (float)Math.Pow(x, exponent), result, forceMapZeros: false); Map(x => (float)Math.Pow(x, exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -525,7 +525,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseExp(Matrix<float> result) protected override void DoPointwiseExp(Matrix<float> result)
{ {
Map(x => (float)Math.Exp(x), result, forceMapZeros: true); Map(x => (float)Math.Exp(x), result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -534,7 +534,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <param name="result">The matrix to store the result.</param> /// <param name="result">The matrix to store the result.</param>
protected override void DoPointwiseLog(Matrix<float> result) protected override void DoPointwiseLog(Matrix<float> result)
{ {
Map(x => (float)Math.Log(x), result, forceMapZeros: true); Map(x => (float)Math.Log(x), result, Zeros.Include);
} }
/// <summary> /// <summary>

4
src/Numerics/LinearAlgebra/Single/SparseMatrix.cs

@ -899,12 +899,12 @@ namespace MathNet.Numerics.LinearAlgebra.Single
var diagonal = diagonalOther.Data; var diagonal = diagonalOther.Data;
if (other.ColumnCount == other.RowCount) if (other.ColumnCount == other.RowCount)
{ {
Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], false, false); Storage.MapIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], Zeros.AllowSkip, ExistingData.Clear);
} }
else else
{ {
result.Storage.Clear(); result.Storage.Clear();
Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, false, true); Storage.MapSubMatrixIndexedTo(result.Storage, (i, j, x) => x*diagonal[j], 0, 0, RowCount, 0, 0, ColumnCount, Zeros.AllowSkip, ExistingData.AssumeZeros);
} }
return; return;
} }

6
src/Numerics/LinearAlgebra/Single/Vector.cs

@ -190,7 +190,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <param name="result">The vector to store the result of the pointwise power.</param> /// <param name="result">The vector to store the result of the pointwise power.</param>
protected override void DoPointwisePower(float exponent, Vector<float> result) protected override void DoPointwisePower(float exponent, Vector<float> result)
{ {
Map(x => (float)Math.Pow(x, exponent), result, forceMapZeros: false); Map(x => (float)Math.Pow(x, exponent), result, Zeros.AllowSkip);
} }
/// <summary> /// <summary>
@ -227,7 +227,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseExp(Vector<float> result) protected override void DoPointwiseExp(Vector<float> result)
{ {
Map(x => (float)Math.Exp(x), result, forceMapZeros: true); Map(x => (float)Math.Exp(x), result, Zeros.Include);
} }
/// <summary> /// <summary>
@ -236,7 +236,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single
/// <param name="result">The vector to store the result.</param> /// <param name="result">The vector to store the result.</param>
protected override void DoPointwiseLog(Vector<float> result) protected override void DoPointwiseLog(Vector<float> result)
{ {
Map(x => (float)Math.Log(x), result, forceMapZeros: true); Map(x => (float)Math.Log(x), result, Zeros.Include);
} }
/// <summary> /// <summary>

28
src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -132,7 +132,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static DenseColumnMajorMatrixStorage<T> OfMatrix(MatrixStorage<T> matrix) public static DenseColumnMajorMatrixStorage<T> OfMatrix(MatrixStorage<T> matrix)
{ {
var storage = new DenseColumnMajorMatrixStorage<T>(matrix.RowCount, matrix.ColumnCount); var storage = new DenseColumnMajorMatrixStorage<T>(matrix.RowCount, matrix.ColumnCount);
matrix.CopyToUnchecked(storage, skipClearing: true); matrix.CopyToUnchecked(storage, ExistingData.AssumeZeros);
return storage; return storage;
} }
@ -327,7 +327,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// MATRIX COPY // MATRIX COPY
internal override void CopyToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal override void CopyToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -356,7 +356,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubMatrixToUnchecked(MatrixStorage<T> target, internal override void CopySubMatrixToUnchecked(MatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -392,7 +392,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// ROW COPY // ROW COPY
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false) internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount,
ExistingData existingData = ExistingData.Clear)
{ {
var targetDense = target as DenseVectorStorage<T>; var targetDense = target as DenseVectorStorage<T>;
if (targetDense != null) if (targetDense != null)
@ -414,7 +415,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// COLUMN COPY // COLUMN COPY
internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false) internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount,
ExistingData existingData = ExistingData.Clear)
{ {
var targetDense = target as DenseVectorStorage<T>; var targetDense = target as DenseVectorStorage<T>;
if (targetDense != null) if (targetDense != null)
@ -434,7 +436,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// TRANSPOSE // TRANSPOSE
internal override void TransposeToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal override void TransposeToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -578,7 +580,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FUNCTIONAL COMBINATORS // FUNCTIONAL COMBINATORS
public override void MapInplace(Func<T, T> f, bool forceMapZeros = false) public override void MapInplace(Func<T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
CommonParallel.For(0, Data.Length, 4096, (a, b) => CommonParallel.For(0, Data.Length, 4096, (a, b) =>
{ {
@ -589,7 +591,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}); });
} }
public override void MapIndexedInplace(Func<int, int, T, T> f, bool forceMapZeros = false) public override void MapIndexedInplace(Func<int, int, T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
CommonParallel.For(0, ColumnCount, Math.Max(4096/RowCount, 32), (a, b) => CommonParallel.For(0, ColumnCount, Math.Max(4096/RowCount, 32), (a, b) =>
{ {
@ -605,7 +607,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}); });
} }
internal override void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<TU>; var denseTarget = target as DenseColumnMajorMatrixStorage<TU>;
if (denseTarget != null) if (denseTarget != null)
@ -632,7 +635,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
internal override void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<TU>; var denseTarget = target as DenseColumnMajorMatrixStorage<TU>;
if (denseTarget != null) if (denseTarget != null)
@ -667,7 +671,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, internal override void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false, bool skipClearing = false) Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<TU>; var denseTarget = target as DenseColumnMajorMatrixStorage<TU>;
if (denseTarget != null) if (denseTarget != null)

22
src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs

@ -105,7 +105,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static DenseVectorStorage<T> OfVector(VectorStorage<T> vector) public static DenseVectorStorage<T> OfVector(VectorStorage<T> vector)
{ {
var storage = new DenseVectorStorage<T>(vector.Length); var storage = new DenseVectorStorage<T>(vector.Length);
vector.CopyToUnchecked(storage, skipClearing: true); vector.CopyToUnchecked(storage, ExistingData.AssumeZeros);
return storage; return storage;
} }
@ -163,7 +163,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// VECTOR COPY // VECTOR COPY
internal override void CopyToUnchecked(VectorStorage<T> target, bool skipClearing = false) internal override void CopyToUnchecked(VectorStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseVectorStorage<T>; var denseTarget = target as DenseVectorStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -185,7 +185,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// ROW COPY // ROW COPY
internal override void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, bool skipClearing = false) internal override void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -207,7 +207,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// COLUMN COPY // COLUMN COPY
internal override void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, bool skipClearing = false) internal override void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -228,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubVectorToUnchecked(VectorStorage<T> target, internal override void CopySubVectorToUnchecked(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count, int sourceIndex, int targetIndex, int count,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseVectorStorage<T>; var denseTarget = target as DenseVectorStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -239,14 +239,14 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
base.CopySubVectorToUnchecked(target, sourceIndex, targetIndex, count, skipClearing); base.CopySubVectorToUnchecked(target, sourceIndex, targetIndex, count, existingData);
} }
// SUB-ROW COPY // SUB-ROW COPY
internal override void CopyToSubRowUnchecked(MatrixStorage<T> target, int rowIndex, internal override void CopyToSubRowUnchecked(MatrixStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -270,7 +270,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopyToSubColumnUnchecked(MatrixStorage<T> target, int columnIndex, internal override void CopyToSubColumnUnchecked(MatrixStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
@ -317,7 +317,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FUNCTIONAL COMBINATORS // FUNCTIONAL COMBINATORS
internal override void MapToUnchecked<TU>(VectorStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapToUnchecked<TU>(VectorStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseVectorStorage<TU>; var denseTarget = target as DenseVectorStorage<TU>;
if (denseTarget != null) if (denseTarget != null)
@ -340,7 +341,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
internal override void MapIndexedToUnchecked<TU>(VectorStorage<TU> target, Func<int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapIndexedToUnchecked<TU>(VectorStorage<TU> target, Func<int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseVectorStorage<TU>; var denseTarget = target as DenseVectorStorage<TU>;
if (denseTarget != null) if (denseTarget != null)

82
src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -193,7 +193,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static DiagonalMatrixStorage<T> OfMatrix(MatrixStorage<T> matrix) public static DiagonalMatrixStorage<T> OfMatrix(MatrixStorage<T> matrix)
{ {
var storage = new DiagonalMatrixStorage<T>(matrix.RowCount, matrix.ColumnCount); var storage = new DiagonalMatrixStorage<T>(matrix.RowCount, matrix.ColumnCount);
matrix.CopyToUnchecked(storage, skipClearing: true); matrix.CopyToUnchecked(storage, ExistingData.AssumeZeros);
return storage; return storage;
} }
@ -262,7 +262,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// MATRIX COPY // MATRIX COPY
internal override void CopyToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal override void CopyToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
var diagonalTarget = target as DiagonalMatrixStorage<T>; var diagonalTarget = target as DiagonalMatrixStorage<T>;
if (diagonalTarget != null) if (diagonalTarget != null)
@ -274,20 +274,20 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
{ {
CopyToUnchecked(denseTarget, skipClearing); CopyToUnchecked(denseTarget, existingData);
return; return;
} }
var sparseTarget = target as SparseCompressedRowMatrixStorage<T>; var sparseTarget = target as SparseCompressedRowMatrixStorage<T>;
if (sparseTarget != null) if (sparseTarget != null)
{ {
CopyToUnchecked(sparseTarget, skipClearing); CopyToUnchecked(sparseTarget, existingData);
return; return;
} }
// FALL BACK // FALL BACK
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -304,9 +304,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
Array.Copy(Data, 0, target.Data, 0, Data.Length); Array.Copy(Data, 0, target.Data, 0, Data.Length);
} }
void CopyToUnchecked(SparseCompressedRowMatrixStorage<T> target, bool skipClearing) void CopyToUnchecked(SparseCompressedRowMatrixStorage<T> target, ExistingData existingData)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -317,9 +317,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
void CopyToUnchecked(DenseColumnMajorMatrixStorage<T> target, bool skipClearing) void CopyToUnchecked(DenseColumnMajorMatrixStorage<T> target, ExistingData existingData)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -333,12 +333,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubMatrixToUnchecked(MatrixStorage<T> target, internal override void CopySubMatrixToUnchecked(MatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
{ {
CopySubMatrixToUnchecked(denseTarget, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing); CopySubMatrixToUnchecked(denseTarget, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, existingData);
return; return;
} }
@ -353,7 +353,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }
@ -412,9 +412,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
void CopySubMatrixToUnchecked(DenseColumnMajorMatrixStorage<T> target, void CopySubMatrixToUnchecked(DenseColumnMajorMatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing) ExistingData existingData)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }
@ -464,9 +464,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetColumnIndex, columnCount); target.Clear(targetColumnIndex, columnCount);
} }
@ -481,9 +481,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetRowIndex, rowCount); target.Clear(targetRowIndex, rowCount);
} }
@ -496,9 +496,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// TRANSPOSE // TRANSPOSE
internal override void TransposeToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal override void TransposeToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
CopyToUnchecked(target, skipClearing); CopyToUnchecked(target, existingData);
} }
// EXTRACT // EXTRACT
@ -581,9 +581,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FUNCTIONAL COMBINATORS // FUNCTIONAL COMBINATORS
public override void MapInplace(Func<T, T> f, bool forceMapZeros = false) public override void MapInplace(Func<T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
if (forceMapZeros) if (zeros == Zeros.Include)
{ {
throw new NotSupportedException("Cannot map non-zero off-diagonal values into a diagonal matrix"); throw new NotSupportedException("Cannot map non-zero off-diagonal values into a diagonal matrix");
} }
@ -597,9 +597,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}); });
} }
public override void MapIndexedInplace(Func<int, int, T, T> f, bool forceMapZeros = false) public override void MapIndexedInplace(Func<int, int, T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
if (forceMapZeros) if (zeros == Zeros.Include)
{ {
throw new NotSupportedException("Cannot map non-zero off-diagonal values into a diagonal matrix"); throw new NotSupportedException("Cannot map non-zero off-diagonal values into a diagonal matrix");
} }
@ -613,9 +613,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}); });
} }
internal override void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var processZeros = forceMapZeros || !Zero.Equals(f(Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(Zero));
var diagonalTarget = target as DiagonalMatrixStorage<TU>; var diagonalTarget = target as DiagonalMatrixStorage<TU>;
if (diagonalTarget != null) if (diagonalTarget != null)
@ -637,7 +638,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
if (!skipClearing && !processZeros) if (existingData == ExistingData.Clear && !processZeros)
{ {
target.Clear(); target.Clear();
} }
@ -661,9 +662,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
internal override void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var processZeros = forceMapZeros || !Zero.Equals(f(0, 1, Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero));
var diagonalTarget = target as DiagonalMatrixStorage<TU>; var diagonalTarget = target as DiagonalMatrixStorage<TU>;
if (diagonalTarget != null) if (diagonalTarget != null)
@ -685,7 +687,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
if (!skipClearing && !processZeros) if (existingData == ExistingData.Clear && !processZeros)
{ {
target.Clear(); target.Clear();
} }
@ -712,19 +714,19 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, internal override void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false, bool skipClearing = false) Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var diagonalTarget = target as DiagonalMatrixStorage<TU>; var diagonalTarget = target as DiagonalMatrixStorage<TU>;
if (diagonalTarget != null) if (diagonalTarget != null)
{ {
MapSubMatrixIndexedToUnchecked(diagonalTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, forceMapZeros); MapSubMatrixIndexedToUnchecked(diagonalTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros);
return; return;
} }
var denseTarget = target as DenseColumnMajorMatrixStorage<TU>; var denseTarget = target as DenseColumnMajorMatrixStorage<TU>;
if (denseTarget != null) if (denseTarget != null)
{ {
MapSubMatrixIndexedToUnchecked(denseTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, forceMapZeros, skipClearing); MapSubMatrixIndexedToUnchecked(denseTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros, existingData);
return; return;
} }
@ -732,7 +734,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }
@ -779,10 +781,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
void MapSubMatrixIndexedToUnchecked<TU>(DiagonalMatrixStorage<TU> target, Func<int, int, T, TU> f, void MapSubMatrixIndexedToUnchecked<TU>(DiagonalMatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false) Zeros zeros)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
var processZeros = forceMapZeros || !Zero.Equals(f(0, 1, Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero));
if (processZeros || sourceRowIndex - sourceColumnIndex != targetRowIndex - targetColumnIndex) if (processZeros || sourceRowIndex - sourceColumnIndex != targetRowIndex - targetColumnIndex)
{ {
throw new NotSupportedException("Cannot map non-zero off-diagonal values into a diagonal matrix"); throw new NotSupportedException("Cannot map non-zero off-diagonal values into a diagonal matrix");
@ -808,11 +810,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
void MapSubMatrixIndexedToUnchecked<TU>(DenseColumnMajorMatrixStorage<TU> target, Func<int, int, T, TU> f, void MapSubMatrixIndexedToUnchecked<TU>(DenseColumnMajorMatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false, bool skipClearing = false) Zeros zeros, ExistingData existingData)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
var processZeros = forceMapZeros || !Zero.Equals(f(0, 1, Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero));
if (!skipClearing && !processZeros) if (existingData == ExistingData.Clear && !processZeros)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }

66
src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -228,7 +228,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// MATRIX COPY // MATRIX COPY
public void CopyTo(MatrixStorage<T> target, bool skipClearing = false) public void CopyTo(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -246,10 +246,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentException(message, "target"); throw new ArgumentException(message, "target");
} }
CopyToUnchecked(target, skipClearing); CopyToUnchecked(target, existingData);
} }
internal virtual void CopyToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal virtual void CopyToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
for (int j = 0; j < ColumnCount; j++) for (int j = 0; j < ColumnCount; j++)
{ {
@ -263,7 +263,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public void CopySubMatrixTo(MatrixStorage<T> target, public void CopySubMatrixTo(MatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -285,13 +285,13 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
sourceColumnIndex, targetColumnIndex, columnCount); sourceColumnIndex, targetColumnIndex, columnCount);
CopySubMatrixToUnchecked(target, sourceRowIndex, targetRowIndex, rowCount, CopySubMatrixToUnchecked(target, sourceRowIndex, targetRowIndex, rowCount,
sourceColumnIndex, targetColumnIndex, columnCount, skipClearing); sourceColumnIndex, targetColumnIndex, columnCount, existingData);
} }
internal virtual void CopySubMatrixToUnchecked(MatrixStorage<T> target, internal virtual void CopySubMatrixToUnchecked(MatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{ {
@ -304,7 +304,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// ROW COPY // ROW COPY
public void CopyRowTo(VectorStorage<T> target, int rowIndex, bool skipClearing = false) public void CopyRowTo(VectorStorage<T> target, int rowIndex, ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -312,12 +312,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateRowRange(target, rowIndex); ValidateRowRange(target, rowIndex);
CopySubRowToUnchecked(target, rowIndex, 0, 0, ColumnCount, skipClearing); CopySubRowToUnchecked(target, rowIndex, 0, 0, ColumnCount, existingData);
} }
public void CopySubRowTo(VectorStorage<T> target, int rowIndex, public void CopySubRowTo(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -330,12 +330,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount); ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount);
CopySubRowToUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing); CopySubRowToUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, existingData);
} }
internal virtual void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, internal virtual void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{ {
@ -345,7 +345,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// COLUMN COPY // COLUMN COPY
public void CopyColumnTo(VectorStorage<T> target, int columnIndex, bool skipClearing = false) public void CopyColumnTo(VectorStorage<T> target, int columnIndex, ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -353,12 +353,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateColumnRange(target, columnIndex); ValidateColumnRange(target, columnIndex);
CopySubColumnToUnchecked(target, columnIndex, 0, 0, RowCount, skipClearing); CopySubColumnToUnchecked(target, columnIndex, 0, 0, RowCount, existingData);
} }
public void CopySubColumnTo(VectorStorage<T> target, int columnIndex, public void CopySubColumnTo(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -371,12 +371,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount); ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount);
CopySubColumnToUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing); CopySubColumnToUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, existingData);
} }
internal virtual void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, internal virtual void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++) for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++)
{ {
@ -386,7 +386,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// TRANSPOSE // TRANSPOSE
public void TransposeTo(MatrixStorage<T> target, bool skipClearing = false) public void TransposeTo(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -404,10 +404,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentException(message, "target"); throw new ArgumentException(message, "target");
} }
TransposeToUnchecked(target, skipClearing); TransposeToUnchecked(target, existingData);
} }
internal virtual void TransposeToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal virtual void TransposeToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
for (int j = 0; j < ColumnCount; j++) for (int j = 0; j < ColumnCount; j++)
{ {
@ -517,7 +517,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FUNCTIONAL COMBINATORS // FUNCTIONAL COMBINATORS
public virtual void MapInplace(Func<T, T> f, bool forceMapZeros = false) public virtual void MapInplace(Func<T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
for (int i = 0; i < RowCount; i++) for (int i = 0; i < RowCount; i++)
{ {
@ -528,7 +528,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
public virtual void MapIndexedInplace(Func<int, int, T, T> f, bool forceMapZeros = false) public virtual void MapIndexedInplace(Func<int, int, T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
for (int i = 0; i < RowCount; i++) for (int i = 0; i < RowCount; i++)
{ {
@ -539,7 +539,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
public void MapTo<TU>(MatrixStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) public void MapTo<TU>(MatrixStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
if (target == null) if (target == null)
@ -553,10 +554,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentException(message, "target"); throw new ArgumentException(message, "target");
} }
MapToUnchecked(target, f, forceMapZeros, skipClearing); MapToUnchecked(target, f, zeros, existingData);
} }
internal virtual void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal virtual void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
for (int i = 0; i < RowCount; i++) for (int i = 0; i < RowCount; i++)
@ -568,7 +570,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
public void MapIndexedTo<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) public void MapIndexedTo<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
if (target == null) if (target == null)
@ -582,10 +585,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentException(message, "target"); throw new ArgumentException(message, "target");
} }
MapIndexedToUnchecked(target, f, forceMapZeros, skipClearing); MapIndexedToUnchecked(target, f, zeros, existingData);
} }
internal virtual void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal virtual void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
for (int j = 0; j < ColumnCount; j++) for (int j = 0; j < ColumnCount; j++)
@ -600,7 +604,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public void MapSubMatrixIndexedTo<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, public void MapSubMatrixIndexedTo<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false, bool skipClearing = false) Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
if (target == null) if (target == null)
@ -622,13 +626,13 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
sourceRowIndex, targetRowIndex, rowCount, sourceRowIndex, targetRowIndex, rowCount,
sourceColumnIndex, targetColumnIndex, columnCount); sourceColumnIndex, targetColumnIndex, columnCount);
MapSubMatrixIndexedToUnchecked(target, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, forceMapZeros, skipClearing); MapSubMatrixIndexedToUnchecked(target, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros, existingData);
} }
internal virtual void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, internal virtual void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false, bool skipClearing = false) Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)

76
src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -274,7 +274,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
Sorting.Sort(ColumnIndices, Values, index, count); Sorting.Sort(ColumnIndices, Values, index, count);
} }
} }
MapInplace(x => x, forceMapZeros: false); MapInplace(x => x, Zeros.AllowSkip);
} }
public override void Clear() public override void Clear()
@ -410,7 +410,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static SparseCompressedRowMatrixStorage<T> OfMatrix(MatrixStorage<T> matrix) public static SparseCompressedRowMatrixStorage<T> OfMatrix(MatrixStorage<T> matrix)
{ {
var storage = new SparseCompressedRowMatrixStorage<T>(matrix.RowCount, matrix.ColumnCount); var storage = new SparseCompressedRowMatrixStorage<T>(matrix.RowCount, matrix.ColumnCount);
matrix.CopyToUnchecked(storage, skipClearing: true); matrix.CopyToUnchecked(storage, ExistingData.AssumeZeros);
return storage; return storage;
} }
@ -794,7 +794,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// MATRIX COPY // MATRIX COPY
internal override void CopyToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal override void CopyToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
var sparseTarget = target as SparseCompressedRowMatrixStorage<T>; var sparseTarget = target as SparseCompressedRowMatrixStorage<T>;
if (sparseTarget != null) if (sparseTarget != null)
@ -806,13 +806,13 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
{ {
CopyToUnchecked(denseTarget, skipClearing); CopyToUnchecked(denseTarget, existingData);
return; return;
} }
// FALL BACK // FALL BACK
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -844,9 +844,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
void CopyToUnchecked(DenseColumnMajorMatrixStorage<T> target, bool skipClearing) void CopyToUnchecked(DenseColumnMajorMatrixStorage<T> target, ExistingData existingData)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -870,7 +870,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubMatrixToUnchecked(MatrixStorage<T> target, internal override void CopySubMatrixToUnchecked(MatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -883,13 +883,13 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
CopySubMatrixToUnchecked(sparseTarget, CopySubMatrixToUnchecked(sparseTarget,
sourceRowIndex, targetRowIndex, rowCount, sourceRowIndex, targetRowIndex, rowCount,
sourceColumnIndex, targetColumnIndex, columnCount, sourceColumnIndex, targetColumnIndex, columnCount,
skipClearing); existingData);
return; return;
} }
// FALL BACK // FALL BACK
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }
@ -914,7 +914,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
void CopySubMatrixToUnchecked(SparseCompressedRowMatrixStorage<T> target, void CopySubMatrixToUnchecked(SparseCompressedRowMatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing) ExistingData existingData)
{ {
var rowOffset = targetRowIndex - sourceRowIndex; var rowOffset = targetRowIndex - sourceRowIndex;
var columnOffset = targetColumnIndex - sourceColumnIndex; var columnOffset = targetColumnIndex - sourceColumnIndex;
@ -959,7 +959,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return; return;
} }
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }
@ -986,9 +986,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetColumnIndex, columnCount); target.Clear(targetColumnIndex, columnCount);
} }
@ -1012,7 +1012,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// TRANSPOSE // TRANSPOSE
internal override void TransposeToUnchecked(MatrixStorage<T> target, bool skipClearing = false) internal override void TransposeToUnchecked(MatrixStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
var sparseTarget = target as SparseCompressedRowMatrixStorage<T>; var sparseTarget = target as SparseCompressedRowMatrixStorage<T>;
if (sparseTarget != null) if (sparseTarget != null)
@ -1024,13 +1024,13 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
var denseTarget = target as DenseColumnMajorMatrixStorage<T>; var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null) if (denseTarget != null)
{ {
TransposeToUnchecked(denseTarget, skipClearing); TransposeToUnchecked(denseTarget, existingData);
return; return;
} }
// FALL BACK // FALL BACK
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -1087,9 +1087,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
void TransposeToUnchecked(DenseColumnMajorMatrixStorage<T> target, bool skipClearing) void TransposeToUnchecked(DenseColumnMajorMatrixStorage<T> target, ExistingData existingData)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -1219,9 +1219,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FUNCTIONAL COMBINATORS // FUNCTIONAL COMBINATORS
public override void MapInplace(Func<T, T> f, bool forceMapZeros = false) public override void MapInplace(Func<T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
if (forceMapZeros || !Zero.Equals(f(Zero))) if (zeros == Zeros.Include || !Zero.Equals(f(Zero)))
{ {
var newRowPointers = RowPointers; var newRowPointers = RowPointers;
var newColumnIndices = new List<int>(ColumnIndices.Length); var newColumnIndices = new List<int>(ColumnIndices.Length);
@ -1272,9 +1272,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
public override void MapIndexedInplace(Func<int, int, T, T> f, bool forceMapZeros = false) public override void MapIndexedInplace(Func<int, int, T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
if (forceMapZeros || !Zero.Equals(f(0, 1, Zero))) if (zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero)))
{ {
var newRowPointers = RowPointers; var newRowPointers = RowPointers;
var newColumnIndices = new List<int>(ColumnIndices.Length); var newColumnIndices = new List<int>(ColumnIndices.Length);
@ -1325,9 +1325,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
internal override void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapToUnchecked<TU>(MatrixStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var processZeros = forceMapZeros || !Zero.Equals(f(Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(Zero));
var sparseTarget = target as SparseCompressedRowMatrixStorage<TU>; var sparseTarget = target as SparseCompressedRowMatrixStorage<TU>;
if (sparseTarget != null) if (sparseTarget != null)
@ -1380,7 +1381,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
if (!skipClearing && !processZeros) if (existingData == ExistingData.Clear && !processZeros)
{ {
target.Clear(); target.Clear();
} }
@ -1419,9 +1420,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
internal override void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var processZeros = forceMapZeros || !Zero.Equals(f(0, 1, Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero));
var sparseTarget = target as SparseCompressedRowMatrixStorage<TU>; var sparseTarget = target as SparseCompressedRowMatrixStorage<TU>;
if (sparseTarget != null) if (sparseTarget != null)
@ -1474,7 +1476,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
if (!skipClearing && !processZeros) if (existingData == ExistingData.Clear && !processZeros)
{ {
target.Clear(); target.Clear();
} }
@ -1516,19 +1518,19 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f, internal override void MapSubMatrixIndexedToUnchecked<TU>(MatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false, bool skipClearing = false) Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var sparseTarget = target as SparseCompressedRowMatrixStorage<TU>; var sparseTarget = target as SparseCompressedRowMatrixStorage<TU>;
if (sparseTarget != null) if (sparseTarget != null)
{ {
MapSubMatrixIndexedToUnchecked(sparseTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, forceMapZeros, skipClearing); MapSubMatrixIndexedToUnchecked(sparseTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros, existingData);
return; return;
} }
// FALL BACK // FALL BACK
var processZeros = forceMapZeros || !Zero.Equals(f(0, 1, Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero));
if (!skipClearing && !processZeros) if (existingData == ExistingData.Clear && !processZeros)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }
@ -1581,11 +1583,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
void MapSubMatrixIndexedToUnchecked<TU>(SparseCompressedRowMatrixStorage<TU> target, Func<int, int, T, TU> f, void MapSubMatrixIndexedToUnchecked<TU>(SparseCompressedRowMatrixStorage<TU> target, Func<int, int, T, TU> f,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool forceMapZeros = false, bool skipClearing = false) Zeros zeros, ExistingData existingData)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
var processZeros = forceMapZeros || !Zero.Equals(f(0, 1, Zero)); var processZeros = zeros == Zeros.Include || !Zero.Equals(f(0, 1, Zero));
if (!skipClearing && !processZeros) if (existingData == ExistingData.Clear && !processZeros)
{ {
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
} }

48
src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs

@ -297,7 +297,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public static SparseVectorStorage<T> OfVector(VectorStorage<T> vector) public static SparseVectorStorage<T> OfVector(VectorStorage<T> vector)
{ {
var storage = new SparseVectorStorage<T>(vector.Length); var storage = new SparseVectorStorage<T>(vector.Length);
vector.CopyToUnchecked(storage, skipClearing: true); vector.CopyToUnchecked(storage, ExistingData.AssumeZeros);
return storage; return storage;
} }
@ -388,7 +388,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// VECTOR COPY // VECTOR COPY
internal override void CopyToUnchecked(VectorStorage<T> target, bool skipClearing = false) internal override void CopyToUnchecked(VectorStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
var sparseTarget = target as SparseVectorStorage<T>; var sparseTarget = target as SparseVectorStorage<T>;
if (sparseTarget != null) if (sparseTarget != null)
@ -399,7 +399,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(); target.Clear();
} }
@ -439,9 +439,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// Row COPY // Row COPY
internal override void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, bool skipClearing = false) internal override void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, ExistingData existingData = ExistingData.Clear)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(rowIndex, 1, 0, Length); target.Clear(rowIndex, 1, 0, Length);
} }
@ -459,9 +459,9 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// COLUMN COPY // COLUMN COPY
internal override void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, bool skipClearing = false) internal override void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, ExistingData existingData = ExistingData.Clear)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(0, Length, columnIndex, 1); target.Clear(0, Length, columnIndex, 1);
} }
@ -481,12 +481,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
internal override void CopySubVectorToUnchecked(VectorStorage<T> target, internal override void CopySubVectorToUnchecked(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count, int sourceIndex, int targetIndex, int count,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
var sparseTarget = target as SparseVectorStorage<T>; var sparseTarget = target as SparseVectorStorage<T>;
if (sparseTarget != null) if (sparseTarget != null)
{ {
CopySubVectorToUnchecked(sparseTarget, sourceIndex, targetIndex, count, skipClearing); CopySubVectorToUnchecked(sparseTarget, sourceIndex, targetIndex, count, existingData);
return; return;
} }
@ -499,7 +499,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
if (sourceFirst < 0) sourceFirst = ~sourceFirst; if (sourceFirst < 0) sourceFirst = ~sourceFirst;
if (sourceLast < 0) sourceLast = ~sourceLast - 1; if (sourceLast < 0) sourceLast = ~sourceLast - 1;
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetIndex, count); target.Clear(targetIndex, count);
} }
@ -512,7 +512,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
void CopySubVectorToUnchecked(SparseVectorStorage<T> target, void CopySubVectorToUnchecked(SparseVectorStorage<T> target,
int sourceIndex, int targetIndex, int count, int sourceIndex, int targetIndex, int count,
bool skipClearing) ExistingData existingData)
{ {
var offset = targetIndex - sourceIndex; var offset = targetIndex - sourceIndex;
@ -534,7 +534,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
indices[i] = Indices[i + sourceFirst]; indices[i] = Indices[i + sourceFirst];
} }
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
Clear(targetIndex, count); Clear(targetIndex, count);
} }
@ -566,7 +566,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return; return;
} }
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
target.Clear(targetIndex, count); target.Clear(targetIndex, count);
} }
@ -619,14 +619,15 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FUNCTIONAL COMBINATORS // FUNCTIONAL COMBINATORS
internal override void MapToUnchecked<TU>(VectorStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapToUnchecked<TU>(VectorStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var sparseTarget = target as SparseVectorStorage<TU>; var sparseTarget = target as SparseVectorStorage<TU>;
if (sparseTarget != null) if (sparseTarget != null)
{ {
var indices = new List<int>(); var indices = new List<int>();
var values = new List<TU>(); var values = new List<TU>();
if (forceMapZeros || !Zero.Equals(f(Zero))) if (zeros == Zeros.Include || !Zero.Equals(f(Zero)))
{ {
int k = 0; int k = 0;
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
@ -660,12 +661,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
var denseTarget = target as DenseVectorStorage<TU>; var denseTarget = target as DenseVectorStorage<TU>;
if (denseTarget != null) if (denseTarget != null)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
denseTarget.Clear(); denseTarget.Clear();
} }
if (forceMapZeros || !Zero.Equals(f(Zero))) if (zeros == Zeros.Include || !Zero.Equals(f(Zero)))
{ {
int k = 0; int k = 0;
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
@ -690,17 +691,18 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
base.MapToUnchecked(target, f, forceMapZeros, skipClearing); base.MapToUnchecked(target, f, zeros, existingData);
} }
internal override void MapIndexedToUnchecked<TU>(VectorStorage<TU> target, Func<int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal override void MapIndexedToUnchecked<TU>(VectorStorage<TU> target, Func<int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
{ {
var sparseTarget = target as SparseVectorStorage<TU>; var sparseTarget = target as SparseVectorStorage<TU>;
if (sparseTarget != null) if (sparseTarget != null)
{ {
var indices = new List<int>(); var indices = new List<int>();
var values = new List<TU>(); var values = new List<TU>();
if (forceMapZeros || !Zero.Equals(f(0, Zero))) if (zeros == Zeros.Include || !Zero.Equals(f(0, Zero)))
{ {
int k = 0; int k = 0;
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
@ -734,12 +736,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
var denseTarget = target as DenseVectorStorage<TU>; var denseTarget = target as DenseVectorStorage<TU>;
if (denseTarget != null) if (denseTarget != null)
{ {
if (!skipClearing) if (existingData == ExistingData.Clear)
{ {
denseTarget.Clear(); denseTarget.Clear();
} }
if (forceMapZeros || !Zero.Equals(f(0, Zero))) if (zeros == Zeros.Include || !Zero.Equals(f(0, Zero)))
{ {
int k = 0; int k = 0;
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
@ -764,7 +766,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK // FALL BACK
base.MapIndexedToUnchecked(target, f, forceMapZeros, skipClearing); base.MapIndexedToUnchecked(target, f, zeros, existingData);
} }
} }
} }

54
src/Numerics/LinearAlgebra/Storage/VectorStorage.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2013 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -187,7 +187,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// VECTOR COPY // VECTOR COPY
public void CopyTo(VectorStorage<T> target, bool skipClearing = false) public void CopyTo(VectorStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -204,10 +204,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target");
} }
CopyToUnchecked(target, skipClearing); CopyToUnchecked(target, existingData);
} }
internal virtual void CopyToUnchecked(VectorStorage<T> target, bool skipClearing = false) internal virtual void CopyToUnchecked(VectorStorage<T> target, ExistingData existingData = ExistingData.Clear)
{ {
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
{ {
@ -217,7 +217,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// ROW COPY // ROW COPY
public void CopyToRow(MatrixStorage<T> target, int rowIndex, bool skipClearing = false) public void CopyToRow(MatrixStorage<T> target, int rowIndex, ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -230,10 +230,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateRowRange(target, rowIndex); ValidateRowRange(target, rowIndex);
CopyToRowUnchecked(target, rowIndex, skipClearing); CopyToRowUnchecked(target, rowIndex, existingData);
} }
internal virtual void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, bool skipClearing = false) internal virtual void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, ExistingData existingData = ExistingData.Clear)
{ {
for (int j = 0; j < Length; j++) for (int j = 0; j < Length; j++)
{ {
@ -243,7 +243,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// COLUMN COPY // COLUMN COPY
public void CopyToColumn(MatrixStorage<T> target, int columnIndex, bool skipClearing = false) public void CopyToColumn(MatrixStorage<T> target, int columnIndex, ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -256,10 +256,10 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateColumnRange(target, columnIndex); ValidateColumnRange(target, columnIndex);
CopyToColumnUnchecked(target, columnIndex, skipClearing); CopyToColumnUnchecked(target, columnIndex, existingData);
} }
internal virtual void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, bool skipClearing = false) internal virtual void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, ExistingData existingData = ExistingData.Clear)
{ {
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
{ {
@ -271,7 +271,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public void CopySubVectorTo(VectorStorage<T> target, public void CopySubVectorTo(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count, int sourceIndex, int targetIndex, int count,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -284,12 +284,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateSubVectorRange(target, sourceIndex, targetIndex, count); ValidateSubVectorRange(target, sourceIndex, targetIndex, count);
CopySubVectorToUnchecked(target, sourceIndex, targetIndex, count, skipClearing); CopySubVectorToUnchecked(target, sourceIndex, targetIndex, count, existingData);
} }
internal virtual void CopySubVectorToUnchecked(VectorStorage<T> target, internal virtual void CopySubVectorToUnchecked(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count, int sourceIndex, int targetIndex, int count,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (ReferenceEquals(this, target)) if (ReferenceEquals(this, target))
{ {
@ -316,7 +316,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public void CopyToSubRow(MatrixStorage<T> target, int rowIndex, public void CopyToSubRow(MatrixStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -329,12 +329,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount); ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount);
CopyToSubRowUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing); CopyToSubRowUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, existingData);
} }
internal virtual void CopyToSubRowUnchecked(MatrixStorage<T> target, int rowIndex, internal virtual void CopyToSubRowUnchecked(MatrixStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{ {
@ -346,7 +346,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
public void CopyToSubColumn(MatrixStorage<T> target, int columnIndex, public void CopyToSubColumn(MatrixStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
if (target == null) if (target == null)
{ {
@ -359,12 +359,12 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount); ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount);
CopyToSubColumnUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing); CopyToSubColumnUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, existingData);
} }
internal virtual void CopyToSubColumnUnchecked(MatrixStorage<T> target, int columnIndex, internal virtual void CopyToSubColumnUnchecked(MatrixStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) ExistingData existingData = ExistingData.Clear)
{ {
for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++) for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++)
{ {
@ -416,7 +416,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FUNCTIONAL COMBINATORS // FUNCTIONAL COMBINATORS
public void MapTo<TU>(VectorStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) public void MapTo<TU>(VectorStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
if (target == null) if (target == null)
@ -429,10 +430,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target");
} }
MapToUnchecked(target, f, forceMapZeros, skipClearing); MapToUnchecked(target, f, zeros, existingData);
} }
internal virtual void MapToUnchecked<TU>(VectorStorage<TU> target, Func<T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal virtual void MapToUnchecked<TU>(VectorStorage<TU> target, Func<T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)
@ -441,7 +443,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
public void MapIndexedTo<TU>(VectorStorage<TU> target, Func<int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) public void MapIndexedTo<TU>(VectorStorage<TU> target, Func<int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
if (target == null) if (target == null)
@ -454,10 +457,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target");
} }
MapIndexedToUnchecked(target, f, forceMapZeros, skipClearing); MapIndexedToUnchecked(target, f, zeros, existingData);
} }
internal virtual void MapIndexedToUnchecked<TU>(VectorStorage<TU> target, Func<int, T, TU> f, bool forceMapZeros = false, bool skipClearing = false) internal virtual void MapIndexedToUnchecked<TU>(VectorStorage<TU> target, Func<int, T, TU> f,
Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
for (int i = 0; i < Length; i++) for (int i = 0; i < Length; i++)

34
src/Numerics/LinearAlgebra/Vector.cs

@ -139,7 +139,7 @@ namespace MathNet.Numerics.LinearAlgebra
public Vector<T> Clone() public Vector<T> Clone()
{ {
var result = Build.SameAs(this); var result = Build.SameAs(this);
Storage.CopyToUnchecked(result.Storage, skipClearing: true); Storage.CopyToUnchecked(result.Storage, ExistingData.AssumeZeros);
return result; return result;
} }
@ -185,7 +185,7 @@ namespace MathNet.Numerics.LinearAlgebra
public Vector<T> SubVector(int index, int count) public Vector<T> SubVector(int index, int count)
{ {
var target = Build.SameAs(this, count); var target = Build.SameAs(this, count);
Storage.CopySubVectorTo(target.Storage, index, 0, count, skipClearing: true); Storage.CopySubVectorTo(target.Storage, index, 0, count, ExistingData.AssumeZeros);
return target; return target;
} }
@ -233,7 +233,7 @@ namespace MathNet.Numerics.LinearAlgebra
public T[] ToArray() public T[] ToArray()
{ {
var result = new DenseVectorStorage<T>(Count); var result = new DenseVectorStorage<T>(Count);
Storage.CopyToUnchecked(result, skipClearing: true); Storage.CopyToUnchecked(result, ExistingData.AssumeZeros);
return result.Data; return result.Data;
} }
@ -246,7 +246,7 @@ namespace MathNet.Numerics.LinearAlgebra
public Matrix<T> ToColumnMatrix() public Matrix<T> ToColumnMatrix()
{ {
var result = Matrix<T>.Build.SameAs(this, Count, 1); var result = Matrix<T>.Build.SameAs(this, Count, 1);
Storage.CopyToColumnUnchecked(result.Storage, 0, skipClearing: true); Storage.CopyToColumnUnchecked(result.Storage, 0, ExistingData.AssumeZeros);
return result; return result;
} }
@ -259,7 +259,7 @@ namespace MathNet.Numerics.LinearAlgebra
public Matrix<T> ToRowMatrix() public Matrix<T> ToRowMatrix()
{ {
var result = Matrix<T>.Build.SameAs(this, 1, Count); var result = Matrix<T>.Build.SameAs(this, 1, Count);
Storage.CopyToRowUnchecked(result.Storage, 0, skipClearing: true); Storage.CopyToRowUnchecked(result.Storage, 0, ExistingData.AssumeZeros);
return result; return result;
} }
@ -316,9 +316,9 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse vectors). /// on the actual data storage implementation (relevant mostly for sparse vectors).
/// </summary> /// </summary>
public void MapInplace(Func<T, T> f, bool forceMapZeros = false) public void MapInplace(Func<T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
Storage.MapToUnchecked(Storage, f, forceMapZeros, skipClearing: true); Storage.MapToUnchecked(Storage, f, zeros, ExistingData.AssumeZeros);
} }
/// <summary> /// <summary>
@ -327,9 +327,9 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse vectors). /// on the actual data storage implementation (relevant mostly for sparse vectors).
/// </summary> /// </summary>
public void MapIndexedInplace(Func<int, T, T> f, bool forceMapZeros = false) public void MapIndexedInplace(Func<int, T, T> f, Zeros zeros = Zeros.AllowSkip)
{ {
Storage.MapIndexedToUnchecked(Storage, f, forceMapZeros, skipClearing: true); Storage.MapIndexedToUnchecked(Storage, f, zeros, ExistingData.AssumeZeros);
} }
/// <summary> /// <summary>
@ -337,10 +337,10 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse vectors). /// on the actual data storage implementation (relevant mostly for sparse vectors).
/// </summary> /// </summary>
public void Map<TU>(Func<T, TU> f, Vector<TU> result, bool forceMapZeros = false) public void Map<TU>(Func<T, TU> f, Vector<TU> result, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
Storage.MapTo(result.Storage, f, forceMapZeros, skipClearing: forceMapZeros); Storage.MapTo(result.Storage, f, zeros, zeros == Zeros.Include ? ExistingData.AssumeZeros : ExistingData.Clear);
} }
/// <summary> /// <summary>
@ -349,10 +349,10 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse vectors). /// on the actual data storage implementation (relevant mostly for sparse vectors).
/// </summary> /// </summary>
public void MapIndexed<TU>(Func<int, T, TU> f, Vector<TU> result, bool forceMapZeros = false) public void MapIndexed<TU>(Func<int, T, TU> f, Vector<TU> result, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
Storage.MapIndexedTo(result.Storage, f, forceMapZeros, skipClearing: forceMapZeros); Storage.MapIndexedTo(result.Storage, f, zeros, zeros == Zeros.Include ? ExistingData.AssumeZeros : ExistingData.Clear);
} }
/// <summary> /// <summary>
@ -360,11 +360,11 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse vectors). /// on the actual data storage implementation (relevant mostly for sparse vectors).
/// </summary> /// </summary>
public Vector<TU> Map<TU>(Func<T, TU> f, bool forceMapZeros = false) public Vector<TU> Map<TU>(Func<T, TU> f, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
var result = Vector<TU>.Build.SameAs(this); var result = Vector<TU>.Build.SameAs(this);
Storage.MapToUnchecked(result.Storage, f, forceMapZeros, skipClearing: true); Storage.MapToUnchecked(result.Storage, f, zeros, ExistingData.AssumeZeros);
return result; return result;
} }
@ -374,11 +374,11 @@ namespace MathNet.Numerics.LinearAlgebra
/// If forceMapZero is not set to true, zero values may or may not be skipped depending /// If forceMapZero is not set to true, zero values may or may not be skipped depending
/// on the actual data storage implementation (relevant mostly for sparse vectors). /// on the actual data storage implementation (relevant mostly for sparse vectors).
/// </summary> /// </summary>
public Vector<TU> MapIndexed<TU>(Func<int, T, TU> f, bool forceMapZeros = false) public Vector<TU> MapIndexed<TU>(Func<int, T, TU> f, Zeros zeros = Zeros.AllowSkip)
where TU : struct, IEquatable<TU>, IFormattable where TU : struct, IEquatable<TU>, IFormattable
{ {
var result = Vector<TU>.Build.SameAs(this); var result = Vector<TU>.Build.SameAs(this);
Storage.MapIndexedToUnchecked(result.Storage, f, forceMapZeros, skipClearing: true); Storage.MapIndexedToUnchecked(result.Storage, f, zeros, ExistingData.AssumeZeros);
return result; return result;
} }
} }

1
src/Numerics/Numerics.csproj

@ -98,6 +98,7 @@
<Compile Include="Interpolation\Barycentric.cs" /> <Compile Include="Interpolation\Barycentric.cs" />
<Compile Include="Interpolation\CubicSpline.cs" /> <Compile Include="Interpolation\CubicSpline.cs" />
<Compile Include="Interpolation\QuadraticSpline.cs" /> <Compile Include="Interpolation\QuadraticSpline.cs" />
<Compile Include="LinearAlgebra\Options.cs" />
<Compile Include="LinearAlgebra\Solvers\DelegateStopCriterion.cs" /> <Compile Include="LinearAlgebra\Solvers\DelegateStopCriterion.cs" />
<Compile Include="Precision.Comparison.cs" /> <Compile Include="Precision.Comparison.cs" />
<Compile Include="Precision.Equality.cs" /> <Compile Include="Precision.Equality.cs" />

66
src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Map.cs

@ -39,27 +39,27 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
[Theory] [Theory]
public void CanMap(Matrix<T> matrix) public void CanMap(Matrix<T> matrix)
{ {
Matrix<T> a = matrix.Map(x => x, false); Matrix<T> a = matrix.Map(x => x, Zeros.AllowSkip);
Assert.That(a, Is.EqualTo(matrix)); Assert.That(a, Is.EqualTo(matrix));
Assert.That(a.Storage.IsDense, Is.EqualTo(matrix.Storage.IsDense)); Assert.That(a.Storage.IsDense, Is.EqualTo(matrix.Storage.IsDense));
Assert.That(a.Storage.IsFullyMutable, Is.EqualTo(matrix.Storage.IsFullyMutable)); Assert.That(a.Storage.IsFullyMutable, Is.EqualTo(matrix.Storage.IsFullyMutable));
T one = Matrix<T>.Build.One; T one = Matrix<T>.Build.One;
Assert.That(matrix.Map(x => x, true), Is.EqualTo(matrix)); Assert.That(matrix.Map(x => x, Zeros.Include), Is.EqualTo(matrix));
Assert.That(matrix.Map(x => one, true), Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one))); Assert.That(matrix.Map(x => one, Zeros.Include), Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one)));
// Map into existing - we skip zeros, but existing values must still be reset to zero // Map into existing - we skip zeros, but existing values must still be reset to zero
var dense = Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one); var dense = Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one);
matrix.Map(x => x, dense, false); matrix.Map(x => x, dense, Zeros.AllowSkip);
Assert.That(dense, Is.EqualTo(matrix)); Assert.That(dense, Is.EqualTo(matrix));
// Map into self, without using the proper MapInplace method: // Map into self, without using the proper MapInplace method:
var copy = matrix.Clone(); var copy = matrix.Clone();
copy.Map(x => x, copy, false); copy.Map(x => x, copy, Zeros.AllowSkip);
Assert.That(copy, Is.EqualTo(matrix)); Assert.That(copy, Is.EqualTo(matrix));
if (matrix.Storage.IsFullyMutable) if (matrix.Storage.IsFullyMutable)
{ {
copy.Map(x => one, copy, false); copy.Map(x => one, copy, Zeros.AllowSkip);
Assert.That(copy, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one))); Assert.That(copy, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one)));
} }
} }
@ -71,31 +71,31 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{ {
if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x)); if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x));
return x; return x;
}, false); }, Zeros.AllowSkip);
Assert.That(a, Is.EqualTo(matrix)); Assert.That(a, Is.EqualTo(matrix));
Assert.That(a.Storage.IsDense, Is.EqualTo(matrix.Storage.IsDense)); Assert.That(a.Storage.IsDense, Is.EqualTo(matrix.Storage.IsDense));
Assert.That(a.Storage.IsFullyMutable, Is.EqualTo(matrix.Storage.IsFullyMutable)); Assert.That(a.Storage.IsFullyMutable, Is.EqualTo(matrix.Storage.IsFullyMutable));
T one = Matrix<T>.Build.One; T one = Matrix<T>.Build.One;
var d = matrix.MapIndexed((i, j, x) => i == j ? one : x, false); var d = matrix.MapIndexed((i, j, x) => i == j ? one : x, Zeros.AllowSkip);
Assert.That(d.Diagonal().All(x => one.Equals(x) || Zero.Equals(x)), Is.True); Assert.That(d.Diagonal().All(x => one.Equals(x) || Zero.Equals(x)), Is.True);
Assert.That(d.EnumerateIndexed().All(z => (z.Item1 == z.Item2) || (matrix.At(z.Item1, z.Item2).Equals(z.Item3)))); Assert.That(d.EnumerateIndexed().All(z => (z.Item1 == z.Item2) || (matrix.At(z.Item1, z.Item2).Equals(z.Item3))));
Assert.That(matrix.MapIndexed((i, j, x) => x, true), Is.EqualTo(matrix)); Assert.That(matrix.MapIndexed((i, j, x) => x, Zeros.Include), Is.EqualTo(matrix));
Assert.That(matrix.MapIndexed((i, j, x) => one, true), Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one))); Assert.That(matrix.MapIndexed((i, j, x) => one, Zeros.Include), Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one)));
// Map into existing - we skip zeros, but existing values must still be reset to zero // Map into existing - we skip zeros, but existing values must still be reset to zero
var dense = Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one); var dense = Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one);
matrix.MapIndexed((i, j, x) => x, dense, false); matrix.MapIndexed((i, j, x) => x, dense, Zeros.AllowSkip);
Assert.That(dense, Is.EqualTo(matrix)); Assert.That(dense, Is.EqualTo(matrix));
// Map into self, without using the proper MapInplace method: // Map into self, without using the proper MapInplace method:
var copy = matrix.Clone(); var copy = matrix.Clone();
copy.MapIndexed((i, j, x) => x, copy, false); copy.MapIndexed((i, j, x) => x, copy, Zeros.AllowSkip);
Assert.That(copy, Is.EqualTo(matrix)); Assert.That(copy, Is.EqualTo(matrix));
if (matrix.Storage.IsFullyMutable) if (matrix.Storage.IsFullyMutable)
{ {
copy.MapIndexed((i, j, x) => one, copy, false); copy.MapIndexed((i, j, x) => one, copy, Zeros.AllowSkip);
Assert.That(copy, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one))); Assert.That(copy, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one)));
} }
} }
@ -104,16 +104,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
public void CanMapInplace(Matrix<T> matrix) public void CanMapInplace(Matrix<T> matrix)
{ {
var a = matrix.Clone(); var a = matrix.Clone();
a.MapInplace(x => x, false); a.MapInplace(x => x, Zeros.AllowSkip);
Assert.That(a, Is.EqualTo(matrix)); Assert.That(a, Is.EqualTo(matrix));
if (matrix.Storage.IsFullyMutable) if (matrix.Storage.IsFullyMutable)
{ {
a.MapInplace(x => x, true); a.MapInplace(x => x, Zeros.Include);
Assert.That(a, Is.EqualTo(matrix)); Assert.That(a, Is.EqualTo(matrix));
T one = Matrix<T>.Build.One; T one = Matrix<T>.Build.One;
a.MapInplace(x => one, true); a.MapInplace(x => one, Zeros.Include);
Assert.That(a, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one))); Assert.That(a, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one)));
} }
} }
@ -127,20 +127,20 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x)); if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x));
return x; return x;
}, false); }, Zeros.AllowSkip);
Assert.That(a, Is.EqualTo(matrix)); Assert.That(a, Is.EqualTo(matrix));
if (matrix.Storage.IsFullyMutable) if (matrix.Storage.IsFullyMutable)
{ {
a.MapIndexedInplace((i, j, x) => x, true); a.MapIndexedInplace((i, j, x) => x, Zeros.Include);
Assert.That(a, Is.EqualTo(matrix)); Assert.That(a, Is.EqualTo(matrix));
T one = Matrix<T>.Build.One; T one = Matrix<T>.Build.One;
a.MapIndexedInplace((i, j, x) => i == j ? one : x, false); a.MapIndexedInplace((i, j, x) => i == j ? one : x, Zeros.AllowSkip);
Assert.That(a.Diagonal().All(x => one.Equals(x) || Zero.Equals(x)), Is.True); Assert.That(a.Diagonal().All(x => one.Equals(x) || Zero.Equals(x)), Is.True);
Assert.That(a.EnumerateIndexed().All(z => (z.Item1 == z.Item2) || (matrix.At(z.Item1, z.Item2).Equals(z.Item3)))); Assert.That(a.EnumerateIndexed().All(z => (z.Item1 == z.Item2) || (matrix.At(z.Item1, z.Item2).Equals(z.Item3))));
a.MapIndexedInplace((i, j, x) => one, true); a.MapIndexedInplace((i, j, x) => one, Zeros.Include);
Assert.That(a, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one))); Assert.That(a, Is.EqualTo(Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount, one)));
} }
} }
@ -152,18 +152,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
// Full Range - not forced // Full Range - not forced
Matrix<T> target = Matrix<T>.Build.SameAs(matrix); Matrix<T> target = Matrix<T>.Build.SameAs(matrix);
matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => x, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, false, false); matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => x, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.AllowSkip, ExistingData.Clear);
Assert.That(target, Is.EqualTo(matrix), "Full Range - not forced"); Assert.That(target, Is.EqualTo(matrix), "Full Range - not forced");
matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => Zero.Equals(x) ? Zero : one, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, false, false); matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => Zero.Equals(x) ? Zero : one, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.AllowSkip, ExistingData.Clear);
Assert.That(target.Enumerate().All(x => Zero.Equals(x) || one.Equals(x)), Is.True); Assert.That(target.Enumerate().All(x => Zero.Equals(x) || one.Equals(x)), Is.True);
if (matrix.Storage.IsFullyMutable) if (matrix.Storage.IsFullyMutable)
{ {
// Full Range - forced // Full Range - forced
target = Matrix<T>.Build.SameAs(matrix); target = Matrix<T>.Build.SameAs(matrix);
matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => x, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, true, false); matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => x, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.Include, ExistingData.Clear);
Assert.That(target, Is.EqualTo(matrix), "Full Range - forced"); Assert.That(target, Is.EqualTo(matrix), "Full Range - forced");
matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => Zero.Equals(x) ? Zero : one, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, true, false); matrix.Storage.MapSubMatrixIndexedTo(target.Storage, (i, j, x) => Zero.Equals(x) ? Zero : one, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.Include, ExistingData.Clear);
Assert.That(target.Enumerate().All(x => Zero.Equals(x) || one.Equals(x)), Is.True); Assert.That(target.Enumerate().All(x => Zero.Equals(x) || one.Equals(x)), Is.True);
} }
} }
@ -179,7 +179,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{ {
if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x)); if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x));
return x; return x;
}, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, false, false); }, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.AllowSkip, ExistingData.Clear);
Assert.That(dense, Is.EqualTo(matrix), "Full Range - not forced"); Assert.That(dense, Is.EqualTo(matrix), "Full Range - not forced");
// Full Range - forced // Full Range - forced
@ -188,12 +188,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{ {
if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x)); if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x));
return x; return x;
}, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, true, false); }, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.Include, ExistingData.Clear);
Assert.That(dense, Is.EqualTo(matrix), "Full Range - forced"); Assert.That(dense, Is.EqualTo(matrix), "Full Range - forced");
// Sub Range - not forced - all except first column padded into 1-border // Sub Range - not forced - all except first column padded into 1-border
dense = Matrix<T>.Build.Dense(matrix.RowCount + 2, matrix.ColumnCount + 1, one); dense = Matrix<T>.Build.Dense(matrix.RowCount + 2, matrix.ColumnCount + 1, one);
matrix.Storage.MapSubMatrixIndexedTo(dense.Storage, (i, j, x) => x, 0, 1, matrix.RowCount, 1, 1, matrix.ColumnCount - 1, false, false); matrix.Storage.MapSubMatrixIndexedTo(dense.Storage, (i, j, x) => x, 0, 1, matrix.RowCount, 1, 1, matrix.ColumnCount - 1, Zeros.AllowSkip, ExistingData.Clear);
Assert.That(dense.SubMatrix(1, dense.RowCount - 2, 1, dense.ColumnCount - 2), Assert.That(dense.SubMatrix(1, dense.RowCount - 2, 1, dense.ColumnCount - 2),
Is.EqualTo(matrix.SubMatrix(0, matrix.RowCount, 1, matrix.ColumnCount - 1)), "Sub Range - not forced - range"); Is.EqualTo(matrix.SubMatrix(0, matrix.RowCount, 1, matrix.ColumnCount - 1)), "Sub Range - not forced - range");
dense.SetSubMatrix(1, 0, matrix.RowCount, 1, 0, matrix.ColumnCount - 1, Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount - 1, one)); dense.SetSubMatrix(1, 0, matrix.RowCount, 1, 0, matrix.ColumnCount - 1, Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount - 1, one));
@ -201,7 +201,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
// Sub Range - forced - all except first row padded into 1-border // Sub Range - forced - all except first row padded into 1-border
dense = Matrix<T>.Build.Dense(matrix.RowCount + 1, matrix.ColumnCount + 2, one); dense = Matrix<T>.Build.Dense(matrix.RowCount + 1, matrix.ColumnCount + 2, one);
matrix.Storage.MapSubMatrixIndexedTo(dense.Storage, (i, j, x) => x, 1, 1, matrix.RowCount - 1, 0, 1, matrix.ColumnCount, true, false); matrix.Storage.MapSubMatrixIndexedTo(dense.Storage, (i, j, x) => x, 1, 1, matrix.RowCount - 1, 0, 1, matrix.ColumnCount, Zeros.Include, ExistingData.Clear);
Assert.That(dense.SubMatrix(1, dense.RowCount - 2, 1, dense.ColumnCount - 2), Assert.That(dense.SubMatrix(1, dense.RowCount - 2, 1, dense.ColumnCount - 2),
Is.EqualTo(matrix.SubMatrix(1, matrix.RowCount - 1, 0, matrix.ColumnCount)), "Sub Range - forced - range"); Is.EqualTo(matrix.SubMatrix(1, matrix.RowCount - 1, 0, matrix.ColumnCount)), "Sub Range - forced - range");
dense.SetSubMatrix(1, 0, matrix.RowCount - 1, 1, 0, matrix.ColumnCount, Matrix<T>.Build.Dense(matrix.RowCount - 1, matrix.ColumnCount, one)); dense.SetSubMatrix(1, 0, matrix.RowCount - 1, 1, 0, matrix.ColumnCount, Matrix<T>.Build.Dense(matrix.RowCount - 1, matrix.ColumnCount, one));
@ -219,7 +219,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{ {
if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x)); if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x));
return x; return x;
}, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, false, false); }, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.AllowSkip, ExistingData.Clear);
Assert.That(sparse, Is.EqualTo(matrix), "Full Range - filled, not forced"); Assert.That(sparse, Is.EqualTo(matrix), "Full Range - filled, not forced");
// Full Range - empty, not forced // Full Range - empty, not forced
@ -228,7 +228,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{ {
if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x)); if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x));
return x; return x;
}, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, false, false); }, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.AllowSkip, ExistingData.Clear);
Assert.That(sparse, Is.EqualTo(matrix), "Full Range - empty, not forced"); Assert.That(sparse, Is.EqualTo(matrix), "Full Range - empty, not forced");
// Full Range - filled, forced // Full Range - filled, forced
@ -237,12 +237,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
{ {
if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x)); if (i != 0 || j != 1) Assert.That(matrix.At(i, j), Is.EqualTo(x));
return x; return x;
}, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, true, false); }, 0, 0, matrix.RowCount, 0, 0, matrix.ColumnCount, Zeros.Include, ExistingData.Clear);
Assert.That(sparse, Is.EqualTo(matrix), "Full Range - filled, forced"); Assert.That(sparse, Is.EqualTo(matrix), "Full Range - filled, forced");
// Sub Range - filled, not forced - all except first column padded into 1-border // Sub Range - filled, not forced - all except first column padded into 1-border
sparse = Matrix<T>.Build.Sparse(matrix.RowCount + 2, matrix.ColumnCount + 1, one); sparse = Matrix<T>.Build.Sparse(matrix.RowCount + 2, matrix.ColumnCount + 1, one);
matrix.Storage.MapSubMatrixIndexedTo(sparse.Storage, (i, j, x) => x, 0, 1, matrix.RowCount, 1, 1, matrix.ColumnCount - 1, false, false); matrix.Storage.MapSubMatrixIndexedTo(sparse.Storage, (i, j, x) => x, 0, 1, matrix.RowCount, 1, 1, matrix.ColumnCount - 1, Zeros.AllowSkip, ExistingData.Clear);
Assert.That(sparse.SubMatrix(1, sparse.RowCount - 2, 1, sparse.ColumnCount - 2), Assert.That(sparse.SubMatrix(1, sparse.RowCount - 2, 1, sparse.ColumnCount - 2),
Is.EqualTo(matrix.SubMatrix(0, matrix.RowCount, 1, matrix.ColumnCount - 1)), "Sub Range - filled, not forced - range"); Is.EqualTo(matrix.SubMatrix(0, matrix.RowCount, 1, matrix.ColumnCount - 1)), "Sub Range - filled, not forced - range");
sparse.SetSubMatrix(1, 0, matrix.RowCount, 1, 0, matrix.ColumnCount - 1, Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount - 1, one)); sparse.SetSubMatrix(1, 0, matrix.RowCount, 1, 0, matrix.ColumnCount - 1, Matrix<T>.Build.Dense(matrix.RowCount, matrix.ColumnCount - 1, one));
@ -250,7 +250,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests
// Sub Range - filled, forced - all except first row padded into 1-border // Sub Range - filled, forced - all except first row padded into 1-border
sparse = Matrix<T>.Build.Sparse(matrix.RowCount + 1, matrix.ColumnCount + 2, one); sparse = Matrix<T>.Build.Sparse(matrix.RowCount + 1, matrix.ColumnCount + 2, one);
matrix.Storage.MapSubMatrixIndexedTo(sparse.Storage, (i, j, x) => x, 1, 1, matrix.RowCount - 1, 0, 1, matrix.ColumnCount, true, false); matrix.Storage.MapSubMatrixIndexedTo(sparse.Storage, (i, j, x) => x, 1, 1, matrix.RowCount - 1, 0, 1, matrix.ColumnCount, Zeros.Include, ExistingData.Clear);
Assert.That(sparse.SubMatrix(1, sparse.RowCount - 2, 1, sparse.ColumnCount - 2), Assert.That(sparse.SubMatrix(1, sparse.RowCount - 2, 1, sparse.ColumnCount - 2),
Is.EqualTo(matrix.SubMatrix(1, matrix.RowCount - 1, 0, matrix.ColumnCount)), "Sub Range - filled, forced - range"); Is.EqualTo(matrix.SubMatrix(1, matrix.RowCount - 1, 0, matrix.ColumnCount)), "Sub Range - filled, forced - range");
sparse.SetSubMatrix(1, 0, matrix.RowCount - 1, 1, 0, matrix.ColumnCount, Matrix<T>.Build.Dense(matrix.RowCount - 1, matrix.ColumnCount, one)); sparse.SetSubMatrix(1, 0, matrix.RowCount - 1, 1, 0, matrix.ColumnCount, Matrix<T>.Build.Dense(matrix.RowCount - 1, matrix.ColumnCount, one));

Loading…
Cancel
Save