# Problem using Compiled Function within NProbability

I've built a very simple function to estimate the probability for a Long Straddle (derivative strategy) to be positive at expiration.

derivativeStrategyLongStraddle[currentPrice_, strikePrice_?NumberQ,
Max[0, currentPrice - strikePrice] - callPremium +
Max[0, strikePrice - currentPrice] - putPremium;

r= NProbability[derivativeStrategyLongStraddle[x, 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763]]


0.575516

Now, I want to accelerate this by compiling my simple derivativeStrategyLongStraddle function.

derivativeStrategyLongStraddleCompiled =
Max[0, currentPrice - strikePrice] - callPremium +
Max[0, strikePrice - currentPrice] - putPremium,
RuntimeAttributes -> {Listable}]


But I get the following error message when I try to run:

rC= NProbability[derivativeStrategyLongStraddleCompiled[x, 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763]]


CompiledFunction::cfsa: Argument x at position 1 should be a machine-size real number. >>

0.575516

Any idea why? It's the first time I use Compile so I might be missing obvious!

Xavier

Update. I've tried using N but get the same error message. How do I fix that?

rC= NProbability[derivativeStrategyLongStraddleCompiled[N[x], 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763]]

• See http://mathematica.stackexchange.com/a/55484/18476 on how to prohibit symbolic evaluation for your compiled function. Commented Oct 19, 2014 at 10:37
• Thanks. I'll try and let you know if it fixed the problem. Commented Oct 19, 2014 at 10:49
• I've tried "RuntimeOptions -> {"EvaluateSymbolically" -> False}and it adds more error messages, so really doesn't fix my problem. I've tried "RuntimeOptions -> {"WarningMessages"->False} and removes the error message but doesn't fix the problem. Any other ideas? Commented Oct 19, 2014 at 13:56

If you use an intermediate function as demonstrated in this answer, you'll get rid of all error messages that are related to the symbolic evaluation:

derivativeStrategyLongStraddleCompiled2[currentPrice_?NumberQ,


Unfortunately, you'll get new error messages when you evaluate

NProbability[derivativeStrategyLongStraddleCompiled2[x, 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763]]

NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration is 0, highly oscillatory integrand, or WorkingPrecision too small. >>
NIntegrate::ncvb: NIntegrate failed to converge to prescribed accuracy after 9 recursive bisections in x near {x} = {41.1848}. NIntegrate obtained 0.5773068754042155 and 0.040915146726462764 for the integral and error estimates. >>

0.577307


You can get rid of the last one by increasing MaxRecursion

NProbability[derivativeStrategyLongStraddleCompiled2[x, 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763],
Method -> {"NIntegrate", MaxRecursion -> 30}]

NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration is 0, highly oscillatory integrand, or WorkingPrecision too small. >>

0.575516


As this gives you the correct result, you might just switch the error message off using

Off[NIntegrate::slwcon]


By changing the Method to "MonteCarlo" you get rid of all error messages:

NProbability[derivativeStrategyLongStraddleCompiled2[x, 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763],
Method -> "MonteCarlo"]

0.575254


However, the result might vary for each evaluation.

When using the Monte Carlo method, the intermediate function isn't needed anymore and one can use

derivativeStrategyLongStraddleCompiled3 =
Max[0, currentPrice - strikePrice] - callPremium +
Max[0, strikePrice - currentPrice] - putPremium,
RuntimeAttributes -> {Listable}, RuntimeOptions -> {"EvaluateSymbolically" -> False}]

NProbability[derivativeStrategyLongStraddleCompiled3[x, 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763],
Method -> "MonteCarlo"]

0.575254


## Update:

If you exclude the points where derivativeStrategyLongStraddleCompiled2 == 0 everything works smooth:

NProbability[derivativeStrategyLongStraddleCompiled2[x, 39, 2.38, 0.02] >= 0,
x \[Distributed] NormalDistribution[41.57339177753672, 0.9105010291072763],
Method -> {"NIntegrate", Exclusions -> {39 + 2.38 + 0.02, 39 - 2.38 - 0.02}}]

0.575516

• @Xavier see my update for a real solution, instead of the workarounds. Commented Oct 20, 2014 at 7:13
• I like that!! Thanks! Commented Oct 21, 2014 at 8:06