Skip to content

Commit

Permalink
Add BasicStats
Browse files Browse the repository at this point in the history
  • Loading branch information
muehlhaus committed May 28, 2017
1 parent 1f9d221 commit 29d9d1e
Show file tree
Hide file tree
Showing 7 changed files with 616 additions and 317 deletions.
1 change: 1 addition & 0 deletions FSharp.Stats.sln
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{83F16175
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D5255-776D-4B61-85F9-73C37AA1FB9A}"
ProjectSection(SolutionItems) = preProject
docs\content\BasicStats.fsx = docs\content\BasicStats.fsx
docs\content\Distributions.fsx = docs\content\Distributions.fsx
docs\content\index.fsx = docs\content\index.fsx
docs\content\Matrix_Vector.fsx = docs\content\Matrix_Vector.fsx
Expand Down
61 changes: 61 additions & 0 deletions docs/content/BasicStats.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
(*** hide ***)
// This block of code is omitted in the generated HTML documentation. Use
// it to define helpers that you do not want to show in the documentation.
#I "../../bin"
#r "../../packages/build/FSharp.Plotly/lib/net40/Fsharp.Plotly.dll"
open FSharp.Plotly
(**
Basic stats
=========================
**)
#r "FSharp.Stats.dll"
open FSharp.Stats




let inline stDevPopulationOfMean mean (items:seq<'T>) : 'U =
use e = items.GetEnumerator()
let rec loop n (acc) =
match e.MoveNext() with
| true -> loop (n + 1) (acc + ((e.Current - mean) * (e.Current - mean)))
| false -> if (n > 1) then sqrt(LanguagePrimitives.DivideByInt< 'U > acc (n )) else Unchecked.defaultof< 'U >
loop 0 LanguagePrimitives.GenericZero< 'U >

let m1 = Seq.mean [1.;2.;3.;4.;]
let stDevPop = stDevPopulationOfMean m1 [1.;2.;3.;4.;]

let stDevPop' = Seq.stDevPopulation [1.;2.;3.;4.;]

(GlobalAssociations.ht.[typeof<float>])


let inline stDevPopulation (items:seq<'T>) : 'U =
use e = items.GetEnumerator()
let zero = LanguagePrimitives.GenericZero< 'U >
let one = LanguagePrimitives.GenericOne< 'U >
let rec loop n m1 m2 =
match e.MoveNext() with
| true ->
let delta = e.Current - m1
let m1' = m1 + (delta / n)
let delta2 = e.Current - m1'
let m2' = m2 + delta * delta2
loop (n + one) m1' m2'
| false -> if (LanguagePrimitives.GenericGreaterThan n one) then sqrt(m2 / (n-one)) else (zero / zero)
loop one zero zero



stDevPopulation [1.;2.]

let zero = LanguagePrimitives.GenericZero< float >
let one = LanguagePrimitives.GenericOne< float >

(zero / zero)

LanguagePrimitives.GenericGreaterThan 2. 1.



6 changes: 4 additions & 2 deletions src/FSharp.Stats/FSharp.Stats.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<Compile Include="Ops.fs" />
<Compile Include="Random.fs" />
<Compile Include="ServiceLocator.fs" />
<Compile Include="Intervals.fs" />
<!-- Math -->
<Compile Include="Permutation.fs" />
<Compile Include="BigRational.fs" />
Expand All @@ -77,8 +78,9 @@
<Compile Include="RowVector.fs" />
<Compile Include="MatrixTopLevelOperators.fs" />
<!-- Col -->
<Compile Include="Intervals.fs" />
<Compile Include="SeqStats.fs" />
<Compile Include="RunningStats.fs" />
<Compile Include="Seq.fs" />
<Compile Include="List.fs" />
<!-- SpecialFunctions -->
<Compile Include="SpecialFunctions\Gamma.fs" />
<Compile Include="SpecialFunctions\Factorial.fs" />
Expand Down
72 changes: 72 additions & 0 deletions src/FSharp.Stats/List.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
namespace FSharp.Stats


/// Module to compute common statistical measure on list
[<AutoOpen>]
module List =


let range (items:list<_>) =
let rec loop l (minimum) (maximum) =
match l with
| h::t -> loop t (min h minimum) (max h maximum)
| [] -> Intervals.create minimum maximum
//Init by fist value
match items with
| h::t -> loop t h h
| [] -> Intervals.Interval.Empty



/// Calculate the median of a list of items.
/// The result is a tuple of two items whose mean is the median.
let median xs =
/// Partition list into three piles; less-than, equal and greater-than
/// x: Current pivot
/// xs: Sublist to partition
/// cont: Continuation function
let rec partition x xs cont =
match xs with
| [] ->
// place pivot in equal pile
cont [] 0 [x] 1 [] 0
| y::ys ->
if y < x then
// place item in less-than pile
partition x ys (fun lts n1 eqs n2 gts n3 ->
cont (y::lts) (n1+1) eqs n2 gts n3)
elif y = x then
// place pivot in equal pile, and use item as new pivot,
// so that the order is preserved
partition y ys (fun lts n1 eqs n2 gts n3 ->
cont lts n1 (x::eqs) (n2+1) gts n3)
else // y > x
// place item in greater-than pile
partition x ys (fun lts n1 eqs n2 gts n3 ->
cont lts n1 eqs n2 (y::gts) (n3+1))
/// Partition input and recurse into the part than contains the median
/// before: Number of elements before this sublist.
/// xs: Current sublist.
/// after: Number of elements after this sublist.
let rec loop before xs after =
match xs with
| [] -> failwith "Median of empty list"
| x::xs ->
partition x xs (fun lts numlt eqs numeq gts numgt ->
if before + numlt > numeq + numgt + after then
// Recurse into less pile
loop before lts (after + numeq + numgt)
elif before + numlt = numeq + numgt + after then
// Median is split between less and equal pile
(List.max lts, x)
elif before + numlt + numeq > numgt + after then
// Median is completely inside equal pile
(x, x)
elif before + numlt + numeq = numgt + after then
// Median is split between equal and greater pile
(x, List.min gts)
else
// Recurse into greater pile
loop (before + numlt + numeq) gts after)
loop 0 xs 0

37 changes: 37 additions & 0 deletions src/FSharp.Stats/RunningStats.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace FSharp.Stats


/// Module to compute common statistical measure on
module RunningStats =

type RunningStats<'T> = {
N : int
M1 : 'T
M2 : 'T
M3 : 'T
M4 : 'T
}

let createRunningStats n m1 m2 m3 m4 =
{N=n;M1=m1;M2=m2;M3=m3;M4=m4}

// let inline ofSeq (items:seq<'T>) : RunningStats< 'U > =
// use e = items.GetEnumerator()
// let rec loop n m1 m2 m3 m4 =
// match e.MoveNext() with
// | true ->
// let n' = n + 1
// let delta = e.Current - m1
// let delta_n = LanguagePrimitives.DivideByInt< 'U > delta n
// let delta_n2 = delta_n * delta_n
// let term1 = delta * delta_n * n'
// let m1' = m1 + delta_n
// let m4' = m4 + (term1 * delta_n2 * (n'*n' - 3*n' + 3) + 6 * delta_n2 * m2 - 4 * delta_n * m3)
// let m3' = m3 + (term1 * delta_n * (n' - 2) - 3 * delta_n * m2)
// let m2' = term1
//
// loop (n + 1) m1' m2' m3' m4'
// | false -> if (n > 1) then createRunningStats n m1 m2 m3 m4 else createRunningStats n Unchecked.defaultof< 'U > Unchecked.defaultof< 'U > Unchecked.defaultof< 'U > Unchecked.defaultof< 'U >
// loop 0 LanguagePrimitives.GenericZero< 'U > LanguagePrimitives.GenericZero< 'U > LanguagePrimitives.GenericZero< 'U > LanguagePrimitives.GenericZero< 'U >


Loading

0 comments on commit 29d9d1e

Please sign in to comment.