// // 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-2013 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. // namespace MathNet.Numerics.LinearAlgebra.Double open MathNet.Numerics.LinearAlgebra.Generic /// A module which implements functional vector operations. [] module Vector = /// Transform a vector into an array. let inline toArray (v: #Vector) = v.ToArray() /// Transform a vector into a list. let inline toList (v: #Vector) = List.init v.Count v.At /// In-place mutation by applying a function to every element of the vector. let inline mapInPlace (f: float -> float) (v: #Vector) = for i=0 to v.Count-1 do v.At(i, f (v.At i)) () /// In-place mutation by applying a function to every element of the vector. let inline mapiInPlace (f: int -> float -> float) (v: #Vector) = for i=0 to v.Count-1 do v.At(i, f i (v.At i)) () /// In-place vector addition. let inline addInPlace (v: #Vector) (w: #Vector) = v.Add(w, v) /// In place vector subtraction. let inline subInPlace (v: #Vector) (w: #Vector) = v.Subtract(w, v) /// Functional map operator for vectors. /// let inline map f (v: #Vector) = let w = v.Clone() mapInPlace (fun x -> f x) w w /// Applies a function to all elements of the vector. let inline iter (f: float -> unit) (v: #Vector) = for i=0 to v.Count-1 do f (v.At i) /// Applies a function to all elements of the vector. let inline iteri (f: int -> float -> unit) (v: #Vector) = for i=0 to v.Count-1 do f i (v.At i) /// Maps a vector to a new vector by applying a function to every element. let inline mapi (f: int -> float -> float) (v: #Vector) = let w = v.Clone() mapiInPlace f w w /// Fold all entries of a vector. let inline fold (f: 'a -> float -> 'a) (acc0: 'a) (v: #Vector) = let mutable acc = acc0 for i=0 to v.Count-1 do acc <- f acc (v.At i) acc /// Fold all entries of a vector in reverse order. let inline foldBack (f: float -> 'a -> 'a) (acc0: 'a) (v: #Vector) = let mutable acc = acc0 for i=2 to v.Count do 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: int -> 'a -> float -> 'a) (acc0: 'a) (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: float -> bool) (v: #Vector) = let mutable b = true let mutable i = 0 while 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 predicate. let inline exists (p: float -> bool) (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: int -> float -> bool) (v: #Vector) = let mutable b = true let mutable i = 0 while b && i < v.Count do b <- b && (p i (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: int -> float -> bool) (v: #Vector) = let mutable b = false let mutable i = 0 while not(b) && i < v.Count do b <- b || (p i (v.At i)) i <- i+1 b /// Scans a vector; like fold but returns the intermediate result. let inline scan (f: float -> float -> float) (v: #Vector) = let w = v.Clone() let mutable p = v.Item(0) for i=1 to v.Count-1 do p <- f p (v.At i) w.At(i, p) w /// Scans a vector in reverse order; like foldBack but returns the intermediate result. let inline scanBack (f: float -> float -> float) (v: #Vector) = let w = v.Clone() let mutable p = v.At (v.Count-1) for i=2 to v.Count do p <- f (v.At (v.Count - i)) p w.At(v.Count - i, p) w /// Reduces a vector: the result of this function will be f(...f(f(v[0],v[1]), v[2]),..., v[n]). let inline reduce (f: float -> float -> float) (v: #Vector) = let mutable p = v.Item(0) for i=1 to v.Count-1 do p <- f p (v.At i) p /// Reduces a vector in reverse order: the result of this function will be f(v[1], ..., f(v[n-2], f(v[n-1],v[n]))...). let inline reduceBack (f: float -> float -> float) (v: #Vector) = let mutable p = v.Item(v.Count-1) for i=2 to v.Count do p <- f (v.At (v.Count - i)) p p /// Creates a new vector and inserts the given value at the given index. let inline insert index value (v: #Vector) = let newV = new DenseVector(v.Count + 1) for i = 0 to index - 1 do newV.At(i, v.At i) newV.At(index, value) for i = index + 1 to v.Count do newV.At(i, v.At (i - 1)) newV /// A module which implements functional dense vector operations. [] module DenseVector = /// Initialize a vector by calling a construction function for every element. let inline init (n: int) (f: int -> float) = DenseVector.Create(n, fun i -> f i) /// Create a vector from a float list. let inline ofList (fl: float list) = DenseVector(Array.ofList fl) /// Create a vector from a sequences. let inline ofSeq (fs: #seq) = DenseVector(Array.ofSeq fs) /// Create a vector with evenly spaced entries: e.g. rangef -1.0 0.5 1.0 = [-1.0 -0.5 0.0 0.5 1.0] let inline rangef (start: float) (step: float) (stop: float) = let n = (int ((stop - start) / step)) + 1 let v = new DenseVector(n) for i=0 to n-1 do v.At(i, (float i) * step + start) v /// Create a vector with integer entries in the given range. let inline range (start: int) (stop: int) = new DenseVector([| for i in [start .. stop] -> float i |]) /// A module which implements functional sparse vector operations. [] module SparseVector = /// Initialize a vector by calling a construction function for every element. let inline init (n: int) (f: int -> float) = SparseVector.Create(n, fun i -> f i) /// Create a sparse vector with a given dimension from a list of entry, value pairs. let inline ofList (dim: int) (fl: list) = let v = new SparseVector(dim) fl |> List.iter (fun (i, f) -> v.[i] <- f) v /// Create a sparse vector with a given dimension from a sequence of entry, value pairs. let inline ofSeq (dim: int) (fs: #seq) = let v = new SparseVector(dim) fs |> Seq.iter (fun (i, f) -> v.[i] <- f) v