F # Generic Math: how to write a function with op_GreaterThan

in F # how to write a generic-math step icon?

An (Oliver) The Heisiside step function is a function that returns zero if x is negative, otherwise it reconfigures one.

Here is a summary of my attempts:

// attempt 1: let inline stepFct1< ^T when ^T : (static member op_GreaterThan: ^T * float -> bool) > (x:^T) : ^T = //if (^T : (static member op_GreaterThan) (x 0.0) ) then x //ouch fails also if (>) x 0.0 then x else 0.0 

the compiler says: error FS0001: the type parameter has no restriction "when ^ T: comparison"

 // attempt 2: let inline stepFct2<^T when ^T : (static member (>): ^T * ^T -> bool) > (x:^T) : ^T = match x with | x when x > 0.0 -> 1.0 | 0.0 

FSC says: error FS0010: Unexpected infix operator in pattern

Motivation:

I am trying to rewrite the Ian Cumulative-Normal and Black-Scholes functions here to use automatic differentiation (DiffSharp). Ian Cumulative Normal works on floats, I need a generic version that works with any number type, including AutoDiff.DualG. The cumulative normal function contains an β€œmore” instruction.

EDIT: Gustavo, thanks, I accepted your answer - now a simple step function is executed.

But it doesn't seem to help with the cumulative normal case. Given this code:

 // Cumulative Normal Distribution Function - attempt to write a generic version let inline CDF(x:^T) : ^T = let (b1,b2,b3) = (0.319381530, -0.356563782, 1.781477937) let (b4,b5) = (-1.821255978, 1.330274429) let (p , c ) = (0.2316419 , 0.39894228) let (zero, one) = (LanguagePrimitives.GenericZero, LanguagePrimitives.GenericOne) if x > zero then let t = one / (one + p * x) (one - c * exp( -x * x / 2.0)* t * (t*(t*(t*(t*b5+b4)+b3)+b2)+b1)) else let t = 1.0 / (one - p * x) (c * exp( -x * x / 2.0)* t * (t*(t*(t*(t*b5+b4)+b3)+b2)+b1)) 

FSI says:

 C:\stdin(116,32): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'float'. val inline CDF : x:float -> float > CDF 0.1M;; CDF 0.1M;; ----^^^^ C:\stdin(122,5): error FS0001: This expression was expected to have type float but here has type decimal > 

Does anyone know how to create a shared CDF?

0
generics math f # diffsharp
Nov 27 '14 at 22:02
source share
1 answer

Use LanguagePrimitives.GenericZero / GenericOne and let the rest of the type do the rest

 // attempt 1: let inline stepFct1 x = let zero = LanguagePrimitives.GenericZero if x > zero then x else zero 

I looked at the link you submitted using the function you want to implement. FSharpPlus (F # +) can help you write general math code, as it contains dedicated Generic Numbers . Or at least you can grab some methods from there.

UPDATE

As for your updated question, which takes complexity to a higher level, here is a solution using the latest version of the F # + project

 let inline CDF(x:^T) : ^T = let num x = fromRational (x </ratio/> 1000000000I) let (b1,b2,b3) = (num 319381530I , num -356563782I , num 1781477937I) let (b4,b5) = (num -1821255978I , num 1330274429I) let (p , c ) = (num 0231641900I , num 0398942280I) let (zero, one, two) = 0G, 1G, 2G if x > zero then let t = one / (one + p * x) (one - c * exp( -x * x / two)* t * (t*(t*(t*(t*b5+b4)+b3)+b2)+b1)) else let t = one / (one - p * x) (c * exp( -x * x / two)* t * (t*(t*(t*(t*b5+b4)+b3)+b2)+b1)) 

Unfortunately, at this time I realized that some functions were marked as internal in the library and therefore were not disclosed, but I re-created them in a working example here so that you can test my function, which works well with float and float32 .

A new version will be released before the end of this year, but at the same time, you can fork it, delete the internals and compile it, or just re-create the functions, as I did in the linked example.

If you are interested in Generic Maths, feel free to contribute using code or usage.

+5
Nov 27 '14 at 22:06
source share



All Articles