From ae31d3a7b54d1abdd99422d96b11e448f9835fd6 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Fri, 25 Nov 2016 15:37:33 +0100 Subject: [PATCH] LA: Vector MapInplace implemented at storage level --- .../Storage/DenseVectorStorage.cs | 26 ++++++- .../Storage/SparseVectorStorage.cs | 72 ++++++++++++++++++- .../LinearAlgebra/Storage/VectorStorage.cs | 20 +++++- src/Numerics/LinearAlgebra/Vector.cs | 12 ++-- 4 files changed, 119 insertions(+), 11 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs index f5ba1401..7d4d7b18 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs @@ -436,7 +436,29 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return base.Find2Unchecked(other, predicate, zeros); } - // FUNCTIONAL COMBINATORS + // FUNCTIONAL COMBINATORS: MAP + + public override void MapInplace(Func f, Zeros zeros = Zeros.AllowSkip) + { + CommonParallel.For(0, Data.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + Data[i] = f(Data[i]); + } + }); + } + + public override void MapIndexedInplace(Func f, Zeros zeros = Zeros.AllowSkip) + { + CommonParallel.For(0, Data.Length, 4096, (a, b) => + { + for (int i = a; i < b; i++) + { + Data[i] = f(i, Data[i]); + } + }); + } internal override void MapToUnchecked(VectorStorage target, Func f, Zeros zeros, ExistingData existingData) { @@ -539,6 +561,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage base.Map2ToUnchecked(target, other, f, zeros, existingData); } + // FUNCTIONAL COMBINATORS: FOLD + internal override TState Fold2Unchecked(VectorStorage other, Func f, TState state, Zeros zeros) { var denseOther = other as DenseVectorStorage; diff --git a/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs index 0fe2baa4..226a8923 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs @@ -774,7 +774,75 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return base.Find2Unchecked(other, predicate, zeros); } - // FUNCTIONAL COMBINATORS + // FUNCTIONAL COMBINATORS: MAP + + public override void MapInplace(Func f, Zeros zeros = Zeros.AllowSkip) + { + var indices = new List(); + var values = new List(ValueCount); + if (zeros == Zeros.Include || !Zero.Equals(f(Zero))) + { + int k = 0; + for (int i = 0; i < Length; i++) + { + var item = k < ValueCount && (Indices[k]) == i ? f(Values[k++]) : f(Zero); + if (!Zero.Equals(item)) + { + values.Add(item); + indices.Add(i); + } + } + } + else + { + for (int i = 0; i < ValueCount; i++) + { + var item = f(Values[i]); + if (!Zero.Equals(item)) + { + values.Add(item); + indices.Add(Indices[i]); + } + } + } + Indices = indices.ToArray(); + Values = values.ToArray(); + ValueCount = values.Count; + } + + public override void MapIndexedInplace(Func f, Zeros zeros = Zeros.AllowSkip) + { + var indices = new List(); + var values = new List(ValueCount); + if (zeros == Zeros.Include) + { + int k = 0; + for (int i = 0; i < Length; i++) + { + var item = k < ValueCount && (Indices[k]) == i ? f(i, Values[k++]) : f(i, Zero); + if (!Zero.Equals(item)) + { + values.Add(item); + indices.Add(i); + } + } + } + else + { + for (int i = 0; i < ValueCount; i++) + { + var item = f(Indices[i], Values[i]); + if (!Zero.Equals(item)) + { + values.Add(item); + indices.Add(Indices[i]); + } + } + } + Indices = indices.ToArray(); + Values = values.ToArray(); + ValueCount = values.Count; + } internal override void MapToUnchecked(VectorStorage target, Func f, Zeros zeros, ExistingData existingData) { @@ -1074,6 +1142,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage base.Map2ToUnchecked(target, other, f, zeros, existingData); } + // FUNCTIONAL COMBINATORS: MAP + internal override TState Fold2Unchecked(VectorStorage other, Func f, TState state, Zeros zeros) { var sparseOther = other as SparseVectorStorage; diff --git a/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs b/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs index 913e72ab..b979b455 100644 --- a/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs @@ -479,7 +479,23 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return null; } - // FUNCTIONAL COMBINATORS + // FUNCTIONAL COMBINATORS: MAP + + public virtual void MapInplace(Func f, Zeros zeros = Zeros.AllowSkip) + { + for (int i = 0; i < Length; i++) + { + At(i, f(At(i))); + } + } + + public virtual void MapIndexedInplace(Func f, Zeros zeros = Zeros.AllowSkip) + { + for (int i = 0; i < Length; i++) + { + At(i, f(i, At(i))); + } + } public void MapTo(VectorStorage target, Func f, Zeros zeros = Zeros.AllowSkip, ExistingData existingData = ExistingData.Clear) @@ -567,6 +583,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + // FUNCTIONAL COMBINATORS: FOLD + public TState Fold2(VectorStorage other, Func f, TState state, Zeros zeros = Zeros.AllowSkip) where TOther : struct, IEquatable, IFormattable { diff --git a/src/Numerics/LinearAlgebra/Vector.cs b/src/Numerics/LinearAlgebra/Vector.cs index 7bd2a51d..21ab4a03 100644 --- a/src/Numerics/LinearAlgebra/Vector.cs +++ b/src/Numerics/LinearAlgebra/Vector.cs @@ -350,8 +350,7 @@ namespace MathNet.Numerics.LinearAlgebra /// public void MapInplace(Func f, Zeros zeros = Zeros.AllowSkip) { - // TODO: actual in-place - Storage.MapToUnchecked(Storage, f, zeros, ExistingData.AssumeZeros); + Storage.MapInplace(f, zeros); } /// @@ -362,8 +361,7 @@ namespace MathNet.Numerics.LinearAlgebra /// public void MapIndexedInplace(Func f, Zeros zeros = Zeros.AllowSkip) { - // TODO: actual in-place - Storage.MapIndexedToUnchecked(Storage, f, zeros, ExistingData.AssumeZeros); + Storage.MapIndexedInplace(f, zeros); } /// @@ -375,8 +373,7 @@ namespace MathNet.Numerics.LinearAlgebra { if (ReferenceEquals(this, result)) { - // TODO: actual in-place - Storage.MapToUnchecked(Storage, f, zeros, ExistingData.AssumeZeros); + Storage.MapInplace(f, zeros); } else { @@ -394,8 +391,7 @@ namespace MathNet.Numerics.LinearAlgebra { if (ReferenceEquals(this, result)) { - // TODO: actual in-place - Storage.MapIndexedToUnchecked(Storage, f, zeros, ExistingData.AssumeZeros); + Storage.MapIndexedInplace(f, zeros); } else {