def __init__(self, size=128, ctype=ctypes.c_double, from_cptr=None): # __new__ creates or sets _inst_ptr, so always supply that to super's # `from_cptr`' VitalObject.__init__(self, self._inst_ptr)
def __new__(cls, rows=2, cols=1, dynamic_rows=False, dynamic_cols=False, dtype=numpy.double, from_cptr=None, owns_data=True): """ Create a new Vital Eigen matrix and interface :param rows: Number of rows in the matrix :param cols: Number of columns in the matrix :param dynamic_rows: If we should not use compile-time generated types in regards to the row specification. :param dynamic_cols: If we should not use compile-time generated types in regards to the column specification. :param dtype: numpy dtype to use :param from_cptr: Optional existing C Eigen matrix instance pointer to use instead of constructing a new one. :param owns_data: When given a c-pointer, if we should take ownership of the underlying data. :return: Interface to a new or existing Eigen matrix instance. :raises ValueError: If a `c_ptr` is provided but is of a different compile-time shape type. E.g. cannot create a 2x1 matrix with dynamic rows from a 2x1 matrix :raises VitalInvalidStaticEigenShape: An invalid (row, column) was specified without stating dynamic rows or columns. This is because Vital and Eigen defines only so many shapes at compile time. """ dtype = numpy.dtype(dtype) func_spec, func_map, c_type = \ cls._init_func_map(rows, cols, dynamic_rows, dynamic_cols, dtype) op_c_type, op_c_type_ptr = cls.TYPE_CACHE.get_types(func_spec) # Create new Eigen matrix # Check if the shape given is either fully dynamic or is a valid # compile-time shape try: cls.VITAL_LIB[func_map['new_sized']] except AttributeError: raise VitalInvalidStaticEigenShape( "Array shape %s is not a valid compile-time specified " "shape given that dynamic rows/cols were specified as %s." % ((rows, cols), (bool(dynamic_rows), bool(dynamic_cols)))) if from_cptr is None: c_new = cls.VITAL_LIB[func_map['new_sized']] c_new.argtypes = [c_ptrdiff_t, c_ptrdiff_t] c_new.restype = op_c_type_ptr inst_ptr = c_new(c_ptrdiff_t(rows), c_ptrdiff_t(cols)) if not bool(inst_ptr): raise RuntimeError("Failed to construct new Eigen matrix") owns_data = True else: if not isinstance(from_cptr, op_c_type_ptr): raise ValueError("Given C-Pointer is not correct for the " "shape-type '%s' (given: %s)" % (func_spec, type(from_cptr))) inst_ptr = from_cptr # Get information, data pointer and base transformed array rows, cols, row_stride, col_stride, data = \ cls._get_data_components(inst_ptr, op_c_type_ptr, c_type, func_map) # Might have to swap out the use of ``dtype_bytes`` for # inner/outer size values from Eigen if matrices are ever NOT # densely packed. dtype_bytes = numpy.dtype(c_type).alignment strides = (row_stride * dtype_bytes, col_stride * dtype_bytes) if data: # data has no __array_interface__ yet, thus... b = numpy.ctypeslib.as_array(data, (rows * cols, )) else: b = buffer('') # args: (subclass, shape, dtype, buffer, offset, strides, order) obj = numpy.ndarray.__new__(cls, (rows, cols), dtype, b, 0, strides) # local properties # instance-specific opaque type obj.C_TYPE = op_c_type obj.C_TYPE_PTR = op_c_type_ptr obj._dynamic_rows = dynamic_rows obj._dynamic_cols = dynamic_cols obj._func_map = func_map obj._c_type = c_type obj._owns_data = owns_data # Always going to have an instance pointer at this point due to above # logic VitalObject.__init__(obj, from_cptr=inst_ptr) return obj
def __new__(cls, rows=2, cols=1, dynamic_rows=False, dynamic_cols=False, dtype=numpy.double, from_cptr=None, owns_data=True): """ Create a new Vital Eigen matrix and interface :param rows: Number of rows in the matrix :param cols: Number of columns in the matrix :param dynamic_rows: If we should not use compile-time generated types in regards to the row specification. :param dynamic_cols: If we should not use compile-time generated types in regards to the column specification. :param dtype: numpy dtype to use :param from_cptr: Optional existing C Eigen matrix instance pointer to use instead of constructing a new one. :param owns_data: When given a c-pointer, if we should take ownership of the underlying data. :return: Interface to a new or existing Eigen matrix instance. :raises ValueError: If a `c_ptr` is provided but is of a different compile-time shape type. E.g. cannot create a 2x1 matrix with dynamic rows from a 2x1 matrix :raises VitalInvalidStaticEigenShape: An invalid (row, column) was specified without stating dynamic rows or columns. This is because Vital and Eigen defines only so many shapes at compile time. """ dtype = numpy.dtype(dtype) func_spec, func_map, c_type = \ cls._init_func_map(rows, cols, dynamic_rows, dynamic_cols, dtype) op_c_type, op_c_type_ptr = cls.TYPE_CACHE.get_types(func_spec) # Create new Eigen matrix # Check if the shape given is either fully dynamic or is a valid # compile-time shape try: cls.VITAL_LIB[func_map['new_sized']] except AttributeError: raise VitalInvalidStaticEigenShape( "Array shape %s is not a valid compile-time specified " "shape given that dynamic rows/cols were specified as %s." % ((rows, cols), (bool(dynamic_rows), bool(dynamic_cols))) ) if from_cptr is None: c_new = cls.VITAL_LIB[func_map['new_sized']] c_new.argtypes = [c_ptrdiff_t, c_ptrdiff_t] c_new.restype = op_c_type_ptr inst_ptr = c_new(c_ptrdiff_t(rows), c_ptrdiff_t(cols)) if not bool(inst_ptr): raise RuntimeError("Failed to construct new Eigen matrix") owns_data = True else: if not isinstance(from_cptr, op_c_type_ptr): raise ValueError("Given C-Pointer is not correct for the " "shape-type '%s' (given: %s)" % (func_spec, type(from_cptr))) inst_ptr = from_cptr # Get information, data pointer and base transformed array rows, cols, row_stride, col_stride, data = \ cls._get_data_components(inst_ptr, op_c_type_ptr, c_type, func_map) # Might have to swap out the use of ``dtype_bytes`` for # inner/outer size values from Eigen if matrices are ever NOT # densely packed. dtype_bytes = numpy.dtype(c_type).alignment strides = (row_stride * dtype_bytes, col_stride * dtype_bytes) if data: # data has no __array_interface__ yet, thus... b = numpy.ctypeslib.as_array(data, (rows * cols,)) else: b = buffer('') # args: (subclass, shape, dtype, buffer, offset, strides, order) obj = numpy.ndarray.__new__(cls, (rows, cols), dtype, b, 0, strides) # local properties # instance-specific opaque type obj.C_TYPE = op_c_type obj.C_TYPE_PTR = op_c_type_ptr obj._dynamic_rows = dynamic_rows obj._dynamic_cols = dynamic_cols obj._func_map = func_map obj._c_type = c_type obj._owns_data = owns_data # Always going to have an instance pointer at this point due to above # logic VitalObject.__init__(obj, from_cptr=inst_ptr) return obj