// // 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. // namespace MathNet.Numerics.LinearAlgebra open System open MathNet.Numerics open MathNet.Numerics.LinearAlgebra /// 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 /// Transform a vector into a sequence. let inline toSeq (v: #Vector<_>) = v.Enumerate(Zeros.Include) /// Transform a vector into an indexed sequence. let inline toSeqi (v: #Vector<_>) = v.EnumerateIndexed(Zeros.Include) |> properTuple2Seq /// Transform a vector into a sequence where zero-values are skipped. Skipping zeros is efficient on sparse data. 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.EnumerateIndexed(Zeros.AllowSkip) |> properTuple2Seq /// Applies a function to all elements of the vector. let inline iter f (v: #Vector<_>) = v |> toSeq |> Seq.iter f /// Applies a function to all indexed elements of the vector. let inline iteri f (v: #Vector<_>) = v |> toSeq |> 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 |> toSeqSkipZeros |> 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 |> toSeqiSkipZeros |> Seq.iter (fun (i,x) -> f i x) /// Fold all entries of a vector. let inline fold f state (v: #Vector<_>) = v |> toSeq |> Seq.fold f state /// Fold all entries of a vector using a position dependent folding function. let inline foldi f state (v: #Vector<_>) = v |> toSeqi |> 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 |> toSeqSkipZeros |> 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 |> toSeqiSkipZeros |> 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 |> toSeq |> Seq.scan f state /// Scan all entries of a vector using a position dependent folding function. let inline scani f state (v: #Vector<_>) = v |> toSeqi |> 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 |> toSeqSkipZeros |> 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 |> toSeqiSkipZeros |> Seq.scan (fun s (i,x) -> f i s x) state /// Reduce all entries of a vector. let inline reduce f (v: #Vector<_>) = v |> toSeq |> 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 |> toSeqSkipZeros |> Seq.reduce f /// Checks whether there is an entry in the vector that satisfies a predicate. let inline exists p (v: #Vector<_>) = v |> toSeq |> 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 |> toSeqi |> 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 |> toSeqSkipZeros |> 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 |> toSeqiSkipZeros |> 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 |> toSeq |> Seq.forall p /// Checks whether all entries in the vector that satisfies a given position dependent predicate. let inline foralli p (v: #Vector<_>) = v |> toSeqi |> 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 |> toSeqSkipZeros |> 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 |> toSeqiSkipZeros |> Seq.forall (fun (i,x) -> p i x) /// 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), Zeros.Include) /// 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), Zeros.Include) /// In-place mutation by applying a function to every element of the vector. /// Zero-values may be skipped (relevant mostly for sparse vectors). 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. /// Zero-values may be skipped (relevant mostly for sparse vectors). 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. 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. /// Zero-values may be skipped (relevant mostly for sparse vectors). 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. 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. /// Zero-values may be skipped (relevant mostly for sparse vectors). let inline mapiSkipZeros f (v: #Vector<_>) = v.MapIndexed((fun i x -> f i x), Zeros.AllowSkip) /// Maps two vectors to a new vector by applying a function to every element pair. let inline map2 f (u: #Vector<_>) (v: #Vector<_>) = u.Map2((fun x y -> f x y), v, Zeros.Include) /// Maps two vectors to a new vector by applying a function to every element pair. /// Zero-Zero value-pairs may be skipped (relevant mostly for sparse vectors). let inline map2SkipZeros f (u: #Vector<_>) (v: #Vector<_>) = u.Map2((fun x y -> f x y), v, Zeros.AllowSkip) /// Folds two vectors by applying a function to update the status for each element pair. let inline fold2 f status (u: #Vector<_>) (v: #Vector<_>) = u.Fold2((fun s x y -> f s x y), status, v, Zeros.Include) /// Folds two vectors by applying a function to update the status for each element pair. /// Zero-Zero value-pairs may be skipped (relevant mostly for sparse vectors). let inline fold2SkipZeros f status (u: #Vector<_>) (v: #Vector<_>) = u.Fold2((fun s x y -> f s x y), status, v, Zeros.AllowSkip) /// Fold all entries of a vector in reverse order. let inline foldBack f state (v: #Vector<_>) = let mutable acc = state for i=2 to v.Count do acc <- f (v.At (v.Count - i)) acc acc /// 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 (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 /// Scans a vector in reverse order; like foldBack but returns the intermediate result. let inline scanBack f state (v: #Vector<_>) = seq { let rstate = ref state yield !rstate for i in v.Count-1..-1..0 do rstate := f (v.At(i)) !rstate yield !rstate } /// Creates a new vector and inserts the given value at the given index. let inline insert index value (v: #Vector<'T>) = let newV = Vector<'T>.Build.SameAs(v, v.Count + 1) v.CopySubVectorTo(newV, 0, 0, index) v.CopySubVectorTo(newV, index, index+1, v.Count - index) newV.At(index, value) newV /// 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) let inline length (A: #Vector<_>) = A.Count let inline conjugate (A: #Vector<_>) = A.Conjugate() let inline norm (A: #Vector<_>) = A.L2Norm() let inline sum (A: #Vector<_>) = A.Sum() let inline min (A: #Vector<_>) = A.Minimum() let inline max (A: #Vector<_>) = A.Maximum() let inline minIndex (A: #Vector<_>) = A.MinimumIndex() let inline maxIndex (A: #Vector<_>) = A.MaximumIndex() let inline minAbs (A: #Vector<_>) = A.AbsoluteMinimum() let inline maxAbs (A: #Vector<_>) = A.AbsoluteMaximum() let inline minAbsIndex (A: #Vector<_>) = A.AbsoluteMinimumIndex() let inline maxAbsIndex (A: #Vector<_>) = A.AbsoluteMaximumIndex() /// A module which helps constructing generic dense vectors. [] module DenseVector = open MathNet.Numerics.Distributions /// Create a vector that directly binds to a storage object. let inline ofStorage (storage: Storage.DenseVectorStorage<'T>) = Vector<'T>.Build.Dense(storage) /// Create a vector that directly binds to a raw storage array, without copying. let inline raw (raw: 'T[]) = Vector<'T>.Build.Dense(raw) /// Initialize an all-zero vector with the given dimension. let inline zero<'T when 'T:struct and 'T :> ValueType and 'T: (new: unit ->'T) and 'T :> IEquatable<'T> and 'T :> IFormattable> (n: int) = Vector<'T>.Build.Dense(n) /// Initialize a random vector with the given dimension and distribution. let inline random<'T when 'T:struct and 'T :> ValueType and 'T: (new: unit ->'T) and 'T :> IEquatable<'T> and 'T :> IFormattable> (n: int) (dist: IContinuousDistribution) = Vector<'T>.Build.Random(n, dist) /// Initialize a random vector with the given dimension and standard distributed values. let inline randomStandard<'T when 'T:struct and 'T :> ValueType and 'T: (new: unit ->'T) and 'T :> IEquatable<'T> and 'T :> IFormattable> (n: int) = Vector<'T>.Build.Random(n) /// Initialize a random vector with the given dimension and standard distributed values using the provided seed. let inline randomSeed<'T when 'T:struct and 'T :> ValueType and 'T: (new: unit ->'T) and 'T :> IEquatable<'T> and 'T :> IFormattable> (n: int) (seed: int) = Vector<'T>.Build.Random(n, seed) /// Initialize an x-valued vector with the given dimension. let inline create (n: int) (x: 'T) = Vector<'T>.Build.Dense(n, x) /// Initialize a vector by calling a construction function for every element. let inline init (n: int) (f: int -> 'T) = Vector<'T>.Build.Dense(n, f) /// Create a vector from a float array (by copying - use raw instead if no copy is needed). let inline ofArray (fa: 'T array) = Vector<'T>.Build.Dense(Array.copy fa) /// Create a vector from a float list. let inline ofList (fl: 'T list) = Vector<'T>.Build.Dense(Array.ofList fl) /// Create a vector from a float sequence. let inline ofSeq (fs: #seq<'T>) = Vector<'T>.Build.DenseOfEnumerable(fs) /// Create a vector with a given dimension from an indexed list of index, value pairs. let inline ofListi (n: int) (fl: list) = Vector<'T>.Build.DenseOfIndexed(n, Seq.ofList fl |> internalTuple2Seq) /// Create a vector with a given dimension from an indexed sequences of index, value pairs. let inline ofSeqi (n: int) (fs: #seq) = Vector<'T>.Build.DenseOfIndexed(n, fs |> internalTuple2Seq) /// Create a vector with integer entries in the given range. let inline range (start: int) (step: int) (stop: int) = raw [| for i in start..step..stop -> float i |] /// 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) = raw [| start..step..stop |] /// A module which helps constructing generic sparse vectors. [] module SparseVector = /// Create a vector that directly binds to a storage object. let inline ofStorage (storage: Storage.SparseVectorStorage<'T>) = Vector<'T>.Build.Sparse(storage) /// Initialize an all-zero vector with the given dimension. let inline zero<'T when 'T:struct and 'T :> ValueType and 'T: (new: unit ->'T) and 'T :> IEquatable<'T> and 'T :> IFormattable> (n: int) = Vector<'T>.Build.Sparse(n) /// Initialize an x-valued vector with the given dimension. let inline create (n: int) (x: 'T) = Vector<'T>.Build.Sparse(n, x) /// Initialize a vector by calling a construction function for every element. let inline init (n: int) (f: int -> 'T) = Vector<'T>.Build.Sparse(n, f) /// Create a sparse vector from a float array. let inline ofArray (fa: 'T array) = Vector<'T>.Build.SparseOfArray(fa) /// Create a sparse vector from a float list. let inline ofList (fl: 'T list) = Vector<'T>.Build.SparseOfEnumerable(Seq.ofList fl) /// Create a sparse vector from a float sequence. let inline ofSeq (fs: #seq<'T>) = Vector<'T>.Build.SparseOfEnumerable(fs) /// Create a sparse vector with a given dimension from an indexed list of index, value pairs. let inline ofListi (n: int) (fl: list) = Vector<'T>.Build.SparseOfIndexed(n, Seq.ofList fl |> internalTuple2Seq) /// Create a sparse vector with a given dimension from an indexed sequence of index, value pairs. let inline ofSeqi (n: int) (fs: #seq) = Vector<'T>.Build.SparseOfIndexed(n, fs |> internalTuple2Seq) /// Module that contains implementation of useful F#-specific extension members for generic vectors [] module VectorExtensions = /// Construct a dense vector from a list of floating point numbers. let inline vector (lst: list<'T>) = DenseVector.ofList lst // A type extension for the generic vector type that // adds the 'GetSlice' method to allow vec.[a .. b] syntax type MathNet.Numerics.LinearAlgebra. Vector<'T when 'T : struct and 'T : (new : unit -> 'T) and 'T :> System.IEquatable<'T> and 'T :> System.IFormattable and 'T :> System.ValueType> with /// Gets a slice of a vector starting at a specified index /// and ending at a specified index (both indices are optional) /// This method can be used via the x.[start .. finish] syntax member x.GetSlice(start, finish) = let start = defaultArg start 0 let finish = defaultArg finish (x.Count - 1) x.SubVector(start, finish - start + 1) /// Sets a slice of a vector starting at a specified index /// and ending at a specified index (both indices are optional) /// This method can be used via the x.[start .. finish] <- v syntax member x.SetSlice(start, finish, values) = let start = defaultArg start 0 let finish = defaultArg finish (x.Count - 1) x.SetSubVector(start, finish - start + 1, values)