Implementing numerator and denominator for multivariate polynomials [with patch]

27 views
Skip to first unread message

luisfe

unread,
Jul 9, 2009, 3:24:44 AM7/9/09
to sage-devel
Hi,

Some days ago I sent a bug report using the notebook link to the
google docs
form. I am unable to find that bug report on the web.

Anyway as the thing is trivial I wrote a patch myself.

The problem is that multivariate polynomials do not admit numerator
and
denominator

sage: K.<x,y>=QQ['x,y']
sage: f=x+y
sage: numerator(f)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call
last)

/home/luisfe/.sage/temp/mychabol/5681/
_home_luisfe__sage_init_sage_0.py in
<module>()

/opt/SAGE/sage/local/lib/python2.5/site-packages/sage/misc/
functional.pyc in
numerator(x)
686 if isinstance(x, (int, long)):
687 return x
--> 688 return x.numerator()
689
690 def numerical_approx(x, prec=None, digits=None):

AttributeError: 'sage.rings.polynomial.multi_polynomial_libsingular'
object
has no attribute 'numerator'


Although numerator and denominator are expectoed for rational
functions only
they might be needed, once would like to write an algorithm valid for
both
polynomials and rational functions, for example the following code in
the same
session:

sage: g=y
sage: h=1-y
sage: (f/(g)).numerator()
x + y
sage: (f/(g+h)).denominator()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call
last)

/home/luisfe/.sage/temp/mychabol/5681/
_home_luisfe__sage_init_sage_0.py in
<module>()

AttributeError: 'sage.rings.polynomial.multi_polynomial_libsingular'
object
has no attribute 'denominator'

In the first case, the fraction is created and the numerator has a
meaning. In
the second the fraction is never created and the code fails.

I have writen a trivial patch for the class MPolynomial. I am not sure
if
denominator should return 1 or self.parent(one) I write 1 because it
seems
inoffensive to me

diff -r 2e793d2a0e12 sage/rings/polynomial/multi_polynomial.pyx
--- a/sage/rings/polynomial/multi_polynomial.pyx Thu Jun 18
23:52:34
2009 -0700
+++ b/sage/rings/polynomial/multi_polynomial.pyx Thu Jul 09
00:05:29
2009 -0700
@@ -980,6 +980,28 @@
from sage.structure.factorization import Factorization
return Factorization(v, unit)

+ def numerator(self):
+ """
+ Numerator of a polynomial
+
+ EXAMPLES:
+ sage: K.<x,y> = QQ['x,y']
+ sage: f = x + y
+ sage: f.numerator()
+ x + y
+ """
+ return self
+
+ def denominator(self):
+ """
+ Denominator of a polynomial
+ EXAMPLES:
+ sage: K.<x,y> = QQ['x,y']
+ sage: f = x + y
+ sage: f.denominator()
+ 1
+ """
+ return 1


cdef remove_from_tuple(e, int ind):

John Cremona

unread,
Jul 9, 2009, 4:34:03 AM7/9/09
to sage-...@googlegroups.com
I can see another problem here. One could argue that the
denominator of (x+y)/2 was 2 while you code gives 1. So the
documentation needs to be very clear, stating that the denominator of
ever polynomial in any number of variables over a field is always 1.

John

2009/7/9 luisfe <lfta...@yahoo.es>:
Message has been deleted

William Stein

unread,
Jul 9, 2009, 4:36:38 PM7/9/09
to sage-...@googlegroups.com
On Thu, Jul 9, 2009 at 1:34 AM, John Cremona<john.c...@gmail.com> wrote:
>
> I can see another problem here.    One could argue that the
> denominator of (x+y)/2 was 2 while you code gives 1.  So the
> documentation needs to be very clear, stating that the denominator of
> ever polynomial in any number of variables over a field is always 1.
>
> John

John raises an extremely important and subtle point. This is a
*MAJOR* problem since currently we have
{{{
sage: R.<x> = QQ[]
sage: denominator(x/2)
2
}}}
however you're proposing making it so
{{{
sage: R.<x,y> = QQ[]
sage: denominator(x/2)
1
}}}

That's very worrisome, simply because it is inconsistent. Either you
change the existing code for univariate polynomials, hence break
backwards compatible that can possibly result in subtle errors all
over the place (in the sage library and in random user code "out
there"), or you change the semantics of denominator for multivariate
polynomials to be consistent with the semantics for univariate
polynomials.

For the record, Magma has a Denominator function that is defined for
about 15-20 different types, but does not apply to multivariate
polynomials.
--
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

luisfe

unread,
Jul 10, 2009, 4:08:28 AM7/10/09
to sage-devel


On 9 jul, 16:36, William Stein <wst...@gmail.com> wrote:
Good point. The thing is not clear:

{{{
sage: R.<x>=QQ['x']
sage: denominator(x/2)
2
sage: denominator(R.fraction_field()(x/2))
1
}}}

Should it be the same result for univariate polynomials and the
coercion to univariate rational functions?

What are the reasons to implement denominator this way for univariate
polynomials?

I have to take a look to the logic behind this, there are further
problems (maybe another track)

{{{
sage: N.<a>=NumberField(x**2-5/2)
sage: denominator(1/a)
5
sage: numerator(1/a)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call
last)

/home/luisfe/.sage/temp/mychabol/4554/
_home_luisfe__sage_init_sage_0.py in <module>()

/opt/SAGE/sage/local/lib/python2.5/site-packages/sage/misc/
functional.pyc in numerator(x)
686 if isinstance(x, (int, long)):
687 return x
--> 688 return x.numerator()
689
690 def numerical_approx(x, prec=None, digits=None):

AttributeError: 'sage.rings.number_field.number_field_element_quadr'
object has no attribute 'numerator'
}}}

Even not every univariate polynomial ring has defined numerator

{{{
sage: R.<y>=N[]
sage: denominator(y)
1
sage: numerator(y)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call
last)

/home/luisfe/.sage/temp/mychabol/4554/
_home_luisfe__sage_init_sage_0.py in <module>()

/opt/SAGE/sage/local/lib/python2.5/site-packages/sage/misc/
functional.pyc in numerator(x)
686 if isinstance(x, (int, long)):
687 return x
--> 688 return x.numerator()
689
690 def numerical_approx(x, prec=None, digits=None):

AttributeError: 'Polynomial_generic_dense_field' object has no
attribute 'numerator'
}}}

John Cremona

unread,
Jul 10, 2009, 4:17:14 AM7/10/09
to sage-...@googlegroups.com
I don't think we can hope to have a mathematically consistent
definition of numerator and denominator which works consistently in
all rings and fields! I guess that in the cases where we think we
know what we mean, it is because the ring in question is constructed
(mathematically) from another ring via the ring-of-fractions
construction (denoted S^{-1}R in books), but there can be many ways of
getting to the same ring. In the example cited Q[x] can be obtained
from Z[x] by inverting all nonzero constants, which looks fairly
canonical until you think of it as a subring of the field Q(x) which
is its field of fractions...

Hence there will never be a "right answer" to this which happens
automatically. Instead, where there is a useful definition we can
implement it on a case-by-case basis with clearly written docstrings
and examples to show what the functions do and do not do.

Having said that it would be good to have consistent behaviour between
Q[x] and Q[x,y].

John

2009/7/10 luisfe <lfta...@yahoo.es>:
Reply all
Reply to author
Forward
0 new messages