Conversation
The local variable `z` is by construction non-negative and the linear case gives `y = 0` for `z = 0`. This makes the symbolic derivative of `erf` continuous around zero.
|
@phannebohm did you sign and re-check the CLA? Thanks! |
|
I asked Claude 4.6 Sonnet (free version; clause.ai), and Claude gave a very detailed answer and especially the Modelica package erf_with_derivative.mo (attached as erf_with_derivative.txt)
I simulated in OpenModelica and got the following plot which looks good. der(y) = er(sin(time)) from OpenModelica/OpenModelica#15118 (comment) works also without problems. I asked Claude to provide a better implementation of Modelica.Math.Special.erf and after a while, Claude provided file Erfimpl.mo (attached as ErfImpl.txt). Claude states:
I quickly checked with OpenModelica and this looks good (but more operations as Modelica.Math.Special.erf, not clear whether this is needed). I do not have time to provide a proper pull request, with documentation and test model included in ModelicaTest. Hopefully, someone else can do it (the quickest solution is to just add erf_derivative(..) from file erf_derivative.txt to MSL, include the derivative annotation to erf(..) and add ErfDemo to ModelicaTest and adapt the documentations). |
|
@MartinOtter I think your comment belongs rather to #4753 - here I provided a full PR (without Claude). |
I agree, but to me the function could be simplified further. The proposed improvement has: I can understand that 1.125 and 0.003379167095512573896158903121545171688 (from the original) are computed differently - but adding them to generate would be straightforward, and avoids having to check if there was any error in the code. |
|
I fixed the constant in the linear approximation, as suggested by @HansOlsson, and I computed a better error bound for that case as well, the relative error in the Maclaurin series is actually below machine precision until I also cleaned up the formatting and simplified the nested cases for |
|
Oh, so |
|
@phannebohm I'm not sure I get the point of this PR. The original motivation was to avoid getting a bad symbolic derivative close to zero. As I understand, erf is the integral of a gaussian function. As such, it is not computable in closed form, so we resort to smart approximation functions. But it doesn't really make sense to rely on symbolic differentiation in this case, since the derivative is known analytically and is very simple. Bottom line, I think what is really needed to get a good derivative is to add a derivative annotation. Do you agree? |
Absolutely! As you say the better solution for that problem is #4753. So the remaining purpose for this PR is to simplify, and potentially clarify the smart approximation for erf. |
Yes, and I assume we all agree on this, but just wanted it stated:
Trying to differentiate a function like erf without smoothOrder annotation is error-prone; as automatic differentiation for the original variant would have given incorrect results at 0, and here you have a nice closed form for the derivative - which can just be used. |
|
@phannebohm pls. wait until #4753 is merged and pull those changes to your PR: |
I think github is able to tell if the changes overlap and in that case it does not allow merging before the conflicts are resolved. |

The local variable
zis by construction non-negative and the linear case givesy = 0forz = 0.This makes the symbolic derivative of(No longer relevant as soon as #4753 is merged.)erfcontinuous around zero.This simplifies the algorithm and clarifies the constant values.