def _grid(func, ptr): grid_ptr = _ffi.new('float**') grid_len = func(ptr, grid_ptr) if grid_len == 0: raise RuntimeError(_ffi.string(_lib.asdf_last_error()).decode()) buffer = _ffi.buffer(grid_ptr[0], grid_len * _np.dtype('float32').itemsize) array = _np.frombuffer(buffer, dtype='float32') # NB: Writing to this array would be Undefined Behavior array.flags.writeable = False return array
def __init__(self, values, slopes=None, grid=None): # TODO: code re-use? values = _np.ascontiguousarray(values, dtype='float32') if values.ndim != 1: raise ValueError("Values must be one-dimensional") if grid is None: grid = _np.arange(len(values), dtype='float32') grid = _np.ascontiguousarray(grid, dtype='float32') if grid.ndim != 1: raise ValueError("Grid must be one-dimensional") values_ptr = _ffi.from_buffer('float[]', values) grid_ptr = _ffi.from_buffer('float[]', grid) if slopes is None: ptr = _ffi.gc( _lib.asdf_monotonecubic( values_ptr, len(values), grid_ptr, len(grid), ), _lib.asdf_monotonecubic_free) else: # TODO: code re-use? slopes = _np.ascontiguousarray(slopes, dtype='float32') if slopes.ndim != 1: raise ValueError("Slopes must be one-dimensional") slopes_ptr = _ffi.from_buffer('float[]', slopes) ptr = _ffi.gc( _lib.asdf_monotonecubic_with_slopes( values_ptr, len(values), slopes_ptr, len(slopes), grid_ptr, len(grid), ), _lib.asdf_monotonecubic_free) if ptr == _ffi.NULL: raise ValueError(_ffi.string(_lib.asdf_last_error()).decode()) self._monotone_ptr = ptr super().__init__(_lib.asdf_monotonecubic_inner(ptr))
def __init__(self, ptr): if ptr == _ffi.NULL: raise ValueError(_ffi.string(_lib.asdf_last_error()).decode()) self._ptr = ptr
def __init__(self, data): positions = [] times = [] speeds = [] tcb = [] closed = False for vertex in data: vertex = dict(vertex) # Make a copy position = vertex.pop('position', None) if position is None: raise ValueError('Every vertex must have a position') time = vertex.pop('time', _np.nan) if not _np.isscalar(time): raise TypeError('Time values must be scalars') times.append(time) if position == 'closed': if vertex: raise ValueError( 'When position is "closed", only time is allowed') closed = True break position = _np.asarray(position, dtype='float32') if position.ndim != 1: raise ValueError("Positions must be one-dimensional") if len(position) == 2: position = _np.append(position, 0) if len(position) != 3: raise ValueError("Positions must be 2- or 3-dimensional") positions.append(position) speed = vertex.pop('speed', _np.nan) if not _np.isscalar(speed): raise TypeError('Speed values must be scalars') speeds.append(speed) tension = vertex.pop('tension', 0) if not _np.isscalar(tension): raise TypeError('Tension values must be scalars') continuity = vertex.pop('continuity', 0) if not _np.isscalar(continuity): raise TypeError('Continuity values must be scalars') bias = vertex.pop('bias', 0) if not _np.isscalar(bias): raise TypeError('Bias values must be scalars') tcb.append((tension, continuity, bias)) if vertex: raise ValueError('Invalid key(s): {}'.format(set(vertex))) if len(positions) < 2: raise ValueError('At least two vertices are needed') if not closed: assert len(tcb) >= 2 if tcb.pop(0) != (0, 0, 0): raise ValueError( 'First vertex cannot have tension/continuity/bias (except for closed curves' ) if tcb.pop(-1) != (0, 0, 0): raise ValueError( 'Last vertex cannot have tension/continuity/bias (except for closed curves)' ) positions = _np.ascontiguousarray(positions, dtype='float32') assert positions.ndim == 2 assert positions.shape[1] == 3 positions_ptr = _ffi.from_buffer('float[]', positions) times = _np.ascontiguousarray(times, dtype='float32') assert times.ndim == 1 times_ptr = _ffi.from_buffer('float[]', times) speeds = _np.ascontiguousarray(speeds, dtype='float32') assert speeds.ndim == 1 speeds_ptr = _ffi.from_buffer('float[]', speeds) tcb = _np.ascontiguousarray(tcb, dtype='float32') tcb_ptr = _ffi.from_buffer('float[]', tcb) ptr = _ffi.gc( _lib.asdf_asdfspline( positions_ptr, len(positions), times_ptr, len(times), speeds_ptr, len(speeds), tcb_ptr, len(tcb), closed, ), _lib.asdf_asdfspline_free) if ptr == _ffi.NULL: raise ValueError(_ffi.string(_lib.asdf_last_error()).decode()) self._ptr = ptr