Search code examples
matlabsymbolic-math

How to define cumulative normal distribution using symbolic math


I have the following code in MATLAB

x=sym('x',[1 2]);
DV=x(1)*ED+x(2);
sv=x(1)*DV;
DD=DV./sv;
p=normcdf(-DD);

where DV and ED are both 13242 x 1 vectors. Up to DD all it is ok. When i define p as above, i obtain this message:

Error using symfun>validateArgNames (line 205)

Second input must be a scalar or vector of unique symbolic variables.

When i define p=1./(1+exp(-DD)) all it is ok. So there is a problem with normcdf.

Any idea?

Regards


Solution

  • normcdf, like most of the functions in the Statistics toolbox, does not support symbolic input. The documentation does not make this clear and I agree that the error message is extremely useless (you might contact MathWorks and file a service request about this to suggest that they add support for symbolic math to the Statistics toolbox).

    The normcdf function doesn't do anything magical. You can use p = 0.5*erfc(DD./sqrt(2)) in place of p = normcdf(-DD). This will also be faster. Type edit normcdf in your command to see the code for the function. There's lots of error checking and cases specific to floating-point which is why the function errors with symbolic inputs.

    Another option is to use MuPAD's stats::normalCDF from within Matlab (this function might only be supported in recent releases). For example:

    x = sym('x',[1 2]);
    ED = ones(1,3);
    DV = x(1)*ED+x(2);
    sv = x(1)*DV;
    DD = DV./sv;
    DDstr = char(-DD);
    p = evalin(symengine, ['f:=stats::normalCDF(0,1):map(' DDstr(9:end-2) ',x->f(x))'])
    

    where f defines a procedure implementing a symbolic normal CDF with mean 0 and variance 1. MuPAD's map function is also used to vectorize this. All in all, this option is probably not necessary.