I have been tasked with migrating some specific Financial functions written in F# to C#
The F# library I am using is excellent (http://archive.msdn.microsoft.com/FinancialFunctions) but environmental considerations prevent the deployment of a CLR assembly to our SQL Server with Unrestricted permissions that it requires to be deployed
The specific function I am having a problem with is the MacAuley Duration formula. I am an absolute novice with F# and would appreciate if an F# expert would explain the code snippet below:
let aggrFunction acc index =
let x5 = float index - 1. + x1
let x6 = pow x3 x5
( x6 <> 0.) |> elseThrow "x6 must be different from 0)"
let x7 = (100. * coupon / frequency) / x6
let a, b = acc
a + x7 * x5, b + x7
let term2, term4 = aggrBetween 1 (int n) aggrFunction (0., 0.)
My best C# attempt looks thus and returns the wrong result (I am running the two side by side). btw frequency is an Enum hence the cast
double term2 = 0;
double term4 = 0;
for (int i = 0; i <= n ; i++)
{
var x5 = i - 1 + x1;
var x6 = Math.Pow(x3, x5);
if (x6 == 0)
{
throw new Exception("x6 must be different from 0)");
}
var x7 = (100D * coupon/(int) frequency) / x6;
term2 += (x7*x5);
term4 += x7;
}
Related
I'm learning F# by implementing a board game engine. In accordance with the principle that invalid states should not be representable, I want to create a type which represents (x, y) coordinates (with x and y integers) where x and y must satisfy 0 <= x <= n and 0 <= y <= m. Creating an instance that does not satisfy those inequalities shouldn't compile. Is this possible?
I don't think compile time assurances on values like this are possible.
I would handle this with a private constructor and the Result or Option type depending whether I wanted to propagate error information.
type Position =
private {
X: int
Y: int
}
static member TryNew(x, y) =
if x >= 0 && x <= 10 then
if y >= 0 && y <=10 then
Ok {
X = x
Y = y
}
else
Error $"Supplied y ({y}) must be between 0 and 10"
else
Error $"Supplied x ({x}) must be between 0 and 10"
module Position =
let moveX1 pos =
Position.TryNew(pos.X + 1, pos.Y)
This does create the issue where Results are now everywhere in your code but they don't have to be visible or cause you a lot of typing. This problem is precisely what computation expression libraries e.g. FsToolkit.ErrorHandling are designed to eliminate.
let example =
result {
let! start = Position.TryNew(0,0)
let! next = start |> moveX1
}
There's no way to do this that takes integers as input, but it can be done with a type that only provides integers as output:
type XCoord = X0 | X1 | X2 with
member this.Int =
match this with
| X0 -> 0
| X1 -> 1
| X2 -> 2
static member (-)(xa : XCoord, xb: XCoord) =
xa.Int - xb.Int
type YCoord = Y0 | Y1 | Y2 with
member this.Int =
match this with
| Y0 -> 0
| Y1 -> 1
| Y2 -> 2
static member (-)(ya : YCoord, yb: YCoord) =
ya.Int - yb.Int
type Point = MkPoint of (XCoord * YCoord) with
member this.Ints =
let (MkPoint (x, y)) = this
x.Int, y.Int
static member (-)((MkPoint (ax, ay)), (MkPoint (bx, by))) =
ax - bx, ay - by
let ptA = MkPoint (X0, Y1)
let ptB = MkPoint (X2, Y0)
printfn "%A" ptA.Ints
printfn "%A" ptB.Ints
printfn "%A" (ptA - ptB)
I think this would be pretty clunky to use in practice, but it might work, depending on exactly what you want to do with it. I guess it's a case of "careful what you ask for". 😀
I am working with an API that represents points like float * float.
These are inconvenient to do arithmetic on:
let a = (3.0, 4.0)
let b = (2.0, 1.0)
let c = (fst a + fst b, snd a + snd b)
I would like to write:
let c = a + b
I can do this if I define my own type:
type Vector2 =
{
X : float;
Y : float;
}
with
static member (+) (a : Vector2, b : Vector2) =
{ X = a.X + b.X; Y = a.Y + b.Y }
But then I need to convert for the API I am using:
let c = a + b
let cAsTuple = (c.X, c.Y)
Alternatively, I could create a free function:
let add (ax, ay) (bx, by) =
(ax + bx, ay + by)
let c = a |> add b
But this is not quite as nice as true infix operators.
Does F# allow me to define custom operators for tuples?
If you are willing to use a different operator like (+.) you can do this:
let inline (+.) (a,b) (c,d) = (a + c, b + d)
it works with ints, floats, strings:
( 4 , 3 ) +. ( 3 , 2 ) // (7, 5)
( 4., 3.) +. ( 3., 2.) // (7.0, 5.0)
("4", "3") +. ("3", "2") // ("43", "32")
TL;DR; #AMieres answer is the real one, this should rather be a comment but comments are length limited and code formatting is not nice ¯_(ツ)_/¯
There is work in progress to make operator extensions become reality: Issue, RFC, PR Once this is done, the following might finally work:
open System
open System.Runtime.CompilerServices
[<Extension>]
type TupleExtensions() =
[<Extension>]
static member inline (+) ((x1, y1), (x2, y2)) = (x1 + x2, y1 + y2)
// or
type Tuple<'T1, 'T2> with
// warning FS1215: Extension members cannot provide operator overloads.
// Consider defining the operator as part of the type definition instead.
static member inline (+) ((x1, y1), (x2, y2)) = (x1 + x2, y1 + y2)
// and then
let t1 = (1., 2.)
let t2 = (42., 3.141)
TupleExtensions.(+) (t1, t2) // (43.0, 5.141)
// error FS0001: Expecting a type supporting the operator '+' but given a tuple type
t1 + t2
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.
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.
The below is in an F# code snippet where I am trying to remove reliance on the input parameters and perform some sort of function composition:
let h x1 x2 = (*) (exp x1) (sin x2) // how to reduce to point free style
I have tried:
let h1 = (*) exp sin
let h2 = exp * sin
let h3 = ((*) << exp) << sin
Compiler not happy with the first two and the last doesn't yield the desired result.
I am in fact trying to solve the more general problem of function composition (using whatever tools F# has available) summarised as follows:
f1: float -> float
f2: float -> float
f3: float -> float -> float
How to construct h = f3(f1(x),f2(y)) represented mathematically.