On Jun 25, 2009, at 5:51 AM, Fabian Pedregosa wrote:

>
> Aaron S. Meurer wrote:
>> 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).
>
> That's nice. It is similar to function guess_solve_strategy in
> sympy.solvers (consider naming these two functions is a similar  
> fashion)
>
>>
>> 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"?
>
> Maybe passing a hints dict: {'type': 'homegeneous', 'lst': True,
> 'coeff': f, 'args': x} or a tuple ...
This seems way more complex than I want.  I think if I document that  
f(x) refers to function and x refers to the independent variable in  
the docstring of classify_ode that it shouldn't be too ambiguous.
>
>> 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.
>>
>
> Seems to me a good strategy. Any ideas how do other CAS implement this
> classification/solving strategy?
Maple has a very expansive ode classification system.  If you do  
with(DEtools);
you get among other things a function odeanalyser, which is about the  
same as my proposed classify_ode.  You can add the classifications as  
arguments to dsolve to have it solve in that way.  See also 
http://www.maplesoft.com/support/help/view.aspx?path=DEtools/odeadvisor 
  and some of the stuff in the side bar under Differential Equations.

I have no idea what Mathematica does, as I do not own it.
>
>> Aaron Meurer
>>>
>>
>
>
> -- 
> http://fseoane.net/blog/
>
> >


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

Reply via email to