this is an EMA calculation:
let EMA (period : int) (data : double[]) : double[] =
let multiplier = 2.0 / (double)(period + 1)
let output = Array.create data.Length System.Double.NaN
output.[period - 1] <- data.[0..period - 1] |> Seq.average
for i in seq {period .. (data.Length - 1)} do
output.[i] <- (data.[i] * multiplier) + (output.[i - 1] * (1. - multiplier))
output
you can test it with:
EMA 3 [|1.;3.;4.;7.;5.;6.;9.;8.|]
and it gives:
[|NaN;Nan;2.66.;4.83;4.91;5.45;7.22;7.61|]
my first question is regarding the loop at the end:
for i in seq {period .. (data.Length - 1)} do
output.[i] <- (data.[i] * multiplier) + (output.[i - 1] * (1. - multiplier))
can this be rewritten using a sequence operator?
my second question is: is there a fast F# implementation floating around? I couldn't find any.
Well, I don't know about floating around, but I did just write an EMA function yesterday. It looks like this:
let ema alpha vs =
(None, vs)
||> Array.scan (fun prev x ->
match prev with
| None -> Some(x)
| Some(s) -> Some(alpha*x + (1. - alpha)*s))
|> Array.choose id
My version looks all the way back, rather than only a number of periods, as your version. If you want that behaviour instead, you could replace the state of type float option in my version with a float[], or even implement it using the Array.windowed function.
Related
Lets say I have an the following Array2D
> let arr = Array2D.init 2 3 (fun i j -> (i+1) * (j+2));;
> printfn "%A" arr
[[2; 3; 4]
[4; 6; 8]]
I know I can access an array element like so
> arr[1, 2];;
8
But what if I have the coordinates saved in a tuple. Why can't I do the following or something similar:
> let coord = (1, 2);;
> arr[coord]
Error: input.fsx (2,1)-(2,11) typecheck error This expression was expected to have type
''a[]'
but here has type
'int[,]'
It feels kinda stupid to unpack the tuple each time before using it. Or is this the only way?
> let x, y = coord;;
> arr[x, y];;
8
You could always use ||> to unpack the tuple rather than using let expressions, along with Array2D.get. The downside is that its a lil more verbose for sure.
- let arr = Array2D.init 2 3 (fun i j -> (i+1) * (j+2))
- let coord = (1,2)
- coord ||> Array2D.get arr;;
val it : int = 8
I don't think there's any direct way to index a 2D array using a tuple. One similar alternative is to use a Map instead:
let map =
seq {
for i = 0 to 1 do
for j = 0 to 2 do
yield (i, j), (i+1) * (j+2)
} |> Map
let coord = (1, 2)
map[coord] // 8
F# treats tupled arguments in a special way. If method is defined not in F#, then it's arguments should be tupled:
System.String.Join(", ", [|1; 2; 3|])
System.String.Join ", " [|1; 2; 3|] // not valid
It's done to help overload resolution.
What you can do is to extend multidimensional array type:
type ``[,]``<'a> with
member inline ar.Item with get ((x, y): (int*int)) : 'a =
ar.[x, y]
And then use it:
let coord = (1, 2)
arr.Item coord |> printfn "%d"
Unfortunately arr.[coord] is not available and looks like a bug in compiler
All problems are solved through functions!
let xss = Array2D.init 2 3 (fun i j -> (i+1) * (j+2));;
let get arr (x,y) = Array2D.get arr x y
get xss (1,2) (* Returns 8 *)
I am working on some homework and we are supposed to be making a combination function in F#. I have got the factorial function down, but it seems to overflow once I get a big number to use factorial on. (Let's say 20) I understand I can use an int64 or a float, but that would change all the inputs on the code. What data type should I use?
let rec Fact (a:int)=
if (a = 0) then 1 else a*Fact(a-1);;
let combo (n:int) (k:int)=
if (n = 0) then 0 else (Fact n)/((Fact k)*(Fact (n-k)));;
On the code right now, when I do combo 20 5;; it gives me 2147. Which is clearly the wrong answer. I looked at the factorial function and when I put 20 in there it gave me a big negative number. Any help would be much appreciated. Thanks in advance.
First of all, if you want to avoid surprises, you can open the Checked module at the top of your file. This will redefine the numerical operators so that they perform overflow checks - and you'll get an exception rather than unexpected number:
open Microsoft.FSharp.Core.Operators.Checked
As Fyodor points out in the comment, you cannot fit factorial of 20 in int and you need int64. However, your combo function then performs division which will make the result of combo 20 5 small enough to fit into int.
One option is to change Fact to use int64, but keep combo as a function that takes and returns integers - you'll need to convert them to int64 before calling Fact and then back to int after performing the division:
let rec Fact (a:int64) =
if (a = 0L) then 1L else a * Fact(a-1L)
let combo (n:int) (k:int) =
if (n = 0) then 0 else int (Fact (int64 n) / (Fact (int64 k) * Fact (int64 (n-k))))
Now you can call combo 20 5 and you'll get 15504 as the result.
EDIT: As noted by #pswg in the other answer, int64 is also quite limited and so you'll need BigInteger for larger factorials. However, the same method should work for you with BigInteger. You can keep the combo function as a function that returns int by converting back from BigInteger to int.
You simply won't be able to do that with an 32-bit integer (int). A 64-bit integer will get you up to 20!, but will fail at 21!. The numbers just get too big, too quickly. To go any further than that you'll need to use System.Numerics.BigInteger (abbreviated bigint in F#).
The parameter can probably stay as an int to be reasonable, but you need to return a bigint:
let rec Fact (n : int) =
if n = 0 then bigint.One else (bigint n) * Fact (n - 1)
Or to be a little more idiomatic:
let rec Fact = function | 0 -> bigint.One | n -> (bigint n) * Fact (n - 1)
And now, in your Combo function, you'll need to use these bigint's internally for all math (thankfully the integer division is all you need in this case).
let Combo (n : int) (k : int) =
if n = 0 then bigint.Zero else (Fact n) / ((Fact k) * (Fact (n - k)))
If you really wanted to make Combo return an int, you can do that conversion here:
let Combo (n : int) (k : int) =
if n = 0 then 0 else (Fact n) / ((Fact k) * (Fact (n - k))) |> int
Examples:
Combo 20 5 // --> 15504
Combo 99 5 // --> 71523144 (would break if you used int64)
Edit: By rethinking your implementation of Combo you can get some big performance improvements out of this. See this question on Math.SE for the basis of this implementation:
let ComboFast (n : int) (k : int) =
let rec Combo_r (n : int) = function
| 0 -> bigint.One
| k -> (bigint n) * (Combo_r (n - 1) (k - 1)) / (bigint k)
Combo_r n (if (2 * k) > n then n - k else k)
A quick benchmark showed this to be significantly faster than the Fact-based version above:
Function Avg. Time (ms)
Combo 99 5 30.12570
ComboFast 99 5 0.72364
Originated from this question, I have this little F# code (github) to generate random values according to a normal distribution:
// val nextSingle : (unit -> float32)
let nextSingle =
let r = System.Random()
r.NextDouble >> float32
// val gauss : (float32 -> float32 -> seq<float32>)
let gauss mean stdDev =
let rec gauss ready = seq {
match ready with
| Some spare ->
yield spare * stdDev + mean
yield! gauss None
| _ ->
let rec loop () =
let u = nextSingle() * 2.f - 1.f
let v = nextSingle() * 2.f - 1.f
let s = pown u 2 + pown v 2
if s >= 1.f || s = 0.f then loop() else
u, v, s
let u, v, s = loop()
let mul = (*)(sqrt(-2.f * log s / s))
yield mul u * stdDev + mean
yield! mul v |> Some |> gauss
}
gauss None
To me it seems that this should only call itself in tail call position, ergo never cause a StackOverflowException when TCO is enabled. But it does when running 64-bit. It does not when running 32-bit (i.e. “Prefer 32-bit” checkbox in project settings).
I'm using .NET Framework 4.5.2 and F# 4.4.0.0.
Can somebody explain what is causing the problem?
Looks like a bug in the compiler's sequence expression compilation mechanism. Here's a simplified repro:
let rec loop r = seq {
if r > 0 then
let rec unused() = unused()
yield r
yield! loop r
}
printfn "%i" (Seq.nth 10000000 (loop 1))
Obviously the presence of the unused recursive definition shouldn't affect whether this generates a stack overflow, but it does.
I'm learning f# and I've got a pretty trivial problem that doesn't seem to make sense. I'm working on Project Euler problem 2 and I've got this:
let fib (x : BigInteger) (y : BigInteger) (max : BigInteger) =
let added = x + y
if added > max then y
else fib y (x + y) max
I've got the error at the recursive fib call:
Value or constructor 'fib' is not defined
And I'm not sure why. Any help?
Because fib is recursive function, it has to start with let rec.
In F#, if you want to write a recursive function, you have to use the rec keyword:
let rec fib (x : BigInteger) (y : BigInteger) (max : BigInteger) =
let added = x + y
if added > max then y
else fib y (x + y) max
That's because in F# under normal circumstances, you can only use identifiers declared before the current code, unlike in C#.
Talking of Project Euler Problem 2, you may consider instead of recursion going with Seq.unfold, which is very idiomatic and gives you all Fibonacci numbers at once:
let fibs = Seq.unfold (fun (current, next) ->
Some(current, (next, current + next))) (1,2)
Now fibs represents lazy sequence of Fibonacci numbers :
>fibs;;
val it : seq<int> = seq[1; 2; 3; 5; ...]
And to make it of BigInteger just substitute (1,2) by (1I,2I), although the solution allows you to stay within ordinary integers.
I have a function to generate doubles in a range:
let gen_doublein =
fun mx mn -> Arb.generate<float> |> Gen.suchThat ( (>) mx ) |> Gen.suchThat ( (<) mn )
and then a function to generate an array of 2 of these:
let gen_params:Gen<double array> =
gen { let! x = gen_doublein 0.0 20000.0
let! y = gen_doublein 0.0 2000.0
return [| x;y|] }
I put:
static member arb_params = Arb.fromGen gen_params
in the Generator class and register it. All seems OK. To test that this is all OK I have:
let f2 (xs:double array) :double= exp (-2.0*xs.[0]) + xs.[1]*exp (-2.0*xs.[0])
let fcheck fn xs = fn xs > 0.0
then using an array generator 'arrayOfLength':
Check.Quick (Prop.forAll (arrayOfLength 2) (fcheck f2))
works as expected, however:
Check.Quick (Prop.forAll (Generators.arb_params) (fcheck f2))
just starts doing some calculation and never comes back. f# gurus please help.
I did not try this, but I think the problem is that the generator creates float values randomly and then checks whether they match the predicate you specified (the range). This means that it has to generate a large number of floats before it (randomly) generates one that matches.
It would be easier to generate values in a specified range by generating float values in a range [0 .. 1]
and then re-scaling them to match the range you need.
I'm not familiar with FsCheck enough, so I don't know if there is a generator for [0 .. 1] floating-point range, but you could start by generating integers and transforming them to floats:
let gen_doublein mx mn = gen {
let! n = Arb.generate<int>
let f = float n / float Int32.MaxValue
return mx + (f * (mn - mx)) }
EDIT I see that you solved the problem already. I think the solution I posted might still be relevant for smaller ranges (where the random generator does not produce enough matching values soon enough).
The problem was the parameters were the wrong way round. Tomas's suggestion is a good one, and there are some helper functions to implement it.
// Another id function
let fd (d:double) = d
// Check that it is in bounds
let mn=1.0
let mx=5.0
let fdcheck d = (fd d <= mx) && (fd d >= mn)
// Run the check with the numbers generated within the bounds
Check.Quick (Prop.forAll (Arb.fromGen (Gen.map (fun x->
match x with
| _ when Double.IsNaN x -> (mn+mx)/2.0
| _ when x> 1e+17 ->mx
| _ when x< -1e17 ->mn
| _ -> mn + (mx-mn)*(sin x+1.0)/2.0
) Arb.generate<double>
)
) fdcheck
)
Here I have a function which passes the test if the parameter is generated correctly. I'm not sure Tomas's idea with integers works because I think that a lot of small integers are generated and so the doubles don't explore the domain much - but maybe somebody who knows FSCheck might enlighten us.
Rewritten a sample from #b1g3ar5 this way
let mapRangeNormal (min : float<_>, max : float<_>) x =
match x with
| _ when Double.IsNaN x -> (min + max) / 2.0
| _ when Double.IsPositiveInfinity x -> max
| _ when Double.IsNegativeInfinity x -> min
| _ -> min + (max - min) * (sin x + 1.0) / 2.0
let mapRangeUniform (min : float<_>, max : float<_>) x =
match x with
| _ when Double.IsNaN x -> (min + max) / 2.0
| _ when Double.IsPositiveInfinity x -> max
| _ when Double.IsNegativeInfinity x -> min
| _ when x < 0.0 ->
let newRange = max - min
min - x * (newRange / Double.MaxValue) - newRange / 2.0
| _ -> let newRange = max - min
min + x * (newRange / Double.MaxValue) + newRange / 2.0