Look at theses 2 examples : what is the simplified formula .
2*cos(x)^2-1 : you wait the combined formula cos(2*x)
cos(2*x)+1 : you wait the expanded formula 2*cos(x)^2
a simplify function must have a purpose.
This purpose is only in the user mind, not in any computer algebra
algorithms.
But expand has a clean description :
An expand formula has more transcendent function calls with smaller
arguments.
sin (x+y) == sin(x)*cos(y)+cos(x)*sin(y)
The opposite way may be a combine or a contract function :
less transcendent call but larger arguments :
combine(exp(a)^3/exp(b))=exp(3*a-b).
> I do not like the approach in Maple and Mathematica, where
> user has one big command for many simplifications and it is not easy
> to find out, what to do, if we do not want to use some of
> simplifications and rewriting rules included in this big command.
>
Please, let me have the opposite taste.
I can only record a very small number of functions in my mind.
I also can explain a little number of theory to my students.
So I prefer choose a complete theory or a large transform and then
refine it by options or examples.
In your case, it may be possible to add optional parameters to expand
functions.
By example you may choose a target : only logarithms or trigonometric
functions.
Burcin proposed a target parameter.
So imagine a Sage 4.xyz with
y = log(2)+log(3)+exp(2)*exp(3)
contract (y) # log(6)+exp(5)
contract(y, target=log) # log(6)+exp(2)*exp(3)
contract(y, target=exp) # log(2)+log(3)+exp(5)
An other option may be a predicate select in order to restrain the
tested subexpression.
contract (exp(x+1)*exp(x-1)*exp(y), target=exp, select=lambda subexpr :
has(subexpr, x))
# the answer will be exp(2*x)*exp(y)
And the last option may add a mainBranchCut option.
In a normal (complex) calculus it's impossible to simplify log(x)+log(y)
to log(x*y). Try with x=y=-1.
But a mainBranchCut option overwrite the general rule and suppose the
right hypothesis to get
log(x*y), and 1/2*log(x) give log(sqrt(x)).
> I think that it is better to have small functions which do their small
> job - they do what the user wants. I think that this is Maxima
> approach.
>
It's very difficult to have an complete view of maxima rules. There are
too many functions.
With only one function, the help docstring can explains all the
refinement options.
And options in a main functions can make the (only one) little
transforms you want to apply.
You don't like maple way because I don't think that maple has this
ability to restrain the convert transform.
> If such a complete solution for rewriting tasks appears, it would be
> great to give to the users enough power for fine tunning, like current
> expand_trig().
>
An other question :
How theses rewriting rules may be coded :
1/ With maxima kernel call ?
2/ In Ginac library ?
3/ By a sage interpreter call ?
My vote goes to the number-3/. I don't like maxima method with its
numerous flags.
Look at the previous mail in sage-support about integrate
(sqrt(sin(x)^2+cos(x)^2), x, 0, 2*pi) = only pi
because there was a little change to an inner flag of maxima.
The 2/ way is the longer method. If I want to code it I must learn sage
and also the ginac code. This method looks like to the axiom(s)
language. A function can be right for the interpreter language, but it
takes hours and hours to code it in the axiom kernel with other compiled
rules.(1)
The 3/ is the easiest way to read and to understand the code. When you
read sage files then you understand its functions. It's almost the maple
way with "the verbose option and print the function" and it was the
mupad way. Bug are easiest to find. Interpreted code isn't so slow, you
may wait 1 second more, and there is less wasted time than in (1).
Thank you for your detailed explanation.
On Thu, 12 Nov 2009 15:17:44 +0100
Francois Maltey <fma...@nerim.fr> wrote:
> An other question :
>
> How theses rewriting rules may be coded :
>
> 1/ With maxima kernel call ?
> 2/ In Ginac library ?
> 3/ By a sage interpreter call ?
The main motivation behind switching to pynac for symbolics was to make
it possible to develop this functionality in Sage, using python/cython.
We were always aiming for the 3rd option.
Hopefully a future 4.xyz release of Sage will allow you to implement all
this using only python. In order to get there, we should just start and
see what functionality needs to be exposed. :)
I know you already have some suggestions. Maybe you can post them here,
or open trac tickets so others can help implement them.
Burcin
Care to help?
Francois has a fairly detailed proposal about a possible interface to
expand, contract, and rewrite. I was planning to implement a prototype
to this for a while, but couldn't find the time.
We could start by putting the draft proposal on the wiki, and work on a
prototype implementation.
Cheers,
Burcin
> On 12 lis, 16:38, Burcin Erocal <bur...@erocal.org> wrote:
>> Care to help?
>
> Many thanks but .... I do not know anything about programming. I can
> write simple artless scripts and thats all. I also do not know enough
> from complex analysis, know nothing about computer algorithms and so
> on. I think that nobody would be interested in CAS with code from
> complete beginner.
>
> I like opensource software and math, but have not enough knowledges to
> bring significant contribution in this topic.
Everyone has something they can contribute: bug reports,
documentation, and even feature requests like you've been doing.
> Could the conclusion be the following?
> "If you want (and if the realease manager includes corresponding
> patches), add support for Maxima commands which you need. When python
> of ginac will be able to replace these commands, these interfaces to
> Maxima commands will be removed."
No, I don't see any reason why we would remove the Maxima interface.
What we might do is change our internal routines to call the a non-
maxima version if available (though when more than one system can do
an operation it is customary to take an optional flag to make it easy
to choose).
For something like simplification, I don't see either as completely
subsuming the other. There will probably be cases that maxima can
handle that nothing else can, and vice-versa, so it'd be very useful
to have both.
- Robert
This is also what I thought when I asked for help. :)
You don't need to be an expert programmer to contribute code to Sage. I
thought the biggest hassle is the initial steps of preparing a patch,
submitting to trac and going through review.
I will try to put a proposal on the wiki and provide an initial patch
this weekend. Maybe that future 4.xyz version Francois mentioned will be
4.3, who knows?
Cheers,
Burcin
> Could the conclusion be the following?
> "If you want (and if the realease manager includes corresponding
> patches), add support for Maxima commands which you need. When python
> of ginac will be able to replace these commands, these interfaces to
> Maxima commands will be removed."
I am really reluctant to keep adding functions, since they would have
to be maintained for a long time because of the deprecation policy.
Let's see if we can quickly come up with a "clean" solution in the
next couple of days. Then you can add the functionality you need (still
using maxima if necessary), using the interface that we will maintain
long term.
If this process takes too long, or if you still want to use only maxima
for this functionality even when we have Sage equivalents, we could
add a .maxima_methods() function to symbolic expressions which returns
a class that hosts wrappers to maxima methods. This would prevent
polluting the namespace of the class Expression, and provide a better
location to search for this functionality.
Thanks.
Burcin
How is this not just
sage: mf = maxima(f)
sage: mf.[tab]
which can already be done?
- Robert
I think the idea is that it should be more transparent to the user,
i.e., the result should be a *Sage* symbolic expression, not a maxima
object. Also, the default maxima interface has the default Maxima
conventions and settings, which don't agree with Sage's internal
maxima interface's conventions (e.g., assumptions, default complex
powers, etc.). Finally, one could imagine the implementation of the
maxima_methods() function being moved to Nils Bruin's new ecl lisp
library interface (is that refereed yet?!), and the maxima_methods
would retain *exactly* the same API, but be faster.
So I think there is a lot of value in Burcin's suggestion. I really like it.
William
This purpose about expression has 3 differents aspects.
A/ The first aspect we discover is the user interface. This interface
must be coherent.
This means that 1/ it's possible to describe it with "few word" 2/ The
most common calculus has no option 3/ This system will be able to be
refined for more difficult computations.
B/ Theses mathematic rules are well known and this coding aspect is a
visit inside the expressions, its branchs, its leaves, its operands and
its operators. I feel that this point is not so difficult when A/ is
well described.
C/ I can't test my ideas about A/ by B/ in sage/python because I need
some primitives I don't find.
a- expr.operator() and expr.operands() are already right.
a'-Extract and test sin in sin(x) is easy, but recognize the + in x+y is
heavy.
b- Burcin is working about an very fine automatic retract.
If the result is an (defined) integer as in 0*x, its type becomes
integer, and doesn't remain expression.
b'- test for rational numbers, real numbers, positive ones will also be
used.
c- I don't find the test "this expression is an atomic variable" True
for x, False for sqrt(2)
d- For a later Sage tests around assume will be integrate in theses
predicates.
After assume (n, Integer), (-1)^(2*n) computes 1, sin(n*pi) answers 0
and cos(n*pi) remains.
But this mail isn't the right place for the test x>0 or x<0 !
One time theses methods exist, code B/ becomes easy.
With some tips, the d- improvement may be partially predict.
From my point of view, the hardest aspect is the B-point.
I used Maple, Mupad and Axiom... and I see what way is nice to use, and
what way is disagreable.
And I don't love Maxima manner with its numerous flags and numerous
functions.
The C-point is a play I'll done one day or an other because I make tipo
every time I type
expr.subs_expr(cos(x)==(exp(i*x)+exp(-i*x))/2), sin(x)==...)
Francois.
But isn't it just operator()???
sage: var('x,y'); a = x+y
(x, y)
sage: a.operator()
<built-in function add>
>
> b- Burcin is working about an very fine automatic retract.
> If the result is an (defined) integer as in 0*x, its type becomes
> integer, and doesn't remain expression.
> b'- test for rational numbers, real numbers, positive ones will also be
> used.
>
> c- I don't find the test "this expression is an atomic variable" True
> for x, False for sqrt(2)
Burcin -- does this needs to be added? I can't figure out how to do
it either? It used to be easy with the old symbolics, but not with
the new ones.
> d- For a later Sage tests around assume will be integrate in theses
> predicates.
> After assume (n, Integer), (-1)^(2*n) computes 1, sin(n*pi) answers 0
> and cos(n*pi) remains.
> But this mail isn't the right place for the test x>0 or x<0 !
Assume in Sage is 100% implemented by Maxima... Inevitably we will
have to implement our own assume system eventually in pynac.
> One time theses methods exist, code B/ becomes easy.
> With some tips, the d- improvement may be partially predict.
>
> From my point of view, the hardest aspect is the B-point.
I personally didn't understand what you meant by B above, actually.
> I used Maple, Mupad and Axiom... and I see what way is nice to use, and
> what way is disagreable.
> And I don't love Maxima manner with its numerous flags and numerous
> functions.
>
> The C-point is a play I'll done one day or an other because I make tipo
> every time I type
> expr.subs_expr(cos(x)==(exp(i*x)+exp(-i*x))/2), sin(x)==...)
>
Thanks for sharing your thoughts and experience!
William
Here's a round-about (and probably failure-prone) way:
a=sqrt(2)
t=a.variables()
if len(t)==1:
print bool(t[0]==a)
else:
print "False"
--
Jason Grout
op = expr.operator
if op == sin : ... # is right
elif op == + : ... # doesn't work (or add or _plus...)
The way I find is to add a dummy variable opplus = (x+y).operator() and
then test
elif op == opplus : ...
I don't find it's a pretty code.
>> From my point of view, the hardest aspect is the B-point.
>>
>
> I personally didn't understand what you meant by B above, actually.
>
This point is about missing ginac primitives in sage :
test if an expression is an atomic variable, if an expression is a
(defined) integer, and so.
Very few primitives are missing (and some are present in ginac, but not
in sage), but it's impossible to climb in an expression by Sage if one
of theses functions are missing.
F. (I hope I'm more expressive in this message)
About operator.add and expr.variables()...
The (real-?) last question is
a=4*x
b=4/3*x
c=4.0*x
d=4*I*x
I can get the constant by a.operands(), a.operands()[-1], but how can I
test (without error) if this term is an integer, a rational, a float or
a complex before next Sage improvement ?
I can force a coerce by expr._integer(), but I get an error if expr (an
expression) isn't a integer ?
Must I define a function with a trap error ? There is also a
_rational_() method for this retract.
I don't find the method for float and complex.
F. again...
Thanks. Note that is_SymbolicVariable (and all other is_Type)
functions are deprecated. However,
sage.symbolic.all.is_SymbolicVariable is *not* deprecated:
sage: sage.symbolic.all.is_SymbolicVariable(x)
True
sage: sage.symbolic.all.is_SymbolicVariable(x+x)
False
sage: sage.symbolic.all.is_SymbolicVariable(sqrt(2))
False
Here's what is_SymbolicVariable does:
def is_SymbolicVariable(x):
...
return is_Expression(x) and is_a_symbol((<Expression>x)._gobj)
So there is a pynac function is_a_symbol that gets used.
William