R2019A "Dirac" function is now slow
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
I noticed one of my scripts that repeatedly calls on a function containing MATLAB's dirac function now runs 100% slower compared to R2018b. After tracking down the reason, it seems the dirac function was updated in R2019A. Previously, it performed a check like this:
if ~isequal(round(n), n) || any(~isinfinite(n(:))) || ~isreal(n) || any(n(:) < 0)
error(message('symbolic:dirac:ExpectingNonNegativeInteger1'));
end
Now, the same lines of code read like this:
if ~isequal(round(n), n) || ~sym.isAllFinite(n(:)) || ~isreal(n) || any(n(:) < 0)
error(message('symbolic:dirac:ExpectingNonNegativeInteger1'));
end
The slowdown is being caused by the ~sym.isAllFinite(n(:)), where it appears to be calling on symengine every single one of my (8K+) iterations. Is there a way to speeed this up, or to revert back to previous functionality?
Of note, the function being called, which contains the dirac function, was originally generated using a symbolic derrivative, which was then converted to a matlab function using "matlabFunction".
Thanks!
2 comentarios
Walter Roberson
el 4 de Jun. de 2019
You could create a local copy of the function.
Somes it makes sense to replace dirac with piecewise and use matlabFunction with File output (matlabFunction cannot convert piecewise for anonymous functions.) This does restrict the input to be scalar, but on the other hand it can permit simplifications, sometimes large simplifications.
Or sometimes it just makes sense to transform x*dirac(expression) to (expression == 0).*x provided that x can never be infinity. This can be a bit tricky to do right automatically, but the new R2019a https://www.mathworks.com/help/symbolic/sym.mapsymtype.html can help. Still, sometimes it is just easier to matlabFunction with file output and edit the result to stick in an anonymous function that maps dirac to @(x) x==0
x == 0 (producing 0 or 1) is of course not the real way that dirac is defined: dirac is defined as returning infinity at 0. But dirac as used in practice in integration has an area of 1 at the one point, so value * dirac(expression) inside integration expresses that the contrabution when the expression is exactly 0 is the value and 0 at any other location.
dirac with matlabFunction gets a bit questionable since when processed numerically it contributes either 0 or infinity and infinity times whatever it is multiplied by is infinity and those infinities tend to "poison" the calculations. If you are using dirac() with integral() then you need to understand the limitations: if integral() does not happen to evaluate at exactly the matching value then there will be no contribution, and if it does evaluate at exactly the matching value you will get an infinity. integral() does not know anything about the special properties of dirac.
Respuestas (0)
Ver también
Categorías
Más información sobre Debugging and Analysis en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!