I just taught a very intense two week workshop on the Riemann Hypothesis
to 24 bright high school students, in which we used SAGE quite a lot
each day for 2.5 hours (http://wstein.org/simuw/). I'm now very
seriously considering some changes to SAGE as a result.
The first is *removing* having predefined symbolic variable
names. I.e., in SAGE right now the variables a..z and A..Z
are prdefined at startup to be symbolic variables (except for I
and e).
This has been discussed several times before on
this list, and in the past I always argued for them. However,
after having watched many actual people using SAGE during
the last two weeks, I have changed my mind. The following
sort of thing happened frequently day after day:
I would make a predefined notebook cell or function or
something like this:
{{{
def R(x):
...
}}}
and students would forget to evaluate it. They would still
try to do things like "plot(R, 0, 10)", and they would end
up getting the identity function, which was very confusing.
This *constantly* happened. An error message that R
isn't defined would have been vastly superior.
Another problem, is that doing, e..g,
v = [y for y in w]
would turn y into the last value in w. It would no longer
be symbolic. So in writing code for the students, I could
never rely on predefined symbolic variables being defined.
So I propose that the only symbolic variables that are predefined
are x (since it's so useful to have this predefined), I (=sqrt(-1)),
and e (=2.7...).
If users want a symbolic variable, they have to use the var command.
One other thing that surprised me was
(1) how little all the symbolic code in SAGE was actually useful for
the workshop,
(2) how annoying it was not having decimal literals be floats by default, and
(3) how annoying it was having certain special functions, e.g.,
log, sin, cos, etc., return symbolic values by default
instead of numerical values.
I.e., Perhaps I'm starting to see why MATLAB is more popular than
Maple/Mathematica for a lot of classes, and I'm starting to wonder if
SAGE should by default tend toward
being less symbolic, though it should still have all that
functionality easily available.
Don't worry -- I'm not gong to make any drastic changes without some significant
feedback. So please, if you have thoughts on the above, let me know!
--
William Stein
Associate Professor of Mathematics
University of Washington
http://www.williamstein.org
In my opinion there should be *no* predefined symbols. For me even
having only these 3 symbols predefined would lead to some initial
confusion. I would very much prefer that it be necessary to ask that
these things be defined via a single import or other initialization at
the top of each notebook/sage session. Then the first question one
asks is "What is this thing at the start of the notebook page? And the
simple answer makes everything clear.
I vote for the Macaulay variables (RR, QQ, ZZ, etc) to be
predefined. I don't care about e but I prefer I to Python's
J or j for sqrt(-1).
In general, I agree with you that user friendliness is very important.
>
> One other thing that surprised me was
> (1) how little all the symbolic code in SAGE was actually useful for
> the workshop,
> (2) how annoying it was not having decimal literals be floats by default, and
> (3) how annoying it was having certain special functions, e.g.,
> log, sin, cos, etc., return symbolic values by default
> instead of numerical values.
Does having two functions, eg Sin (symbolic) and sin (numerical),
make sense?
> So I propose that the only symbolic variables that are predefined
> are x (since it's so useful to have this predefined), I (=sqrt(-1)),
> and e (=2.7...).
> If users want a symbolic variable, they have to use the var command.
I prefer having nothing defined, although I suppose a case could be
made for 'e' and 'I'. If 'x' is pre-defined, then one could as "why
not 'y'?", and it's downhill from there :-}
Having an explicit "var()" in a computation/script seems preferable.
On this subject, the question of "protection" for variable names was
raised earlier, but I don't recall the outcome.
> One other thing that surprised me was
> (1) how little all the symbolic code in SAGE was actually useful for
> the workshop,
This, I think, really depends on the user's habits, and it's really
difficult to predict. I often take advantage of the symbolic stuff,
but then I sometimes trip over it. Having it optional, as above, may
be the best we can do.
> (2) how annoying it was not having decimal literals be floats by
> default, and
> (3) how annoying it was having certain special functions, e.g.,
> log, sin, cos, etc., return symbolic values by default
> instead of numerical values.
On this one, I'm neutral.
How many configuration/usage options can we have before it starts
getting too complex to deal with?
Justin
--
Justin C. Walker, Curmudgeon at Large
Director
Institute for the Enhancement of the Director's Income
-----------
Nobody knows the trouble I've been
-----------
Not having x predefined would be reasonable. It has always been
predefined since SAGE-0.9, mainly because it makes it much easier
to create number fields, etc. However, it can lead to code and
examples that really make me nervous. For example, if one
things the standard way to make a number field is:
K.<a> = NumberField(x^3 + 1)
but one happens to define x to be a number or something
else in a session, e.g., by using x as a looping variable, e.g.,
for x in object:
print x
then there are problems. It's probably much better to think
that the following are ways to make a number field:
x = polygen(QQ)
K.<a> = NumberField(x^3 + 1)
or
x = var('x')
K.<a> = NumberField(x^3+1)
> Having an explicit "var()" in a computation/script seems preferable.
Yep.
> On this subject, the question of "protection" for variable names was
> raised earlier, but I don't recall the outcome.
I think this sort of thing just doesn't work -- and shouldn't even be attempted
-- since Python is a dynamically typed language, so types and values
of a variable can (and must be allowed to) change at any time, unlike
with a statically typed language.
> > One other thing that surprised me was
> > (1) how little all the symbolic code in SAGE was actually useful for
> > the workshop,
>
> This, I think, really depends on the user's habits, and it's really
> difficult to predict. I often take advantage of the symbolic stuff,
> but then I sometimes trip over it. Having it optional, as above, may
> be the best we can do.
>
> > (2) how annoying it was not having decimal literals be floats by
> > default, and
> > (3) how annoying it was having certain special functions, e.g.,
> > log, sin, cos, etc., return symbolic values by default
> > instead of numerical values.
>
> On this one, I'm neutral.
>
> How many configuration/usage options can we have before it starts
> getting too complex to deal with?
0. We don't have any configuration/usage options and we shouldn't.
I'm just trying to figure out what the best 1 default option will be.
William
> The first is *removing* having predefined symbolic variable
> names. I.e., in SAGE right now the variables a..z and A..Z
> are prdefined at startup to be symbolic variables (except for I
> and e).
+1 for nothing but e, I, and x defined by default. This has caused me
much more frustration than it has helped. (There should be an easy
way to import all of a-z,A-Z however).
Ideally, e would be an element of a "lazy real" field, x an element
of ZZ['x'] (if I want to do something quick, having x handy is really
nice, and almost everyone tries to create/factor/integrate a
polynomial the first time they try SAGE), and I an element of the
Gaussian integers. Having to define these every time does get tedious.
> (2) how annoying it was not having decimal literals be floats by
> default, and
-1. I've probably given you enough feedback on this matter already...
> (3) how annoying it was having certain special functions, e.g.,
> log, sin, cos, etc., return symbolic values by default
> instead of numerical values.
I mostly to agree here that sin(1) = 0.841470984807897 is more
useful, but one concern is how one would get the symbolic "sin(1)" if
one wanted it. Regarding (2), would the return value be float? Could
one specify the precision? Would "asin(sqrt(3)/2)" still be pi/3? (I
think so.) What about sqrt? I don't think that behavior should
revert back to a floating point. Maybe have two ways to call the
function/two functions (one symbolic like now, one numeric)?
- Robert
david
-Marshall
On Jul 7, 2:39 pm, Robert Bradshaw <rober...@math.washington.edu>
wrote:
+1, I like this behavior as well. And I like that currently you can
mix both symbolic and numerical types (e.g. in polynomial
expressions).
> this I think is good. What I think is bad is that something like
> 1.0*sin(1) is not numerical - in mathematica the sin(1) would be
Some people like symbolic expression, some like numerical expressions
for the above case :) .
This is off-topic: given a floating-point number, I think it would be
cool to have a way of telling users, "BTW,34.0191213743 is quite close
to 7*(pi + e - 1) in the field you're working with". This is probably
very hard.
2007/7/7, William Stein <wst...@gmail.com>:
> So I propose that the only symbolic variables that are predefined
> are x (since it's so useful to have this predefined), I (=sqrt(-1)),
> and e (=2.7...).
What about pi? :) . It seems to me that pi is as "special" as e.
didier
I myself prefer to import everything by hand in Python. Thus the sage
module can have many things (even all letters) preloaded, because
there cannot be any confusion -- I want to use it like this:
from sage import e, I, sin, x
print I*sin(x)
and actually even the "x" is kind of confusing, in SymPy we need to
create it by hand, like "x=Symbol('x')". Then there can be some very
limited environment, that imports some things automatically, for
example "isympy" (which is just ipython) in our project does
from sympy import *
x = Symbol("x")
y = Symbol("y")
z = Symbol("z")
at the beginning automatically, so that one can use it interactively.
But for any serious working, I prefer to do it by hand from my own
script. Like any other python library.
Ondrej
Thanks for all the feedback from everybody about symbolic variables,
special functions, etc. For now (i.e., the very near term), I think
the best thing to do is:
(1) remove all predefined *symbolic* variables except x,
leave in e, pi, and I:
-- everybody basically wants this.
(2) don't make any changes to how special functions behave.
-- doesn't seem necessary.
(3) don't make any changes to how floating point literals behave.
-- basically put making any changes here on hold, since
substantial discussion still hasn't revealed a
sufficiently good solution.
If one wants purely C-library float special functions,
doing, e.g.,
from math import sin, cos, tan
etc., works very well right now. And using float(2.5) or "2.5r"
works fine now.
I'm intrigued by Marshall's remark about "What I think is bad is
that something like 1.0*sin(1) is not numerical - in mathematica
the sin(1) would be forced into a numerical type."
Here's what Maxima/Mathematica/Maple/Mupad do:
sage: maxima.eval('2.5*sin(1)')
'2.5*sin(1)'
sage: mathematica.eval('2.5*Sin[1]')
2.10368
sage: maple.eval('2.5*sin(1)')
'2.5*sin(1)'
sage: mupad.eval('2.5*sin(1)')
2.5 sin(1)
Here's what SAGE does:
sage: 2.5*sin(1)
2.50000000000000*sin(1)
Here's what REDUCE does -- which is totally different
(and nuts, IMHO):
1: 2.5*sin(1);
5*sin(1)
----------
2
So Mathematica is in fact the only system that makes sin(1)
symbolic but 2.5*sin(1) numerical. I.e., Maple, SAGE, Mupad,
and Reduce all tend toward 2.5*sin(1) being as symbolic as
possible for some reason.
From an implementation point of view, given the SAGE rules,
it makes way more sense for 2.5*sin(1) to remain symbolic,
since:
(1) this is what the backend simplification system (maxima) does,
and
(2) 2.5 * sin(1) in SAGE is computed by making "2.5" symbolic,
then doing the multiply formally.
I'm not saying we shouldn't find a way to make 2.5 * sin(1) possibly
be numerical. I'm just remarking that this is a complicated issue
and it definitely deserves further discussion.
-- William
> From an implementation point of view, given the SAGE rules,
> it makes way more sense for 2.5*sin(1) to remain symbolic,
> since:
> (1) this is what the backend simplification system (maxima) does,
> and
> (2) 2.5 * sin(1) in SAGE is computed by making "2.5" symbolic,
> then doing the multiply formally.
>
> I'm not saying we shouldn't find a way to make 2.5 * sin(1) possibly
> be numerical. I'm just remarking that this is a complicated issue
> and it definitely deserves further discussion.
I too noticed that for the kind of work high school students do, and
also the kind of work technical students do in general, obtaining
numerical approximates of symbolic expressions occurs very frequently.
What I liked about Mathematica is that it made it very easy to obtain
numerical approximates of symbolic expressions. For example, it
seemed to me that the N[] function's name was shortened to just N to
make it easy to type and the //N syntax placed after any expression
would return its numerical approximate.
I must admit, I also use to force Mathematica to return numerical
results by placing .0 after one of the numbers in an expression, but
this technique always had a hacked feeling to me. When I discovered
the //N technique, I used it most of the time and was very happy with
it.
In SAGE, I have ended up using the numerical_approx() method as an
equivalent to N[] and //N in Mathematica, but I have found it not to
be as quick and easy to use.
Ted
> In SAGE, I have ended up using the numerical_approx() method as an
> equivalent to N[] and //N in Mathematica, but I have found it not to
> be as quick and easy to use.
I use RR(expr) and find it at least as usable as the N[expr] notation
of Mathematica.
Nick
I hadn't realized that mathematica was so unusual in its behavior in
this regard. However, there's another environment that behaves that
way - python itself! If you multiply 1.0*1, the answer is a float.
-Marshall
On Jul 10, 1:39 am, Nick Alexander <ncale...@math.uci.edu> wrote:
So far I've been refraining from posting here, since I don't have
strong feelings one way or the other, but the discussion so far has
been great and I'd like to leave a few comments.
On 7/8/07, William Stein <wst...@gmail.com> wrote:
>
> Hi,
>
> Thanks for all the feedback from everybody about symbolic variables,
> special functions, etc. For now (i.e., the very near term), I think
> the best thing to do is:
> (1) remove all predefined *symbolic* variables except x,
> leave in e, pi, and I:
> -- everybody basically wants this.
This is fine. I'm not sure which approach is better. There will be
lots of Maple/Mathematica users who will find it bizarre that they
have to manually declare their variables, but I guess there's nothing
wrong with that.
> (2) don't make any changes to how special functions behave.
> -- doesn't seem necessary.
I agree. RR(expr) is very easy to use. As is float(expr).
> (3) don't make any changes to how floating point literals behave.
> -- basically put making any changes here on hold, since
> substantial discussion still hasn't revealed a
> sufficiently good solution.
>
> If one wants purely C-library float special functions,
> doing, e.g.,
> from math import sin, cos, tan
> etc., works very well right now. And using float(2.5) or "2.5r"
> works fine now.
Agreed.
I actually really like Mathematica's behavior on this one. I think
it's worth considering. From a pragmatic point of view, it seems to me
that if I'm multiplying something symbolic by something approximate, I
don't want to see anything symbolic in the result, since my result is
inherently limited by the approximation. It's less clear in the case
of addition.
I think ultimately we will need to get feedback from a broader group
of users. What we as developers think is best might not actually
correspond to what most people who will be using SAGE want and expect.
~Bobby
> -- William
>
> >
>
--
Bobby Moretti
mor...@u.washington.edu
Also note that RDF(expr) works too, and is marginally to extremely faster, depending on the precision that RR is using.
set_style('mathematica')
which would define the N() function, and some other favorite
mathematica functions. Conceivably it would even change the behavior
of symbolic objects so that 1.0*sin(1) would evaluate to a numerical
answer, although that seems like more of a pain to implement.
-Marshall
david
I agree completely with this. We should learn a lot about how
Mathematica/Maple, etc., work, and why, but then make a _choice_
for SAGE that is a reasonable trade-off between various options.
Python is flexible enough that individual users can always create
such customizations for themselves. For example, people who like
"N" being "make it numeric" might just put this in their .sage/init.sage
file:
N = RDF
> But I *do* like the idea of the clean initial
> namespace, which gets subsequently polluted on demand when requested by
> the user.
I do not think this should be the default for everybody, because it
is less user friendly. Many people might be annoyed by having to type
from sage.all import plot
first, just to try out drawing a plot. Then they realize halfway
into a plot command that they also need to import sin, and line, and
point, and other things they forgot. For interactive work for many
peopl it would be very painful.
However, it would likely be very easy to support what you
want in some form. For example, I just implemented something;
see attached patch, which you can apply by typing
hg_scripts.apply("265-scripts.patch")
in SAGE. The effect of this patch is that when you set
the environment variable SAGE_IMPORTALL to "no", e.g.,
via
export SAGE_IMPORTALL="no"
then the SAGE command line has exactly the behavior you
requested:
$ export SAGE_IMPORTALL="no"
$ sage
Loading SAGE library. Current Mercurial branch is: tomorrow
sage: 2/3
2/3
sage: 22.50303
22.5030300000000
sage: EllipticCurve
---------------------------------------------------------------------------
<type 'exceptions.NameError'> Traceback (most recent call last)
/Users/was/<ipython console> in <module>()
<type 'exceptions.NameError'>: name 'EllipticCurve' is not defined
sage: from sage.all import EllipticCurve
sage: EllipticCurve
<function EllipticCurve at 0xb70be30>
------
By the way, a related new feature in SAGE-2.7 is that you can
turn the preparser on or off at any time from the command
line:
sage: preparser(on=False)
sage: 2/3
0
sage: preparser(on=True)
sage: 2/3
2/3
-- William
>
> I don't really like the idea of "modules that imitate various
> environments", i.e. I don't think it's possible or desirable for us to
> try to look specifically like any other system. Mathematica semantics
> are so different from SAGE's, it would be misleading to suggest
> anything like that.
I agree. Even suggesting that such a thing is possible could lead to
support headaches, as those with a strong background in My Favorite
CAS try to get precisely the semantics they are used to.
I think it is better to suggest that one can use a startup file of
the user's own devising to try to emulate what they like about MFCAS,
without claiming that it's really feasible.
> But I *do* like the idea of the clean initial
> namespace, which gets subsequently polluted on demand when
> requested by
> the user.
Yeah! Let the polluters clean up their own sandboxes :-}
Justin
--
Justin C. Walker, Curmudgeon-At-Large, Director
Institute for the Enhancement of the Director's Income
--------
The path of least resistance:
it's not just for electricity any more.
--------
That being said, I don't want to fill the global namespace with
everything possible, but I think (with the OO nature of Python) one
should be able to do all but the most technical things without having
to type an import statement.
- Robert
On Jul 10, 2007, at 2:20 PM, David Harvey wrote:
Just to keep this ball rolling around a bit longer, I don't think
that David's suggestion necessarily leads to this. It's one thing to
have SAGE functionality at the ready at startup. It's another to
have a lot of "optional" environmentally friendly names cluttering up
the namespace.
This started with the discussion of predefining the "symbolic
calculus" variables by default. I think that has been the thrust of
most of the comments so far.
Justin
--
Justin C. Walker, Curmudgeon-At-Large
Institute for the Absorption of Federal Funds
--------
If you're not confused,
You're not paying attention
--------
> I use RR(expr) and find it at least as usable as the N[expr] notation
> of Mathematica.
and William wrote:
>We should learn a lot about how
>Mathematica/Maple, etc., work, and why, but then make a _choice_
>for SAGE that is a reasonable trade-off between various options.
>Python is flexible enough that individual users can always create
>such customizations for themselves. For example, people who like
>"N" being "make it numeric" might just put this in their .sage/init.sage
>file:
I don't have a preference for the name N over the name RR just because
this is what Mathematica uses :-) I have been using the
numerical_approx method over using RR(expr) mainly because I am trying
to emulate the way I found myself using //N in Mathmatica ( I used //N
much more than the N[] function). When doing a multi-step
calculation, I wanted to keep the results symbolic as much as
possible, but I also wanted to take frequent quick peeks at the
numerical approximates of these results in order to determine if they
were reasonable or not.
So, I would place a quick //N at the end of the result I received,
take a look at its numerical approximate, and then erase the //N and
move to the next step. Since //N is placed at the end of a line, it
was easy to put there and easy to erase.
I have found myself using numerical_approx() instead of RR() because
it is also placed at the end of the line and so is relatively easy to
locate the cursor there and add it. With RR(), one has to wrap the
code in a function and then unwrap it when finished, which I have
found takes more time (and is more error prone) than just having to
deal with code that is all at the end of a line.
My main complaint with numerical_approx so far is that it is a lot of
typing when used for taking quick peeks at the numerical approximate
of a symbolic expression. I am thinking that a shorter method name,
perhaps .RR() to keep it in sync with the existing RR(expr), would be
helpful :-)
Ted
I would be happy to introduce a short-cut alias for numerical_approx,
e.g., N() or n() or ??. You can try out a few by doing this:
sage: import sage.calculus.calculus
sage: sage.calculus.calculus.SymbolicExpression.N =
sage.calculus.calculus.SymbolicExpression.numerical_approx # all one
line
sage: a = sin(2) + pi + cos(2/3)
sage: a.N()
4.83677734119242
Something simple like a.N() might be quite reasonable as a shortcut
for a.numerical_approx(), and would be very simple to implement (just
one line of code in an appropriate place).
Thoughts?
William
I think the init file idea needs to be pushed harder. I already do this and the
flexibility is absolutely critical to my happiness. I even have my init file
call another file in the current directory so I can have different things
defined depending on which project I'm working on (Of course, that idea doesn't
have much merit from the notebook).
We could publish init files for various CAS's. I realize we can't match
semantics, but for myself I don't think the semantics are the hard part -- the
hard part is remembering the new function name.
We could also publish init files for various branches of mathematics -- applied,
number theory, etc.
I realize this could lead to support questions when people do dumb things in
their init file, but I think it is easily worth to publish this huge amount of
flexibility.
--
Joel
I think this is definitely worth a try, and will probably be pretty fun to do.
It may or may not be successful (e.g., if you type foo? the examples could
easily fail because of how you customized your session -- this could be
very bad). It would make sense to do something like this at least
for the following systems, in order of priority:
1. mathematica
2. matlab
3. maple
4. magma
5. pari
6. gap
For some of these, it is hard to think of where to begin, since there are
thousands of commands (e.g., matlab has over 8000 commands).
One could begin by creating a "mathematica.sage" that defines common
commands like
Integrate
Sin
Cos
Derivative (?)
N
etc., with the case conventions of mathematica. This file could look
like:
Integrate = integrate
Sin = sin
Cos = cos
...
N = RDF # or something more sophisticated?? I.e., take number of
digits as input...
...
Thoughts? Volunteers?
William
-Marshall
On Jul 11, 1:32 pm, "William Stein" <wst...@gmail.com> wrote:
Thanks! Let me know what happens. And definitely feel free to
post a list of the reasons migrating from Mathematica to SAGE
"definitely won't be easy". Obviously, bad 3d graphics support
is one reason, but I would love to hear about any and all other
reasons as they arise. I want to be as aware as possible about them,
so we have some hope of addressing as soon as possible.
-- William
On Jul 11, 2:38 pm, "William Stein" <wst...@gmail.com> wrote:
> I would be happy to introduce a short-cut alias for numerical_approx,
> e.g., N() or n() or ??.
>...
> Something simple like a.N() might be quite reasonable as a shortcut
> for a.numerical_approx(), and would be very simple to implement (just
> one line of code in an appropriate place).
>
> Thoughts?
I can not think of a better shortcut for numerical_approx() than
either N() or n() and between these two, I have found that I type n()
quicker than N(). Also, since numerical_approx() begins with a lower
case letter, I like the idea that its shortcut also begins with a
lower case letter. Therefore, I would vote for using n() as the
shortcut.
As for usability, I have found that both of these shortcut methods are
much quicker to type and erase than numerical_approx() and their
usability is very similar to mathematica's //N shortcut.
Ted