Thanks a lot for the instructions. I revised my code as follows.

from sage.structure.coerce_maps import CallableConvertMap

class ParametricRealFieldElement(FieldElement):

    def __init__(self, value, parent=None):
        FieldElement.__init__(self, parent) 
        self._val = value

    def __hash__(self):
        return hash(self._val)

class ParametricRealField(Field):

    def __init__(self, values=[], names=()):
        Field.__init__(self, self)
        self._element_class = ParametricRealFieldElement
        self._zero_element = ParametricRealFieldElement(0, parent=self)
        self._one_element =  ParametricRealFieldElement(1, parent=self)
        self._gens = [ ParametricRealFieldElement(value, parent=self) for 
value in values ]

    def _an_element_impl(self):
        return ParametricRealFieldElement(1, parent=self)

    def _coerce_map_from_(self, S):
        return CallableConvertMap(S, self, lambda s: 
ParametricRealFieldElement(s, parent=self), parent_as_first_arg=False)

    def _coerce_impl(self, x):
        return self(x)

Now I have 
sage: K.<a,b> = ParametricRealField([2, 1])

sage: K in CommutativeRings()

True


However, sage: R.<x,y> = PolynomialRing(K) raises NotImplementedError.


I suspect that the _element_constructor_ method of the class 
ParametricRealField needs to be provided. 

I tried the following in class ParametricRealField(Field):
    def _element_constructor_(self, elt):
        if elt.parent() == self:
            return elt
        return ParametricRealFieldElement(elt, parent=self)

This allows me to construct K and R, but I'm not able to get the generators 
of R.

sage: K.<a,b> = ParametricRealField([2, 1])

sage: R.<x,y> = PolynomialRing(K)

sage: x

---------------------------------------------------------------------------

TypeError: unsupported operand parent(s) for '*': '<class 
'__main__.ParametricRealField_with_category'>' and '<class 
'__main__.ParametricRealField_with_category'>'


On Wednesday, July 13, 2016 at 6:57:56 PM UTC+1, vdelecroix wrote:
>
> Please read the extensive documentation at 
>
>
> http://doc.sagemath.org/html/en/thematic_tutorials/coercion_and_categories.html#coercion-and-categories
>  
>
>
> Concerning your code, you need at least to: 
>
> 1 - remove the attribute _parent and the method parent in 
> ParametricRealFieldElement 
>
> 2 - remove the __call__ in ParametricRealField 
>
> 3 - call the constructor of FieldElement as in 
>
> class ParametricRealFieldElement(FieldElement): 
>      def __init__(self, value, parent=None): 
>          ... 
>          ... 
>          FieldElement.__init__(self, parent) 
>
> 4 - call the constructor of Field as in 
>
> class ParametricRealField(Field): 
>      def __init__(self, values=[], names=()): 
>          ... 
>          ... 
>          Field.__init__(self) 
>
> On 13/07/16 08:55, Yuan ZHOU wrote: 
> > Hi, 
> > 
> > I wish to construct a new class ParametricRealField. I implemented it as 
> > follows. 
> > 
> > class ParametricRealFieldElement(FieldElement): 
> > 
> >     def __init__(self, value, parent=None): 
> >         FieldElement.__init__(self, parent) ## this is so that 
> > canonical_coercion works. 
> >         self._val = value 
> >         self._parent = parent ## this is so that .parent() works. 
> > 
> >     def parent(self): 
> >         return self._parent 
> > 
> >     def __hash__(self): 
> >         return hash(self._val) 
> > 
> > class ParametricRealField(Field): 
> > 
> >     def __init__(self, values=[], names=()): 
> >         NumberField.__init__(self) 
> >         self._element_class = ParametricRealFieldElement 
> >         self._zero_element = ParametricRealFieldElement(0, parent=self) 
> >         self._one_element =  ParametricRealFieldElement(1, parent=self) 
> >         self._gens = [ ParametricRealFieldElement(value, parent=self) 
> for 
> > value in values ] 
> > 
> >     def _an_element_impl(self): 
> >         return ParametricRealFieldElement(1, parent=self) 
> > 
> >     def _coerce_map_from_(self, S): 
> >         return CallableConvertMap(S, self, lambda s: 
> > ParametricRealFieldElement(s, parent=self), parent_as_first_arg=False) 
> > 
> >     def __call__(self, elt): 
> >         if parent(elt) == self: 
> >             return elt 
> >         return ParametricRealFieldElement(elt, parent=self) 
> > 
> >     def _coerce_impl(self, x): 
> >         return self(x) 
> > 
> > Then I got an error when running the following code. 
> > 
> > sage: K.<a,b> = ParametricRealField([2, 1]) 
> > 
> > sage: K.is_commutative() 
> > 
> > True 
> > 
> > sage: K.is_ring() 
> > 
> > True 
> > 
> > sage: K in CommutativeRings() 
> > 
> > False 
> > 
> > sage: R = PolynomialRing(K, 'x') 
> > 
> > 
> --------------------------------------------------------------------------- 
> > 
> > TypeError: Base ring <class '__main__.ParametricRealField'> must be a 
> > commutative ring. 
> > 
> > 
> > How can I make K commutative? 
> > 
> > Thanks, 
> > Yuan 
> > 
>

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.

Reply via email to