Thanks for your reply Aaron. I've suggested a possible solution and
patch at issue 1685 which does not appear to affect your ode.py code.

http://code.google.com/p/sympy/issues/detail?id=1685&sort=-id

This is my first attempt to contribute a patch to sympy (or any other
project) so please forgive any errors! If anyone has time to review
this issue and offer advice I would be grateful.

Cheers,
andy

(I think the problem is caused by an attempted performace optimisation
in simplify.py, which tries to avoid calling a function make_expression
(..) but fails to handle the general case.)

On Oct 25, 11:07 pm, "Aaron S. Meurer" <asmeu...@gmail.com> wrote:
> See ode.py, line 542 for at least one place where the collecting of  
> derivatives is used.  In this case, it says collect(eq, f(x).diff(x))
> Changing this to collect(eq, f(x)) causes almost all tests in  
> test_ode.py to fail (meaning it doesn't collect in the same way).
>
> The behavior of collect to collect derivatives existed long before  
> that line in ode.py (which I wrote), so I wouldn't be surprised if it  
> is used somewhere else.
>
> By the way, this issue looks similar to issue 1644 (closed). I don't  
> know if they are related at all though.
>
> Also, if you create a fix that breaks line 542 in ode.py, my comment  
> #4 applies.  I was just taking advantage of the existing behavior, so  
> if it changes the code I used can change too.
>
> Aaron Meurer
> On Oct 25, 2009, at 4:24 PM, andy2O wrote:
>
>
>
> > Ok - here's the result of a little digging: In collect(...), which
> > lives in simplify.py, an expression is parsed by a sub-function called
> > 'parse_expression(...), split, and then recreated. By turning
> > SYMPY_DEBUG to True, you find:
>
> >>>> a=Derivative(f(x),x)
> >>>> collect(a,f(x))
> > DEBUG: parsing of expression [(f(x), 1, None, (x, 1))] with symbol f
> > (x)
> > DEBUG: returned ([], [(f(x), 1, None, (x, 1))], 1, False)
> >                                      ^^^^^^
> >                                       This indicates the first order
> >                                       derivative w.r.t. x.
>
> > So parse_expression(...) considers that Derivative(f(x),x) matches the
> > pattern f(x). From the 'collect(...)' docstring I guess this is
> > deliberate, and sometimes useful?
>
> > However, in the definition of 'collect' around line 650 of
> > simplify.py, the following code is used to rebuild an expression from
> > the output of 'parse_expression(...)'. This rebuilding code ignores
> > derivatives when it is reconstructing the expression:
>
> >           if result is not None:
> >                terms, elems, common_expo, has_deriv = result
>
> >                # when there was derivative in current pattern we
> >                # will need to rebuild its expression from scratch
> >                if not has_deriv:
> >                    index = 1
> >                    for elem in elems:
> >                        index *= Pow(elem[0], elem[1])
> >                        if elem[2] is not None:
> >                            index **= elem[2]
>
> > Note how elem[3], which contains information about any derivatives, is
> > involved is not used at all in rebuilding the expression. Also note
> > that the 'if not has_deriv' test applies to the pattern, not the
> > expression.
>
> > I think this is where the error is, but I'm not quite sure what the
> > desired fix should be:
>
> > 1) Should parse_expression(...) be changed to not match derivatives
> > when given a function?
> > 2) Or should the above code that rebuilds the expression be changed?
> > 3) Or something else?
>
> > I think something needs changing, as:
>
> >>>> collect(5*f(x)+3*Derivative(f(x),x),f(x))
> > 8*f(x)
>
> > is clearly wrong!!
>
> > Thanks for your help.
> > Andy
>
> > On Oct 25, 6:47 pm, andy2O <and...@hotmail.com> wrote:
> >> Thanks for your replies.
>
> >> as_coeff_exponent(...) does the right thing for the (similar)  
> >> Integral
> >> operation on f(x), so I'm not sure big changes are needed to fix this
> >> little glitch.
>
> >> I think this traces back to something slightly strange in  
> >> sympy.collect
> >> (...) which is used by as_coeff_exponent. The behaviour for the  
> >> fourth
> >> line of input below seems odd.
>
> >> I'll dig a little more and see what I find.
>
> >> Cheers,
> >> andy
>
> >>>>> Integral(f(x),x).as_coeff_exponent(f(x)) #This is OK
>
> >> (Integral(f(x), x), 0)>>> Derivative(f(x),x).as_coeff_exponent(f
> >> (x)) #This is what I first posted about, seems very odd.
> >> (1, 1)
> >>>>> collect(Integral(f(x),x),f(x),evaluate=False) #This seems OK.
>
> >> {1: Integral(f(x), x)}>>> collect(Derivative(f(x),x),f
> >> (x),evaluate=False) #This looks odd to me - collect has lost track  
> >> of the derivative.
>
> >> {f(x): 1}
>
> >> also:
>
> >>>>> collect(Derivative(2*f(x),x,x),f(x),evaluate=False) #Probably  
> >>>>> OK...
>
> >> {1: D(2*f(x), x, x)}>>> collect(2*Derivative(f(x),x,x),f
> >> (x),evaluate=False) #Weird result again - collect loses derivative  
> >> operation again.
>
> >> {f(x): 2}
>
> >> On Oct 22, 10:47 pm, Ondrej Certik <ond...@certik.cz> wrote:
>
> >>> On Thu, Oct 22, 2009 at 3:43 PM, Ronan Lamy <ronan.l...@gmail.com>  
> >>> wrote:
>
> >>>> Le jeudi 22 octobre 2009 à 14:42 -0700, Ondrej Certik a écrit :
> >>>>> On Thu, Oct 22, 2009 at 2:34 PM, andy2O <and...@hotmail.com>  
> >>>>> wrote:
>
> >>>>>> Hi all,
>
> >>>>>> as_coeff_exponent(...) seems to ignore derivatives, as shown  
> >>>>>> below
>
> >>>>>> Is this behaviour intended? If so I can report it as an issue  
> >>>>>> - but
> >>>>>> last time recorded an issue it turned out I just misunderstood  
> >>>>>> atoms
> >>>>>> (), so I thought I'd check first here! :)
>
> >>>>> Sure. :)
>
> >>>>>> Thanks,
> >>>>>> andy
>
> >>>>>>>>> ================================ RESTART  
> >>>>>>>>> ================================
> >>>>>>>>> from sympy import *
> >>>>>>>>> var('x')
> >>>>>> x
> >>>>>>>>> f=Function('f')
> >>>>>>>>> d=diff(f(x),x)
> >>>>>>>>> d
> >>>>>> D(f(x), x)
> >>>>>>>>> d.as_coeff_exponent(f(x))
> >>>>>> (1, 1)
>
> >>>>> What do you suggest to be a correct answer?  I never used
> >>>>> as_coeff_exponent inside a derivative.
>
> >>>>> Ondrej
>
> >>>> The correct answer is clearly (D(f(x), x), 0), by analogy with
> >>>> cos(x).as_coeff_exponent(sin(x)) == (cos(x), 0). So, yes, Andy,  
> >>>> you've
> >>>> uncovered a real issue.
>
> >>>> I think that the fundamental problem here is that there is no  
> >>>> object
> >>>> representing the derivative of a function (the current Derivative  
> >>>> is an
> >>>> operation applying to expressions, not functions).
>
> >>> Yes, I think the Derivative should be improved to be able to  
> >>> represent
> >>> a general derivative of a function f(x).
>
> >>> Ondrej
>
>
--~--~---------~--~----~------------~-------~--~----~
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