Stan Schymanski wrote: > Dear all, > > Could anyone tell me how to controll the order in which arguments are > evaluated when they are passed to python functions? It seems that the > functions are evaluated first and then the variables are substituted, > which leads to failures in the following example: > > var('c') > > def piece(c,x): > if x < 1.: > return c*x^2 > if x >= 1.: > return 1/x-c > > plot(piece(0.2,x),0,2) > Traceback (click to the left for traceback) > ... > TypeError: no way to make fast_float from None > > numerical_integral(piece(0.2,x),0,2) > Traceback (click to the left for traceback) > ... > TypeError: a float is required > > How can I get sage to substitute the values for x before calling piece > (0.2,x)?
You are correct. In both of these cases, you are calling piece(0.2,x) and putting that result in for the first argument of plot and numerical_integral. Instead, you want the first argument to be a call to piece(0.2,x), so put a function in that returns piece, rather than putting piece in there that returns an expression. There are several ways to do this (these below are not comprehensive): Note that I define your function slightly more efficiently (I only compare x once) sage: def piece(c,x): ....: if x<1.: ....: return c*x^2 ....: else: ....: return 1/x-c ....: Now I put in the first argument a function which calls piece for every input value. sage: plot(lambda x: piece(0.2,x), 0, 2) Another way to do it is to use the partial function in the functools module. This basically does the same thing as above, but seems more efficient. sage: from functools import partial sage: piece02 = partial(piece, 0.2) sage: piece02(2) 0.300000000000000 sage: plot(piece02, 0, 2) Unfortunately, we haven't extended fast_float to handle an if statement, so fast_float won't work on the above example. Well, except that we could use fast_float inside of our piecewise function. sage: f1 = lambda x: piece(0.2,x) sage: f2 = partial(piece,0.2) sage: from sage.ext.fast_eval import fast_float sage: subf1 = fast_float(c*x^2, 'c', 'x') sage: subf2 = fast_float(1/x-c, 'c', 'x') sage: def piece_ff(c,x): ....: if x<float(1.0): ....: return subf1(c,x) ....: else: ....: return subf2(c,x) ....: sage: f1_ff = lambda x: piece_ff(0.2,x) sage: f2_ff = partial(piece_ff, float(0.2)) sage: f1_ff = lambda x: piece_ff(float(0.2),x) sage: timeit('[f1_ff(i) for i in range(-10r,10r)]') 625 loops, best of 3: 506 µs per loop sage: timeit('[f2_ff(i) for i in range(-10r,10r)]') 625 loops, best of 3: 287 µs per loop sage: timeit('[f1(i) for i in range(-10r,10r)]') 625 loops, best of 3: 904 µs per loop sage: timeit('[f2(i) for i in range(-10r,10r)]') 625 loops, best of 3: 707 µs per loop Jason --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-support@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-support URLs: http://www.sagemath.org -~----------~----~----~----~------~----~------~--~---