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