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
> <class 'sage.calculus.calculus.SymbolicConstant'>
> whereas
> type(1)
> is
> <type 'sage.rings.integer.Integer'>
>
> 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 different definitions of the integral function.
It would be bad if all this code were moved to one long method:

 def integral(f):
     if type of f is ...
     else
     ... 42 times.

There would be maintenance nightmares, etc.

In any case, in some of what you're discussing above is probably forced
on Sage by us using Python.  There are certainly pros and cons to this
choice, i.e., of using Python instead of inventing a new language, but
the pros far outweigh the cons, at least for many applications.

> One thing I know I'm going to miss from Mathematica is the loosely
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Please quite loudly tell us *everything* you are going to miss from
Mathematica.  We want to know!

> 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.

We might consider something like f \\ g in Sage.  E.g., it
could turn
    sage: pi + e  \\  N
into
    sage: N(  pi + e )
    5.85987448204884

How does this work in Mathematica exactly?  How loose is the binding?
E.g., what does

     pi + e \\ N   + 5 \\ N

turn into.  By the way, in Mathematica I can't get this to work at all:

In[3]:= Pi \\ N
Syntax::sntxf: "Pi" cannot be followed by " \\ N".


In[4]:= f \\ g

Syntax::sntxf: "f" cannot be followed by " \\ g".

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/
-~----------~----~----~----~------~----~------~--~---

Reply via email to