From 0eef2b15b3b5fd324932416ab3ce3dba74176ed6 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Fri, 27 Jun 2014 11:26:21 +0200 Subject: [PATCH] LA: consistency: enumerators should leverage Zeros-enum, like map/fold already does. --- src/FSharp/LinearAlgebra.Matrix.fs | 52 +++++++++---------- src/FSharp/LinearAlgebra.Vector.fs | 52 +++++++++---------- src/Numerics/LinearAlgebra/Matrix.Solve.cs | 2 +- src/Numerics/LinearAlgebra/Matrix.cs | 45 +++++++++++++++- src/Numerics/LinearAlgebra/Vector.cs | 38 ++++++++++++++ .../LinearAlgebraTests/Complex/VectorTests.cs | 2 +- .../Complex32/VectorTests.cs | 2 +- .../LinearAlgebraTests/Double/VectorTests.cs | 2 +- .../LinearAlgebraTests/Single/VectorTests.cs | 2 +- 9 files changed, 138 insertions(+), 59 deletions(-) diff --git a/src/FSharp/LinearAlgebra.Matrix.fs b/src/FSharp/LinearAlgebra.Matrix.fs index fc88cff9..2ae77f57 100644 --- a/src/FSharp/LinearAlgebra.Matrix.fs +++ b/src/FSharp/LinearAlgebra.Matrix.fs @@ -43,16 +43,16 @@ module Matrix = /// Transform a matrix into a sequence. - let inline toSeq (m: #Matrix<_>) = m.Enumerate() + let inline toSeq (m: #Matrix<_>) = m.Enumerate(Zeros.Include) /// Transform a matrix into an indexed sequence. - let inline toSeqi (m: #Matrix<_>) = m.EnumerateIndexed() + let inline toSeqi (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.Include) /// Transform a matrix into a sequence where zero-values are skipped. Skipping zeros is efficient on sparse data. - let inline toSeqSkipZeros (m: #Matrix<_>) = m.EnumerateNonZero() + let inline toSeqSkipZeros (m: #Matrix<_>) = m.Enumerate(Zeros.AllowSkip) /// Transform a matrix into an indexed sequence where zero-values are skipped. Skipping zeros is efficient on sparse data. - let inline toSeqiSkipZeros (m: #Matrix<_>) = m.EnumerateNonZeroIndexed() + let inline toSeqiSkipZeros (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.AllowSkip) /// Transform a matrix into a column sequence. let inline toColSeq (m: #Matrix<_>) = m.EnumerateColumns() @@ -68,16 +68,16 @@ module Matrix = /// Applies a function to all elements of the matrix. - let inline iter f (m: #Matrix<_>) = m.Enumerate() |> Seq.iter f + let inline iter f (m: #Matrix<_>) = m.Enumerate(Zeros.Include) |> Seq.iter f /// Applies a function to all indexed elements of the matrix. - let inline iteri f (m: #Matrix<_>) = m.EnumerateIndexed() |> Seq.iter (fun (i, j, x) -> f i j x) + let inline iteri f (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.Include) |> Seq.iter (fun (i, j, x) -> f i j x) /// Applies a function to all non-zero elements of the matrix. Skipping zeros is efficient on sparse data. - let inline iterSkipZerosnz f (m: #Matrix<_>) = m.EnumerateNonZero() |> Seq.iter f + let inline iterSkipZerosnz f (m: #Matrix<_>) = m.Enumerate(Zeros.AllowSkip) |> Seq.iter f /// Applies a function to all non-zero indexed elements of the matrix. Skipping zeros is efficient on sparse data. - let inline iteriSkipZeros f (m: #Matrix<_>) = m.EnumerateNonZeroIndexed() |> Seq.iter (fun (i, j, x) -> f i j x) + let inline iteriSkipZeros f (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.AllowSkip) |> Seq.iter (fun (i, j, x) -> f i j x) /// Applies a function to all columns of the matrix. let inline iterCols f (m: #Matrix<_>) = m.EnumerateColumns() |> Seq.iter f @@ -93,16 +93,16 @@ module Matrix = /// Fold all entries of a matrix. - let inline fold f state (m: #Matrix<_>) = m.Enumerate() |> Seq.fold f state + let inline fold f state (m: #Matrix<_>) = m.Enumerate(Zeros.Include) |> Seq.fold f state /// Fold all entries of a matrix with an indexed folding function. - let inline foldi f state (m: #Matrix<_>) = m.EnumerateIndexed() |> Seq.fold (fun s (i,j,x) -> f i j s x) state + let inline foldi f state (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.Include) |> Seq.fold (fun s (i,j,x) -> f i j s x) state /// Fold all non-zero entries of a matrix. Skipping zeros is efficient on sparse data. - let inline foldSkipZeros f state (m: #Matrix<_>) = m.EnumerateNonZero() |> Seq.fold f state + let inline foldSkipZeros f state (m: #Matrix<_>) = m.Enumerate(Zeros.AllowSkip) |> Seq.fold f state /// Fold all non-zero entries of a matrix with an indexed folding function. Skipping zeros is efficient on sparse data. - let inline foldiSkipZeros f state (m: #Matrix<_>) = m.EnumerateNonZeroIndexed() |> Seq.fold (fun s (i,j,x) -> f i j s x) state + let inline foldiSkipZeros f state (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.AllowSkip) |> Seq.fold (fun s (i,j,x) -> f i j s x) state /// Fold all columns of a matrix. let inline foldCols f state (m: #Matrix<_>) = m.EnumerateColumns() |> Seq.fold f state @@ -118,16 +118,16 @@ module Matrix = /// Scan all entries of a matrix. - let inline scan f state (m: #Matrix<_>) = m.Enumerate() |> Seq.scan f state + let inline scan f state (m: #Matrix<_>) = m.Enumerate(Zeros.Include) |> Seq.scan f state /// Scan all entries of a matrix with an indexed folding function. - let inline scani f state (m: #Matrix<_>) = m.EnumerateIndexed() |> Seq.scan (fun s (i,j,x) -> f i j s x) state + let inline scani f state (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.Include) |> Seq.scan (fun s (i,j,x) -> f i j s x) state /// Scan all non-zero entries of a matrix. Skipping zeros is efficient on sparse data. - let inline scanSkipZeros f state (m: #Matrix<_>) = m.EnumerateNonZero() |> Seq.scan f state + let inline scanSkipZeros f state (m: #Matrix<_>) = m.Enumerate(Zeros.AllowSkip) |> Seq.scan f state /// Scan all non-zero entries of a matrix with an indexed folding function. Skipping zeros is efficient on sparse data. - let inline scaniSkipZeros f state (m: #Matrix<_>) = m.EnumerateNonZeroIndexed() |> Seq.scan (fun s (i,j,x) -> f i j s x) state + let inline scaniSkipZeros f state (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.AllowSkip) |> Seq.scan (fun s (i,j,x) -> f i j s x) state /// Scan all columns of a matrix. let inline scanCols f state (m: #Matrix<_>) = m.EnumerateColumns() |> Seq.scan f state @@ -143,10 +143,10 @@ module Matrix = /// Reduce all entries of a matrix. - let inline reduce f (m: #Matrix<_>) = m.Enumerate() |> Seq.reduce f + let inline reduce f (m: #Matrix<_>) = m.Enumerate(Zeros.Include) |> Seq.reduce f /// Reduce all non-zero entries of a matrix. Skipping zeros is efficient on sparse data. - let inline reduceSkipZeros f (m: #Matrix<_>) = m.EnumerateNonZero() |> Seq.reduce f + let inline reduceSkipZeros f (m: #Matrix<_>) = m.Enumerate(Zeros.AllowSkip) |> Seq.reduce f /// Reduce all columns of a matrix. let inline reduceCols f (m: #Matrix<_>) = m.EnumerateColumns() |> Seq.reduce f @@ -156,16 +156,16 @@ module Matrix = /// Checks whether there is an entry in the matrix that satisfies a predicate. - let inline exists p (m: #Matrix<_>) = m.Enumerate() |> Seq.exists p + let inline exists p (m: #Matrix<_>) = m.Enumerate(Zeros.Include) |> Seq.exists p /// Checks whether there is an entry in the matrix that satisfies a position dependent predicate. - let inline existsi p (m: #Matrix<_>) = m.EnumerateIndexed() |> Seq.exists (fun (i,j,x) -> p i j x) + let inline existsi p (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.Include) |> Seq.exists (fun (i,j,x) -> p i j x) /// Checks whether there is a non-zero entry in the matrix that satisfies a predicate. Skipping zeros is efficient on sparse data. - let inline existsSkipZeros p (m: #Matrix<_>) = m.EnumerateNonZero() |> Seq.exists p + let inline existsSkipZeros p (m: #Matrix<_>) = m.Enumerate(Zeros.AllowSkip) |> Seq.exists p /// Checks whether there is a non-zero entry in the matrix that satisfies a position dependent predicate. Skipping zeros is efficient on sparse data. - let inline existsiSkipZeros p (m: #Matrix<_>) = m.EnumerateNonZeroIndexed() |> Seq.exists (fun (i,j,x) -> p i j x) + let inline existsiSkipZeros p (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.AllowSkip) |> Seq.exists (fun (i,j,x) -> p i j x) /// Checks whether there is a column in the matrix that satisfies a predicate. let inline existsCol p (m: #Matrix<_>) = m.EnumerateColumns() |> Seq.exists p @@ -181,16 +181,16 @@ module Matrix = /// Checks whether all entries in the matrix that satisfies a given predicate. - let inline forall p (m: #Matrix<_>) = m.Enumerate() |> Seq.forall p + let inline forall p (m: #Matrix<_>) = m.Enumerate(Zeros.Include) |> Seq.forall p /// Checks whether all entries in the matrix that satisfies a given position dependent predicate. - let inline foralli p (m: #Matrix<_>) = m.EnumerateIndexed() |> Seq.forall (fun (i,j,x) -> p i j x) + let inline foralli p (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.Include) |> Seq.forall (fun (i,j,x) -> p i j x) /// Checks whether all non-zero entries in the matrix that satisfies a given predicate. Skipping zeros is efficient on sparse data. - let inline forallSkipZeros p (m: #Matrix<_>) = m.EnumerateNonZero() |> Seq.forall p + let inline forallSkipZeros p (m: #Matrix<_>) = m.Enumerate(Zeros.AllowSkip) |> Seq.forall p /// Checks whether all non-zero entries in the matrix that satisfies a given position dependent predicate. Skipping zeros is efficient on sparse data. - let inline foralliSkipZeros p (m: #Matrix<_>) = m.EnumerateNonZeroIndexed() |> Seq.forall (fun (i,j,x) -> p i j x) + let inline foralliSkipZeros p (m: #Matrix<_>) = m.EnumerateIndexed(Zeros.AllowSkip) |> Seq.forall (fun (i,j,x) -> p i j x) /// Checks whether all columns in the matrix that satisfy a predicate. let inline forallCols p (m: #Matrix<_>) = m.EnumerateColumns() |> Seq.forall p diff --git a/src/FSharp/LinearAlgebra.Vector.fs b/src/FSharp/LinearAlgebra.Vector.fs index c6bcc619..301dae77 100644 --- a/src/FSharp/LinearAlgebra.Vector.fs +++ b/src/FSharp/LinearAlgebra.Vector.fs @@ -46,88 +46,88 @@ module Vector = /// Transform a vector into a sequence. - let inline toSeq (v: #Vector<_>) = v.Enumerate() + let inline toSeq (v: #Vector<_>) = v.Enumerate(Zeros.Include) /// Transform a vector into an indexed sequence. - let inline toSeqi (v: #Vector<_>) = v.EnumerateIndexed() + let inline toSeqi (v: #Vector<_>) = v.EnumerateIndexed(Zeros.Include) /// Transform a vector into a sequence where zero-values are skipped. Skipping zeros is efficient on sparse data. - let inline toSeqSkipZeros (v: #Vector<_>) = v.EnumerateNonZero() + let inline toSeqSkipZeros (v: #Vector<_>) = v.Enumerate(Zeros.AllowSkip) /// Transform a vector into an indexed sequence where zero-values are skipped. Skipping zeros is efficient on sparse data. - let inline toSeqiSkipZeros (v: #Vector<_>) = v.EnumerateNonZeroIndexed() + let inline toSeqiSkipZeros (v: #Vector<_>) = v.EnumerateIndexed(Zeros.AllowSkip) /// Applies a function to all elements of the vector. - let inline iter f (v: #Vector<_>) = v.Enumerate() |> Seq.iter f + let inline iter f (v: #Vector<_>) = v.Enumerate(Zeros.Include) |> Seq.iter f /// Applies a function to all indexed elements of the vector. - let inline iteri f (v: #Vector<_>) = v.Enumerate() |> Seq.iteri f + let inline iteri f (v: #Vector<_>) = v.Enumerate(Zeros.Include) |> Seq.iteri f /// Applies a function to all non-zero elements of the vector. Skipping zeros is efficient on sparse data. - let inline iterSkipZeros f (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.iter f + let inline iterSkipZeros f (v: #Vector<_>) = v.Enumerate(Zeros.AllowSkip) |> Seq.iter f /// Applies a function to all non-zero indexed elements of the vector. Skipping zeros is efficient on sparse data. - let inline iteriSkipZeros f (v: #Vector<_>) = v.EnumerateNonZeroIndexed() |> Seq.iter (fun (i,x) -> f i x) + let inline iteriSkipZeros f (v: #Vector<_>) = v.EnumerateIndexed(Zeros.AllowSkip) |> Seq.iter (fun (i,x) -> f i x) /// Fold all entries of a vector. - let inline fold f state (v: #Vector<_>) = v.Enumerate() |> Seq.fold f state + let inline fold f state (v: #Vector<_>) = v.Enumerate(Zeros.Include) |> Seq.fold f state /// Fold all entries of a vector using a position dependent folding function. - let inline foldi f state (v: #Vector<_>) = v.EnumerateIndexed() |> Seq.fold (fun s (i,x) -> f i s x) state + let inline foldi f state (v: #Vector<_>) = v.EnumerateIndexed(Zeros.Include) |> Seq.fold (fun s (i,x) -> f i s x) state /// Fold all non-zero entries of a vector. Skipping zeros is efficient on sparse data. - let inline foldSkipZeros f state (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.fold f state + let inline foldSkipZeros f state (v: #Vector<_>) = v.Enumerate(Zeros.AllowSkip) |> Seq.fold f state /// Fold all non-zero entries of a vector using a position dependent folding function. Skipping zeros is efficient on sparse data. - let inline foldiSkipZeros f state (v: #Vector<_>) = v.EnumerateNonZeroIndexed() |> Seq.fold (fun s (i,x) -> f i s x) state + let inline foldiSkipZeros f state (v: #Vector<_>) = v.EnumerateIndexed(Zeros.AllowSkip) |> Seq.fold (fun s (i,x) -> f i s x) state /// Scan all entries of a vector. - let inline scan f state (v: #Vector<_>) = v.Enumerate() |> Seq.scan f state + let inline scan f state (v: #Vector<_>) = v.Enumerate(Zeros.Include) |> Seq.scan f state /// Scan all entries of a vector using a position dependent folding function. - let inline scani f state (v: #Vector<_>) = v.EnumerateIndexed() |> Seq.scan (fun s (i,x) -> f i s x) state + let inline scani f state (v: #Vector<_>) = v.EnumerateIndexed(Zeros.Include) |> Seq.scan (fun s (i,x) -> f i s x) state /// Scan all non-zero entries of a vector. Skipping zeros is efficient on sparse data. - let inline scanSkipZeros f state (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.scan f state + let inline scanSkipZeros f state (v: #Vector<_>) = v.Enumerate(Zeros.AllowSkip) |> Seq.scan f state /// Scan all non-zero entries of a vector using a position dependent folding function. Skipping zeros is efficient on sparse data. - let inline scaniSkipZeros f state (v: #Vector<_>) = v.EnumerateNonZeroIndexed() |> Seq.scan (fun s (i,x) -> f i s x) state + let inline scaniSkipZeros f state (v: #Vector<_>) = v.EnumerateIndexed(Zeros.AllowSkip) |> Seq.scan (fun s (i,x) -> f i s x) state /// Reduce all entries of a vector. - let inline reduce f (v: #Vector<_>) = v.Enumerate() |> Seq.reduce f + let inline reduce f (v: #Vector<_>) = v.Enumerate(Zeros.Include) |> Seq.reduce f /// Reduce all non-zero entries of a vector. Skipping zeros is efficient on sparse data. - let inline reduceSkipZeros f (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.reduce f + let inline reduceSkipZeros f (v: #Vector<_>) = v.Enumerate(Zeros.AllowSkip) |> Seq.reduce f /// Checks whether there is an entry in the vector that satisfies a predicate. - let inline exists p (v: #Vector<_>) = v.Enumerate() |> Seq.exists p + let inline exists p (v: #Vector<_>) = v.Enumerate(Zeros.Include) |> Seq.exists p /// Checks whether there is an entry in the vector that satisfies a position dependent predicate. - let inline existsi p (v: #Vector<_>) = v.EnumerateIndexed() |> Seq.exists (fun (i,x) -> p i x) + let inline existsi p (v: #Vector<_>) = v.EnumerateIndexed(Zeros.Include) |> Seq.exists (fun (i,x) -> p i x) /// Checks whether there is a non-zero entry in the vector that satisfies a predicate. Skipping zeros is efficient on sparse data. - let inline existsSkipZeros p (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.exists p + let inline existsSkipZeros p (v: #Vector<_>) = v.Enumerate(Zeros.AllowSkip) |> Seq.exists p /// Checks whether there is a non-zero entry in the vector that satisfies a position dependent predicate. Skipping zeros is efficient on sparse data. - let inline existsiSkipZeros p (v: #Vector<_>) = v.EnumerateNonZeroIndexed() |> Seq.exists (fun (i,x) -> p i x) + let inline existsiSkipZeros p (v: #Vector<_>) = v.EnumerateIndexed(Zeros.AllowSkip) |> Seq.exists (fun (i,x) -> p i x) /// Checks whether all entries in the vector that satisfies a given predicate. - let inline forall p (v: #Vector<_>) = v.Enumerate() |> Seq.forall p + let inline forall p (v: #Vector<_>) = v.Enumerate(Zeros.Include) |> Seq.forall p /// Checks whether all entries in the vector that satisfies a given position dependent predicate. - let inline foralli p (v: #Vector<_>) = v.EnumerateIndexed() |> Seq.forall (fun (i,x) -> p i x) + let inline foralli p (v: #Vector<_>) = v.EnumerateIndexed(Zeros.Include) |> Seq.forall (fun (i,x) -> p i x) /// Checks whether all non-zero entries in the vector that satisfies a given predicate. Skipping zeros is efficient on sparse data. - let inline forallSkipZeros p (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.forall p + let inline forallSkipZeros p (v: #Vector<_>) = v.Enumerate(Zeros.AllowSkip) |> Seq.forall p /// Checks whether all non-zero entries in the vector that satisfies a given position dependent predicate. Skipping zeros is efficient on sparse data. - let inline foralliSkipZeros p (v: #Vector<_>) = v.EnumerateNonZeroIndexed() |> Seq.forall (fun (i,x) -> p i x) + let inline foralliSkipZeros p (v: #Vector<_>) = v.EnumerateIndexed(Zeros.AllowSkip) |> Seq.forall (fun (i,x) -> p i x) diff --git a/src/Numerics/LinearAlgebra/Matrix.Solve.cs b/src/Numerics/LinearAlgebra/Matrix.Solve.cs index 52217fc6..8142833a 100644 --- a/src/Numerics/LinearAlgebra/Matrix.Solve.cs +++ b/src/Numerics/LinearAlgebra/Matrix.Solve.cs @@ -205,7 +205,7 @@ namespace MathNet.Numerics.LinearAlgebra solver.Solve(this, input.Column(column), solution, iterator, preconditioner); - foreach (var element in solution.EnumerateNonZeroIndexed()) + foreach (var element in solution.EnumerateIndexed(Zeros.AllowSkip)) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Matrix.cs b/src/Numerics/LinearAlgebra/Matrix.cs index 26be9ed2..e0003d03 100644 --- a/src/Numerics/LinearAlgebra/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Matrix.cs @@ -1331,7 +1331,7 @@ namespace MathNet.Numerics.LinearAlgebra /// /// An array containing the matrix's elements. /// - /// + /// public T[] ToColumnWiseArray() { return Storage.ToColumnMajorArray(); @@ -1347,7 +1347,7 @@ namespace MathNet.Numerics.LinearAlgebra /// /// An array containing the matrix's elements. /// - /// + /// public T[] ToRowWiseArray() { return Storage.ToRowMajorArray(); @@ -1367,6 +1367,26 @@ namespace MathNet.Numerics.LinearAlgebra return Storage.Enumerate(); } + /// + /// Returns an IEnumerable that can be used to iterate through all values of the matrix. + /// + /// + /// The enumerator will include all values, even if they are zero. + /// The ordering of the values is unspecified (not necessarily column-wise or row-wise). + /// + /// + /// + public IEnumerable Enumerate(Zeros zeros = Zeros.Include) + { + switch (zeros) + { + case Zeros.AllowSkip: + return Storage.EnumerateNonZero(); + default: + return Storage.Enumerate(); + } + } + /// /// Returns an IEnumerable that can be used to iterate through all values of the matrix and their index. /// @@ -1380,12 +1400,32 @@ namespace MathNet.Numerics.LinearAlgebra return Storage.EnumerateIndexed(); } + /// + /// Returns an IEnumerable that can be used to iterate through all values of the matrix and their index. + /// + /// + /// The enumerator returns a Tuple with the first two values being the row and column index + /// and the third value being the value of the element at that index. + /// The enumerator will include all values, even if they are zero. + /// + public IEnumerable> EnumerateIndexed(Zeros zeros = Zeros.Include) + { + switch (zeros) + { + case Zeros.AllowSkip: + return Storage.EnumerateNonZeroIndexed(); + default: + return Storage.EnumerateIndexed(); + } + } + /// /// Returns an IEnumerable that can be used to iterate through all non-zero values of the matrix. /// /// /// The enumerator will skip all elements with a zero value. /// + [Obsolete("Use Enumerate(Zeros.AllowSkip) instead. Will be removed in v4.")] public IEnumerable EnumerateNonZero() { return Storage.EnumerateNonZero(); @@ -1399,6 +1439,7 @@ namespace MathNet.Numerics.LinearAlgebra /// and the third value being the value of the element at that index. /// The enumerator will skip all elements with a zero value. /// + [Obsolete("Use EnumerateIndexed(Zeros.AllowSkip) instead. Will be removed in v4.")] public IEnumerable> EnumerateNonZeroIndexed() { return Storage.EnumerateNonZeroIndexed(); diff --git a/src/Numerics/LinearAlgebra/Vector.cs b/src/Numerics/LinearAlgebra/Vector.cs index 074335d7..641cfe9f 100644 --- a/src/Numerics/LinearAlgebra/Vector.cs +++ b/src/Numerics/LinearAlgebra/Vector.cs @@ -287,6 +287,23 @@ namespace MathNet.Numerics.LinearAlgebra return Storage.Enumerate(); } + /// + /// Returns an IEnumerable that can be used to iterate through all values of the vector. + /// + /// + /// The enumerator will include all values, even if they are zero. + /// + public IEnumerable Enumerate(Zeros zeros = Zeros.Include) + { + switch (zeros) + { + case Zeros.AllowSkip: + return Storage.EnumerateNonZero(); + default: + return Storage.Enumerate(); + } + } + /// /// Returns an IEnumerable that can be used to iterate through all values of the vector and their index. /// @@ -300,12 +317,32 @@ namespace MathNet.Numerics.LinearAlgebra return Storage.EnumerateIndexed(); } + /// + /// Returns an IEnumerable that can be used to iterate through all values of the vector and their index. + /// + /// + /// The enumerator returns a Tuple with the first value being the element index + /// and the second value being the value of the element at that index. + /// The enumerator will include all values, even if they are zero. + /// + public IEnumerable> EnumerateIndexed(Zeros zeros = Zeros.Include) + { + switch (zeros) + { + case Zeros.AllowSkip: + return Storage.EnumerateNonZeroIndexed(); + default: + return Storage.EnumerateIndexed(); + } + } + /// /// Returns an IEnumerable that can be used to iterate through all non-zero values of the vector. /// /// /// The enumerator will skip all elements with a zero value. /// + [Obsolete("Use Enumerate(Zeros.AllowSkip) instead. Will be removed in v4.")] public IEnumerable EnumerateNonZero() { return Storage.EnumerateNonZero(); @@ -319,6 +356,7 @@ namespace MathNet.Numerics.LinearAlgebra /// and the second value being the value of the element at that index. /// The enumerator will skip all elements with a zero value. /// + [Obsolete("Use EnumerateIndexed(Zeros.AllowSkip) instead. Will be removed in v4.")] public IEnumerable> EnumerateNonZeroIndexed() { return Storage.EnumerateNonZeroIndexed(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs index da6a753c..39ed5865 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs @@ -251,7 +251,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanEnumerateOverVectorUsingNonZeroEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.EnumerateNonZeroIndexed()) + foreach (var pair in vector.EnumerateIndexed(Zeros.AllowSkip)) { Assert.AreEqual(Data[pair.Item1], pair.Item2); Assert.AreNotEqual(Complex.Zero, pair.Item2); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs index 75c1b699..295dc704 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs @@ -247,7 +247,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanEnumerateOverVectorUsingNonZeroEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.EnumerateNonZeroIndexed()) + foreach (var pair in vector.EnumerateIndexed(Zeros.AllowSkip)) { Assert.AreEqual(Data[pair.Item1], pair.Item2); Assert.AreNotEqual(Complex32.Zero, pair.Item2); diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index 4094e96f..83bbecc7 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -243,7 +243,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanEnumerateOverVectorUsingNonZeroEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.EnumerateNonZeroIndexed()) + foreach (var pair in vector.EnumerateIndexed(Zeros.AllowSkip)) { Assert.AreEqual(Data[pair.Item1], pair.Item2); Assert.AreNotEqual(0d, pair.Item2); diff --git a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs index 427aefda..9cf49eb0 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs @@ -244,7 +244,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanEnumerateOverVectorUsingNonZeroEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.EnumerateNonZeroIndexed()) + foreach (var pair in vector.EnumerateIndexed(Zeros.AllowSkip)) { Assert.AreEqual(Data[pair.Item1], pair.Item2); Assert.AreNotEqual(0f, pair.Item2);