So before I spend a lot of time implementing this, I figured it would  
be a good idea to get some feedback here on what I plan on doing.

As most of you probably know, my Google Summer of Code project is to  
improve the ordinary differential equation solving capabilities of  
SymPy.  So far, I have been able to implement quite a few methods  
(though none of them except for Bernoulli have actually made it in  
yet).  Just for 1st order alone, dsolve, in my branch, can solve  
linear, Bernoulli, exact, first order equations with homogeneous  
coefficients, and I am finishing separable equations.  Each of these  
is rather simple for the most part.  dsolve matches the equation to a  
pattern, and as soon as it finds a pattern that it fits, for example  
a(x)*b(f(x)) + c(x)*d(f(x))*f'(x) for separable, then it applies the  
appropriate solution, which usually just involves rearranging the  
matched terms in an integral.

The thing is that, sometimes, an ODE can fit more than one kind of  
pattern, expecially for first order ODE's.  Here is an example:

2xy + (x**2 + y**2)*dy/dx is exact, because ∂(2xy)/∂y == ∂(x**2 +  
y**2)/∂x == 2x (those are partials, in case they don't render).   
Also, the substitutions u == y/x and v == x/y make the equation  
separable, because the terms are homogeneous of the same order (see my  
blog: 
http://asmeurersympy.wordpress.com/2009/05/31/first-order-differential-equations-with-homogeneous-coefficients/)
 
.  These three methods produce the same result written in three  
different ways (the solution is not solvable in y, so SymPy would  
return all three ways as they are).  The three ways are:
exact:  x**2*y + y**3/3 == C1
substitution u == y/x:  x == C2(y**3/x**3+3y/x)**(-1/3)
substitution u == x/y:  y == C3(3x**3/y**3+1)**(-1/3)

These three solutions are all equivalent, though the arbitrary  
constants in each one are not necessarily equal to one another (see my  
blog post for a proof of their equivalence).  Because the arbitrary  
constants are not equal, SymPy would be unable to recognize their  
equivalence (though I hope to fix this with issue 1336).

So as you can see, many differential equations can be solved in more  
than one way.  Currently, dsolve just spits out the solution for the  
first method that it matches the ODE to.  I would like to have it so  
that the user can choose to return a different (equivalent) solution  
if he wants to.

So here is what I propose.  Please let me know if you think this is a  
good idea and how it could be improved upon:

First, create the function classify_ode.  The function will apply  
match patterns to an ode and return a list of strings of possible  
patterns, like ("exact", "1st_homogeneous_coeff",  
"1st_homogeneous_coeff_alt") for the above.  The list would be ordered  
such that dsolve would use the first hint by default.  I would  
determine the default ordering based on testing of many odes to see  
which methods generally return cleaner solutions than others.  Also,  
dsolve will call the function as classify_ode(ode, match=True) (what  
is a better word than match?), and it will return a dict with the key  
type set to the first string that would be returned in the list, and  
the other keys are the match keys that dsolve needs to solve the ode  
(that way it doesn't have to match it twice).

For hints like "1st_homogeneous_coeff" which always have two possible  
solutions, there will be two hints, one with '_alt' at the end.  The  
'_alt' one is chosen so that the one without '_alt' is the better one  
based on a metric (see below).  Another option would be to use  
"1st_homogeneous_coeff_f(x)/x" and "1st_homogeneous_coeff_x/f(x)",  
which is more explicit, but doesn't allow classify_ode to place the  
better one first without evaluating integrals (which I don't want to  
do, because the integrals for those problems tend to be hard and takes  
SymPy some time).  I could also just use all 4.  The only disadvantage  
with that is that it would be redundant, though I don't think it would  
be ambiguously so.

Also, what is the best hint name for "1st_homogeneous_coeff_f(x)/x"?   
The function and independent variable might not necessarily be f and  
x, but I want the hint name to be same regardless of the function.  Is  
it clear enough that that means "function divided by independent  
variable", regardless of whether those happen to be f and x or not?   
Of course, it would all be in the docstring.

Second, add the following to dsolve:  add default argument  
hint="default" (so dsolve(ode, function, hint="default").  If hint is  
set to a different hint from classify_ode, then it will return the  
solution based on that method (of course, if hint is something that  
isn't a supported type or doesn't match the ode, it will raise an  
exception).  Also, hint="all" would return a dict of method:solution  
items, and hint="best" would try all fitted methods and return the one  
that is the simplest based on a metric (contains no Integral class  
(i.e., unsolvable integrals), solvable in the function, and shortest  
expression, in that order. Any other good ideas for this?).

So what do you think?  Is this a good strategy?  Are there any good  
features that I could add?  Sorry for the kind of long post.

Aaron Meurer
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sympy@googlegroups.com
To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sympy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to