its commit:bfbd7711354ea4826a231e6712d34f8bb2801d44

In [8]: hint = 'nth_linear_constant_coeff_variation_of_parameters'

In [9]: eq6 = f(x).diff(x, 2) - 2*f(x).diff(x) - 8*f(x) - 9*x*exp(x) -
10*exp(-x)

In [10]: sol6 = Eq(f(x), -x*exp(x) - 2*exp(-x) + C1*exp(-2*x) + C2*exp(4*x))

In [11]: d6 = dsolve(eq6, f(x), hint=hint)

In [12]: d6 == sol6
Out[12]: False

In [13]: d6
Out[13]:
                         -x              /      -5*x    -3*x      -3*x\
       /      x\  x   5*e         -2*x   |     e       e       x*e    |  4*x
f(x) = |1/6 - -|*e  - ----- + C1*e     + |C2 - ----- - ----- - -------|*e
       \      2/        3                \       3       6        2   /

In [14]: sol6
Out[14]:
            x      -x       -2*x       4*x
f(x) = - x*e  - 2*e   + C1*e     + C2*e

-- Andy

On Thu, Aug 20, 2009 at 11:43 AM, Aaron S. Meurer<asmeu...@gmail.com> wrote:
>
> What is your SHA1 hash of HEAD?  This test passes just fine on my
> machine.  Could you maybe copy eq6 from the test file and run
>
> dsolve(eq6, f(x),
> hint='nth_linear_constant_coeff_variation_of_parameters')
>
> and paste the result here?
>
> Aaron Meurer
> On Aug 20, 2009, at 9:44 AM, Andy Ray Terrel wrote:
>
>>
>> Running tests on HEAD I get the following error:
>>
>> sympy/solvers/tests/
>> test_ode.py:test_nth_linear_constant_coeff_variation_of_parameters
>>  File "/Users/aterrel/workspace/sympy/sympy/solvers/tests/
>> test_ode.py",
>> line 899, in test_nth_linear_constant_coeff_variation_of_parameters
>>    assert dsolve(eq6, f(x), hint=hint) == sol6
>> AssertionError
>>
>> tests finished: 1615 passed, 1 failed, 2 skipped, 44 xfailed, 1
>> xpassed in 333.83 seconds
>>
>>
>> -- Andy
>>
>> On Thu, Aug 20, 2009 at 6:23 AM, Vinzent
>> Steinberg<vinzent.steinb...@googlemail.com> wrote:
>>> Thank you, this is an impressive result. :)
>>>
>>> 2009/8/20 Aaron S. Meurer <asmeu...@gmail.com>
>>>>
>>>> I have finished up my Google Summer of Code 2009 project, which
>>>> was to
>>>> implement various ODE solvers in SymPy.  Please pull
>>>> fromhttp://github.com/asmeurer/sympy/tree/odes-review
>>>> .  Note that I have elected to do only moderate rebasing from my
>>>> original tree (branch odes), so you should really only be reviewing
>>>> the HEAD.
>>>>
>>>> This includes the following features:
>>>>
>>>> - All ODE solving now happens in ode.py, instead of solvers.py where
>>>> it was crowding stuff.
>>>> - dsolve() remains the function to use to solve an ODE.  The
>>>> syntax is
>>>> the same for default solving: dsolve(ode, func).
>>>> For example:
>>>>  >>> dsolve(diff(f(x), x, 2) - 1, f(x))
>>>> f(x) == C1 + C2*x + x**2/2
>>>>
>>>> dsolve() always returns an Equality instance, because it very often
>>>> cannot solve for f(x) and must return an implicit solution.
>>>>
>>>> - The function classify_ode() was added.  This function classifies
>>>> ODEs into the various methods (or "hints", as I also call them) that
>>>> dsolve() can use to solve them.
>>>> For example:
>>>>  >>> classify_ode(f(x).diff(x) - 1, f(x))
>>>> ('separable', '1st_exact', '1st_linear', 'Bernoulli',
>>>> '1st_homogeneous_coeff_best',
>>>> '1st_homogeneous_coeff_subs_indep_div_dep',
>>>> '1st_homogeneous_coeff_subs_dep_div_indep',
>>>> 'nth_linear_constant_coeff_undetermined_coefficients',
>>>> 'nth_linear_constant_coeff_variation_of_parameters',
>>>> 'separable_Integral', '1st_exact_Integral', '1st_linear_Integral',
>>>> 'Bernoulli_Integral',
>>>> '1st_homogeneous_coeff_subs_indep_div_dep_Integral',
>>>> '1st_homogeneous_coeff_subs_dep_div_indep_Integral',
>>>> 'nth_linear_constant_coeff_variation_of_parameters_Integral')
>>>>
>>>> - The function deriv_degree() remains the function to use for
>>>> determining the degree, or order, of an ODE.
>>>> For example:
>>>>  >>> deriv_degree(f(x).diff(x, 5) + sin(x) + f(x).diff(x, 2), f(x))
>>>> 5
>>>>
>>>> - The new function checkodesol() checks if a solution to an ODE is
>>>> valid by substituting it in and either returning True if it finds 0
>>>> equivalence or the expression that it could not reduce to 0.
>>>> For example:
>>>>  >>> checkodesol(f(x).diff(x, 2) - 1, f(x), Eq(f(x), C1 + C2*x +
>>>> x**2/2))
>>>> True
>>>>  >>> checkodesol(f(x).diff(x, 2) - 1, f(x), Eq(f(x), C1 + C2*x +
>>>> x**2))
>>>> 1
>>>
>>> This is problematic, because this way
>>>
>>> if not checkodesol(...):
>>>     print 'not a solution'
>>>
>>> does not work, because most expressions evaluate to True. I'd prefer
>>> returning just 0 instead of True, this is more consistent and useful.
>>>
>>>>
>>>> - The function separatevars(), which I wrote to help with the 1st
>>>> order separable method, attempts to intelligently separate variables
>>>> an expression  multiplicatively.
>>>> For example:
>>>>  >>> separatevars(x**2 + x**2*sin(y))
>>>> x**2*(1 + sin(y))
>>>>  >>> separatevars(exp(x + y))
>>>> exp(x)*exp(y)
>>>>
>>>> This function resides in simplify.py.
>>>>
>>>> - The new function homogeneous_order(), which I wrote to help with
>>>> the
>>>> 1st order ODE with homogeneous coefficients method, determines the
>>>> homogeneous order of an expression.  An expression F(x, y, ...) is
>>>> homogeneous of order n if F(x*t, y*t, t*...) == t**n*F(x, y, ...).
>>>> For example:
>>>>  >>> homogeneous_order(x**2*sqrt(x**2 + y**2) + x*y**2*sin(x/y),
>>>> x, y)
>>>> 3
>>>>
>>>> - dsolve() will simplify arbitrary constants, and renumber them in
>>>> order in the expression.  You should never see something like x +
>>>> 2*C1
>>>> or 1 + C2*x + C1*x**2 returned from dsolve().  You can disable
>>>> this by
>>>> using simplify=False in dsolve().
>>>>
>>>> - Internally, the solving engine has been completely refactored.
>>>> The
>>>> old way was to match the ODE to various solvers in a predetermined
>>>> order, and as soon as it matched one, it would solve it using that
>>>> method and return a result.  This had several problems with it.
>>>>
>>>> First, several ODEs can be solved with more than one method (c.f.
>>>> the
>>>> simple ODE in the classify_ode() example above), and sometimes you
>>>> want to see the result from a different method.
>>>>
>>>> Second, sometimes the default solver would return a result that was
>>>> much more complex than another one would have returned if the ODE
>>>> had
>>>> gotten to it.  For example, it may return an implicit solution
>>>> that is
>>>> difficult for solve() to solve, whereas the other method would
>>>> return
>>>> the equation already solver.
>>>
>>>
>>> typo
>>>
>>>>
>>>>  Another common case is that one method
>>>> would set up an integral that integrate() could not do, whereas
>>>> another method would set up a simpler integral.  That leads to the
>>>> third point.
>>>>
>>>> Third, whenever a solver would set up a hard integral, integrate()
>>>> would either hand for a while then return an Integral, or it would
>>>> hang forever.  Either way, you would get an unevaluatable (by SymPy)
>>>> integral, when sometimes another method might not give you that.
>>>>
>>>> Fourth, there was a lot of code duplicated this way.  For example,
>>>> whenever a method had the potential to return an implicit
>>>> solution, it
>>>> had to duplicate the same code chunk that tried to solve it and
>>>> return
>>>> a solved solution if it could be solved or else an implicit
>>>> solution.
>>>>
>>>> The new way is for dsolve to have an optional hint argument that you
>>>> can use to specify whatever method you want to use, if it fits.
>>>> dsolve() calls classify_ode() on the ODE and gets all of the
>>>> possible
>>>> hints.  By default, hint="default" is used, which uses a
>>>> predetermined
>>>> order, much like the old way.  But you can easily use something like
>>>> hint="1st_exact" to change the hint from the default method to the
>>>> 1st
>>>> order exact ODE solver.  Aside from "default", there are also some
>>>> other 'meta-hints' that you can use.  "all" will return a dictionary
>>>> of hint: solution terms for all matching hints.  "best" will use a
>>>> heuristic to return the simplest of all possible solutions.  This
>>>> heuristic is based on whether the solution has unevaluated Integrals
>>>> in it, whether it can be solved explicitly, and finally, just which
>>>> one is the shortest.  All hints that set up integrals also have a
>>>> coresponding "hint_Integral" hint, which will not attempt to
>>>> evaluate
>>>> the integrals but instead return unevaluated Integrals in the
>>>> solution.  "all_Integral" acts like "all", but it skips hints that
>>>> attempt to evaluate integrals.  This is so you can quickly get an
>>>> unevaluated integral of something you know SymPy cannot do,
>>>> instead of
>>>> letting integrate() hang.  It also lets you discover how the solvers
>>>> work by showing you what integrals they do.
>>>>
>>>> - Along with extensive documentation on all of the functions, I have
>>>> included a guide in the module docstring on how to add more
>>>> methods to
>>>> the module using the hints system.  It can give you an idea of how
>>>> the
>>>> system works internally.
>>>>
>>>>
>>>> The following ODE solving methods have been implemented.  See the
>>>> internal docstrings for more information on each method:
>>>> - 1st order separable differential equations
>>>> - 1st order differential equations whose coefficients or dx and dy
>>>>  are functions homogeneous of the same order.
>>>> - 1st order exact differential equations.
>>>> - 1st order linear differential equations.  (this is already
>>>> implemented in the current SymPy)
>>>> - 1st order Bernoulli differential equations. (this is already
>>>> implemented in the current SymPy by a patch I sent in in the spring)
>>>> - 2nd order Liouville differential equations.
>>>> - nth order linear homogeneous differential equation with constant
>>>>  coefficients.
>>>> - nth order linear inhomogeneous differential equation with constant
>>>>  coefficients using the method of undetermined coefficients.
>>>> - nth order linear inhomogeneous differential equation with constant
>>>>  coefficients using the method of variation of parameters.
>>>>
>>>> In addition to the ode module, this branch includes fixes to the
>>>> following issues, which were necessary for me throughout my work:
>>>> - Issues 1582, 1566, 1530, and 1429 (the first part only).
>>>> - Integral.__getnewargs__ now properly works.  If r is an Integral
>>>> instance, then r == r.new(r.__getnewargs__(r.args)) should always be
>>>> True.
>>>> - Changed two assertions and one raise TypeError in solve() to raise
>>>> NotImplementedError.  This way, you do not have to check for
>>>> AssertionError or TypeError to see if solve() has failed, only
>>>> NotImplementedError.  See issues 1425 and 1338.
>>>
>>> I'll have to play around with this. :)
>>>
>>> Vinzent
>>>
>>>>
>>>
>>
>> >
>
>
> >
>

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

Reply via email to