I am working through an F# function that calculates variance. I'm trying to step through each iteration to get the correct answer but think im getitng off track somewhere because I keep getting the wrong answer. Could someone please walk me through one iteration of this function to get me back on track
let variance values
let average = Seq.average values
let length = Seq.length values
values
|> Seq.map (fun x -> 1.0 / float length * (x - average) ** 2.0)
|> Seq.sum
call is variance [1.0..6.0]
To me the first value passed is 1.0 so it would be (1.0 / 6 * (1.0-3.5) ** 2.0) and therefore .166 * -2.5 ** 2.0
I'm also unsure what the ** means in formula I'm assuming multiply.
Correct answer should be 2.9166666667
To make it easier to understand, you can rewrite the code as follows:
let variance values =
let average = Seq.average values
let length = Seq.length values
let sum = values
|> Seq.map (fun x -> (x - average) ** 2.0)
|> Seq.sum in sum / float length
variance [1.0..6.0] |> printfn "%A"
Print: 2.916666667
Link: https://dotnetfiddle.net/09PHXn
By iteration:
let variancetest values =
let average = Seq.average values
let length = Seq.length values
values
|> Seq.iteri(fun i x ->
printfn "%i [%f]: %f ^ 2 = %A" i x (x - average) ((x - average) ** 2.0))
let sum = values
|> Seq.map (fun x -> (x - average) ** 2.0)
|> Seq.sum
let flength = float length
printfn "Sum = %f" sum
printfn "1/length = %f" (1.0 / flength)
printfn "Result / length = %f" (sum / flength)
variancetest [1.0..6.0]
Print:
0 [1.000000]: -2.500000 ^ 2 = 6.25
1 [2.000000]: -1.500000 ^ 2 = 2.25
2 [3.000000]: -0.500000 ^ 2 = 0.25
3 [4.000000]: 0.500000 ^ 2 = 0.25
4 [5.000000]: 1.500000 ^ 2 = 2.25
5 [6.000000]: 2.500000 ^ 2 = 6.25
Sum = 17.500000
1/length = 0.166667
Result / length = 2.916667
https://dotnetfiddle.net/02r3qG
Related
I'm new to F# and I'm struggling to figure out how I could combine the numbers in a float list to a float.
If I have the list
let floatList = [ 9.0; 8.0; 3.0 ]
I would like a function where the return value is a float of value 983.0. How would I go about this problem?
You go through the list, multiply the previously accumulated number by 10, then add the current element of the list:
((9 * 10) + 8) * 10 + 3 = 983
A handy way to go through the list while keeping an "accumulator" is List.fold:
floatList
|> List.fold (fun acc n -> acc*10 + n) 0
Chain rev, mapi(map with index) and sum functions
let digits = [| 9.0; 8.0; 3.0 |]
let result =
Array.rev digits
|> Array.mapi (fun i x -> x * (10.0 ** float i))
|> Array.sum
printfn "%f" result
Because array can return it's length without iterating over the collection, you can remove "reversing" and calculate offset for power based on the index and length
let digits = [| 9.0; 8.0; 3.0 |]
let result =
Array.mapi (fun i x -> x * (10.0 ** float (digits.Length - i))) digits
|> Array.sum
printfn "%f" result
This is a way to do it
let floatList = [ 9.0; 8.0; 3.0 ]
let rec loop mult list =
match list with
| head :: tail -> (mult * head) + (loop (mult / 10.) tail)
| [] -> 0.
let mult = 10. ** float ((List.length floatList) - 1) // len 1 = 1. len 2 = 10. len 3 = 100
let result = loop mult floatList
printfn "%f" result
I'm trying to write Taylor series in F#.
Have a look at my code
let rec iter a b f i =
if a > b then i;
else f a (iter (a+1) b f i)
let sum a b = iter a b (+) 0 // from 0
// e^x = 1 + x + (x^2)/2 + ... (x^n)/n! + ...
let fact n = iter 1 n (*) 1 // factorial
let pow x n = iter 1 n (fun n acc -> acc * x) 1
let exp x =
iter 0 x
(fun n acc ->
acc + (pow x n) / float (fact n)) 0
In the last row I am trying cast int fact n to float, but seems like I'm wrong because this code isn't compileable :(
Am I doing the right algorithm?
Can I call my code functional-first?
The code doesn't compile, because:
You're trying to divide an integer pow x n by a float. Division has to have operands of the same type.
You're specifying the terminal case of the wrong type. Literal 0 is integer. If you want float zero, use 0.0 or abbreviated 0.
Try this:
let exp x =
iter 0 x
(fun n acc ->
acc + float (pow x n) / float (fact n)) 0.
P.S. In the future, please provide the exact error messages and/or unexpected results that you're getting. Simply saying "doesn't work" is not a good description of a problem.
Let's say I have following equation . My goal is to create sequence which returns next elements of this. Here's my solution and it works:
let rec factorial(n:float) =
match n with
|0.0 -> 1.0
|n -> n * factorial(n-1.0)
let seq1 = Seq.initInfinite( fun i -> factorial(float(i)) / sqrt(float(i)+1.0) ))
Now, analogically, I would like to create sequence which return elements according to equation:
I've got some code, but it's wrong so how to make it work?
let seq2(x:float) = Seq.initInfinite(fun a -> let i = float(a)
(1.0/factorial(0.0)) + System.Math.Pow(x,i)/factorial(i) )
Can't you skip the (1.0/factorial(0.0)) part of the equation (or maybe I misunderstood the question).
edit: i.e
let seq2(x:float) =
Seq.initInfinite(fun a ->
let i = float(a) in
System.Math.Pow(x,i)/factorial(i))
edit: to truncate a seq you can use 'take' and to sum you can use 'sum'. As in
let seq2sum nbelems =
seq2 >> Seq.take nbelems >> Seq.sum
then you get seq2sum 12 3.0 equal to approx 20 :-)
The great thing about functional languages is that you can have your solution be as close an expression of the original definition as possible.
You can avoid explicit type declarations for most functions:
let rec factorial = function
| 0 -> 1
| n -> n * (factorial (n-1))
let e x n =
seq { 0 .. n }
|> Seq.map(fun i -> x ** (float i) / float (factorial i))
|> Seq.sum
In the infinite series, you will have to take the first n entries before you sum, as an infinite series will never finish evaluating:
let e' x n =
Seq.initInfinite(fun i -> x ** (float i) / float (factorial i))
|> Seq.take n
|> Seq.sum
e 1.0 10 //2.718281801
e' 1.0 10 //2.718281801
So I have verified that the starting version of what I'm trying to do works, but for some reason when putting it into the Matrix.map high order function it breaks down.
Here is the failing function:
let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
let m = trainingData.RowCount
let theta' = theta.ToRowMatrix()
trainingData
|> Matrix.mapRows(fun a r -> (theta' * r) - y.[a] )
Here are some sample tests
Set up:
let tData = matrix [[1.0; 2.0]
[1.0; 3.0]
[1.0; 3.0]
[1.0; 4.0]]
let yVals = vector [5.0; 6.0; 7.0; 11.0]
let theta = vector [1.0; 0.2]
Test raw functionality of basic operation (theta transpose * vector - actual)
let theta' = theta.ToRowMatrix()
(theta.ToRowMatrix() * tData.[0, 0 .. 1]) - yVals.[0]
Testing in actual function:
tData |> SumSquares theta yVals
Here is a copy/paste of actual error. It reads as though its having issues of me mapping a larger vector to a smaller vector.
Parameter name: target
at MathNet.Numerics.LinearAlgebra.Storage.VectorStorage1.CopyToRow(MatrixStorage1 target, Int32 rowIndex, ExistingData existingData)
at FSI_0061.SumSquares(Vector1 theta, Vector1 y, Matrix`1 trainingData) in C:\projects\deleteme\ASPNet5Test\ConsoleApplication1\ConsoleApplication1\MachineLearning.fsx:line 23
at .$FSI_0084.main#() in C:\projects\deleteme\ASPNet5Test\ConsoleApplication1\ConsoleApplication1\MachineLearning.fsx:line 39
Stopped due to error
I found an even better easier way to do this. I have to credit s952163 for starting me down a good path, but this approach is even more optimized:
let square (x:Vector<float>) = x * x
let subtract (x:Vector<float>) (y:Vector<float>) = y - x
let divideBy (x:float) (y:float) = y / x
let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
let m = trainingData.RowCount |> float
(trainingData * theta)
|> subtract y
|> square
|> divideBy m
Since you know the number of rows you can just map to that. Arguably this is not pretty:
let SumSquares (theta:Vector<float>) (y:Vector<float>) (trainingData:Matrix<float>) =
let m = trainingData.RowCount
let theta' = theta.ToRowMatrix()
[0..m-1] |> List.map (fun i -> (((theta' * trainingData.[i,0..1]) |> Seq.exactlyOne) - yVals.[i] ))
Edit:
My guess is that mapRows wants everything to be in the same shape, and your output vector is different. So if you want to stick to the Vector type, this will just enumerate the indexed rows:
tData.EnumerateRowsIndexed() |> Seq.map (fun (i,r) -> (theta' * r) - yVals.[i])
and you can also use Matrix.toRowSeqi if you prefer to pipe it through, and get back a Matrix:
tData
|> Matrix.toRowSeqi
|> Seq.map (fun (i,x) -> (theta' * x) - yVals.[i])
|> DenseMatrix.ofRowSeq
I am trying to do an "unfold" - (I think), by starting with an initial value, applying some function to it repeatedly, and then getting a sequence as a result.
In this example, I'm trying to start with 1.0, multiply it by .80, and do it 4 times, such that I end up with an array = [| 1.0; 0.80; 0.64; 0.512 |]
VS 2010 says I'm using "i" in an invalid way, and that mutable values cannot be captured by closures - so this function does not compile. Can anyone possibly suggest a clean approach that actually works? Thank you.
let expSeries seed fade n =
//take see and repeatedly multiply it by the fade factor n times...
let mutable i = 0;
let mutable weight = seed;
[| while(i < n) do
yield weight;
weight <- weight * fade |]
let testWeights = expSeries 1.0 0.80 4
let exp_series seed fade n =
Array.init (n) (fun i -> seed * fade ** (float i))
I think this recursive version should work.
let expSeries seed fade n =
let rec buildSeq i weight = seq {
if i < n then
yield weight;
yield! buildSeq (i + 1) (weight * fade)
}
buildSeq 0 seed
|> Seq.toArray
Based on the anwer to this question, you can create an unfold, and take a number of values of it:
let weighed startvalue factor =
startvalue |> Seq.unfold (fun x -> Some (x, factor * x))
let fivevalues = weighed 1.0 .8 |> Seq.take 5
If you want to explicitly use an unfold, here's how:
let expSeries seed fade n =
Seq.unfold
(fun (weight,k) ->
if k > n then None
else Some(weight,(weight*fade, k+1)))
(seed,1)
|> Array.ofSeq
let arr = expSeries 1.0 0.80 4
Note that the reason your original code won't work is that mutable bindings can't be captured by closures, and sequence, list, and array expressions implicitly use closures.