Ask Your Question
0

wrapping vector class

asked 2019-06-25 19:40:19 +0200

updated 2019-06-25 23:00:54 +0200

I am trying to wrap the vector class to add some extra cases, but I am having trouble doing so. This is the code I have:

def lower_triangular_entries(dim,x,y):
    return upper_triangular_entries(dim,y,x)

def upper_triangular_entries(dim,x,y):
    if y<=x:
        return 1
    else:
        return 0

class OneParamSubgroup(vector):
    #TO DO: define scalar multiplication
    def __init__(self, data, type_A=False):
        if type_A:
            BasisChange=matrix(ZZ, len(data)-1, len(data)-1,
                                lambda x,y: lower_triangular(len(data)-1,x,y))
            v=vector(data[0:len(data)-1])
            v=tuple(BasisChange*v)
        #data given in terms of basis T
        else:
            v=data
        vector.__init__(self, v)
    def __repr__(self):
        return self

However, I get the following error when running on terminal

Traceback (most recent call last):
  File "test.sage.py", line 7, in <module>
    load("GIT/Group.sage")
  File "sage/structure/sage_object.pyx", line 1057, in sage.structure.sage_object.load (build/cythonized/sage/structure/sage_object.c:12915)
  File "/opt/sagemath-8.1/local/lib/python2.7/site-packages/sage/repl/load.py", line 247, in load
    exec(preparse_file(open(fpath).read()) + "\n", globals)
  File "<string>", line 3, in <module>
ImportError: cannot import name vector

and the following on the Notebook

TypeError                                 Traceback (most recent call last)
<ipython-input-1-ec2394617192> in <module>()
      8         return Integer(0)
      9 
---> 10 class OneParamSubgroup(vector):
     11     #TO DO: define scalar multiplication
     12     def __init__(self, data, type_A=False):

TypeError: Error when calling the metaclass bases
    cannot create 'builtin_function_or_method' instances

Any idea of what I am doing wrong?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2019-06-25 22:50:19 +0200

updated 2019-06-26 02:01:00 +0200

In Sage, vector is a function, not a class, so you can't inherit from it. You should use Vector instead:

from sage.structure.element import Vector
class OneParamSubgroup(Vector):
    ...

I found this by looking at the help for vector (vector?). At the end, it tells me

File:           ..../sage/local/lib/python2.7/site-packages/sage/modules/free_module_element.pyx
Type:           builtin_function_or_method

Actually, Vector may not be perfect. What sort of vectors are you working with? Some other classes may provide more methods. Some examples:

sage: type(vector([1, 2])).mro() # integer entries
[<type 'sage.modules.vector_integer_dense.Vector_integer_dense'>,
 <type 'sage.modules.free_module_element.FreeModuleElement'>,
 <type 'sage.structure.element.Vector'>,
 <type 'sage.structure.element.ModuleElement'>,
 <type 'sage.structure.element.Element'>,
 <type 'sage.structure.sage_object.SageObject'>,
 <type 'object'>]
sage: type(vector([1., 2])).mro() # real
[<type 'sage.modules.free_module_element.FreeModuleElement_generic_dense'>,
 <type 'sage.modules.free_module_element.FreeModuleElement'>,
 <type 'sage.structure.element.Vector'>,
 <type 'sage.structure.element.ModuleElement'>,
 <type 'sage.structure.element.Element'>,
 <type 'sage.structure.sage_object.SageObject'>,
 <type 'object'>]
sage: type(vector([1/2, 2])).mro() # rational
[<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>,
 <type 'sage.modules.free_module_element.FreeModuleElement'>,
 <type 'sage.structure.element.Vector'>,
 <type 'sage.structure.element.ModuleElement'>,
 <type 'sage.structure.element.Element'>,
 <type 'sage.structure.sage_object.SageObject'>,
 <type 'object'>]

So you could instead inherit from Vector_rational_dense, etc.

Edit: to use Vector_rational_dense, you could do this:

from sage.modules.vector_rational_dense import Vector_rational_dense

class test(Vector_rational_dense):
    def __init__(self, parent, value):
        Vector_rational_dense.__init__(self, parent, value)

xi2 = test(QQ**3, [2,2,1])

# or do this:

def vector_constructor(value):
    return test(QQ**len(value), value)

xi3 = vector_constructor([2,2,1])
edit flag offensive delete link more

Comments

@John_Palmieri Thank you thank you, you can't believe how long I've been struggling with this. How did you know where to import it from? And when I do w=OneParamSubgroup([1,2]), if it is just the empty wrapper calling Vector.__init__, will it have the same effect as doing vecctor([1,2])?

Jesus Martinez Garcia gravatar imageJesus Martinez Garcia ( 2019-06-25 23:05:32 +0200 )edit

@John_Palmieri I guess I want rational vectors (to keep it safe). Should I use from sage.structure.element import Vector_rational_dense?

Jesus Martinez Garcia gravatar imageJesus Martinez Garcia ( 2019-06-25 23:09:11 +0200 )edit
1

To find where to import, use import_statements('Vector_rational_dense'). Also, calling Vector.__init__(self, data, ...) should have the same effect as Vector(data, ...). As far as vector([1,2]), you need to read the source code to see exactly what that does. It looks like it tries to determine the base ring, then creates a free module M of the appropriate rank over that ring, then does M(data). I think that in turn calls the _element_constructor_ method for the free module.

John Palmieri gravatar imageJohn Palmieri ( 2019-06-25 23:14:49 +0200 )edit

@John_Palmieri Actually, (disregard original comment, there was mistake), it doesn't work. I do MWE:

from sage.structure.element import Vector
class test(Vector):
  def __init__(self,value):
      Vector.__init__(self, value)
xi2=test([2,2,1])

Get error:

  File "test.sage.py", line 23, in <module>
    xi2=test([_sage_const_2 ,_sage_const_2 ,_sage_const_1 ])
  File "<string>", line 4, in __init__
  File "sage/structure/element.pyx", line 388, in sage.structure.element.Element.__init__ (build/cythonized/sage/structure/element.c:4248)
TypeError: Cannot convert list to sage.structure.parent.Parent
Jesus Martinez Garcia gravatar imageJesus Martinez Garcia ( 2019-06-25 23:25:30 +0200 )edit
2

First, use Vector_rational_dense instead of Vector. Or if you use Vector, be prepared to implement lots of things from scratch, since this class is pretty general purpose and doesn't even have an __init__ method. Next, it seems that Vector_rational_dense requires two arguments, the vector space and then the data; furthermore, for any class that inherits from it, it intercepts the arguments, so your __init__ method should have those same arguments. (Vector_rational_denseis defined using Cython; see https://cython.readthedocs.io/en/late....) See my edited answer.

John Palmieri gravatar imageJohn Palmieri ( 2019-06-26 01:59:00 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2019-06-25 19:40:19 +0200

Seen: 559 times

Last updated: Jun 26 '19