If you look at the code in dmp_cancel(), it is special-cased for f == 0 or g == 0, in which case it just returns f, g for include=True or K.one, K.one, f, g for include=False. So there is no bug, per se, just a design flaw.
I think you wrote this code. Is there a reason you special-cased this? Perhaps for speed? Or maybe some stuff fails when g == 0 (I didn't try it)? Aaron Meurer On Tue, Jul 19, 2011 at 9:10 PM, Mateusz Paprocki <[email protected]> wrote: > Hi, > > On 20 July 2011 05:02, Aaron Meurer <[email protected]> wrote: >> >> Hi. >> >> This question is mainly for Mateusz, but I encourage others to chime >> in too if they have an opinion. >> >> I need the following behavior in the polys: >> >> >>> Poly(0, t).cancel(Poly(t, t), include=True) >> (Poly(0, t), Poly(1, t)) >> >> Whereas it currently does the following: >> >> >>> Poly(0, t).cancel(Poly(t, t), include=True) >> (Poly(0, t), Poly(t, t)) >> >> (notice that the denominator is reduced to 1 in the first case and >> left alone in the second). I need the former to make it easier to >> deal with zero rational functions in my Risch code. >> >> Now, this is one of four possibilities in cancel. They are: >> >> 1. Poly(0, t).cancel(Poly(t, t), include=True) # 0/q include=True; >> this is the one I use >> 2. Poly(0, t).cancel(Poly(t, t), include=False) # 0/q include=False >> 3. Poly(t, t).cancel(Poly(0, t), include=True) # p/0 include=True >> 4. Poly(t, t).cancel(Poly(0, t), include=False) # p/0 include=False >> >> I did not change 2-4 in my branch yet because I only ever use the >> first idiom in my code, but I think we should try to make it >> consistant. So my questions are: >> >> - Should 2 return a one denominator too? I don't actually care if it >> does, but it seems like it should to be consistant with 1. >> - What should the returned coefficient from 2 be? I never actually >> use include=False, so I don't really have a feel for this. >> - Should 3 and 4 even work? To me they should raise an exception, but >> maybe it isn't necessary to think of f.cancel(g) as f/g (though that >> is what the docstring says). > > I didn't yet analyze all the cases pointed out above, but it seems there is > a bug in cancel(): > In [1]: gcd(0, t) > Out[1]: t > In [2]: Poly(0, t).cancel(Poly(t, t)) > Out[2]: (1, Poly(0, t, domain='ZZ'), Poly(t, t, domain='ZZ')) > gcd(0, something) always returns something, thus no matter what `include` is > set to, cancel() whould give Poly(1, t) as the denominator. Note that > cofactors() works correctly: > In [3]: Poly(0, t).cofactors(Poly(t, t)) > Out[3]: (Poly(t, t, domain='ZZ'), Poly(0, t, domain='ZZ'), Poly(1, t, > domain='ZZ')) > (it gives GCD, cofactor(lhs), cofactor(rhs)). > >> >> Aaron Meurer >> >> -- >> 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. >> > > Mateusz > > -- > 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. > -- 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.
