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 ...
> 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?
> 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
-~----------~----~----~----~------~----~------~--~---