Hi Jason,
Thanks a lot for that! This brings me back to the original problem. I
expected plot and find_root to replace the variable with a float and
call the function, but it does not seem to do that. For example, it
would be nice if the following worked:
var('a b c d x dummy')
F = fast_float(a*x^3 + b*x^2 + c*x + d, 'a', 'b', 'c', 'd', 'x')
ff = lambda a,b,c,d,x: F(a,b,c,d,x)
plot(ff(a=1,b=2,c=3,d=4,x=dummy),(dummy,0,6))
Traceback (click to the left for traceback)
...
TypeError: a float is required
This works:
[ff(a=1,b=2,c=3,d=4,x=dummy) for dummy in srange(6)]
[4.0, 10.0, 26.0, 58.0, 112.0, 194.0]
Why don't plot and find_root just replace 'dummy' with a float and run
ff just like in the list?
The example taken from your post:
ff = partial(lambda a,b,c,d,x: F(a,b,c,d,x), a=1,b=2,d=5,x=-2)
ff(c=3)
-1.0
plot(ff,(c,0,3))
verbose 0 (2949: plot.py, generate_plot_points) WARNING: When plotting,
failed to evaluate function at 400 points.
verbose 0 (2949: plot.py, generate_plot_points) Last error message:
'<lambda>() got multiple values for keyword argument 'a''
However, implicit calling works (the other example from you post):
gg = partial(lambda a,b,c,d,x: F(a,b,c,d,x), 1,2,d=5,x=-2)
gg(3)
-1.0
plot(gg,-1,1)
<plots fine>
I hoped that the lambda function would provide a way for using
fast_float with explicit variable calling, but it did not work out. Do
you know of another way? This is especially important for find_root as
it makes it sooo much faster.
Anyway, your suggestions helped a lot already and I can solve my current
problems now.
Cheers,
Stan
Jason Grout wrote:
> Stan Schymanski wrote:
>
>> Hi Jason,
>>
>> That's awesome, thanks a lot! I had a bit of trouble understanding the
>> documentation of partial, but your example helped tremendously. This
>> should definitely be included in any upcoming documentation on
>> fast_float. As far as I understand, partial(F,1) just replaces the first
>> variable in F by 1. If I define something like F = fast_float(a*x^3 +
>> b*x^2 + c*x + d, 'a', 'b', 'c', 'd', 'x'), could I then use partial to
>> replace a, b, d and x and leave c as a variable, or would I have to
>> re-define F to take c as the last argument?
>>
>>
>
> Apparently fast_float things don't take keyword arguments, so you have
> to use a lambda function (that will take keyword arguments) to put
> things in the right order.
>
> sage: var('a,b,c,d,x')
> (a, b, c, d, x)
> sage: F = fast_float(a*x^3 + b*x^2 + c*x + d, 'a', 'b', 'c', 'd', 'x')
> sage: ff=partial(lambda a,b,c,d,x: F(a,b,c,d,x), a=1,b=2,d=5,x=-2)
> sage: ff(c=3)
> -1.0
>
> alternatively, since arguments to gg (below) are just appended to the
> non-keyword arguments, you can have one "hole" in the non-keyword
> arguments. To have more than this, you need to do something more special.
>
> sage: gg=partial(lambda a,b,c,d,x: F(a,b,c,d,x), 1,2,d=5,x=-2)
> sage: gg(3)
> -1.0
>
>
> It would be nice (and pretty straightforward to write) a partial
> function that took a dictionary like:
>
> partial(f, {0: 10, 'x': 3, 2: 20})
>
> which would make a function that behaved like:
>
> f(10, *, 20, *args, x=3)
>
> (i.e., the keys above are the places in the non-keyword arguments; since
> we don't have a value specified for the position 1 in the non-keyword
> arguments, it is left blank.) Then your example above would be
> something like:
>
> sage: ff=partial(F, {0:1, 1: 2, 4: 5, 5: -2})
> sage: ff(3)
> -1.0
>
> Thanks,
>
> Jason
>
>
>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---