Ask Your Question

creating a group of similar functions with similar names

asked 2012-06-02 08:26:12 -0500

daniel.e2718 gravatar image

updated 2012-06-02 09:04:25 -0500

namelist = ['f'+str(i) for i in range(10)]; namelist
for i in range(len(namelist)):
    namelist[i] = lambda x: 1/x^i

1 - create a list of function names (f0, f1, f2, ...)

2 - for each item in namelist

3 - take that that item and make it a function that raises x to a negative power equal to the position of that item (f0(x) = 1/x^0, f1(x) = 1/x^1, ...)

Is this possible?


Made some progress by changing the type of namelist[i] to Expression by var(i)...

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2012-06-02 10:48:23 -0500

DSM gravatar image

updated 2012-06-02 13:53:03 -0500

You're hitting a lot of subtle bits about the way Sage's type system works. There are at least three types of function-like things:

Sage Expressions -- not functions, but you can substitute into them, so it's not entirely unlike one -- which live in the Symbolic Ring:

sage: x = var("x")
sage: f = 1/x^3
sage: f
sage: parent(f)
Symbolic Ring
sage: f.subs(x=3)
sage: f(x=3)

Sage functions:

sage: g(x) = 1/x^3
sage: parent(g)
Callable function ring with arguments (x,)
sage: g(3)

and Python functions (including lambdas):

sage: def h(x): return 1/x^3
sage: parent(h)
<type 'function'>
sage: h(3)

Where possible, it's usually desirable to stick with the Sage objects because they have lots of useful methods inside them whereas the Python functions don't.

You seem to be trying to make a number of objects which have names like 'f0', 'f1', 'f2', etc, and put them into the namespace. You could do that, but it's generally a bad idea, so I won't explain how. The usual rule is "Don't put your data in variable names!"

It's easy to make a list of Expressions or Sage functions instead:

sage: fs = [1/x^i for i in range(10)]
sage: fs
[1, 1/x, x^(-2), x^(-3), x^(-4), x^(-5), x^(-6), x^(-7), x^(-8), x^(-9)]
sage: fs[3]
sage: fs[3](3)

sage: gs = [(1/x^i).function(x) for i in range(10)]
sage: gs
[x |--> 1, x |--> 1/x, x |--> x^(-2), x |--> x^(-3), x |--> x^(-4), x |--> x^(-5), x |--> x^(-6), x |--> x^(-7), x |--> x^(-8), x |--> x^(-9)]
sage: gs[3](x=3)

Note that I've used the .function syntax to inline what "g(x)=1/x^3" does.

edit flag offensive delete link more


Thanks again for a detailed response! You've helped me realize (though I already knew) that I know very little about programming and such. The more you know, the more you know you don't know...

daniel.e2718 gravatar imagedaniel.e2718 ( 2012-06-02 13:31:41 -0500 )edit

Thank you, @DSM, for the extremely useful explanation. I do have a follow-up question. How do you classify functions defined with the piecewise command. This seems to be a separate class. When I use the parent() command on a piecewise function, Sage says it is an "instance." Can you help me understand what that means? Thanks!

calc314 gravatar imagecalc314 ( 2012-06-06 16:01:14 -0500 )edit

@calc314: if you have a followup, please make it a separate question-- that way lots of people who can answer will see it. It's easy to miss questions buried in comments. :^)

DSM gravatar imageDSM ( 2012-06-07 03:13:10 -0500 )edit

Will do! Thanks for your patience...I'm still learning the etiquette for this question/answer system.

calc314 gravatar imagecalc314 ( 2012-06-07 08:28:44 -0500 )edit

answered 2012-06-02 10:39:26 -0500

niles gravatar image

Do you really not want to just have a function of two variables, such as the following?

sage: def f(i,x):                   
....:     return x^(-i)

sage: f(2,2)
sage: f(3,2)

I think there is some problem with making a list of lambda functions, but you could use the idea of a "factory" -- a function that returns another function:

sage: def named_function_factory(i):
....:     def f(x):
....:         return x^(-i)
....:     return f
sage: functionlist = [named_function_factory(i) for i in range(10)]
sage: functionlist[2](2)
sage: functionlist[3](2)

But note that this is really not so different from just using a function of two variables, i and x, so maybe I still haven't answered your question. But I also don't see an appreciable difference between typing "functionnamei(x)" and "functionname[i](x)" or "functionname(i,x)" for that matter. These are of course quite different in terms of their data types, but is that so significant here?

edit flag offensive delete link more


I see what you mean regarding "functionnamei(x)", "functionname[i](x)", about "functionname(i,x)." I think I ask questions a bit prematurely... haha. Thanks anyway!

daniel.e2718 gravatar imagedaniel.e2718 ( 2012-06-02 13:37:17 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2012-06-02 08:26:12 -0500

Seen: 152 times

Last updated: Jun 02 '12