forked from dotnet/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsnippet33.fs
47 lines (40 loc) · 1.75 KB
/
snippet33.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
let generateInfiniteSequence fDenominator isAlternating =
if (isAlternating) then
Seq.initInfinite (fun index -> 1.0 /(fDenominator index) * (if (index % 2 = 0) then -1.0 else 1.0))
else
Seq.initInfinite (fun index -> 1.0 /(fDenominator index))
// This is the series of recipocals of the squares.
let squaresSeries = generateInfiniteSequence (fun index -> float (index * index)) false
// This function sums a sequence, up to the specified number of terms.
let sumSeq length sequence =
Seq.unfold (fun state ->
let subtotal = snd state + Seq.nth (fst state + 1) sequence
if (fst state >= length) then None
else Some(subtotal, (fst state + 1, subtotal))) (0, 0.0)
// This function sums an infinite sequence up to a given value
// for the difference (epsilon) between subsequent terms,
// up to a maximum number of terms, whichever is reached first.
let infiniteSum infiniteSeq epsilon maxIteration =
infiniteSeq
|> sumSeq maxIteration
|> Seq.pairwise
|> Seq.takeWhile (fun elem -> abs (snd elem - fst elem) > epsilon)
|> List.ofSeq
|> List.rev
|> List.head
|> snd
let pi = System.Math.PI
// Because this is not an alternating series, a much smaller epsilon
// value and more terms are needed to obtain an accurate result.
let computeSum epsilon =
let maxTerms = 10000000
async {
let result = infiniteSum squaresSeries epsilon maxTerms
printfn "Result: %f pi*pi/6: %f" result (pi*pi/6.0)
}
// Start the computation on a new thread.
Async.Start(computeSum 1.0e-8)
// Because the computation is running on a separate thread,
// this message is printed to the console without any delay.
printfn "Computing. Press any key to stop waiting."
System.Console.ReadLine() |> ignore