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.Fri, 30 Dec 2016 18:54:07 +0100Plotting 2d vector fields – how to delay function evaluationhttps://ask.sagemath.org/question/36127/plotting-2d-vector-fields-how-to-delay-function-evaluation/I want to plot, for example, the following 2d vector field:
$$\vec{F}(x,y)= \begin{cases}
(0.1,0.1), & \text{for }r\le d_{min}\newline
\frac{\vec{r}}{r^3}, & \text{otherwise}.
\end{cases}$$
In one SageMath cell I have defined corresponding Python function:
reset()
dmin = 0.03
def my_vector_field_2D(x,y):
vector_field = vector([0.1,0.1])
r = vector([x,y])
if r.norm()>dmin:
vector_field = 1/ r.norm()^3 * r
return vector_field
In another cell, I use function `plot_vector_field` to plot the field:
var('x','y')
plot_vector_field(my_vector_field_2D(x,y),(x,-0.3,0.3),(y,-0.3,0.3))
However, function my_vector_field_2D(x,y) is evaluated before it is given to the function `plot_vector_field` and because in this evaluation my_vector_field_2D receives instead of numbers symbolic variables `x` and `y`, expression `r.norm()>dmin` is always `False`. As a result, my_vector_field_2D(x,y) is evalueted to: (0.100000000000000, 0.100000000000000). So the plotted filed is actually $\vec{F}(x,y)=(0.1,0.1)$ everywhere and that is not what I want.
How can I prevent this function evaluation?
I tried something that works with the `plot` function (provide the `plot` function with just the name of a function that you want to plot (without parameters) in order to prevent function evaluation):
plot_vector_field(my_vector_field_2D,(-0.3,0.3),(-0.3,0.3))
But here this method does not work: **TypeError**: 'function' object is not iterable.
**My first why question**: Why this does not work? It works for `plot` function and also for `contour_plot` function and probably for some other plot functions.
Then I found in the SageMath documentation that “when plotting non-symbolic functions, they should be wrapped in `lambda`”. So I tried:
plot_vector_field(lambda x,y:my_vector_field_2D(x,y),(-0.3,0.3),(-0.3,0.3))
And the same error popped up: **TypeError**: 'function' object is not iterable.
But this works:
plot_vector_field((lambda x,y:my_vector_field_2D(x,y)[0],lambda x,y:my_vector_field_2D(x,y)[1]),(-0.3,0.3),(-0.3,0.3))
**My second why question**: Why do I need two `lambda` functions or why do I need to manually decompose vector returned by my_vector_field_2D function into its two components?
vkFri, 30 Dec 2016 18:54:07 +0100https://ask.sagemath.org/question/36127/Plot evaluation different than function evalutionhttps://ask.sagemath.org/question/11063/plot-evaluation-different-than-function-evalution/My sage input is
sage: eta, chi, omega, omega_n = var('eta chi omega omega_n')
sage: exp1=integrate(e**(-eta**2*chi**2/2)*e**(I*(omega_n - omega)*chi),(chi,-1,1))
sage: exp2 = e**(-(omega - omega_n)**2/(2*eta**2))
It turns out that exp1 is
$\newcommand{\Bold}[1]{\mathbf{#1}}-\frac{\sqrt{2} \sqrt{\pi} \text{ erf}\left(-\frac{\sqrt{2} \eta^{2} + i \sqrt{2} \omega - i \sqrt{2} \omega_{n}}{2 \eta}\right) e^{\left(-\frac{\omega^{2}}{2 \eta^{2}} + \frac{\omega \omega_{n}}{\eta^{2}} - \frac{\omega_{n}^{2}}{2 \eta^{2}}\right)}}{2 \eta} + \frac{\sqrt{2} \sqrt{\pi} \text{ erf}\left(\frac{\sqrt{2} \eta^{2} - i \sqrt{2} \omega + i \sqrt{2} \omega_{n}}{2 \eta}\right) e^{\left(-\frac{\omega^{2}}{2 \eta^{2}} + \frac{\omega \omega_{n}}{\eta^{2}} - \frac{\omega_{n}^{2}}{2 \eta^{2}}\right)}}{2 \eta}$
I wanted to check if exp2 can be used as an approximation of exp1.
Now suppose I choose to evaluate the absolute error
sage: N(abs((exp1-exp2).subs(omega=2**4,omega_n=0,eta=0.4)))
0.0321314939737044
This is what it should be. However if I plot it (choosing five points for simplicity)
sage: p1 = plot(abs((exp1-exp2).subs(omega=2**4,omega_n=0)),(eta,0,1),plot_points=5)
sage: list(p1[0])
[(0.0025,0.0),(0.148624441929,0.0),(0.347230931288,0.0),(0.396882553627,0.0),(0.446534175967,0.031240245935),(0.545837420646,0.0291057729397),(0.741443657239,0.0242243187304),(1.0,0.0172533234321)]
For some reason below about 0.41 the plot function evaluates it to 0, but a call like
sage: N(abs((exp1-exp2).subs(omega=2**4,omega_n=0,eta=0.0025)))
0.0359877559973356
shows that this is incorrect behavior.
Any idea why plot fails to evaluate this correctly for "small" values?
The larger omega is, the worse the cutoff is. That is, large omega means that the plot goes to 0 for even if eta is larger than 0.41 in general. For example choosing omega=2**5 gives a cutoff at about eta = 0.84, so that plot just puts zeros for eta < .84 in this case.KyleThu, 20 Feb 2014 19:33:02 +0100https://ask.sagemath.org/question/11063/