From 88d26ccee0571d73861f7c954d4f7a2f28768040 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Tue, 27 Aug 2013 21:01:02 +0200 Subject: [PATCH] LA: Clean up and extend vector enumeration --- .../LinearAlgebra/VectorDataAccessor.cs | 12 +++- src/FSharp/LinearAlgebra.Vector.fs | 65 ++++++++++--------- .../Complex/Solvers/Iterative/BiCgStab.cs | 2 +- .../Solvers/Iterative/CompositeSolver.cs | 2 +- .../Complex/Solvers/Iterative/GpBiCg.cs | 2 +- .../Complex/Solvers/Iterative/MlkBiCgStab.cs | 2 +- .../Complex/Solvers/Iterative/TFQMR.cs | 2 +- .../Complex32/Solvers/Iterative/BiCgStab.cs | 2 +- .../Solvers/Iterative/CompositeSolver.cs | 2 +- .../Complex32/Solvers/Iterative/GpBiCg.cs | 2 +- .../Solvers/Iterative/MlkBiCgStab.cs | 2 +- .../Complex32/Solvers/Iterative/TFQMR.cs | 2 +- .../Double/Solvers/Iterative/BiCgStab.cs | 2 +- .../Solvers/Iterative/CompositeSolver.cs | 2 +- .../Double/Solvers/Iterative/GpBiCg.cs | 2 +- .../Double/Solvers/Iterative/MlkBiCgStab.cs | 2 +- .../Double/Solvers/Iterative/TFQMR.cs | 2 +- .../Single/Solvers/Iterative/BiCgStab.cs | 2 +- .../Solvers/Iterative/CompositeSolver.cs | 2 +- .../Single/Solvers/Iterative/GpBiCg.cs | 2 +- .../Single/Solvers/Iterative/MlkBiCgStab.cs | 2 +- .../Single/Solvers/Iterative/TFQMR.cs | 2 +- .../Storage/DenseVectorStorage.cs | 8 ++- .../Storage/SparseVectorStorage.cs | 11 ++++ .../LinearAlgebra/Storage/VectorStorage.cs | 8 +++ src/Numerics/LinearAlgebra/Vector.BCL.cs | 15 ++++- src/Numerics/LinearAlgebra/Vector.cs | 39 ++++++----- .../LinearAlgebraTests/Complex/VectorTests.cs | 16 ++++- .../Complex32/VectorTests.cs | 16 ++++- .../LinearAlgebraTests/Double/VectorTests.cs | 16 ++++- .../LinearAlgebraTests/Single/VectorTests.cs | 16 ++++- 31 files changed, 190 insertions(+), 72 deletions(-) diff --git a/src/Examples/LinearAlgebra/VectorDataAccessor.cs b/src/Examples/LinearAlgebra/VectorDataAccessor.cs index 2efa17ec..7c5740e4 100644 --- a/src/Examples/LinearAlgebra/VectorDataAccessor.cs +++ b/src/Examples/LinearAlgebra/VectorDataAccessor.cs @@ -148,7 +148,17 @@ namespace Examples.LinearAlgebraExamples // 11. Indexed enumerator usage Console.WriteLine(@"11. Enumerator usage"); - foreach (var value in vectorA.GetIndexedEnumerator()) + foreach (var value in vectorA.EnumerateIndexed()) + { + Console.WriteLine(@"Index = {0}; Value = {1}", value.Item1, value.Item2.ToString("#0.00\t", formatProvider)); + } + + Console.WriteLine(); + Console.WriteLine(); + + // 12. Indexed non-zero enumerator usage + Console.WriteLine(@"11. Non-Zero Enumerator usage"); + foreach (var value in vectorA.EnumerateNonZero()) { Console.WriteLine(@"Index = {0}; Value = {1}", value.Item1, value.Item2.ToString("#0.00\t", formatProvider)); } diff --git a/src/FSharp/LinearAlgebra.Vector.fs b/src/FSharp/LinearAlgebra.Vector.fs index 1b2ebf60..f8fe2270 100644 --- a/src/FSharp/LinearAlgebra.Vector.fs +++ b/src/FSharp/LinearAlgebra.Vector.fs @@ -68,6 +68,15 @@ module Vector = /// Transform a vector into a list. let inline toList (v: #Vector<_>) = List.init v.Count v.At + /// Transform a vector into a sequence. + let inline toSeq (v: #Vector<_>) = v.Enumerate() + + /// Transform a vector into an indexed sequence. + let inline toSeqi (v: #Vector<_>) = v.EnumerateIndexed() + + /// Transform a vector into an indexed sequence where zero-values may be skipped. + let inline toSeqinz (v: #Vector<_>) = v.EnumerateNonZero() + /// 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) @@ -119,22 +128,28 @@ module Vector = let inline subInPlace (v: #Vector<_>) (w: #Vector<_>) = v.Subtract(w, v) /// Applies a function to all elements of the vector. - let inline iter f (v: #Vector<_>) = - for i=0 to v.Count-1 do - f (v.At i) + let inline iter f (v: #Vector<_>) = Seq.iter f (v.Enumerate()) - /// Applies a function to all elements of the vector. - let inline iteri f (v: #Vector<_>) = - for i=0 to v.Count-1 do - f i (v.At i) + /// Applies a function to all indexed elements of the vector. + let inline iteri f (v: #Vector<_>) = Seq.iteri f (v.Enumerate()) + + /// Applies a function to all non-zero elements of the vector. + let inline iternz f (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.iter (fun (_,v) -> f v) + /// Applies a function to all non-zero indexed elements of the vector. + let inline iterinz f (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.iter (fun (i,v) -> f i v) /// Fold all entries of a vector. - let inline fold f acc0 (v: #Vector<_>) = - let mutable acc = acc0 - for i=0 to v.Count-1 do - acc <- f acc (v.At i) - acc + let inline fold f state (v: #Vector<_>) = Seq.fold f state (v.Enumerate()) + + /// Fold all entries of a vector using a position dependent folding function. + let inline foldi f acc0 (v: #Vector<_>) = v.EnumerateIndexed() |> Seq.fold (fun s (i,x) -> f i s x) acc0 + + /// Fold all non-zero entries of a vector. + let inline foldnz f acc0 (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.fold (fun s (_,x) -> f s x) acc0 + + /// Fold all non-zero entries of a vector using a position dependent folding function. + let inline foldinz f acc0 (v: #Vector<_>) = v.EnumerateNonZero() |> Seq.fold (fun s (i,x) -> f i s x) acc0 /// Fold all entries of a vector in reverse order. let inline foldBack f acc0 (v: #Vector<_>) = @@ -143,13 +158,6 @@ module Vector = acc <- f (v.At (v.Count - i)) acc acc - /// Fold all entries of a vector using a position dependent folding function. - let inline foldi f acc0 (v: #Vector<_>) = - let mutable acc = acc0 - for i=0 to v.Count-1 do - acc <- f i acc (v.At i) - acc - /// Checks whether a predicate is satisfied for every element in the vector. let inline forall p (v: #Vector<_>) = let mutable b = true @@ -159,15 +167,6 @@ module Vector = i <- i+1 b - /// Checks whether there is an entry in the vector that satisfies a given predicate. - let inline exists p (v: #Vector<_>) = - let mutable b = false - let mutable i = 0 - while not(b) && i < v.Count do - b <- b || (p (v.At i)) - i <- i+1 - b - /// Checks whether a predicate is true for all entries in a vector. let inline foralli p (v: #Vector<_>) = let mutable b = true @@ -177,6 +176,15 @@ module Vector = i <- i+1 b + /// Checks whether there is an entry in the vector that satisfies a given predicate. + let inline exists p (v: #Vector<_>) = + let mutable b = false + let mutable i = 0 + while not(b) && i < v.Count do + b <- b || (p (v.At i)) + i <- i+1 + b + /// Checks whether there is an entry in the vector that satisfies a given position dependent predicate. let inline existsi p (v: #Vector<_>) = let mutable b = false @@ -217,4 +225,3 @@ module Vector = for i=2 to v.Count do p <- f (v.At (v.Count - i)) p p - diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/BiCgStab.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/BiCgStab.cs index b32802c2..5ffba2fc 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/BiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/BiCgStab.cs @@ -532,7 +532,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/CompositeSolver.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/CompositeSolver.cs index a6e9084d..9a533133 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/CompositeSolver.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/CompositeSolver.cs @@ -623,7 +623,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/GpBiCg.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/GpBiCg.cs index f5f37b9c..c2a0b1ab 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/GpBiCg.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/GpBiCg.cs @@ -632,7 +632,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs index ff4b04d0..333c43b2 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/MlkBiCgStab.cs @@ -797,7 +797,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs index 73c7f0b4..a28ccad5 100644 --- a/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Complex/Solvers/Iterative/TFQMR.cs @@ -531,7 +531,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/BiCgStab.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/BiCgStab.cs index 5c738a78..c48795a2 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/BiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/BiCgStab.cs @@ -526,7 +526,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/CompositeSolver.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/CompositeSolver.cs index 595bbc5d..9b35eb3d 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/CompositeSolver.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/CompositeSolver.cs @@ -623,7 +623,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/GpBiCg.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/GpBiCg.cs index cf19778a..f85afe52 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/GpBiCg.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/GpBiCg.cs @@ -631,7 +631,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs index ef3cceb7..ad485878 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/MlkBiCgStab.cs @@ -796,7 +796,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs index ef3b8668..fe894536 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Solvers/Iterative/TFQMR.cs @@ -530,7 +530,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/BiCgStab.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/BiCgStab.cs index 4c085fa2..ddd5862b 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/BiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/BiCgStab.cs @@ -524,7 +524,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/CompositeSolver.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/CompositeSolver.cs index 9cb92ad4..7639ddcd 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/CompositeSolver.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/CompositeSolver.cs @@ -620,7 +620,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/GpBiCg.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/GpBiCg.cs index 0fb78138..01dff3a1 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/GpBiCg.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/GpBiCg.cs @@ -635,7 +635,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs index d01ddac1..5e713132 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/MlkBiCgStab.cs @@ -794,7 +794,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs index dd8c7421..ed03de6d 100644 --- a/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Double/Solvers/Iterative/TFQMR.cs @@ -528,7 +528,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/BiCgStab.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/BiCgStab.cs index 8b4553f9..9aabe393 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/BiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/BiCgStab.cs @@ -524,7 +524,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/CompositeSolver.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/CompositeSolver.cs index 307e5074..d972b1a4 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/CompositeSolver.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/CompositeSolver.cs @@ -623,7 +623,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/GpBiCg.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/GpBiCg.cs index e17eed1c..dc076997 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/GpBiCg.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/GpBiCg.cs @@ -629,7 +629,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs index 867a35d3..6c4491fb 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/MlkBiCgStab.cs @@ -797,7 +797,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector)input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs index 5d37f29c..99874562 100644 --- a/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs +++ b/src/Numerics/LinearAlgebra/Single/Solvers/Iterative/TFQMR.cs @@ -528,7 +528,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single.Solvers.Iterative for (var column = 0; column < input.ColumnCount; column++) { var solution = Solve(matrix, (Vector) input.Column(column)); - foreach (var element in solution.GetIndexedEnumerator()) + foreach (var element in solution.EnumerateNonZero()) { result.At(element.Item1, column, element.Item2); } diff --git a/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs index 2676c048..7f0b8bf2 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs @@ -30,6 +30,7 @@ using System; using System.Collections.Generic; +using System.Linq; using MathNet.Numerics.Properties; using MathNet.Numerics.Threading; @@ -133,7 +134,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return new DenseVectorStorage(copy.Length, copy); } - var array = System.Linq.Enumerable.ToArray(data); + var array = Enumerable.ToArray(data); return new DenseVectorStorage(array.Length, array); } @@ -159,6 +160,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return Data; } + public override IEnumerable> EnumerateIndexed() + { + return Data.Select((t, i) => new Tuple(i, t)); + } + public override IEnumerable> EnumerateNonZero() { for (var i = 0; i < Data.Length; i++) diff --git a/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs index ca6a606c..b59b6cf5 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs @@ -389,6 +389,17 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + public override IEnumerable> EnumerateIndexed() + { + int k = 0; + for (int i = 0; i < Length; i++) + { + yield return k < ValueCount && Indices[k] == i + ? new Tuple(i, Values[k++]) + : new Tuple(i, Zero); + } + } + public override IEnumerable> EnumerateNonZero() { for (var i = 0; i < ValueCount; i++) diff --git a/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs b/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs index 89caa3a1..2e92d95f 100644 --- a/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs @@ -208,6 +208,14 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + public virtual IEnumerable> EnumerateIndexed() + { + for (var i = 0; i < Length; i++) + { + yield return new Tuple(i, At(i)); + } + } + public virtual IEnumerable> EnumerateNonZero() { for (var i = 0; i < Length; i++) diff --git a/src/Numerics/LinearAlgebra/Vector.BCL.cs b/src/Numerics/LinearAlgebra/Vector.BCL.cs index d3bb848a..5d80a3f8 100644 --- a/src/Numerics/LinearAlgebra/Vector.BCL.cs +++ b/src/Numerics/LinearAlgebra/Vector.BCL.cs @@ -228,6 +228,17 @@ namespace MathNet.Numerics.LinearAlgebra Storage.CopySubVectorTo(new DenseVectorStorage(array.Length, (T[]) array), 0, index, Count); } + /// + /// Returns an enumerator that iterates through the collection. + /// + /// + /// A that can be used to iterate through the collection. + /// + IEnumerator IEnumerable.GetEnumerator() + { + return Enumerate().GetEnumerator(); + } + /// /// Returns an enumerator that iterates through a collection. /// @@ -236,7 +247,7 @@ namespace MathNet.Numerics.LinearAlgebra /// IEnumerator IEnumerable.GetEnumerator() { - return Storage.Enumerate().GetEnumerator(); + return Enumerate().GetEnumerator(); } /// @@ -281,7 +292,7 @@ namespace MathNet.Numerics.LinearAlgebra var stringBuilder = new StringBuilder(); - var iterator = GetEnumerator(); + var iterator = Enumerate().GetEnumerator(); for (var line = 0; line < fullLines; line++) { if (line > 0) diff --git a/src/Numerics/LinearAlgebra/Vector.cs b/src/Numerics/LinearAlgebra/Vector.cs index eb1335ab..258b2e13 100644 --- a/src/Numerics/LinearAlgebra/Vector.cs +++ b/src/Numerics/LinearAlgebra/Vector.cs @@ -289,29 +289,38 @@ namespace MathNet.Numerics.LinearAlgebra } /// - /// Returns an enumerator that iterates through the collection. + /// Returns an IEnumerable that can be used to iterate through all values of the vector. /// - /// - /// A that can be used to iterate through the collection. - /// - public IEnumerator GetEnumerator() + /// + /// The enumerator will include all values, even if they are zero. + /// + public IEnumerable Enumerate() { - return Storage.Enumerate().GetEnumerator(); + return Storage.Enumerate(); } /// - /// Returns an that contains the position and value of the element, for all non-zero elements. + /// Returns an IEnumerable that can be used to iterate through all values of the vector and their index. + /// + /// + /// The enumerator returns a 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() + { + return Storage.EnumerateIndexed(); + } + + /// + /// Returns an IEnumerable that can be used to iterate through all non-zero values of the vector and their index. /// - /// - /// An over this vector that contains the position and value of each element. - /// /// - /// The enumerator returns a - /// with the first value being the element index and the second value - /// being the value of the element at that index. - /// The enumerator will exclude all elements with a zero value. + /// The enumerator returns a with the first value being the element index + /// and the second value being the value of the element at that index. + /// The enumerator will skip all elements with a zero value. /// - public IEnumerable> GetIndexedEnumerator() + public IEnumerable> EnumerateNonZero() { return Storage.EnumerateNonZero(); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs index ecad7d94..8fd7de0d 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/VectorTests.cs @@ -245,12 +245,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex public void CanEnumerateOverVectorUsingIndexedEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.GetIndexedEnumerator()) + foreach (var pair in vector.EnumerateIndexed()) { Assert.AreEqual(Data[pair.Item1], pair.Item2); } } + /// + /// Can enumerate over a vector using non-zero enumerator. + /// + [Test] + public void CanEnumerateOverVectorUsingNonZeroEnumerator() + { + var vector = CreateVector(Data); + foreach (var pair in vector.EnumerateNonZero()) + { + Assert.AreEqual(Data[pair.Item1], pair.Item2); + Assert.AreNotEqual(Complex.Zero, pair.Item2); + } + } + /// /// Can convert a vector to array. /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs index b04ee180..0786fcb7 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs @@ -245,12 +245,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 public void CanEnumerateOverVectorUsingIndexedEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.GetIndexedEnumerator()) + foreach (var pair in vector.EnumerateIndexed()) { Assert.AreEqual(Data[pair.Item1], pair.Item2); } } + /// + /// Can enumerate over a vector using non-zero enumerator. + /// + [Test] + public void CanEnumerateOverVectorUsingNonZeroEnumerator() + { + var vector = CreateVector(Data); + foreach (var pair in vector.EnumerateNonZero()) + { + Assert.AreEqual(Data[pair.Item1], pair.Item2); + Assert.AreNotEqual(Complex32.Zero, pair.Item2); + } + } + /// /// Can convert a vector to array. /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index ce671dd7..495f3528 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -242,12 +242,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public void CanEnumerateOverVectorUsingIndexedEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.GetIndexedEnumerator()) + foreach (var pair in vector.EnumerateIndexed()) { Assert.AreEqual(Data[pair.Item1], pair.Item2); } } + /// + /// Can enumerate over a vector using non-zero enumerator. + /// + [Test] + public void CanEnumerateOverVectorUsingNonZeroEnumerator() + { + var vector = CreateVector(Data); + foreach (var pair in vector.EnumerateNonZero()) + { + Assert.AreEqual(Data[pair.Item1], pair.Item2); + Assert.AreNotEqual(0d, pair.Item2); + } + } + /// /// Can convert a vector to array. /// diff --git a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs index ab175db0..af85ca68 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.cs @@ -242,12 +242,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single public void CanEnumerateOverVectorUsingIndexedEnumerator() { var vector = CreateVector(Data); - foreach (var pair in vector.GetIndexedEnumerator()) + foreach (var pair in vector.EnumerateIndexed()) { Assert.AreEqual(Data[pair.Item1], pair.Item2); } } + /// + /// Can enumerate over a vector using non-zero enumerator. + /// + [Test] + public void CanEnumerateOverVectorUsingNonZeroEnumerator() + { + var vector = CreateVector(Data); + foreach (var pair in vector.EnumerateNonZero()) + { + Assert.AreEqual(Data[pair.Item1], pair.Item2); + Assert.AreNotEqual(0f, pair.Item2); + } + } + /// /// Can convert a vector to array. ///