Exemplo n.º 1
0
def vector_memoryview(obj: sexp.SexpVector, sizeof_str: str,
                      cast_str: str) -> memoryview:
    """
    - sizeof_str: type in a string to use with ffi.sizeof()
        (for example "int")
    - cast_str: type in a string to use with memoryview.cast()
        (for example "i")
    """
    b = openrlib.ffi.buffer(obj._R_GET_PTR(obj.__sexp__._cdata),
                            openrlib.ffi.sizeof(sizeof_str) * len(obj))
    shape = bufferprotocol.getshape(obj.__sexp__._cdata)
    # One could have expected to only need builtin Python
    # and do something like
    # ```
    # mv = memoryview(b).cast(cast_str, shape, order='F')
    # ```
    # but Python does not handle FORTRAN-ordered arrays without having
    # to write C extensions. We have to use numpy.
    # TODO: Having numpy a requirement just for this is a problem.
    # TODO: numpy needed for memoryview
    #   (as long as https://bugs.python.org/issue34778 not resolved)
    import numpy
    a = numpy.frombuffer(b, dtype=cast_str).reshape(shape, order='F')
    mv = memoryview(a)
    return mv
Exemplo n.º 2
0
    def __array_interface__(self):
        """Return an `__array_interface__` version 3.

        Note that the pointer returned in the items 'data' corresponds to
        a memory area under R's memory management and that it will become
        invalid once the area once R frees the object. It is safer to keep
        the rpy2 object proxying the R object alive for the duration the
        pointer is used in Python / numpy."""
        return {
            'shape': bufferprotocol.getshape(self.__sexp__._cdata),
            'typestr': self._NP_TYPESTR,
            'strides': bufferprotocol.getstrides(self.__sexp__._cdata),
            'data': self._R_GET_PTR(self.__sexp__._cdata),
            'version': 3
        }
Exemplo n.º 3
0
    def __array_interface__(self: NPCOMPAT_TYPE) -> dict:
        """Return an `__array_interface__` version 3.

        Note that the pointer returned in the items 'data' corresponds to
        a memory area under R's memory management and that it will become
        invalid once the area once R frees the object. It is safer to keep
        the rpy2 object proxying the R object alive for the duration the
        pointer is used in Python / numpy."""
        shape = bufferprotocol.getshape(self.__sexp__._cdata)
        data = openrlib.ffi.buffer(self._R_GET_PTR(self.__sexp__._cdata))
        strides = bufferprotocol.getstrides(self.__sexp__._cdata, shape,
                                            self._R_SIZEOF_ELT)
        return {
            'shape': shape,
            'typestr': self._NP_TYPESTR,
            'strides': strides,
            'data': data,
            'version': 3
        }
Exemplo n.º 4
0
 def memoryview(self) -> memoryview:
     b = _rinterface.ffi.buffer(openrlib._REAL(self.__sexp__._cdata),
                                openrlib.ffi.sizeof('double') * len(self))
     shape = bufferprotocol.getshape(self.__sexp__._cdata)
     mv = memoryview(b).cast('d', shape)
     return mv
Exemplo n.º 5
0
 def memoryview(self):
     b = _rinterface.ffi.buffer(openrlib._LOGICAL(self.__sexp__._cdata),
                                openrlib.ffi.sizeof('int') * len(self))
     shape = bufferprotocol.getshape(self.__sexp__._cdata)
     mv = memoryview(b).cast('i', shape)
     return mv