Browse Source

add foldBack to Vector and Matrix

la-knuth
Gustavo Guerra 15 years ago
committed by Christoph Ruegg
parent
commit
a1618854ba
  1. 10
      src/FSharp/Matrix.fs
  2. 11
      src/FSharp/Vector.fs
  3. 12
      src/FSharpUnitTests/Program.fs

10
src/FSharp/Matrix.fs

@ -46,6 +46,16 @@ module Matrix =
acc <- f acc (A.Item(i,j))
acc
/// Fold a function over all matrix elements in reverse order.
let inline foldBack (f: float -> 'a -> 'a) (acc0: 'a) (A: #Matrix<float>) =
let n = A.RowCount
let m = A.ColumnCount
let mutable acc = acc0
for i in n-1 .. -1 .. 0 do
for j in n-1 .. -1 .. 0 do
acc <- f (A.Item(i,j)) acc
acc
/// Fold a matrix by applying a given function to all matrix elements.
let inline foldi (f: int -> int -> 'a -> float -> 'a) (acc0: 'a) (A: #Matrix<float>) =
let n = A.RowCount

11
src/FSharp/Vector.fs

@ -93,6 +93,13 @@ module Vector =
acc <- f acc (v.Item(i))
acc
/// Fold all entries of a vector in reverse order.
let inline foldBack (f: float -> 'a -> 'a) (acc0: 'a) (v: #Vector<float>) =
let mutable acc = acc0
for i=2 to v.Count do
acc <- f (v.Item(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<float>) =
let mutable acc = acc0
@ -145,7 +152,7 @@ module Vector =
w.[i] <- p
w
/// Scans a vector; like fold but returns the intermediate result.
/// Scans a vector in reverse order; like foldBack but returns the intermediate result.
let inline scanBack (f: float -> float -> float) (v: #Vector<float>) =
let w = v.Clone()
let mutable p = v.Item(v.Count-1)
@ -161,7 +168,7 @@ module Vector =
p <- f p (v.Item(i))
p
/// Reduces a vector: the result of this function will be f(v[1], ..., f(v[n-2], f(v[n-1],v[n]))...).
/// 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<float>) =
let mutable p = v.Item(v.Count-1)
for i=2 to v.Count do

12
src/FSharpUnitTests/Program.fs

@ -75,7 +75,9 @@ let VectorTests =
spec "Vector.mapi"
(Vector.mapi (fun i x -> float i / 100.0) largev |> should equal largev)
spec "Vector.fold"
(Vector.fold (fun a b -> a + b) 0.0 smallv |> should equal 1.5)
(Vector.fold (fun a b -> a - b) 0.0 smallv |> should equal -1.5)
spec "Vector.foldBack"
(Vector.foldBack (fun a b -> a - b) 0.0 smallv |> should equal 0.0)
spec "Vector.foldi"
(Vector.foldi (fun i a b -> a + b) 0.0 smallv |> should equal 1.5)
spec "Vector.forall"
@ -90,9 +92,9 @@ let VectorTests =
(Vector.scan (fun acc x -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|0.3;0.6;0.9;1.2;1.5|] ) :> Vector<float>) )
spec "Vector.scanBack"
(Vector.scanBack (fun x acc -> acc + x) smallv |> should approximately_vector_equal 14 (new DenseVector( [|1.5;1.2;0.9;0.6;0.3|] ) :> Vector<float>) )
spec "Vector.reduce_left"
spec "Vector.reduce"
(Vector.reduce (fun acc x -> acc ** x) smallv |> should approximately_equal 14 0.990295218585507)
spec "Vector.reduce_right"
spec "Vector.reduceBack"
(Vector.reduceBack (fun x acc -> x ** acc) smallv |> should approximately_equal 14 0.488911287726319)
]
@ -108,7 +110,9 @@ let MatrixTests =
specs "Matrix" [
spec "Matrix.fold"
(Matrix.fold (fun a b -> a + b) 0.0 smallM |> should equal 1.2)
(Matrix.fold (fun a b -> a - b) 0.0 smallM |> should equal -1.2)
spec "Matrix.foldBack"
(Matrix.foldBack (fun a b -> a - b) 0.0 smallM |> should equal 0.0)
spec "Matrix.foldi"
(Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2)
spec "Matrix.toArray2"

Loading…
Cancel
Save