ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Mon, 10 Jan 2022 15:58:44 +0100fast_callable x numpyhttps://ask.sagemath.org/question/60600/fast_callable-x-numpy/`fast_callable` is very handy for evaluating symbolic expressions with numpy arrays. Like
my_expr = integral(sin(x),x)
f = fast_callable(my_expr, vars=[x])
import numpy as np
z = np.linspace(0,10,5)
f(z)
However, it does't work when the expression involves a special function.
my_expr2 = integral(sin(x^2),x)
g = fast_callable(my_expr2, vars=[x])
g(z)
Throws `The Function erf does not support numpy arrays as arguments`.
Is there any way of turn symbolic expressions containing special functions into numpy-callable? Thus avoiding to rewrite them using scipy special functions? Sun, 09 Jan 2022 22:18:27 +0100https://ask.sagemath.org/question/60600/fast_callable-x-numpy/Answer by Emmanuel Charpentier for <p><code>fast_callable</code> is very handy for evaluating symbolic expressions with numpy arrays. Like</p>
<pre><code>my_expr = integral(sin(x),x)
f = fast_callable(my_expr, vars=[x])
import numpy as np
z = np.linspace(0,10,5)
f(z)
</code></pre>
<p>However, it does't work when the expression involves a special function.</p>
<pre><code>my_expr2 = integral(sin(x^2),x)
g = fast_callable(my_expr2, vars=[x])
g(z)
</code></pre>
<p>Throws <code>The Function erf does not support numpy arrays as arguments</code>.</p>
<p>Is there any way of turn symbolic expressions containing special functions into numpy-callable? Thus avoiding to rewrite them using scipy special functions? </p>
https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?answer=60601#post-id-60601What about :
sage: import numpy
sage: my_exp=integral(sin(x),x)
sage: f=fast_callable(my_exp.substitute_function({sin:numpy.sin, cos:numpy.cos}), vars=[x])
sage: z=numpy.linspace(0,10,5)
sage: %time f(z)
CPU times: user 47 µs, sys: 0 ns, total: 47 µs
Wall time: 51.5 µs
array([-1. , 0.80114362, -0.28366219, -0.34663532, 0.83907153])
sage: lz=list(map(SR, z))
sage: time list(map(sin, lz))
CPU times: user 154 µs, sys: 0 ns, total: 154 µs
Wall time: 159 µs
[0,
0.5984721441039564,
-0.9589242746631385,
0.9379999767747389,
-0.5440211108893698]
A "general sage-numpy dictionary" could be prepared and used at will (could even be packaged or Sage patched to include it).
Alternativelty, `fast_callable` could be adapted to accept sage's equivalent of standard numpy functions, for example by buildind a Sage->numpy [ExpressionTreeWalker](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression_conversions.html. (a reveres numpy->Sage converter might be harder to build...)...
HTH,Mon, 10 Jan 2022 00:09:17 +0100https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?answer=60601#post-id-60601Comment by Emmanuel Charpentier for <p>What about :</p>
<pre><code>sage: import numpy
sage: my_exp=integral(sin(x),x)
sage: f=fast_callable(my_exp.substitute_function({sin:numpy.sin, cos:numpy.cos}), vars=[x])
sage: z=numpy.linspace(0,10,5)
sage: %time f(z)
CPU times: user 47 µs, sys: 0 ns, total: 47 µs
Wall time: 51.5 µs
array([-1. , 0.80114362, -0.28366219, -0.34663532, 0.83907153])
sage: lz=list(map(SR, z))
sage: time list(map(sin, lz))
CPU times: user 154 µs, sys: 0 ns, total: 154 µs
Wall time: 159 µs
[0,
0.5984721441039564,
-0.9589242746631385,
0.9379999767747389,
-0.5440211108893698]
</code></pre>
<p>A "general sage-numpy dictionary" could be prepared and used at will (could even be packaged or Sage patched to include it).</p>
<p>Alternativelty, <code>fast_callable</code> could be adapted to accept sage's equivalent of standard numpy functions, for example by buildind a Sage->numpy [ExpressionTreeWalker](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression_conversions.html. (a reveres numpy->Sage converter might be harder to build...)...</p>
<p>HTH,</p>
https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?comment=60605#post-id-60605That amounts to completing `sympy` with your definitions of "misssing" function. Not a small undertaking...
Numerical analysis is a bitch, and [DLMF](https://dlmf.nist.gov/) (née Abramowitz and Stegun) is your friend...Mon, 10 Jan 2022 10:17:31 +0100https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?comment=60605#post-id-60605Comment by cav_rt for <p>What about :</p>
<pre><code>sage: import numpy
sage: my_exp=integral(sin(x),x)
sage: f=fast_callable(my_exp.substitute_function({sin:numpy.sin, cos:numpy.cos}), vars=[x])
sage: z=numpy.linspace(0,10,5)
sage: %time f(z)
CPU times: user 47 µs, sys: 0 ns, total: 47 µs
Wall time: 51.5 µs
array([-1. , 0.80114362, -0.28366219, -0.34663532, 0.83907153])
sage: lz=list(map(SR, z))
sage: time list(map(sin, lz))
CPU times: user 154 µs, sys: 0 ns, total: 154 µs
Wall time: 159 µs
[0,
0.5984721441039564,
-0.9589242746631385,
0.9379999767747389,
-0.5440211108893698]
</code></pre>
<p>A "general sage-numpy dictionary" could be prepared and used at will (could even be packaged or Sage patched to include it).</p>
<p>Alternativelty, <code>fast_callable</code> could be adapted to accept sage's equivalent of standard numpy functions, for example by buildind a Sage->numpy [ExpressionTreeWalker](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression_conversions.html. (a reveres numpy->Sage converter might be harder to build...)...</p>
<p>HTH,</p>
https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?comment=60608#post-id-60608I see, thanks!Mon, 10 Jan 2022 15:58:44 +0100https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?comment=60608#post-id-60608Comment by cav_rt for <p>What about :</p>
<pre><code>sage: import numpy
sage: my_exp=integral(sin(x),x)
sage: f=fast_callable(my_exp.substitute_function({sin:numpy.sin, cos:numpy.cos}), vars=[x])
sage: z=numpy.linspace(0,10,5)
sage: %time f(z)
CPU times: user 47 µs, sys: 0 ns, total: 47 µs
Wall time: 51.5 µs
array([-1. , 0.80114362, -0.28366219, -0.34663532, 0.83907153])
sage: lz=list(map(SR, z))
sage: time list(map(sin, lz))
CPU times: user 154 µs, sys: 0 ns, total: 154 µs
Wall time: 159 µs
[0,
0.5984721441039564,
-0.9589242746631385,
0.9379999767747389,
-0.5440211108893698]
</code></pre>
<p>A "general sage-numpy dictionary" could be prepared and used at will (could even be packaged or Sage patched to include it).</p>
<p>Alternativelty, <code>fast_callable</code> could be adapted to accept sage's equivalent of standard numpy functions, for example by buildind a Sage->numpy [ExpressionTreeWalker](https://doc.sagemath.org/html/en/reference/calculus/sage/symbolic/expression_conversions.html. (a reveres numpy->Sage converter might be harder to build...)...</p>
<p>HTH,</p>
https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?comment=60603#post-id-60603For expressions with only elementary functions, there is no need of `substitute_function`. A callable function (or `fast_callable`) does the job.
-cos(z)
array([-1. , 0.80114362, -0.28366219, -0.34663532, 0.83907153])
The problem are the special functions. `erf` in my minimal example. But the sage-numpy dictionary and `substitute_function` simplify the hard work. Thanks!!
I had a look at the documentation for expression conversion, but it not clear for me how to implement a general Sage->numpy conversion.Mon, 10 Jan 2022 02:52:47 +0100https://ask.sagemath.org/question/60600/fast_callable-x-numpy/?comment=60603#post-id-60603