Symbolic differentiation with CDF function

My code is as below:


using SymEngine, Distributions

dist = Normal(0, 1)

    
    V = PTB*cdf(dist, 1/SP*log(PTB/(K*PTB))+SP/2) - K*PT0*cdf(dist, 1/SP*log(PTB/(K*PTB))-SP/2)

    diff(V, PTB)

I got the error message:


ERROR: MethodError: no method matching cdf(::Distributions.Normal{Float64}, ::SymEngine.Basic)

I’d follow an issue there, or look into how you can add the appropriate methods yourself.
The derivative should of cdf(dist, g(x)) with respect to x should of course be pdf(dist, g(x))*g'(x), so I’d expect it to be pretty straightforward to support Distributions.jl.

Can you be more specific?

What is your problem?

  1. Do you want an answer to the specific code you posted?
  2. Do you want some algorithm that takes many derivatives of the sort you posted?
  3. Or do you want to get SymEngine.jl to support Distributions.jl?
  4. Other?

I don’t know the implementation details of SymEngine, but if it is β€œ3.”, I would start by looking here:
https://github.com/symengine/SymEngine.jl/blob/master/src/mathfuns.jl

If it is β€œ2.”, I would just drop the dependency on Distributions, and use SpecialFunctions instead. Eg, the cdf of a normal distribution is just (1+erf((x-mu)/sigma*sqrt(2)))/2.

This could also work for β€œ2”, depending on the algorithm, but definitely in case of β€œ1”, it’d probably be easier to just apply the chain rule. Ie, you can find the derivative of

d = diff(1/SP*log(PTB/(K*PTB))+SP/2,PTB) 
@assert d == diff(1/SP*log(PTB/(K*PTB))-SP/2,PTB)

and just find

cdf(dist, 1/SP*log(PTB/(K*PTB))+SP/2) + PTB*pdf(dist, 1/SP*log(PTB/(K*PTB))+SP/2)*d -  K*PT0*df(dist, 1/SP*log(PTB/(K*PTB))-SP/2)*d
1 Like

Thanks for your reply. I was wondering if SymEngine enables symbolic integration, if that it does, then I can hand code pdf and use symbolic integration to create cdf.