desolve problems

654 views
Skip to first unread message

YURi KARADZhOV

unread,
Mar 22, 2010, 9:26:52 AM3/22/10
to sage-...@googlegroups.com
I played around with sage and found some problems with desolve command.
To solve ode diff(y(x),x)+a*y(x)+b*x+c we should first define variables and functions

x = var('x')

a,b,c=var('a b c')

y=function('y',x)

eq=diff(y,x)+a*y+b*x+c

but than unless it is obvious that the dependent variable is x and independent is y we should write such command

desolve(eq,y,ivar=x)

which is really annoying. And what is worse - we get a wrong answer

-((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - c)*e^(-a*x)

but the right answer is

-((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - _C1)*e^(-a*x)

where _C1 - arbitrary constant.

Of course, if we don't use c as a variable in equation we will get a right answer, but another problem will rise. If we have a bunch of ODE and want their solutions to interact somehow, than we expect different arbitrary constant for each one. But sage uses one letter c in every solution, which causes problems.


Actually the first problem is easy to solve. We can correct devel/sage-main/build/sage/calculus/desolvers.py

First - make dvar variable which represent dependent variable optional by giving it default value None.

< #64
def desolve(de, dvar, ics=None, ivar=None, show_method=False, contrib_ode=False):
>
def desolve(de, dvar=None, ics=None, ivar=None, show_method=False, contrib_ode=False):

Second - add definition of dvar.
dvar - is one of the functions differentiated.

> after #319
if dvar is None
    dvars = extract_func_from_diff(de)
    if len(dvars) != 1:
        raise ValueError, "Unable to determine dependent variable, please specify."
    dvar = dvars.pop()

Finally - change definition of ivar.
ivar - is argument of dvar and it is also in parameter_set of FDerivativeOperator

< #324-329
elif ivar is None:
    ivars = de.variables()
    ivars = [t for t in ivars if t is not dvar]
    if len(ivars) != 1:
        raise ValueError, "Unable to determine independent variable, please specify."
    ivar = ivars[0]
>
elif ivar is None:
    ivars = set(dvar.arguments()).intersection(extract_var_from_diff(de))
    if len(ivars) != 1:
        raise ValueError, "Unable to determine independent variable, please specify."
    ivar = ivars.pop()

where extract_*_from_diff(de) - are blackboxes which return set of functions or variables in FDerivativeOperators from de. They can be implemented by using type checking (instanceof) and operator function (I'm not sure is it possible to solve the problem using wild card and if it is any analog of Maple type function)

After the changes it will be possible to call desolve(de) in most cases.

At least it is clever to make simple correction

<#325-326
ivars = de.variables()
ivars = [t for t in ivars if t is not dvar]
>
ivars=dvar.arguments()

After that it will be possible to call desolve(de, dvar) if dvar has only one argument.

The second problem is harder and there are several solution. Anyway we need to implement new variable generator (like SR.symbol()) Then we can either change a little Maxima algorithm to be able to use variables generated by sage as integration constants or just rename all variables in equation, pass it to Maxima and then translate the result back using generated variables.

David Joyner

unread,
Mar 22, 2010, 5:43:56 PM3/22/10
to sage-...@googlegroups.com
Thank you for reporting this.

I think Robert Marik is the best person to reply to this
issue. I guess he is busy now but I hope he will reply in a
fairly soon and give his opinion.

> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to
> sage-devel+...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org
>
> To unsubscribe from this group, send email to
> sage-devel+unsubscribegooglegroups.com or reply to this email with the words
> "REMOVE ME" as the subject.
>

William Stein

unread,
Mar 22, 2010, 5:47:03 PM3/22/10
to sage-devel
2010/3/22 YURi KARADZhOV <yuri.ka...@gmail.com>:

> I played around with sage and found some problems with desolve command.
> To solve ode diff(y(x),x)+a*y(x)+b*x+c we should first define variables and functions
>
> x = var('x')
>
> a,b,c=var('a b c')
>
> y=function('y',x)
>
> eq=diff(y,x)+a*y+b*x+c
>
> but than unless it is obvious that the dependent variable is x and independent is y we should write such command
>
> desolve(eq,y,ivar=x)
>
> which is really annoying. And what is worse - we get a wrong answer
>
> -((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - c)*e^(-a*x)
>
> but the right answer is
>
> -((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - _C1)*e^(-a*x)
>
> where _C1 - arbitrary constant.
>
> Of course, if we don't use c as a variable in equation we will get a right answer, but another problem will rise. If we have a bunch of ODE and want their solutions to interact somehow, than we expect different arbitrary constant for each one. But sage uses one letter c in every solution, which causes problems.
>
>
> Actually the first problem is easy to solve.

You should implement the change and post a patch to

http://trac.sagemath.org/sage_trac/

for review. That's how Sage development happens. Hundreds of people
have done this. It's like notices a problem in a wikipedia article,
and fixing it.

Thanks!

William

yuri.k

unread,
Mar 23, 2010, 10:56:32 AM3/23/10
to sage-devel
Actually I finished the improvements I mentioned. And even more - I
developed simple type checking and function which return subexpression
of given expression by given symbolic type.

But I still have questions:
1. Is there an easy way to check if some class belongs to package in
python?
2. Where should I check in my new developed function?

David Joyner

unread,
Mar 23, 2010, 11:48:16 AM3/23/10
to sage-...@googlegroups.com
On Tue, Mar 23, 2010 at 10:56 AM, yuri.k <yuri.ka...@gmail.com> wrote:
> Actually I finished the improvements I mentioned. And even more - I
> developed simple type checking and function which return subexpression
> of given expression by given symbolic type.

Thank you for your work.

>
> But I still have questions:
> 1. Is there an easy way to check if some class belongs to package in
> python?
> 2. Where should I check in my new developed function?

Have you read the developers giude?
http://www.sagemath.org/doc/developer/index.html

ma...@mendelu.cz

unread,
Mar 23, 2010, 5:14:36 PM3/23/10
to sage-devel

On 22 bře, 14:26, YURi KARADZhOV <yuri.karadz...@gmail.com> wrote:
> I played around with sage and found some problems with desolve command.
> To solve ode diff(y(x),x)+a*y(x)+b*x+c we should first define variables and
> functions
>
> x = var('x')
>
> a,b,c=var('a b c')
>
> y=function('y',x)
>
> eq=diff(y,x)+a*y+b*x+c
>
> but than unless it is obvious that the dependent variable is x and
> independent is y we should write such command

Thanks for working on this problem, it would be nice to declare a,b,c
as constants, but I guess that it is not possible in Sage now. Any
idea how to extend Sage in this way?

>
> desolve(eq,y,ivar=x)
>
> which is really annoying. And what is worse - we get a wrong answer
>
> -((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - c)*e^(-a*x)
>
> but the right answer is
>
> -((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - _C1)*e^(-a*x)

The problem is that
sage: maxima("%c").sage()

returns c, but should return some more resonable free variable, say
_C1.

I am not sure if this will work for DE's involving term like y'(a*x
+b). But if you find a secure method how to find dependent and
independent variables from derivative, you can also fix bug
http://trac.sagemath.org/sage_trac/ticket/7401

Another related question: if we use topoly_solve=True in solve
command, we get free variabkles, say z2 and z4, if we run the same
command for the second time, we get other variables, say z_5 and z_7.
Should we have similar behavior with free variables from desolve
command? I think that it is better to get the same answer avery time
when I solve the same equation.

Thanks for working on this.

Robert

ma...@mendelu.cz

unread,
Mar 23, 2010, 5:36:49 PM3/23/10
to sage-devel
On 22 bře, 14:26, YURi KARADZhOV <yuri.karadz...@gmail.com> wrote:
> desolve(eq,y,ivar=x)
>
> which is really annoying. And what is worse - we get a wrong answer
>
> -((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - c)*e^(-a*x)
>
> but the right answer is
>
> -((a*x - 1)*b*e^(a*x)/a^2 + c*e^(a*x)/a - _C1)*e^(-a*x)
>
> where _C1 - arbitrary constant.
>
> Of course, if we don't use c as a variable in equation we will get a right
> answer, but another problem will rise. If we have a bunch of ODE and want
> their solutions to interact somehow, than we expect different arbitrary
> constant for each one. But sage uses one letter c in every solution, which
> causes problems.

See also http://trac.sagemath.org/sage_trac/ticket/6882 for similar
problems with %i and %e.

Robert

yuri.k

unread,
Mar 24, 2010, 7:46:17 AM3/24/10
to sage-devel
> I am not sure if this will work for DE's involving term like y'(a*x
> +b). But if you find a secure method how to find dependent and
> independent variables from derivative, you can also fix bughttp://trac.sagemath.org/sage_trac/ticket/7401

Neither Maple nor Maxima can solve the differential equation involving
function of symbolic expression y=function('y',a*x+b) It's not a
problem to determine what is differential function and what is it's
argument. But to solve such equation we should:
1. declare new variable t=a*x+b
2. express x in term of t x=(t-b)/a
3. substitute it into our equation and solve it
4. return to the old variable
All of this steps are able to be automatic. So I think they should be
implemented in desolve.

> Another related question: if we use topoly_solve=True in solve
> command, we get free variabkles, say z2 and z4, if we run the same
> command for the second time, we get other variables, say z_5 and z_7.
> Should we have similar behavior with free variables from desolve
> command? I think that it is better to get the same answer avery time
> when I solve the same equation.

Hmm.. It IS interesting question, but let's think why should we want
constants to be the same or different.
-If the constants are the same: it helps us to compare results we
obtain, but on the other hand it is hard to compute expression
depending on different general solution of the equation.
e.g. y'+y+1 have general solution c*exp(-x)-1
but if we want to find difference of two general solution we should
1. find all integration constants (which is unpleasant operation) - c
2. create new one - b
3. subs them into solution and find the difference which is (c-b)*exp(-
x)
-If the constants are different: it is really easy to compute any
expression of general solutions of equation. And what is better it is
also really easy to compare two solutions being the same. If sol1-sol2
is constant then solutions sol1 and sol2 are equal (the same)
So in my opinion it is better to make difference in constants cause
it's much more convenient to deal with.

> See also http://trac.sagemath.org/sage_trac/ticket/6882 for similar
> problems with %i and %e.

So.. an easy way is to use second way I proposed before. But the right
way is to implement native desolve command in sage. I wonder is there
any Lie algebra support in sage? Cause it will help a lot.

P.S.; I think of sage as a symbolic tool and find it kinda lame. So I
tried to improve it and make it more "symbolic sage" rather then
"native python". Actually it is possible to use mixins and be "native
python" and "symbolic sage" at the same time. But I don't need such
functionality, so I ask for opinions.

What is done - I implemented some sort of topology on existing types
(simple wraps) which is more like Maple ones. I post the code and the
article after a while to explain all good and bad sides of such
approach. I will need some help to finished my topology, cause I'm
sure it is not cover all the types.

P.P.S.: I don't understand diff function. It change the
differentiation order which is sometime is bad. It should be improved
too.

yuri.k

unread,
Mar 24, 2010, 9:04:28 AM3/24/10
to sage-devel
> -If the constants are different: it is really easy to compute any
> expression of general solutions of equation. And what is better it is
> also really easy to compare two solutions being the same. If sol1-sol2
> is constant then solutions sol1 and sol2 are equal (the same)
> So in my opinion it is better to make difference in constants cause
> it's much more convenient to deal with.

sol1-sol2 should depends on difference ci1-ci2 of course, but it is
still easier to implement

yuri.k

unread,
Mar 27, 2010, 3:38:50 PM3/27/10
to sage-devel
I add changes to the trac. So it will be possible to autodetect
dependent and independent variables in most cases (actually in all
cases sage is able to solve in this moment).

The same can be done with systems I guess and of course with bug
http://trac.sagemath.org/sage_trac/ticket/7401

Anyone who are interested in can do it in similar way (look through
http://groups.google.com/group/sage-devel/browse_thread/thread/f2ba2198dc5b79ed
to get help)

My opinion is - it is necessary to create native sage module to solve
ODE.

some new and easy to solve bugs:

sage: x,t=var('x t')
sage: f=function('f',x)
sage: g=function('g',t,x)
sage: de1=diff(f,x)+f+1
sage: de2=diff(g,x)+g+1
sage: dsolve(de1)
(c - e^x)*e^(-x)
sage: dsolve(de2)
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call
last)

/media/cellar/sage/sage-4.3.3-linux-64bit-ubuntu_9.10-x86_64-Linux/
<ipython console> in <module>()

/media/cellar/sage/sage-4.3.3-linux-64bit-ubuntu_9.10-x86_64-Linux/
local/lib/python2.6/site-packages/sage/calculus/desolvers.pyc in
desolve(de, dvar, ics, ivar, show_method, contrib_ode)
375 raise NotImplementedError, "Maxima was unable
to solve this ODE."
376 else:
--> 377 raise NotImplementedError, "Maxima was unable to
solve this ODE. Consider to set option contrib_ode to True."
378
379 if show_method:

NotImplementedError: Maxima was unable to solve this ODE. Consider to
set option contrib_ode to True.

In second case answer is the same, but c = function('c',t)

P.S.: Please look at http://groups.google.com/group/sage-devel/browse_thread/thread/f2ba2198dc5b79ed

yuri.k

unread,
Mar 27, 2010, 3:39:02 PM3/27/10
to sage-devel

yuri.k

unread,
Mar 27, 2010, 3:38:39 PM3/27/10
to sage-devel

yuri.k

unread,
Mar 27, 2010, 4:45:45 PM3/27/10
to sage-devel

ma...@mendelu.cz

unread,
Mar 28, 2010, 9:23:12 AM3/28/10
to sage-devel
I got some problems after installing the patch, see the comment at
trac.sagemath.org

yuri.k

unread,
Mar 28, 2010, 10:46:09 AM3/28/10
to sage-devel
On Mar 28, 4:23 pm, "ma...@mendelu.cz" <ma...@mendelu.cz> wrote:
> I got some problems after installing the patch, see the comment at
> trac.sagemath.org

I added new file sage/symbolic/mtype.py - which is symbolic module.
(it was marked as ? instead of M in patch log)
I think patch does not create new files. I'll try to figure it out and
fix the patch.

P.S.: If you have any ideas what should I do - please help me to save
some time.

David Joyner

unread,
Mar 28, 2010, 11:21:42 AM3/28/10
to sage-...@googlegroups.com
On Sun, Mar 28, 2010 at 10:46 AM, yuri.k <yuri.ka...@gmail.com> wrote:
> On Mar 28, 4:23 pm, "ma...@mendelu.cz" <ma...@mendelu.cz> wrote:
>> I got some problems after installing the patch, see the comment at
>> trac.sagemath.org
>
> I added new file sage/symbolic/mtype.py - which is symbolic module.
> (it was marked as ? instead of M in patch log)
> I think patch does not create new files. I'll try to figure it out and
> fix the patch.


Did you use hg_sage.add? It is explained here:
http://www.sagemath.org/doc/developer/producing_patches.html#quick-mercurial-tutorial-for-sage


>
> P.S.: If you have any ideas what should I do - please help me to save
> some time.
>

Message has been deleted

yuri.k

unread,
Mar 28, 2010, 1:12:49 PM3/28/10
to sage-devel

> Did you use hg_sage.add? It is explained here:http://www.sagemath.org/doc/developer/producing_patches.html#quick-me...

No I didn't. Thank you for your help. I almost ready with patch.

Burcin Erocal

unread,
Mar 28, 2010, 1:30:55 PM3/28/10
to sage-...@googlegroups.com
Hi Yuri,

Thank you for taking the time to fix the problems you see in the
symbolic module.

I suggest that you provide two different patches instead of bundling
all your changes together. One for the desolve fixes, and another one
for your mtype interface.

Note that each trac ticket should be on one issue only [1].

[1]
http://www.sagemath.org/doc/developer/trac.html#reasons-to-invalidate-tickets


This way, your fixes for the desolve function can go through the review
process quickly. I suppose the mtype interface will need to be
discussed longer. (I'll comment on it when I have more time.)


Cheers,
Burcin

yuri.k

unread,
Mar 28, 2010, 1:56:33 PM3/28/10
to sage-devel
> I suggest that you provide two different patches instead of bundling
> all your changes together. One for the desolve fixes, and another one
> for your mtype interface.
>
> Note that each trac ticket should be on one issue only [1].
>
> [1]http://www.sagemath.org/doc/developer/trac.html#reasons-to-invalidate...

>
> This way, your fixes for the desolve function can go through the review
> process quickly. I suppose the mtype interface will need to be
> discussed longer. (I'll comment on it when I have more time.)
>
> Cheers,
> Burcin

Unfortunately I can't afford to separate patches. The problem is - my
1Gb memory computer give me allocate memory errors and the clone
process stops. Even if it is succed - it takes about 20 minutes. So it
is pain for me to do another patch. Actually I use symbolic module to
deal with desolve problems so you need all functionality. If you are
able to make different patches - I can send you whatever file you ask
for.

P.S.: patch is in the trac

Regards
Yuri Karadzhov

yuri.k

unread,
Mar 29, 2010, 5:58:49 AM3/29/10
to sage-devel
> ivars = set(dvar.arguments()).intersection(extract_var_from_diff(de))

I forgot to make intersection in first patch. Changes are in the
second one.

It helps us to solve

sage: x,t=var('x
t')
sage:
f=function('f',x)
sage:
g=function('g',t,x)

sage: de=diff(f,x)+f+diff(g,t,x)
sage: desolve(de,f)
(c - integrate(e^x*D[0, 1](g)(t, x), x))*e^(-x)

without specifying of independent variable.

ma...@mendelu.cz

unread,
Apr 9, 2010, 3:28:23 AM4/9/10
to sage-devel
Hi Yuri,

thanks for working on this topis, it is a nice idea to extract
variables from ODE automatically. I vote also for splitting into two
patches and if you have problems with this, I can try it to split them
by myself. Anyway, the ODE patch depends on the mtype interface and
this interface should be the first one which should got positive
review.

However giving positive review exceeds my skills. I looked at the code
and I have seen that you test (startin gon line 202), if a function
equals this or that function. I think that each time when someone adds
new symbolic function to Sage (hope someone adds Bessel functions as
symbolic functions :), see [1]) or if someone decides to work with
another arccot function than sage.functions.trig.Function_arccot, this
interface becomes broken. Is there any cleaner way how to implement
mtype? I am not clever enough in Pyhton, but I think that a better
solution must exist.

Thank you for working on this


Robert Marik

[1] http://groups.google.cz/group/sage-support/browse_thread/thread/10935806a04b79cb/d3f2e3c4a18ff491

yuri.k

unread,
Apr 10, 2010, 12:14:08 PM4/10/10
to sage-devel
> thanks for working on this topis, it is a nice idea to extract
> variables from ODE automatically. I vote also for splitting into two
> patches and if you have problems with this, I can try it to split them
> by myself. Anyway, the ODE patch depends on the mtype interface and
> this interface should be the first one which should got positive
> review.

It will be great if you can help to split the patches.

> However giving positive review exceeds my skills. I looked at the code
> and I have seen that you test (startin gon line 202), if a function
> equals this or that function. I think that each time when someone adds
> new symbolic function to Sage (hope someone adds Bessel functions as
> symbolic functions :), see [1]) or if someone decides to work with
> another arccot function than sage.functions.trig.Function_arccot, this
> interface becomes broken. Is there any cleaner way how to implement
> mtype? I am not clever enough in Pyhton, but I think that a better
> solution must exist.

The best way to solve this problem is - to implement all different
symbolic and python type as different classes with presented
hierarchy, but it's lot of work because sage is big project now. This
approach was acceptable at the planing satge, but now it is too hard.
The second one is what I proposed - implement simple interface which
gather all existing classes unify methods and provide symbolic (text)
type. If someone adds new function or type - the interface defined it
as 'unknown' which means it should be added to the interface or may be
it should be accessed some other way. It is impossible to predict
what type or class will be added furthe so it is impossible to predict
'unknown' types without changing mtype.

Actually there is one way. As Python types are staying stable I
recommend to add mtype function to SymbolicExpression class. So mtype
interface can check if it is SymbolicExpression and if it is it just
call mtype function of it. The benefit is - if someone wants to add
new symbolic function (extend Symbolic expression class) than mtype
function should be implemented and there is no need to change basic
mtype interface.

As I wrote It is only good sketch which can be really helpful (as you
can see on dsolve exapmple). Now I am concentrated on my articles so
unfortunately I can't spend much time on sage. But sketch is clear and
I explain all Ideas how it can be extended or reimplemented.

Thank You for spend Your time on review

Sincerely,
Yuri Karadzhov

Reply all
Reply to author
Forward
0 new messages