[sage-support] Re: Weaning
On Dec 7, 2007 10:39 PM, pgdoyle <[EMAIL PROTECTED]> wrote: > > Please quite loudly tell us *everything* you are going to miss from > > Mathematica. We want to know! > > > > I can tell some things that I know how to do in Mathematica but don't > know how to do in sage. > Here are two such for starters. > > 1. ListPlot > http://reference.wolfram.com/mathematica/ref/ListPlot.html > > The function ListPlot plots a list of numbers, or ordered pairs of > numbers. So to illustrate the central limit theorem > we can simply write: > > Table[Sum[Random[],{10}],{1000}]//Sort//ListPlot > > This generates 1000 sums X_1+...+X_10, with X_i uniform in the unit > interval; sorts these sums; and then plots the resulting list, > giving a very convincing graph (turned on its side) of the cumulative > distribution for a Gaussian random variable. In Sage you use the command "list_plot". The person -- Alex Clemesha -- who wrote the 2d plotting interface in Sage really likes Mathematica, so he modeled much of the plotting on the function names in mathematica. To do the above example in Sage, do this: sage: show(list_plot(sorted([sum([random() for _ in [1..10]]) for _ in [1..1000]]))) > 2. Listable > http://reference.wolfram.com/mathematica/ref/Listable.html > > The attribute Listable enables automatic threading over lists, > including nested lists and specifically matrices. > > In[15]:= N[{{1,2},{3,4}}] > > Out[15]= {{1., 2.}, {3., 4.}} > > In[16]:= Log[{{1,2},{3,4}}] > > Out[16]= {{0, Log[2]}, {Log[3], Log[4]}} > > In[24]:= barf[{{1,2},{3,4}}] > > Out[24]= barf[{{1, 2}, {3, 4}}] > > In[25]:= SetAttributes[barf,Listable] > > In[26]:= barf[{{1,2},{3,4}}] > > Out[26]= {{barf[1], barf[2]}, {barf[3], barf[4]}} > I think Sage doesn't have that exactly, though you can do something similar with matrices: sage: v = matrix([[1,2], [3,4]]) sage: v.apply_map(N) [1.00 2.00] [3.00 4.00] sage: matrix([[1,2],[3,4]]).apply_map(log) [ 0 log(2)] [log(3) log(4)] I think it would be pretty easy to write a Python function that does what you describe above though, and add it to sage. It could be called map_thread, since Python has a map function and this would just be an extension of it: sage: map(log, [1,2,3,e]) [0, log(2), log(3), 1] sage: map_threaded(log, [[1,2], [3,e]] # pseudo-code [[0, log(2)], [log(3), 1]] OK, actually this was easy to write in one line: def map_threaded(function, sequence): return [map_threaded(function, x) if isinstance(x, (list, tuple)) else function(x) for x in sequence] (This will go into Sage soon unless there are big objections -- I agree that it seems like a very useful thing to have for amthematics!) Sorry if this is too obfuscated -- i.e., using a conditional expression and list comprehension -- all this talk of Mathematica is making me prone to write incomprehensible code! -- William --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
> In[16]:= Log[{{1,2},{3,4}}] > > Out[16]= {{0, Log[2]}, {Log[3], Log[4]}} > Well, actually this would be a good example of when the Listable runs amok, since this isn't giving the Log of the matrix as one might expect. Another example along this line is multiplication of matrices: In[28]:= {{1,1},{1,0}} * {{1,1},{1,0}} Out[28]= {{1, 1}, {1, 0}} In[29]:= {{1,1},{1,0}} . {{1,1},{1,0}} Out[29]= {{2, 1}, {1, 1}} Still, the ability to thread an operation over lists can be pretty handy. Cheers, Peter --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
> > Please quite loudly tell us *everything* you are going to miss from > Mathematica. We want to know! > I can tell some things that I know how to do in Mathematica but don't know how to do in sage. Here are two such for starters. 1. ListPlot http://reference.wolfram.com/mathematica/ref/ListPlot.html The function ListPlot plots a list of numbers, or ordered pairs of numbers. So to illustrate the central limit theorem we can simply write: Table[Sum[Random[],{10}],{1000}]//Sort//ListPlot This generates 1000 sums X_1+...+X_10, with X_i uniform in the unit interval; sorts these sums; and then plots the resulting list, giving a very convincing graph (turned on its side) of the cumulative distribution for a Gaussian random variable. 2. Listable http://reference.wolfram.com/mathematica/ref/Listable.html The attribute Listable enables automatic threading over lists, including nested lists and specifically matrices. In[15]:= N[{{1,2},{3,4}}] Out[15]= {{1., 2.}, {3., 4.}} In[16]:= Log[{{1,2},{3,4}}] Out[16]= {{0, Log[2]}, {Log[3], Log[4]}} In[24]:= barf[{{1,2},{3,4}}] Out[24]= barf[{{1, 2}, {3, 4}}] In[25]:= SetAttributes[barf,Listable] In[26]:= barf[{{1,2},{3,4}}] Out[26]= {{barf[1], barf[2]}, {barf[3], barf[4]}} Cheers, Peter --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
On Dec 7, 10:17 pm, "Mike Hansen" <[EMAIL PROTECTED]> wrote: > I think what confusing is the following: > > In[1]:= Pi // N > Out[1]= 3.14159 > In[2]:= Pi // N + 2 > Out[2]= (2 + N)[Pi] > > What does it mean in Mathematica to add 2 to N? Does it just treat N > as a formal symbol when you add 2 to it N? Mathematica leaves (2+N)[Pi] alone because it has no rule for simplifying (a+b)[x]. Let's tell it to do the sensible thing: In[6]:= (a_+b_)[args___]:=a[args]+b[args] SetDelayed::write: Tag Plus in ((a_) + (b_))[args___] is Protected. Out[6]= $Failed This didn't work, because we're trying to muck around with the way Mathematica understands addition, which could be a very bad idea. However, let's live dangerously: In[7]:= Unprotect[Plus] Out[7]= {Plus} In[8]:= (a_+b_)[args___]:=a[args]+b[args] In[9]:= (2+N)[Pi] Out[9]= 3.14159 + 2[Pi] Mathematica doesn't know how to interpret 2[Pi], so it leaves it at that. In Mathematica, you can write what looks like code in a procedural language, but Mathematica will `run' it by repeatedly simplifying the input until it becomes the output. The whole shebang works using simplification rules. Cheers, Peter --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
Mike Hansen wrote: >> It means 5.+N applied to 5.85987. (In Mathematica f[x] is how you >> would express applying f to x). > > I think what confusing is the following: > > In[1]:= Pi // N > Out[1]= 3.14159 > In[2]:= Pi // N + 2 > Out[2]= (2 + N)[Pi] > > What does it mean in Mathematica to add 2 to N? Does it just treat N > as a formal symbol when you add 2 to it N? I believe that is right, it is treating N as a formal symbol. We discussed things like this when you wrote the patch to handle stuff like (sin+1)(x), I believe. Literally, Mathematica views the above as Plus[2,N][Pi] (i.e., the plus function applied to 2 and the symbol N, applied then to Pi): In[2]:= Pi // N+2 // FullForm Out[2]//FullForm= Plus[2, N][Pi] In practice, I have never used something like Pi//N+2. I've always used the // operator with a function (or a lambda function) following it: Pi // N[#,20]& creates a lambda function, where # represents the argument and the & marks the end of the function definition. This would print Pi out to 20-digit precision. Using // also works very nicely as chains of function applications (i.e., composition with postfix notation). It's very natural to me to think of taking an object, then doing this to it, then doing that to the result, etc. As a contrived example: (x^2 - 2)^2 // D[#, x] & // Solve[# == 0, x] & takes (x^2-2)^2, takes the first derivative with respect to x, and then solves for where that derivative is equal to zero. To have the same flow in Sage, we could write: ((x^2-2)^2).diff().solve('x') This works fine if you have member functions diff and solve, but if you don't or want to apply your own function, you can't use this postfix-ish style. This postfix notation is something I've found extremely convenient in Mathematica and is something that I miss a lot as well. I find that it is easier to experiment and try new things when I can build up an expression bit by bit by appending new operations. I've resolved in my mind that we can do the same sort of thing in Sage by just creating an object and acting on it on successive lines. It doesn't feel as fast or as natural, but it's probably more readable and maintainable in the end. This issue has also come up before on the mailing list, where someone mentioned that they missed being able to do a long calculation and then double-checking the algebraic result by just putting a "// N" at the very end. They concluded that in Sage, enclosing the entire thing in parentheses and putting ".n()" (to call the numeric approximation function) was almost as easy. It would be nice if we had a way to invoke a function with prefix or postfix notation in Sage. Whether or not this breaks too far from python syntax should probably be discussed, though. -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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
> It means 5.+N applied to 5.85987. (In Mathematica f[x] is how you > would express applying f to x). I think what confusing is the following: In[1]:= Pi // N Out[1]= 3.14159 In[2]:= Pi // N + 2 Out[2]= (2 + N)[Pi] What does it mean in Mathematica to add 2 to N? Does it just treat N as a formal symbol when you add 2 to it N? --Mike --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
> > In[7]:= Pi + E // N + 5 // N > > > Out[7]= (5. + N)[5.85987] > > Gees -- what in the heck does "(5. + N)[5.85987]" mean? It means 5.+N applied to 5.85987. (In Mathematica f[x] is how you would express applying f to x). And here's why: In[8]:= a+b//c+d//e Out[8]= e[(c + d)[a + b]] So Pi + E // N + 5 // N = N((5+N)[Pi+E]]. Mathematica's rules tell it that N[f[g]] = N[f][N[g] and N[f+g]=N[f]+N[g] so N[(5+N)[Pi+E]] = (5.+N)[5.85987] It doesn't have a rule telling it how to simplify (f+g)[x], so it quits here. This is a good example of Mathematica's model of computation based based on simplification rules. Mathematica take an expression, sees if any simplification rules apply, and if so it does the simplification and repeats until the expression stops changing. Issues arise when more than one rule would apply, and Mathematica's idea of which one to use differs from what you would expect. Still it's pretty cool the way Mathematica's conceptual model unites computation and algebraic simplification. Of course theoretically this isn't surprising. What's cool is that it works as well as it does. Cheers, Peter --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Python in sage notebook
On Dec 7, 2007 9:32 AM, pgdoyle <[EMAIL PROTECTED]> wrote: > > Consider this python program: > > > def foo(): > return 'foo' > > print foo() > > def mumble(): > print 'mumble',foo() > > mumble() > > > If put this in a file foo.py and type `python foo.py' it prints > > foo > mumble foo > > Same thing if I type 'sage foo.py'. Same thing if I put it in a cell > of a sage notebook and evaluate with sage. > But if switch the evaluation option for the notebook from sage to > python I get an error: > > foo > mumble > Traceback (most recent call last): > File "", line 1, in > File "/home/doyle/.sage/sage_notebook/worksheets/admin/2/code/ > 68.py", line 12, in > print mumble()''', '/home/doyle/.sage/sage_notebook/worksheets/ > admin/2/cells/5') > File "/usr/local/sage/local/lib/python2.5/site-packages/sage/server/ > support.py", line 258, in syseval > return system.eval(cmd, locals = sage_globals) > File "/usr/local/sage/local/lib/python2.5/site-packages/sage/misc/ > python.py", line 21, in eval > eval(z, globals, locals) > File "/usr/local/sage-2.8.15-ubuntu32bit-i686-Linux/data/extcode/ > sage/", line 1, in > > File "/usr/local/sage-2.8.15-ubuntu32bit-i686-Linux/data/extcode/ > sage/", line 7, in mumble > > NameError: global name 'foo' is not defined > > I get the same error if I change the notebook evaluation option back > to sage, put %python at the beginning of the cell, and evaluate. > > Is this a bug or a feature? This is definitely a bug. Thanks for reporting it! I've put it here: http://trac.sagemath.org/sage_trac/ticket/1423 I only have a minute at the moment, but just want to remark that when you do %python in the notebook or use python mode, here is the Python code that actually evaluates the input to the cell: sage: python.eval?? File: /Users/was/s/local/lib/python2.5/site-packages/sage/misc/python.py Source Code (starting at line 5): def eval(self, x, globals={}, locals={}): x = x.strip() y = x.split('\n') if len(y) == 0: return '' s = '\n'.join(y[:-1]) + '\n' t = y[-1] try: z = compile(t + '\n', '', 'single') except SyntaxError: s += '\n' + t z = None #else: #s += '\n' + t eval(compile(s, '', 'exec'), globals, locals) if not z is None: eval(z, globals, locals) return '' Looking at that code, does anybody see why the second global foo gets ignored inside the function body of mumble? I don't immediately see why. William --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
On Dec 7, 2007 12:24 PM, Paul Zimmermann <[EMAIL PROTECTED]> wrote: > > > In[3]:= Pi \\ N > > Syntax::sntxf: "Pi" cannot be followed by " \\ N". > > > > In[4]:= f \\ g > > > > Syntax::sntxf: "f" cannot be followed by " \\ g". > > please turn your '\' key by Pi/2: Thanks. That we couldn't use in Sage, since // is already taken. But we could maybe use \\ instead. > > In[2]:= f // g > > Out[2]= g[f] > > In[3]:= Pi // N > > Out[3]= 3.14159 > > In[7]:= Pi + E // N + 5 // N > > Out[7]= (5. + N)[5.85987] Gees -- what in the heck does "(5. + N)[5.85987]" mean? But thanks! William --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
> In[3]:= Pi \\ N > Syntax::sntxf: "Pi" cannot be followed by " \\ N". > > In[4]:= f \\ g > > Syntax::sntxf: "f" cannot be followed by " \\ g". please turn your '\' key by Pi/2: In[2]:= f // g Out[2]= g[f] In[3]:= Pi // N Out[3]= 3.14159 In[7]:= Pi + E // N + 5 // N Out[7]= (5. + N)[5.85987] Paul Zimmermann --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
> Is there some easy way I could have figured out that m would respond > to the message `apply_map'? > (Or whatever messages are called in the post-Smalltalk era.) In Python, they're known as methods and they come associated with an object based on its type. To get a list of all the methods that m has, you would type in m. and then press tab. > However, > 1.rational_simplify() > causes an error. The explanation is that > type(((x^2-1)/(x-1)-x).rational_simplify()) > is > > whereas > type(1) > is > You are correct on this. > But it seems like this could be a more natural and useful way to > handle an operation like ratsimp. This is because there is a pretty clean split in Sage between the symbolic stuff (which is using Maxima) and everything else. All the symbolic stuff lives in the SymbolicExpressionRing. sage: SR = SymbolicExpressionRing() sage: a = SR(1) sage: type(a) sage: a 1 sage: a.rational_simplify() 1 > > Maybe the problem is that I just don't have a model yet that would > allow me to predict, for example, that > to find the length of something I should feed it to the function len, > rather than sending it the message len(), > whereas if I want to do something to each entry of a matrix, I should > send a message apply_map to the > matrix, rather than feeding the matrix to a function called apply_map. Pretty much everything is in the methods (or at least should be). There are some global level functions for convenience that basically just call the object's method. len() is a builtin Python function and will call the objects .__len__() method. > to know or care, as apparently they do in sage. In which case I think > it might work better to try to stick with functions > rather than messages, where possible. Under Python's object-oriented approach, the objects and methods are the preferred way of handling things. And, when it comes to working with a wide range of types as Sage does, the code is much cleaner and easier to work with. > > One thing I know I'm going to miss from Mathematica is the loosely > binding operator \\, as in f \\ g, which is another way of writing > g[f]. This allows you to build up a computation by writing first > things first. And because of the loose binding, you can write > longcomplicatedexpression \\ ratsimp > without fear that ratsimp will stingily only simplify the denominator > of the expression. Because Sage adopts Python's syntax, nothing exactly like that will be added to Sage. On the other hand, the Python interpreter regards _ as the last object. You could do something like this: sage: (x^2-1)/(x-1)-x (x^2 - 1)/(x - 1) - x sage: _.rational_simplify() 1 --Mike --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Re: Weaning
On Dec 7, 2007 11:44 AM, pgdoyle <[EMAIL PROTECTED]> wrote: > Thanks for the help - much appreciated! > > On Dec 3, 9:30 pm, "Mike Hansen" <[EMAIL PROTECTED]> wrote: > > > If you just need to substitute, you can do: > > > > sage: m.subs(x=1) > > [-1 -1] > > [-1 0] > > > > If you want to apply a more general map to the coefficients, then you can > > do: > > > > sage: m.apply_map(lambda e: e.subs(x=1)) > > [-1 -1] > > [-1 0] > > > > Is there some easy way I could have figured out that m would respond > to the message `apply_map'? > (Or whatever messages are called in the post-Smalltalk era.) Yes. Just type sage: m.[tab key] I.e., type m. then press the tab key on your keyboard. This will work both in the notebook and on the command line. In both cases it will list all the "messages" that you can send to m. Actually we tend to call them "member functions" rather than messages. > > > 3) How do I get access to maxima's ratsimp? > > > > sage: n = m.apply_map(lambda e: e.rational_simplify()); n > > [ -1/(x^2 + x - 1) -x/(x^2 + x - 1)] > > [ -x/(x^2 + x - 1) (x - 1)/(x^2 + x - 1)] > > sage: n.subs(x=1) > > [-1 -1] > > [-1 0] > > Here's an issue: > > ((x^2-1)/(x-1)-x).rational_simplify() > yields 1. > ((x^2-1)/(x-1)-x).rational_simplify().rational_simplify() > also yields 1, which is gratifying. > However, > 1.rational_simplify() > causes an error. The explanation is that > type(((x^2-1)/(x-1)-x).rational_simplify()) > is > > whereas > type(1) > is > > > To me, this points out a problematic feature of implementing something > like ratsimp through messages, > rather than defining a function called ratsimp Presumably I don't > want > to encumber the definition of integers with code telling how to > respond to the message rational_simplify(). > But I would still like an integer to simplify to an integer. I could > (and will) define my own function > ratsimp that will send its argument the message rational_simplify(), > and then do something appropriate if this > doesn't work, i.e. if it's a matrix, apply ratsimp recursively to the > entries, otherwise just return the argument. > But it seems like this could be a more natural and useful way to > handle an operation like ratsimp. Good idea. There is actually already quite a lot like this in Sage already, e.g., in this file: http://www.sagemath.org/hg/sage-main/file/7110a20969c8/sage/misc/functional.py For example the integral function is defined as follows: def integral(x, *args, **kwds): """ Return an indefinite integral of an object x. First call x.integrate() and if that fails make an object and integrate it using maxima, maple, etc, as specified by algorithm. EXAMPLES: sage: f = cyclotomic_polynomial(10) sage: integral(f) 1/5*x^5 - 1/4*x^4 + 1/3*x^3 - 1/2*x^2 + x sage: integral(sin(x),x) -cos(x) sage: y = var('y') sage: integral(sin(x),y) sin(x)*y sage: integral(sin(x), x, 0, pi/2) 1 sage: sin(x).integral(x, 0,pi/2) 1 """ if hasattr(x, 'integral'): return x.integral(*args, **kwds) else: from sage.calculus.calculus import SR return SR(x).integral(*args, **kwds) What the above does is (1) checks to see if there is an "integral" message that can be sent to an object. If so, do it. If not create a symbolic calculus object (for which integration makes sense), then integrate that. This is why sage: integral(1,x) x works even though 1.integral(x) doesn't. It is good to have some functions like above, but not *too* many. > Maybe the problem is that I just don't have a model yet that would > allow me to predict, for example, that > to find the length of something I should feed it to the function len, > rather than sending it the message len(), > whereas if I want to do something to each entry of a matrix, I should > send a message apply_map to the > matrix, rather than feeding the matrix to a function called apply_map. > > By the way, Mathematica handles this issue by attaching simplification > rules either to a `function' like ratsimp, or alternatively to > the object to which the `function' is being applied. Actually,it's > not fair to talk about functions, because > Mathematica works uniformly according to simplification rules. Which > can have all kinds of consequences, > many of them useful, and not a few of them potentially very > confusing. In this case, ratsimp[1] could cause Mathemica eitther > to feed the `argument' 1 to the `function' ratsimp, or else send the > object 1 the `message' ratsimp. Users don't need > to know or care, as apparently they do in sage. In which case I think > it might work better to try to stick with functions > rather than messages, where possible. "Sticking with functions rather than messages where possible" in general just doesn't work. If you do sage: search_src('def integr') you'll see there are nearly 40 differ
[sage-support] Re: Weaning
Mike, Thanks for the help - much appreciated! On Dec 3, 9:30 pm, "Mike Hansen" <[EMAIL PROTECTED]> wrote: > If you just need to substitute, you can do: > > sage: m.subs(x=1) > [-1 -1] > [-1 0] > > If you want to apply a more general map to the coefficients, then you can do: > > sage: m.apply_map(lambda e: e.subs(x=1)) > [-1 -1] > [-1 0] > Is there some easy way I could have figured out that m would respond to the message `apply_map'? (Or whatever messages are called in the post-Smalltalk era.) > > 3) How do I get access to maxima's ratsimp? > > sage: n = m.apply_map(lambda e: e.rational_simplify()); n > [ -1/(x^2 + x - 1) -x/(x^2 + x - 1)] > [ -x/(x^2 + x - 1) (x - 1)/(x^2 + x - 1)] > sage: n.subs(x=1) > [-1 -1] > [-1 0] Here's an issue: ((x^2-1)/(x-1)-x).rational_simplify() yields 1. ((x^2-1)/(x-1)-x).rational_simplify().rational_simplify() also yields 1, which is gratifying. However, 1.rational_simplify() causes an error. The explanation is that type(((x^2-1)/(x-1)-x).rational_simplify()) is whereas type(1) is To me, this points out a problematic feature of implementing something like ratsimp through messages, rather than defining a function called ratsimp Presumably I don't want to encumber the definition of integers with code telling how to respond to the message rational_simplify(). But I would still like an integer to simplify to an integer. I could (and will) define my own function ratsimp that will send its argument the message rational_simplify(), and then do something appropriate if this doesn't work, i.e. if it's a matrix, apply ratsimp recursively to the entries, otherwise just return the argument. But it seems like this could be a more natural and useful way to handle an operation like ratsimp. Maybe the problem is that I just don't have a model yet that would allow me to predict, for example, that to find the length of something I should feed it to the function len, rather than sending it the message len(), whereas if I want to do something to each entry of a matrix, I should send a message apply_map to the matrix, rather than feeding the matrix to a function called apply_map. By the way, Mathematica handles this issue by attaching simplification rules either to a `function' like ratsimp, or alternatively to the object to which the `function' is being applied. Actually,it's not fair to talk about functions, because Mathematica works uniformly according to simplification rules. Which can have all kinds of consequences, many of them useful, and not a few of them potentially very confusing. In this case, ratsimp[1] could cause Mathemica eitther to feed the `argument' 1 to the `function' ratsimp, or else send the object 1 the `message' ratsimp. Users don't need to know or care, as apparently they do in sage. In which case I think it might work better to try to stick with functions rather than messages, where possible. One thing I know I'm going to miss from Mathematica is the loosely binding operator \\, as in f \\ g, which is another way of writing g[f]. This allows you to build up a computation by writing first things first. And because of the loose binding, you can write longcomplicatedexpression \\ ratsimp without fear that ratsimp will stingily only simplify the denominator of the expression. Cheers, Peter --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---
[sage-support] Python in sage notebook
Consider this python program: def foo(): return 'foo' print foo() def mumble(): print 'mumble',foo() mumble() If put this in a file foo.py and type `python foo.py' it prints foo mumble foo Same thing if I type 'sage foo.py'. Same thing if I put it in a cell of a sage notebook and evaluate with sage. But if switch the evaluation option for the notebook from sage to python I get an error: foo mumble Traceback (most recent call last): File "", line 1, in File "/home/doyle/.sage/sage_notebook/worksheets/admin/2/code/ 68.py", line 12, in print mumble()''', '/home/doyle/.sage/sage_notebook/worksheets/ admin/2/cells/5') File "/usr/local/sage/local/lib/python2.5/site-packages/sage/server/ support.py", line 258, in syseval return system.eval(cmd, locals = sage_globals) File "/usr/local/sage/local/lib/python2.5/site-packages/sage/misc/ python.py", line 21, in eval eval(z, globals, locals) File "/usr/local/sage-2.8.15-ubuntu32bit-i686-Linux/data/extcode/ sage/", line 1, in File "/usr/local/sage-2.8.15-ubuntu32bit-i686-Linux/data/extcode/ sage/", line 7, in mumble NameError: global name 'foo' is not defined I get the same error if I change the notebook evaluation option back to sage, put %python at the beginning of the cell, and evaluate. Is this a bug or a feature? Cheers, Peter --~--~-~--~~~---~--~~ 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://sage.math.washington.edu/sage/ and http://sage.scipy.org/sage/ -~--~~~~--~~--~--~---