# Unable to Simplify to Float Approximation for a Numerical Integral

Hello,

I'm trying to approximate a curve, here is my code:

a = 1        # x radius length
b = 1        # y radius length
cut = pi/4   # angle of plane

theta = var('theta')
phi = var('phi')
diffx = diff(a*cos(theta), theta)
diffy = diff(b*sin(theta), theta)
func = (diffx^2+diffy^2)^(1/2)

def getnumerical(i):
approx = numerical_integral(func, 0, i)
return approx

parametric_plot((getnumerical(phi), b*sin(phi)*tan(cut)), (phi, 2*pi, 4*pi), aspect_ratio = 1)


The integral defining the x term in the parametric plot is elliptic, so it must be numerically approximated. So far, I have had little success getting any numerical integral methods to work, including nintegral, and am frustrated because I cannot discern the problem. This implementation gives the error:

Traceback (most recent call last):
File "", line 1, in <module>

File "/tmp/tmpDAHxNF/___code___.py", line 17, in <module>
exec compile(u'parametric_plot((getnumerical(phi), b*sin(phi)*tan(cut)), (phi, _sage_const_2 *pi, _sage_const_4 *pi), aspect_ratio = _sage_const_1 )
File "", line 1, in <module>

File "/tmp/tmpDAHxNF/___code___.py", line 14, in getnumerical
approx = numerical_integral(func, _sage_const_0 , i)
File "sage/gsl/integration.pyx", line 332, in sage.gsl.integration.numerical_integral (build/cythonized/sage/gsl/integration.c:3159)
File "sage/symbolic/expression.pyx", line 1177, in sage.symbolic.expression.Expression.__float__ (build/cythonized/sage/symbolic/expression.cpp:8897)
TypeError: unable to simplify to float approximation


Edit: With the constants defined as they currently are, this should plot a sine wave.

edit retag close merge delete

Sort by » oldest newest most voted

The problem is this:

sage: getnumerical(phi)
TypeError: unable to simplify to float approximation


Since you are giving this expression as a parameter, you get this error before the integration code ever comes into play. You need to delay the actual evaluation of the numerical integral code until you're actually passing it numerical data. You've already done the required work. This works:

sage: parametric_plot((getnumerical, b*sin(phi)*tan(cut)), (phi, 2*pi, 4*pi), aspect_ratio = 1)


The interface for parametric_plot gets confusing because on one hand it requires a symbolic variable specification in its range specification, but the coordinates of the point specification does not need to be symbolic, and in your case is hard to express. What should have worked but doesn't is:

sage: I=integral(func(theta),0,phi,hold=True)
sage: parametric_plot((I, b*sin(phi)*tan(cut)), (phi, 2*pi, 4*pi), aspect_ratio = 1)

more

Well... this is really quite confusing. I don't completely understand how getnumerical gets passed a value to be plotted, but I think it's just my unfamiliarity with python; I don't find myself using it often. I appreciate the help, I'm really glad it works now!

Well, the thing that isn't confusing is that what you did try originally doesn't work. You can see from the error traceback what happens there and that parametric_plot doesn't even come into play. The confusing part is how to construct your input in a way that does work. And for that, the current input design doesn't help much, because the interface is tied too much to symbolic expressions.