I have some chemical models, which are based on sparse matrices of some coefficients. So, given the model parameters, I generate F# code based on only non-zero elements of these coefficients. The generated model is then fed to ALGLIB (http://www.alglib.net/) ODE solver. The matrices of coefficients are about 99.9% to 99.99% sparse, which means that only 0.01% to 0.1% of coefficients are not exact zeros. Below is a very simplified example of how a generated F# model file looks like. It is the function update (x : array<double>) : array<double> that is fed to ALGLIB ODE solver using 64-bit FSI.
Now, the ALGLIB ODE solver is perfectly capable of handling at least 1M variables for a simple input function. I've tested that and it works with no issues. I have under 10K variables for a typical model.
However, when I increase the model size, I start getting stack overflow exception at run time: the model with about 100K LOC works fine, but the model with about 150K LOC fails with stack overflow exception.
I am guessing that this is related to how initialization / processing of large "hard-coded" arrays is handled and I wonder how should I tweak the generated code OR how can I increase the stack size for FSI and/or F# 64-bit program, let's say to 1 GB.
I shall stress that this is not a typical recursive function stack overflow issue, but just the overall size of the model, which causes the problem.
If you look at update function, you will see that it has a generated array, each element of which is produced by taking another array and applying |> Array.sum. This becomes huge for a large model and I am guessing that that could be causing a stack overflow.
Thanks a lot!
PS Below is a very simplified example of the model. It does have all the necessary structures that appear in the real model.
namespace Model
open Clm.Substances
open Clm.Model
open Clm.ReactionTypes
module ModelData =
let seedValue = 123456
let numberOfAminoAcids = NumberOfAminoAcids.OneAminoAcid
let maxPeptideLength = MaxPeptideLength.TwoMax
let numberOfSubstances = 7
let aminoAcids = AminoAcid.getAminoAcids numberOfAminoAcids
let chiralAminoAcids = ChiralAminoAcid.getAminoAcids numberOfAminoAcids
let peptides = Peptide.getPeptides maxPeptideLength numberOfAminoAcids
let allSubst =
[ Substance.food ]
#
(chiralAminoAcids |> List.map (fun a -> Chiral a))
#
(peptides |> List.map (fun p -> PeptideChain p))
let allInd = allSubst |> List.mapi (fun i s -> (s, i)) |> Map.ofList
let getTotalSubst (x : array<double>) =
[|
x.[0] // Y
x.[1] // A
x.[2] // a
2.0 * x.[3] // AA
2.0 * x.[4] // Aa
2.0 * x.[5] // aA
2.0 * x.[6] // aa
|]
|> Array.sum
let getTotals (x : array<double>) =
[|
// A
(
[|
x.[1] // A
2.0 * x.[3] // AA
x.[4] // Aa
x.[5] // aA
|]
|> Array.sum
,
[|
x.[2] // a
x.[4] // Aa
x.[5] // aA
2.0 * x.[6] // aa
|]
|> Array.sum
)
|]
let update (x : array<double>) : array<double> =
let xSum = (x |> Array.sum) - x.[0]
let xSumN =
[|
1.0 * x.[1] // A
1.0 * x.[2] // a
2.0 * x.[3] // AA
2.0 * x.[4] // Aa
2.0 * x.[5] // aA
2.0 * x.[6] // aa
|]
|> Array.sum
let xSumSquaredN =
[|
1.0 * x.[1] * x.[1] // A
1.0 * x.[2] * x.[2] // a
2.0 * x.[3] * x.[3] // AA
2.0 * x.[4] * x.[4] // Aa
2.0 * x.[5] * x.[5] // aA
2.0 * x.[6] * x.[6] // aa
|]
|> Array.sum
[|
// 0 - Y
[|
0.0001 * x.[2] // a | SynthesisName: Y <-> a
-0.001 * x.[0] // Y | SynthesisName: Y <-> a
0.0001 * x.[1] // A | SynthesisName: Y <-> A
-0.001 * x.[0] // Y | SynthesisName: Y <-> A
|]
|> Array.sum
// 1 - A
[|
0.0001 * x.[5] // aA | LigationName: a + A <-> aA
-0.001 * x.[2] * x.[1] // a + A | LigationName: a + A <-> aA
0.0001 * x.[4] // Aa | LigationName: A + a <-> Aa
-0.001 * x.[1] * x.[2] // A + a | LigationName: A + a <-> Aa
0.0001 * x.[3] // AA | LigationName: A + A <-> AA
0.0001 * x.[3] // AA | LigationName: A + A <-> AA
-0.001 * x.[1] * x.[1] // A + A | LigationName: A + A <-> AA
-0.001 * x.[1] * x.[1] // A + A | LigationName: A + A <-> AA
-0.0001 * x.[1] // A | SynthesisName: Y <-> A
0.001 * x.[0] // Y | SynthesisName: Y <-> A
|]
|> Array.sum
// 2 - a
[|
0.0001 * x.[5] // aA | LigationName: a + A <-> aA
-0.001 * x.[2] * x.[1] // a + A | LigationName: a + A <-> aA
0.0001 * x.[4] // Aa | LigationName: A + a <-> Aa
-0.001 * x.[1] * x.[2] // A + a | LigationName: A + a <-> Aa
0.0001 * x.[6] // aa | LigationName: a + a <-> aa
0.0001 * x.[6] // aa | LigationName: a + a <-> aa
-0.001 * x.[2] * x.[2] // a + a | LigationName: a + a <-> aa
-0.001 * x.[2] * x.[2] // a + a | LigationName: a + a <-> aa
-0.0001 * x.[2] // a | SynthesisName: Y <-> a
0.001 * x.[0] // Y | SynthesisName: Y <-> a
|]
|> Array.sum
// 3 - AA
[|
-0.0001 * x.[3] // AA | LigationName: A + A <-> AA
0.001 * x.[1] * x.[1] // A + A | LigationName: A + A <-> AA
|]
|> Array.sum
// 4 - Aa
[|
-0.0001 * x.[4] // Aa | LigationName: A + a <-> Aa
0.001 * x.[1] * x.[2] // A + a | LigationName: A + a <-> Aa
|]
|> Array.sum
// 5 - aA
[|
-0.0001 * x.[5] // aA | LigationName: a + A <-> aA
0.001 * x.[2] * x.[1] // a + A | LigationName: a + A <-> aA
|]
|> Array.sum
// 6 - aa
[|
-0.0001 * x.[6] // aa | LigationName: a + a <-> aa
0.001 * x.[2] * x.[2] // a + a | LigationName: a + a <-> aa
|]
|> Array.sum
|]
let modelDataParams =
{
numberOfSubstances = 7
numberOfAminoAcids = OneAminoAcid
maxPeptideLength = TwoMax
getTotals = getTotals
getTotalSubst = getTotalSubst
allSubst = allSubst
allInd = allInd
allRawReactions =
[
]
allReactions =
[
(SynthesisName, 2)
(LigationName, 4)
]
}
To summarize our findings.
After a series of trial an errors testing, tracing and debugging different hypothesis #Konstantin was able to discover that the issue was due to the JIT compiler. Apparently it was trying to compile the update function prior to its first execution. This function was too large and that was causing the Stack Overflow.
Splitting the function into smaller ones was the solution.
Bravo Konstantin!
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 am looking for some pointers/snippets to resolve below task.
type Rel =
{
id:int,
from:int,
to:int,
percent:float
IsLeafNode:string
}
I have below data
id from to percent isLeafNode`
1 A B 0.6 N
2 A C 0.4 N
3 B D 0.2 N
4 B E 0.8 Y
5 C F 1.0 N
6 D G 1.0 Y
7 F H 0.7 Y
8 F B 0.3 N
9 I J 1.0 N
10 J K 1.0 Y
I need to build a tree or graph like relationship between from and to values and multiply percentages from some specific nodes (A and I in this case) to leaf nodes and figure out starting id to leaf level Id and computed percentage. I am looking for below results
1 - 6 (A to G via B,D) = 0.6 * 0.2 * 1.0 = 0.12
1 - 4 (A to E via B) = 0.6 * 0.8 = 0.48
1 - 7 (A to H via C,F) = 0.4 * 1.0 * 0.7 = 0.28
1 - 6 (A to G via C,F,B,D,G) = 0.4 * 1.0 * 0.3 * 0.2 * 1.0 = 0.024
1 - 4 (A to E via C,F,B,E) = 0.4 * 1.0 * 0.3 * 0.8 = 0.096
9 - 10(I to K via J) = 1.0 * 1.0 = 1.0
I am trying to figure what will be right type of structure to use and how to use some of already resolved nodes e.g. B already resolved while resolving left side of A; F to B should be able to use already computed B to G and B to E percentages. I have lot of data to process using this approach and it could be up to 50 levels deep.
just taking first few nodes, here is what I am doing
type internal LeafNode
{
ID:int;
to:string;
percent:float;
}
type internal ChurnNode =
{
ID:int;
from:string;
percent:float;
}
type internal Tree<'L,'N> =
| Leaf of 'L
| Node of 'N * Tree<'L,'N> seq
type internal Eq = Tree<LeafNode, ChurnNode>
let rec Fold fLeaf fNode acc (tree: Tree<'L,'N>) : 'r =
let recurse = Fold fLeaf fNode
match tree with
| Leaf leafInfo ->
fLeaf acc leafINfo
| Node (nodeInfo, children) ->
let localAcc = fNode acc nodeInfo
let finalAcc = children |> Seq.fold recurse localAcc
finalAcc //return
let ComputePercent eq =
let fleaf acc (leaf:LeafNode) =
acc * leaf.percent
let fNode acc (node:ChurnNode) =
acc * node.percent
Fold fleaf fNode 1.0 eq
let RunProcess() =
let nodeA = {ID=0;from="A";percent=1.0}
let nodeB = {ID=1;from="B";percent=0.6}
let leafC = {ID=2;to="C";percent=0.4}
let leafD = {ID=2;to="D";percent=0.2}
let leafE = {ID=2;to="E";percent=0.8}
let t = Node(nodeA, [NodeB, [Leaf(leafD); Leaf(leafE)]; Leaf(leafC)]
t |> ComputePercentage
For A to B to D & E, this code returns 1.0 * 0.6 * 0.2 * 0.8 but I need A to B to D = 1.0 * 0.6 * 0.2 and A to B to E = 1.0 * 0.6 * 0.8. Can you let me how how to reset the accumulator when done with a leaf. May be I got off wrong foot here but it's bit tricky for me.
I have a bunch of functions that I want to compute with the same inputs. Is there a better way to see the outputs than the way I chose below?
open MathNet.Numerics.Distributions
// The functions
let EuVanillaPut S0 K T r sigma =
let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
let d2 = d1 - sqrt(T)*sigma
K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2) - S0*Normal.CDF(0.0,1.0,-d1)
let BSMdelta S0 K T r sigma =
let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
Normal.CDF(0.0,1.0,d1)
let BSMgamma S0 K T r sigma =
let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
Normal.PDF(0.0,1.0,d1) / (S0 * sigma * sqrt(T))
let BSMvega S0 K T r sigma =
let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
Normal.PDF(0.0,1.0,d1) * S0 * sqrt(T)
let BSMthetacall S0 K T r sigma =
let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
let d2 = d1 - sqrt(T)*sigma
-S0 * Normal.PDF(0.0,1.0,d1) * sigma / (2.0*sqrt(T)) - r*K*exp(-r*T)*Normal.CDF(0.0,1.0,d2)
let BSMthetaput S0 K T r sigma =
let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
let d2 = d1 - sqrt(T)*sigma
-S0 * Normal.PDF(0.0,1.0,d1) * sigma / (2.0*sqrt(T)) + r*K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2)
// Calling them all at once on the same inputs
// So ugly! Is there a better way?
(30.0, 25.0, 5.0, 0.02, 0.05)
|> fun (S0, K, T, r, sigma) -> [EuVanillaPut S0 K T r sigma;
BSMdelta S0 K T r sigma;
BSMgamma S0 K T r sigma;
BSMvega S0 K T r sigma;
BSMthetacall S0 K T r sigma;
BSMthetaput S0 K T r sigma]
I'm pretty new to F#, should I make a type for this? Should I be using a different data structure as an input for the functions? Any and all pointers are much appreciated.
As suggested in the comments, one option is to create a list of functions and then use List.map to iterate over all the functions and call them:
let results =
[ EuVanillaPut; BSMdelta; BSMgamma ]
|> List.map (fun f -> f 30.0 25.0 5.0 0.02 0.05)
I suppose you'd then also want to extract the individual results - to do that, you can use pattern matching (but you will get a warning, because the compiler cannot know that the number of elements in the list is correct):
let [euVanillaPut; bsmdelta; bsmgamma] = results
To avoid the warning, you'd have to write:
match results with
| [euVanillaPut; bsmdelta; bsmgamma] -> // all good
| _ -> failwith "This should not happen..."
Alternatively, you could change the function definition to use tuple (or a record):
let EuVanillaPut (S0, K, T, r, sigma) =
let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
let d2 = d1 - sqrt(T)*sigma
K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2) - S0*Normal.CDF(0.0,1.0,-d1)
Then you can define a single tuple to hold the parameters and use it as an argument to multiple functions:
let ps = (30.0, 25.0, 5.0, 0.02, 0.05)
let euVanillaPut = EuVanillaPut ps
let bsmdelta = BSMdelta ps
let bsmgamma = BSMgamma ps
The first approach is a clever trick, but if you are doing this often, then extracting the individual results from the list will be a bit ugly. The second approach is simpler and makes more sense if you have a lot of functions with the same group of parameters.
I could really do with some help with tail call optimization in F#.
I am trying to parse a tree like structure and perform a calculation on each leaf.
The function I'm having problems with is calcLength
type Location = float * float
type Radius = float
type Width = float
type Angle = float
type Primitive =
| Circle of Location * Radius
| Ellipse of Location * Radius * Radius
| Square of Location * Width * Angle
| MultiPrimitive of Primitive List
type Primitive with
member x.Length =
let rec calcLength x =
match x with
| Circle (_,r) -> System.Math.PI * r * 2.
| Ellipse (_,r1,r2) -> System.Math.PI * 2. * sqrt( (r1 * r1 ) + (r2 * r2 ) / 2.)
| Square (_, w,_) -> w * 4.
| MultiPrimitive [] -> 0.
| MultiPrimitive (head::tail) -> calcLength (MultiPrimitive tail) + (calcLength head)
[<Fact>]
let ``test discriminated unions``() =
let pattern = MultiPrimitive(
[
MultiPrimitive(
[
MultiPrimitive(
[
Square( (10.,10.), 10., 45. );
Circle( (3.,7.), 3. );
Circle( (7.,7.), 3. );
Square( (5.,2.), 3., 45. );
] );
Square( (10.,10.), 10., 45. );
Circle( (3.,7.), 3. );
Circle( (7.,7.), 3. );
Square( (5.,2.), 3., 45. );
] );
Square( (10.,10.), 10., 45. );
Circle( (3.,7.), 3. );
Circle( (7.,7.), 3. );
Square( (5.,2.), 3., 45. );
] )
let r = pattern.Length
I attempted to use the continuation approach with the following:
let rec calcLength x f =
match x with
| Circle (_,r) -> f() + System.Math.PI * r * 2.
| Ellipse (_,r1,r2) -> f() + System.Math.PI * 2. * sqrt( (r1 * r1 ) + (r2 * r2 ) / 2.)
| Square (_, w,_) -> f() + w * 4.
| MultiPrimitive [] -> f()
| MultiPrimitive (head::tail) -> calcLength head (fun () -> calcLength(MultiPrimitive tail) f )
calcLength x (fun () -> 0.)
But stepping through with the debugger showed the stack growing, any help would be Really appreciated.
The usual way to use CPS is to pass the result to the given continuation:
let rec calcLength x k =
match x with
| Circle (_,r) -> k (System.Math.PI * r * 2.)
| Ellipse (_,r1,r2) -> k (System.Math.PI * 2. * sqrt( (r1 * r1 ) + (r2 * r2 ) / 2.))
| Square (_, w,_) -> k (w * 4.)
| MultiPrimitive [] -> k 0.
| MultiPrimitive (head::tail) -> (calcLength head (fun h -> calcLength(MultiPrimitive tail) (fun t -> k (h + t))))
so in the MultiPrimitive case you need to pass another continuation to deal with the result from calculating the head.
I m trying to implement something in f# that I already have in c# to see how much more succinct the syntax is. I used an option pricing formula (Black 76) as test because this seems like a functional problem to me. All seems fine but I have trouble computing the implied vol as I need to call a method of the same class from within. Here is what I have so far:
module Module1
open System
type Black76 (CallPutFlag, Fwd, Strike, time, rf, vol, ?BlackPrice:float) =
let d1 = (Math.Log(Fwd / Strike) + (vol * vol * 0.5) * time) / (vol * Math.Sqrt(time))
let d2 = d1 - vol * Math.Sqrt(time)
let n = new MathNet.Numerics.Distributions.Normal()
member x.valuation =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> Math.Exp(-rf * time) * (Fwd * n.InverseCumulativeDistribution(d1) - Strike * n.InverseCumulativeDistribution(d2))
| "p" | "P" | "Put" | "put" -> Math.Exp(-rf * time) * (Strike * n.InverseCumulativeDistribution(-d2)- Fwd * n.InverseCumulativeDistribution(-d1))
| _ -> failwith "Unrecognized option type"
member x.delta =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> Math.Exp(-rf * time) * n.InverseCumulativeDistribution(d1)
| "p" | "P" | "Put" | "put" -> Math.Exp(-rf * time) * n.InverseCumulativeDistribution(-d1)
| _ -> failwith "Unrecognized option type"
member x.gamma =
Math.Exp(-rf * time) * (n.Density(d1) / (Fwd * vol * Math.Sqrt(time)))
member x.vega =
Math.Exp(-rf * time) * n.Density(d1) * Fwd * Math.Sqrt(time)
member x.rho =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> time * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(d2)
| "p" | "P" | "Put" | "put" -> -time * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(-d2)
| _ -> failwith "Unrecognized option type"
member x.theta =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> -(Fwd * vol * n.Density(d1)) / (2.0 * Math.Sqrt(time)) - rf * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(d2)
| "p" | "P" | "Put" | "put" -> -(Fwd * vol * n.Density(d1)) / (2.0 * Math.Sqrt(time)) + rf * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(-d2)
| _ -> failwith "Unrecognized option type"
member x.impliedvol =
let vst = Math.Sqrt(2.0*Math.Abs((Math.Log(Fwd/Strike)+rf*time)/time))
let tol = 0.0001
let mutable v = vst
let mutable sigmadiff = 1.0
let mutable k = 1
let kmax = 100
while (sigmadiff >= tol && k < kmax) do
let option = Black76.valuation(CallPutFlag, Fwd, Strike, time, rf, v)
let cvega = Black76.vega(CallPutFlag, Fwd, Strike, time, rf, v)
let increment = (option - BlackPrice) / cvega
v <- v - increment
k < - k + 1
sigmadiff = Math.Abs(increment)
v
This all works apart from the implied vol function. Also it does not seem to be much more succinct than the c# version. Could you please let me know how I can call the method from within for the implied vol funcitons? Also do you know how to get rid of the let mutable (after all you are not supposed to use this in fsharp (I think).
thanks
If you want to make the code more succinct and more functional, then I would probably try to restructure it a bit more. I think something along these lines below should work.
First of all, you definitely don't want to repeat the matching on strings, so I'd define a discriminated union to capture the kinds of computations (you can then parse the string just once):
type CallPutFlag = Call | Put
Next, we can define record to keep the results of the equation (I added just the things that you were using, but you would probably want to add more here):
type Black76Results = { Vega : float; Valuation : float }
Now, I think it makes good sense to separate the black76 function from the implied volatility. The black76 function can run the calculation for given inputs and return the results as a value of Black76Results record:
let black76 flag fwd strike time rf vol =
let d1 = (Math.Log(fwd / strike) + (vol * vol * 0.5) * time) / (vol * Math.Sqrt(time))
let d2 = d1 - vol * Math.Sqrt(time)
let n = new MathNet.Numerics.Distributions.Normal()
match flag with
| Call ->
let valuation = Math.Exp(-rf * time) * (fwd * n.InverseCumulativeDistribution(d1) - strike * n.InverseCumulativeDistribution(d2))
let delta = Math.Exp(-rf * time) * n.InverseCumulativeDistribution(d1)
let gamma = Math.Exp(-rf * time) * (n.Density(d1) / (fwd * vol * Math.Sqrt(time)))
let vega = Math.Exp(-rf * time) * n.Density(d1) * fwd * Math.Sqrt(time)
let rho = time * strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(d2)
let theta = -(fwd * vol * n.Density(d1)) / (2.0 * Math.Sqrt(time)) - rf * strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(d2)
{ Vega = vega; Valuation = valuation }
| Put ->
failwith "TODO: Similar for Put"
Although there is some shared code in Call and Put, I think it looks a lot more readable when you separate the two into different branches (you could still extract common pieces of code into a separate function).
Now, impliedVol is simply a function that calls black76 repeatedly:
let impliedVol flag fwd strike time rf blackPrice =
let vst = Math.Sqrt(2.0*Math.Abs((Math.Log(fwd/strike)+rf*time)/time))
let tol = 0.0001
let mutable v = vst
let mutable sigmadiff = 1.0
let mutable k = 1
let kmax = 100
while (sigmadiff >= tol && k < kmax) do
let b = black76 flag fwd strike time rf v
let option = b.Valuation
let cvega = b.Vega
let increment = (option - blackPrice) / cvega
v <- v - increment
k <- k + 1
sigmadiff <- Math.Abs(increment)
v
So your problem is the lines:
let option = Black76.valuation(CallPutFlag, Fwd, Strike, time, rf, v)
let cvega = Black76.vega(CallPutFlag, Fwd, Strike, time, rf, v)
Your trying to call them on the type Black76, when they're instance members of an object of type Black76. You should use x.valuation(...) instead, (x because that's what you've called your this variable).
F# doesn't have a fixed keyword for what in C# is known as this. Instead when you declare a member you give any name you want before the dot.
member this.method_name =
member x.another_method =