/pypy/module/micronumpy/types.py
Python | 2755 lines | 2517 code | 195 blank | 43 comment | 168 complexity | 75df483c3a37a08bd4fcca7f701324e8 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
Large files files are truncated, but you can click here to view the full file
- import functools
- import math
- from rpython.rlib.unroll import unrolling_iterable
- from pypy.interpreter.error import OperationError, oefmt
- from pypy.objspace.std.floatobject import float2string
- from pypy.objspace.std.complexobject import str_format
- from pypy.interpreter.baseobjspace import W_Root, ObjSpace
- from rpython.rlib import clibffi, jit, rfloat, rcomplex
- from rpython.rlib.objectmodel import specialize, we_are_translated
- from rpython.rlib.rarithmetic import widen, byteswap, r_ulonglong, \
- most_neg_value_of, LONG_BIT
- from rpython.rlib.rawstorage import (alloc_raw_storage,
- raw_storage_getitem_unaligned, raw_storage_setitem_unaligned)
- from rpython.rlib.rstring import StringBuilder, UnicodeBuilder
- from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, unpack_float,
- pack_float80, unpack_float80)
- from rpython.rlib.rstruct.nativefmttable import native_is_bigendian
- from rpython.rlib.rstruct.runpack import runpack
- from rpython.rtyper.annlowlevel import cast_instance_to_gcref,\
- cast_gcref_to_instance
- from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
- from rpython.tool.sourcetools import func_with_new_name
- from pypy.module.micronumpy import boxes, support
- from pypy.module.micronumpy.concrete import SliceArray, VoidBoxStorage, V_OBJECTSTORE
- from pypy.module.micronumpy.strides import calc_strides
- from . import constants as NPY
- degToRad = math.pi / 180.0
- log2 = math.log(2)
- log2e = 1. / log2
- log10 = math.log(10)
- '''
- if not we_are_translated():
- _raw_storage_setitem_unaligned = raw_storage_setitem_unaligned
- _raw_storage_getitem_unaligned = raw_storage_getitem_unaligned
- def raw_storage_setitem_unaligned(storage, offset, value):
- assert offset >=0
- try:
- assert offset < storage._obj.getlength()
- except AttributeError:
- pass
- return _raw_storage_setitem_unaligned(storage, offset, value)
- def raw_storage_getitem_unaligned(T, storage, offset):
- assert offset >=0
- try:
- assert offset < storage._obj.getlength()
- except AttributeError:
- pass
- return _raw_storage_getitem_unaligned(T, storage, offset)
- '''
- def simple_unary_op(func):
- specialize.argtype(1)(func)
- @functools.wraps(func)
- def dispatcher(self, v):
- return self.box(
- func(
- self,
- self.for_computation(self.unbox(v)),
- )
- )
- return dispatcher
- def complex_unary_op(func):
- specialize.argtype(1)(func)
- @functools.wraps(func)
- def dispatcher(self, v):
- return self.box_complex(
- *func(
- self,
- self.for_computation(self.unbox(v))
- )
- )
- return dispatcher
- def complex_to_real_unary_op(func):
- specialize.argtype(1)(func)
- @functools.wraps(func)
- def dispatcher(self, v):
- return self.box_component(
- func(
- self,
- self.for_computation(self.unbox(v))
- )
- )
- return dispatcher
- def raw_unary_op(func):
- specialize.argtype(1)(func)
- @functools.wraps(func)
- def dispatcher(self, v):
- return func(
- self,
- self.for_computation(self.unbox(v))
- )
- return dispatcher
- def simple_binary_op(func):
- specialize.argtype(1, 2)(func)
- @functools.wraps(func)
- def dispatcher(self, v1, v2):
- return self.box(
- func(
- self,
- self.for_computation(self.unbox(v1)),
- self.for_computation(self.unbox(v2)),
- )
- )
- return dispatcher
- def complex_binary_op(func):
- specialize.argtype(1, 2)(func)
- @functools.wraps(func)
- def dispatcher(self, v1, v2):
- return self.box_complex(
- *func(
- self,
- self.for_computation(self.unbox(v1)),
- self.for_computation(self.unbox(v2)),
- )
- )
- return dispatcher
- def raw_binary_op(func):
- specialize.argtype(1, 2)(func)
- @functools.wraps(func)
- def dispatcher(self, v1, v2):
- return func(self,
- self.for_computation(self.unbox(v1)),
- self.for_computation(self.unbox(v2))
- )
- return dispatcher
- class BaseType(object):
- _immutable_fields_ = ['space']
- strlen = 0 # chars needed to print any possible value of the type
- def __init__(self, space):
- assert isinstance(space, ObjSpace)
- self.space = space
- def __repr__(self):
- return self.__class__.__name__
- def malloc(self, size, zero=True):
- if zero:
- return alloc_raw_storage(size, track_allocation=False, zero=True)
- else:
- return alloc_raw_storage(size, track_allocation=False, zero=False)
- @classmethod
- def basesize(cls):
- return rffi.sizeof(cls.T)
- class Primitive(object):
- _mixin_ = True
- def get_element_size(self):
- return rffi.sizeof(self.T)
- @specialize.argtype(1)
- def box(self, value):
- return self.BoxType(rffi.cast(self.T, value))
- @specialize.argtype(1, 2)
- def box_complex(self, real, imag):
- #XXX this is the place to display a warning
- return self.box(real)
- def box_raw_data(self, data):
- # For pickle
- array = rffi.cast(rffi.CArrayPtr(self.T), data)
- return self.box(array[0])
- def unbox(self, box):
- if isinstance(box, self.BoxType):
- return box.value
- elif isinstance(box, boxes.W_ObjectBox):
- return self._coerce(self.space, box).value
- else:
- raise oefmt(self.space.w_NotImplementedError,
- "%s dtype cannot unbox %s", str(self), str(box))
- def coerce(self, space, dtype, w_item):
- if isinstance(w_item, self.BoxType):
- return w_item
- return self.coerce_subtype(space, space.gettypefor(self.BoxType), w_item)
- def coerce_subtype(self, space, w_subtype, w_item):
- # XXX: ugly
- w_obj = space.allocate_instance(self.BoxType, w_subtype)
- assert isinstance(w_obj, self.BoxType)
- w_obj.__init__(self._coerce(space, w_item).value)
- return w_obj
- def to_builtin_type(self, space, box):
- return space.wrap(self.for_computation(self.unbox(box)))
- def _coerce(self, space, w_item):
- raise NotImplementedError
- def default_fromstring(self, space):
- raise NotImplementedError
- def _read(self, storage, i, offset, native):
- res = raw_storage_getitem_unaligned(self.T, storage, i + offset)
- if not native:
- res = byteswap(res)
- return res
- def _write(self, storage, i, offset, value, native):
- if not native:
- value = byteswap(value)
- raw_storage_setitem_unaligned(storage, i + offset, value)
- def read(self, arr, i, offset, dtype):
- with arr as storage:
- return self.box(self._read(storage, i, offset, dtype.is_native()))
- def read_bool(self, arr, i, offset, dtype):
- with arr as storage:
- return bool(self.for_computation(
- self._read(storage, i, offset, dtype.is_native())))
- def store(self, arr, i, offset, box, native):
- with arr as storage:
- self._write(storage, i, offset, self.unbox(box), native)
- def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
- value = self.unbox(box)
- for i in xrange(start, stop, width):
- self._write(storage, i, offset, value, native)
- def runpack_str(self, space, s, native):
- v = rffi.cast(self.T, runpack(self.format_code, s))
- if not native:
- v = byteswap(v)
- return self.box(v)
- @simple_binary_op
- def add(self, v1, v2):
- return v1 + v2
- @simple_binary_op
- def sub(self, v1, v2):
- return v1 - v2
- @simple_binary_op
- def mul(self, v1, v2):
- return v1 * v2
- @simple_unary_op
- def pos(self, v):
- return +v
- @simple_unary_op
- def neg(self, v):
- return -v
- def byteswap(self, w_v):
- # no for_computation here
- return self.box(byteswap(self.unbox(w_v)))
- @simple_unary_op
- def conj(self, v):
- return v
- @simple_unary_op
- def real(self, v):
- return v
- @simple_unary_op
- def imag(self, v):
- return 0
- @simple_unary_op
- def abs(self, v):
- return abs(v)
- @raw_unary_op
- def isnan(self, v):
- return False
- @raw_unary_op
- def isinf(self, v):
- return False
- @raw_binary_op
- def eq(self, v1, v2):
- return v1 == v2
- @raw_binary_op
- def ne(self, v1, v2):
- return v1 != v2
- @raw_binary_op
- def lt(self, v1, v2):
- return v1 < v2
- @raw_binary_op
- def le(self, v1, v2):
- return v1 <= v2
- @raw_binary_op
- def gt(self, v1, v2):
- return v1 > v2
- @raw_binary_op
- def ge(self, v1, v2):
- return v1 >= v2
- @raw_binary_op
- def logical_and(self, v1, v2):
- if bool(v1) and bool(v2):
- return Bool._True
- return Bool._False
- @raw_binary_op
- def logical_or(self, v1, v2):
- if bool(v1) or bool(v2):
- return Bool._True
- return Bool._False
- @raw_unary_op
- def logical_not(self, v):
- return not bool(v)
- @raw_binary_op
- def logical_xor(self, v1, v2):
- a = bool(v1)
- b = bool(v2)
- return (not b and a) or (not a and b)
- @raw_unary_op
- def bool(self, v):
- return bool(v)
- @simple_binary_op
- def max(self, v1, v2):
- return max(v1, v2)
- @simple_binary_op
- def min(self, v1, v2):
- return min(v1, v2)
- @raw_binary_op
- def argmax(self, v1, v2):
- return v1 >= v2
- @raw_binary_op
- def argmin(self, v1, v2):
- return v1 <= v2
- @raw_unary_op
- def rint(self, v):
- float64 = Float64(self.space)
- return float64.rint(float64.box(v))
- class Bool(BaseType, Primitive):
- T = lltype.Bool
- num = NPY.BOOL
- kind = NPY.GENBOOLLTR
- char = NPY.BOOLLTR
- BoxType = boxes.W_BoolBox
- format_code = "?"
- strlen = 5 # "False"
- _True = BoxType(True)
- _False = BoxType(False)
- @specialize.argtype(1)
- def box(self, value):
- boolean = rffi.cast(self.T, value)
- if boolean:
- return self._True
- else:
- return self._False
- @specialize.argtype(1, 2)
- def box_complex(self, real, imag):
- box = Primitive.box(self, real)
- if box.value:
- return self._True
- box = Primitive.box(self, imag)
- if box.value:
- return self._True
- return self._False
- def coerce_subtype(self, space, w_subtype, w_item):
- # Doesn't return subclasses so it can return the constants.
- return self._coerce(space, w_item)
- def _coerce(self, space, w_item):
- if space.is_none(w_item):
- return self.box(False)
- return self.box(space.is_true(w_item))
- def to_builtin_type(self, space, w_item):
- return space.wrap(self.unbox(w_item))
- def str_format(self, box, add_quotes=True):
- return "True" if self.unbox(box) else "False"
- @staticmethod
- def for_computation(v):
- return int(v)
- def default_fromstring(self, space):
- return self.box(True)
- @simple_binary_op
- def lshift(self, v1, v2):
- return v1 << v2
- @simple_binary_op
- def rshift(self, v1, v2):
- return v1 >> v2
- @simple_binary_op
- def bitwise_and(self, v1, v2):
- return v1 & v2
- @simple_binary_op
- def bitwise_or(self, v1, v2):
- return v1 | v2
- @simple_binary_op
- def bitwise_xor(self, v1, v2):
- return v1 ^ v2
- @simple_unary_op
- def invert(self, v):
- return not v
- @raw_unary_op
- def isfinite(self, v):
- return True
- @raw_unary_op
- def signbit(self, v):
- return False
- @simple_unary_op
- def reciprocal(self, v):
- if v:
- return 1
- return 0
- @specialize.argtype(1)
- def round(self, v, decimals=0):
- if decimals == 0:
- return Float64(self.space).box(self.unbox(v))
- # numpy 1.10 compatibility
- raise oefmt(self.space.w_TypeError, "ufunc casting failure")
-
-
- class Integer(Primitive):
- _mixin_ = True
- signed = True
- def _base_coerce(self, space, w_item):
- if w_item is None:
- return self.box(0)
- return self.box(space.int_w(space.call_function(space.w_int, w_item)))
- def _coerce(self, space, w_item):
- return self._base_coerce(space, w_item)
- def str_format(self, box, add_quotes=True):
- return str(self.for_computation(self.unbox(box)))
- @staticmethod
- def for_computation(v):
- return widen(v)
- def default_fromstring(self, space):
- return self.box(0)
- @specialize.argtype(1, 2)
- def div(self, b1, b2):
- v1 = self.for_computation(self.unbox(b1))
- v2 = self.for_computation(self.unbox(b2))
- if v2 == 0:
- return self.box(0)
- if (self.T is rffi.SIGNEDCHAR or self.T is rffi.SHORT or self.T is rffi.INT or
- self.T is rffi.LONG or self.T is rffi.LONGLONG):
- if v2 == -1 and v1 == self.for_computation(most_neg_value_of(self.T)):
- return self.box(0)
- return self.box(v1 / v2)
- @specialize.argtype(1, 2)
- def floordiv(self, b1, b2):
- v1 = self.for_computation(self.unbox(b1))
- v2 = self.for_computation(self.unbox(b2))
- if v2 == 0:
- return self.box(0)
- if (self.T is rffi.SIGNEDCHAR or self.T is rffi.SHORT or self.T is rffi.INT or
- self.T is rffi.LONG or self.T is rffi.LONGLONG):
- if v2 == -1 and v1 == self.for_computation(most_neg_value_of(self.T)):
- return self.box(0)
- return self.box(v1 / v2)
- @simple_binary_op
- def mod(self, v1, v2):
- return v1 % v2
- @simple_binary_op
- @jit.look_inside_iff(lambda self, v1, v2: jit.isconstant(v2))
- def pow(self, v1, v2):
- if v2 < 0:
- return 0
- res = 1
- while v2 > 0:
- if v2 & 1:
- res *= v1
- v2 >>= 1
- if v2 == 0:
- break
- v1 *= v1
- return res
- @simple_binary_op
- def lshift(self, v1, v2):
- return v1 << v2
- @simple_binary_op
- def rshift(self, v1, v2):
- return v1 >> v2
- @simple_unary_op
- def sign(self, v):
- if v > 0:
- return 1
- elif v < 0:
- return -1
- else:
- assert v == 0
- return 0
- @raw_unary_op
- def isfinite(self, v):
- return True
- @raw_unary_op
- def isnan(self, v):
- return False
- @raw_unary_op
- def isinf(self, v):
- return False
- @simple_binary_op
- def bitwise_and(self, v1, v2):
- return v1 & v2
- @simple_binary_op
- def bitwise_or(self, v1, v2):
- return v1 | v2
- @simple_binary_op
- def bitwise_xor(self, v1, v2):
- return v1 ^ v2
- @simple_unary_op
- def invert(self, v):
- return ~v
- @specialize.argtype(1)
- def reciprocal(self, v):
- raw = self.for_computation(self.unbox(v))
- ans = 0
- if raw == 0:
- # XXX good place to warn
- if self.T is rffi.INT or self.T is rffi.LONG or self.T is rffi.LONGLONG:
- ans = most_neg_value_of(self.T)
- elif abs(raw) == 1:
- ans = raw
- return self.box(ans)
- @specialize.argtype(1)
- def round(self, v, decimals=0):
- raw = self.for_computation(self.unbox(v))
- if decimals < 0:
- # No ** in rpython
- factor = 1
- for i in xrange(-decimals):
- factor *=10
- #int does floor division, we want toward zero
- if raw < 0:
- ans = - (-raw / factor * factor)
- else:
- ans = raw / factor * factor
- else:
- ans = raw
- return self.box(ans)
- @raw_unary_op
- def signbit(self, v):
- return v < 0
- class Int8(BaseType, Integer):
- T = rffi.SIGNEDCHAR
- num = NPY.BYTE
- kind = NPY.SIGNEDLTR
- char = NPY.BYTELTR
- BoxType = boxes.W_Int8Box
- format_code = "b"
- class UInt8(BaseType, Integer):
- T = rffi.UCHAR
- num = NPY.UBYTE
- kind = NPY.UNSIGNEDLTR
- char = NPY.UBYTELTR
- BoxType = boxes.W_UInt8Box
- format_code = "B"
- signed = False
- class Int16(BaseType, Integer):
- T = rffi.SHORT
- num = NPY.SHORT
- kind = NPY.SIGNEDLTR
- char = NPY.SHORTLTR
- BoxType = boxes.W_Int16Box
- format_code = "h"
- class UInt16(BaseType, Integer):
- T = rffi.USHORT
- num = NPY.USHORT
- kind = NPY.UNSIGNEDLTR
- char = NPY.USHORTLTR
- BoxType = boxes.W_UInt16Box
- format_code = "H"
- signed = False
- class Int32(BaseType, Integer):
- T = rffi.INT
- num = NPY.INT
- kind = NPY.SIGNEDLTR
- char = NPY.INTLTR
- BoxType = boxes.W_Int32Box
- format_code = "i"
- class UInt32(BaseType, Integer):
- T = rffi.UINT
- num = NPY.UINT
- kind = NPY.UNSIGNEDLTR
- char = NPY.UINTLTR
- BoxType = boxes.W_UInt32Box
- format_code = "I"
- signed = False
- def _int64_coerce(self, space, w_item):
- try:
- return self._base_coerce(space, w_item)
- except OperationError as e:
- if not e.match(space, space.w_OverflowError):
- raise
- bigint = space.bigint_w(w_item)
- try:
- value = bigint.tolonglong()
- except OverflowError:
- raise OperationError(space.w_OverflowError, space.w_None)
- return self.box(value)
- class Int64(BaseType, Integer):
- T = rffi.LONGLONG
- num = NPY.LONGLONG
- kind = NPY.SIGNEDLTR
- char = NPY.LONGLONGLTR
- BoxType = boxes.W_Int64Box
- format_code = "q"
- if LONG_BIT == 32:
- _coerce = func_with_new_name(_int64_coerce, '_coerce')
- def _uint64_coerce(self, space, w_item):
- try:
- return self._base_coerce(space, w_item)
- except OperationError as e:
- if not e.match(space, space.w_OverflowError):
- raise
- bigint = space.bigint_w(w_item)
- try:
- value = bigint.toulonglong()
- except OverflowError:
- raise OperationError(space.w_OverflowError, space.w_None)
- return self.box(value)
- class UInt64(BaseType, Integer):
- T = rffi.ULONGLONG
- num = NPY.ULONGLONG
- kind = NPY.UNSIGNEDLTR
- char = NPY.ULONGLONGLTR
- BoxType = boxes.W_UInt64Box
- format_code = "Q"
- signed = False
- _coerce = func_with_new_name(_uint64_coerce, '_coerce')
- class Long(BaseType, Integer):
- T = rffi.LONG
- num = NPY.LONG
- kind = NPY.SIGNEDLTR
- char = NPY.LONGLTR
- BoxType = boxes.W_LongBox
- format_code = "l"
- def _ulong_coerce(self, space, w_item):
- try:
- return self._base_coerce(space, w_item)
- except OperationError as e:
- if not e.match(space, space.w_OverflowError):
- raise
- bigint = space.bigint_w(w_item)
- try:
- value = bigint.touint()
- except OverflowError:
- raise OperationError(space.w_OverflowError, space.w_None)
- return self.box(value)
- class ULong(BaseType, Integer):
- T = rffi.ULONG
- num = NPY.ULONG
- kind = NPY.UNSIGNEDLTR
- char = NPY.ULONGLTR
- BoxType = boxes.W_ULongBox
- format_code = "L"
- signed = False
- _coerce = func_with_new_name(_ulong_coerce, '_coerce')
- class Float(Primitive):
- _mixin_ = True
- strlen = 32
- def _coerce(self, space, w_item):
- if w_item is None:
- return self.box(0.0)
- if space.is_none(w_item):
- return self.box(rfloat.NAN)
- return self.box(space.float_w(space.call_function(space.w_float, w_item)))
- def str_format(self, box, add_quotes=True):
- return float2string(self.for_computation(self.unbox(box)), "g",
- rfloat.DTSF_STR_PRECISION)
- @staticmethod
- def for_computation(v):
- return float(v)
- def default_fromstring(self, space):
- return self.box(-1.0)
- @simple_binary_op
- def div(self, v1, v2):
- try:
- return v1 / v2
- except ZeroDivisionError:
- if v1 == v2 == 0.0:
- return rfloat.NAN
- return rfloat.copysign(rfloat.INFINITY, v1 * v2)
- @simple_binary_op
- def floordiv(self, v1, v2):
- try:
- return math.floor(v1 / v2)
- except ZeroDivisionError:
- if v1 == v2 == 0.0:
- return rfloat.NAN
- return rfloat.copysign(rfloat.INFINITY, v1 * v2)
- @simple_binary_op
- def mod(self, v1, v2):
- # partial copy of pypy.objspace.std.floatobject.W_FloatObject.descr_mod
- if v2 == 0.0:
- return rfloat.NAN
- mod = math.fmod(v1, v2)
- if mod:
- # ensure the remainder has the same sign as the denominator
- if (v2 < 0.0) != (mod < 0.0):
- mod += v2
- else:
- # the remainder is zero, and in the presence of signed zeroes
- # fmod returns different results across platforms; ensure
- # it has the same sign as the denominator; we'd like to do
- # "mod = v2 * 0.0", but that may get optimized away
- mod = rfloat.copysign(0.0, v2)
- return mod
- @simple_binary_op
- def pow(self, v1, v2):
- try:
- return math.pow(v1, v2)
- except ValueError:
- return rfloat.NAN
- except OverflowError:
- if math.modf(v2)[0] == 0 and math.modf(v2 / 2)[0] != 0:
- # Odd integer powers result in the same sign as the base
- return rfloat.copysign(rfloat.INFINITY, v1)
- return rfloat.INFINITY
- @simple_binary_op
- def copysign(self, v1, v2):
- return math.copysign(v1, v2)
- @simple_unary_op
- def sign(self, v):
- if v == 0.0:
- return 0.0
- if rfloat.isnan(v):
- return rfloat.NAN
- return rfloat.copysign(1.0, v)
- @raw_unary_op
- def signbit(self, v):
- return rfloat.copysign(1.0, v) < 0.0
- @simple_unary_op
- def fabs(self, v):
- return math.fabs(v)
- @simple_binary_op
- def max(self, v1, v2):
- return v1 if v1 >= v2 or rfloat.isnan(v1) else v2
- @simple_binary_op
- def min(self, v1, v2):
- return v1 if v1 <= v2 or rfloat.isnan(v1) else v2
- @raw_binary_op
- def argmax(self, v1, v2):
- return v1 >= v2 or rfloat.isnan(v1)
- @raw_binary_op
- def argmin(self, v1, v2):
- return v1 <= v2 or rfloat.isnan(v1)
- @simple_binary_op
- def fmax(self, v1, v2):
- return v1 if v1 >= v2 or rfloat.isnan(v2) else v2
- @simple_binary_op
- def fmin(self, v1, v2):
- return v1 if v1 <= v2 or rfloat.isnan(v2) else v2
- @simple_binary_op
- def fmod(self, v1, v2):
- try:
- return math.fmod(v1, v2)
- except ValueError:
- return rfloat.NAN
- @simple_unary_op
- def reciprocal(self, v):
- if v == 0.0:
- return rfloat.copysign(rfloat.INFINITY, v)
- return 1.0 / v
- @simple_unary_op
- def floor(self, v):
- return math.floor(v)
- @simple_unary_op
- def ceil(self, v):
- return math.ceil(v)
- @specialize.argtype(1)
- def round(self, v, decimals=0):
- raw = self.for_computation(self.unbox(v))
- if rfloat.isinf(raw):
- return v
- elif rfloat.isnan(raw):
- return v
- ans = rfloat.round_double(raw, decimals, half_even=True)
- return self.box(ans)
- @simple_unary_op
- def trunc(self, v):
- if v < 0:
- return math.ceil(v)
- else:
- return math.floor(v)
- @simple_unary_op
- def exp(self, v):
- try:
- return math.exp(v)
- except OverflowError:
- return rfloat.INFINITY
- @simple_unary_op
- def exp2(self, v):
- try:
- return math.pow(2, v)
- except OverflowError:
- return rfloat.INFINITY
- @simple_unary_op
- def expm1(self, v):
- try:
- return rfloat.expm1(v)
- except OverflowError:
- return rfloat.INFINITY
- @simple_unary_op
- def sin(self, v):
- return math.sin(v)
- @simple_unary_op
- def cos(self, v):
- return math.cos(v)
- @simple_unary_op
- def tan(self, v):
- return math.tan(v)
- @simple_unary_op
- def arcsin(self, v):
- if not -1.0 <= v <= 1.0:
- return rfloat.NAN
- return math.asin(v)
- @simple_unary_op
- def arccos(self, v):
- if not -1.0 <= v <= 1.0:
- return rfloat.NAN
- return math.acos(v)
- @simple_unary_op
- def arctan(self, v):
- return math.atan(v)
- @simple_binary_op
- def arctan2(self, v1, v2):
- return math.atan2(v1, v2)
- @simple_unary_op
- def sinh(self, v):
- return math.sinh(v)
- @simple_unary_op
- def cosh(self, v):
- return math.cosh(v)
- @simple_unary_op
- def tanh(self, v):
- return math.tanh(v)
- @simple_unary_op
- def arcsinh(self, v):
- return math.asinh(v)
- @simple_unary_op
- def arccosh(self, v):
- if v < 1.0:
- return rfloat.NAN
- return math.acosh(v)
- @simple_unary_op
- def arctanh(self, v):
- if v == 1.0 or v == -1.0:
- return math.copysign(rfloat.INFINITY, v)
- if not -1.0 < v < 1.0:
- return rfloat.NAN
- return math.atanh(v)
- @simple_unary_op
- def sqrt(self, v):
- try:
- return math.sqrt(v)
- except ValueError:
- return rfloat.NAN
- @simple_unary_op
- def square(self, v):
- return v*v
- @raw_unary_op
- def isnan(self, v):
- return rfloat.isnan(v)
- @raw_unary_op
- def isinf(self, v):
- return rfloat.isinf(v)
- @raw_unary_op
- def isfinite(self, v):
- return rfloat.isfinite(v)
- @simple_unary_op
- def radians(self, v):
- return v * degToRad
- deg2rad = radians
- @simple_unary_op
- def degrees(self, v):
- return v / degToRad
- @simple_unary_op
- def log(self, v):
- try:
- return math.log(v)
- except ValueError:
- if v == 0.0:
- # CPython raises ValueError here, so we have to check
- # the value to find the correct numpy return value
- return -rfloat.INFINITY
- return rfloat.NAN
- @simple_unary_op
- def log2(self, v):
- try:
- return math.log(v) / log2
- except ValueError:
- if v == 0.0:
- # CPython raises ValueError here, so we have to check
- # the value to find the correct numpy return value
- return -rfloat.INFINITY
- return rfloat.NAN
- @simple_unary_op
- def log10(self, v):
- try:
- return math.log10(v)
- except ValueError:
- if v == 0.0:
- # CPython raises ValueError here, so we have to check
- # the value to find the correct numpy return value
- return -rfloat.INFINITY
- return rfloat.NAN
- @simple_unary_op
- def log1p(self, v):
- try:
- return rfloat.log1p(v)
- except OverflowError:
- return -rfloat.INFINITY
- except ValueError:
- return rfloat.NAN
- @simple_binary_op
- def logaddexp(self, v1, v2):
- tmp = v1 - v2
- if tmp > 0:
- return v1 + rfloat.log1p(math.exp(-tmp))
- elif tmp <= 0:
- return v2 + rfloat.log1p(math.exp(tmp))
- else:
- return v1 + v2
- def npy_log2_1p(self, v):
- return log2e * rfloat.log1p(v)
- @simple_binary_op
- def logaddexp2(self, v1, v2):
- tmp = v1 - v2
- if tmp > 0:
- return v1 + self.npy_log2_1p(math.pow(2, -tmp))
- if tmp <= 0:
- return v2 + self.npy_log2_1p(math.pow(2, tmp))
- else:
- return v1 + v2
- @simple_unary_op
- def rint(self, v):
- x = float(v)
- if rfloat.isfinite(x):
- import math
- y = math.floor(x)
- r = x - y
- if r > 0.5:
- y += 1.0
- if r == 0.5:
- r = y - 2.0 * math.floor(0.5 * y)
- if r == 1.0:
- y += 1.0
- return y
- else:
- return x
- class Float16(Float, BaseType):
- _STORAGE_T = rffi.USHORT
- T = rffi.SHORT
- num = NPY.HALF
- kind = NPY.FLOATINGLTR
- char = NPY.HALFLTR
- BoxType = boxes.W_Float16Box
- max_value = 65000.
- @specialize.argtype(1)
- def box(self, value):
- return self.BoxType(rffi.cast(rffi.DOUBLE, value))
- def runpack_str(self, space, s, native):
- assert len(s) == 2
- fval = self.box(unpack_float(s, native_is_bigendian))
- if not native:
- fval = self.byteswap(fval)
- return fval
- def default_fromstring(self, space):
- return self.box(-1.0)
- def byteswap(self, w_v):
- value = self.unbox(w_v)
- hbits = float_pack(value, 2)
- swapped = byteswap(rffi.cast(self._STORAGE_T, hbits))
- return self.box(float_unpack(r_ulonglong(swapped), 2))
- def _read(self, storage, i, offset, native):
- hbits = raw_storage_getitem_unaligned(self._STORAGE_T, storage, i + offset)
- if not native:
- hbits = byteswap(hbits)
- return float_unpack(r_ulonglong(hbits), 2)
- def _write(self, storage, i, offset, value, native):
- try:
- hbits = float_pack(value, 2)
- except OverflowError:
- hbits = float_pack(rfloat.INFINITY, 2)
- hbits = rffi.cast(self._STORAGE_T, hbits)
- if not native:
- hbits = byteswap(hbits)
- raw_storage_setitem_unaligned(storage, i + offset, hbits)
- class Float32(Float, BaseType):
- T = rffi.FLOAT
- num = NPY.FLOAT
- kind = NPY.FLOATINGLTR
- char = NPY.FLOATLTR
- BoxType = boxes.W_Float32Box
- format_code = "f"
- max_value = 3.4e38
- class Float64(Float, BaseType):
- T = rffi.DOUBLE
- num = NPY.DOUBLE
- kind = NPY.FLOATINGLTR
- char = NPY.DOUBLELTR
- BoxType = boxes.W_Float64Box
- format_code = "d"
- max_value = 1.7e308
- class ComplexFloating(object):
- _mixin_ = True
- strlen = 64
- def _coerce(self, space, w_item):
- if w_item is None:
- return self.box_complex(0.0, 0.0)
- if space.is_none(w_item):
- return self.box_complex(rfloat.NAN, rfloat.NAN)
- w_item = space.call_function(space.w_complex, w_item)
- real, imag = space.unpackcomplex(w_item)
- return self.box_complex(real, imag)
- def coerce(self, space, dtype, w_item):
- if isinstance(w_item, self.BoxType):
- return w_item
- return self.coerce_subtype(space, space.gettypefor(self.BoxType), w_item)
- def coerce_subtype(self, space, w_subtype, w_item):
- w_tmpobj = self._coerce(space, w_item)
- w_obj = space.allocate_instance(self.BoxType, w_subtype)
- assert isinstance(w_obj, self.BoxType)
- w_obj.__init__(w_tmpobj.real, w_tmpobj.imag)
- return w_obj
- def str_format(self, box, add_quotes=True):
- real, imag = self.for_computation(self.unbox(box))
- imag_str = str_format(imag)
- if not rfloat.isfinite(imag):
- imag_str += '*'
- imag_str += 'j'
- # (0+2j) => 2j
- if real == 0 and math.copysign(1, real) == 1:
- return imag_str
- real_str = str_format(real)
- op = '+' if imag >= 0 or rfloat.isnan(imag) else ''
- return ''.join(['(', real_str, op, imag_str, ')'])
- def runpack_str(self, space, s, native):
- comp = self.ComponentBoxType._get_dtype(space)
- l = len(s) // 2
- real = comp.runpack_str(space, s[:l])
- imag = comp.runpack_str(space, s[l:])
- if not native:
- real = comp.itemtype.byteswap(real)
- imag = comp.itemtype.byteswap(imag)
- return self.composite(real, imag)
- @staticmethod
- def for_computation(v):
- return float(v[0]), float(v[1])
- @raw_unary_op
- def _to_builtin_type(self, v):
- return v
- def to_builtin_type(self, space, box):
- real, imag = self.for_computation(self.unbox(box))
- return space.newcomplex(real, imag)
- def bool(self, v):
- real, imag = self.for_computation(self.unbox(v))
- return bool(real) or bool(imag)
- def read_bool(self, arr, i, offset, dtype):
- with arr as storage:
- v = self.for_computation(
- self._read(storage, i, offset, dtype.is_native()))
- return bool(v[0]) or bool(v[1])
- def get_element_size(self):
- return 2 * rffi.sizeof(self.T)
- def byteswap(self, w_v):
- real, imag = self.unbox(w_v)
- return self.box_complex(byteswap(real), byteswap(imag))
- @specialize.argtype(1)
- def box(self, value):
- return self.BoxType(
- rffi.cast(self.T, value),
- rffi.cast(self.T, 0.0))
- @specialize.argtype(1)
- def box_component(self, value):
- return self.ComponentBoxType(
- rffi.cast(self.T, value))
- @specialize.argtype(1, 2)
- def box_complex(self, real, imag):
- return self.BoxType(
- rffi.cast(self.T, real),
- rffi.cast(self.T, imag))
- def box_raw_data(self, data):
- # For pickle
- array = rffi.cast(rffi.CArrayPtr(self.T), data)
- return self.box_complex(array[0], array[1])
- def composite(self, v1, v2):
- assert isinstance(v1, self.ComponentBoxType)
- assert isinstance(v2, self.ComponentBoxType)
- real = v1.value
- imag = v2.value
- return self.box_complex(real, imag)
- def unbox(self, box):
- if isinstance(box, self.BoxType):
- return box.real, box.imag
- elif isinstance(box, boxes.W_ObjectBox):
- retval = self._coerce(self.space, box)
- return retval.real, retval.imag
- else:
- raise oefmt(self.space.w_NotImplementedError,
- "%s dtype cannot unbox %s", str(self), str(box))
- def _read(self, storage, i, offset, native):
- real = raw_storage_getitem_unaligned(self.T, storage, i + offset)
- imag = raw_storage_getitem_unaligned(self.T, storage, i + offset + rffi.sizeof(self.T))
- if not native:
- real = byteswap(real)
- imag = byteswap(imag)
- return real, imag
- def read(self, arr, i, offset, dtype):
- with arr as storage:
- real, imag = self._read(storage, i, offset, dtype.is_native())
- return self.box_complex(real, imag)
- def _write(self, storage, i, offset, value, native):
- real, imag = value
- if not native:
- real = byteswap(real)
- imag = byteswap(imag)
- raw_storage_setitem_unaligned(storage, i + offset, real)
- raw_storage_setitem_unaligned(storage, i + offset + rffi.sizeof(self.T), imag)
- def store(self, arr, i, offset, box, native):
- with arr as storage:
- self._write(storage, i, offset, self.unbox(box), native)
- def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
- value = self.unbox(box)
- for i in xrange(start, stop, width):
- self._write(storage, i, offset, value, native)
- @complex_binary_op
- def add(self, v1, v2):
- return rcomplex.c_add(v1, v2)
- @complex_binary_op
- def sub(self, v1, v2):
- return rcomplex.c_sub(v1, v2)
- @complex_binary_op
- def mul(self, v1, v2):
- return rcomplex.c_mul(v1, v2)
- @complex_binary_op
- def div(self, v1, v2):
- try:
- return rcomplex.c_div(v1, v2)
- except ZeroDivisionError:
- if rcomplex.c_abs(*v1) == 0 or \
- (rfloat.isnan(v1[0]) and rfloat.isnan(v1[1])):
- return rfloat.NAN, rfloat.NAN
- return rfloat.INFINITY, rfloat.INFINITY
- @complex_unary_op
- def pos(self, v):
- return v
- @complex_unary_op
- def neg(self, v):
- return -v[0], -v[1]
- @complex_unary_op
- def conj(self, v):
- return v[0], -v[1]
- @complex_to_real_unary_op
- def real(self, v):
- return v[0]
- @complex_to_real_unary_op
- def imag(self, v):
- return v[1]
- @complex_to_real_unary_op
- def abs(self, v):
- try:
- return rcomplex.c_abs(v[0], v[1])
- except OverflowError:
- # warning ...
- return rfloat.INFINITY
- @raw_unary_op
- def isnan(self, v):
- '''a complex number is nan if one of the parts is nan'''
- return rfloat.isnan(v[0]) or rfloat.isnan(v[1])
- @raw_unary_op
- def isinf(self, v):
- '''a complex number is inf if one of the parts is inf'''
- return rfloat.isinf(v[0]) or rfloat.isinf(v[1])
- def _eq(self, v1, v2):
- return v1[0] == v2[0] and v1[1] == v2[1]
- @raw_binary_op
- def eq(self, v1, v2):
- #compare the parts, so nan == nan is False
- return self._eq(v1, v2)
- @raw_binary_op
- def ne(self, v1, v2):
- return not self._eq(v1, v2)
- def _lt(self, v1, v2):
- (r1, i1), (r2, i2) = v1, v2
- if r1 < r2 and not rfloat.isnan(i1) and not rfloat.isnan(i2):
- return True
- if r1 == r2 and i1 < i2:
- return True
- return False
- @raw_binary_op
- def lt(self, v1, v2):
- return self._lt(v1, v2)
- @raw_binary_op
- def le(self, v1, v2):
- return self._lt(v1, v2) or self._eq(v1, v2)
- @raw_binary_op
- def gt(self, v1, v2):
- return self._lt(v2, v1)
- @raw_binary_op
- def ge(self, v1, v2):
- return self._lt(v2, v1) or self._eq(v2, v1)
- def _cbool(self, v):
- return bool(v[0]) or bool(v[1])
- @raw_binary_op
- def logical_and(self, v1, v2):
- if self._cbool(v1) and self._cbool(v2):
- return Bool._True
- return Bool._False
- @raw_binary_op
- def logical_or(self, v1, v2):
- if self._cbool(v1) or self._cbool(v2):
- return Bool._True
- return Bool._False
- @raw_unary_op
- def logical_not(self, v):
- return not self._cbool(v)
- @raw_binary_op
- def logical_xor(self, v1, v2):
- a = self._cbool(v1)
- b = self._cbool(v2)
- return (not b and a) or (not a and b)
- def min(self, v1, v2):
- if self.le(v1, v2) or self.isnan(v1):
- return v1
- return v2
- def max(self, v1, v2):
- if self.ge(v1, v2) or self.isnan(v1):
- return v1
- return v2
- def argmin(self, v1, v2):
- if self.le(v1, v2) or self.isnan(v1):
- return True
- return False
- def argmax(self, v1, v2):
- if self.ge(v1, v2) or self.isnan(v1):
- return True
- return False
- @complex_binary_op
- def floordiv(self, v1, v2):
- (r1, i1), (r2, i2) = v1, v2
- if r2 < 0:
- abs_r2 = -r2
- else:
- abs_r2 = r2
- if i2 < 0:
- abs_i2 = -i2
- else:
- abs_i2 = i2
- if abs_r2 >= abs_i2:
- if abs_r2 == 0.0:
- return rfloat.NAN, 0.
- else:
- ratio = i2 / r2
- denom = r2 + i2 * ratio
- rr = (r1 + i1 * ratio) / denom
- elif rfloat.isnan(r2):
- rr = rfloat.NAN
- else:
- ratio = r2 / i2
- denom = r2 * ratio + i2
- assert i2 != 0.0
- rr = (r1 * ratio + i1) / denom
- return math.floor(rr), 0.
- #complex mod does not exist in numpy
- #@simple_binary_op
- #def mod(self, v1, v2):
- # return math.fmod(v1, v2)
- def pow(self, v1, v2):
- y = self.for_computation(self.unbox(v2))
- if y[1] == 0:
- if y[0] == 0:
- return self.box_complex(1, 0)
- if y[0] == 1:
- return v1
- if y[0] == 2:
- return self.mul(v1, v1)
- x = self.for_computation(self.unbox(v1))
- if x[0] == 0 and x[1] == 0:
- if y[0] > 0 and y[1] == 0:
- return self.box_complex(0, 0)
- return self.box_complex(rfloat.NAN, rfloat.NAN)
- b = self.for_computation(self.unbox(self.log(v1)))
- return self.exp(self.box_complex(b[0] * y[0] - b[1] * y[1],
- b[0] * y[1] + b[1] * y[0]))
- #complex copysign does not exist in numpy
- #@complex_binary_op
- #def copysign(self, v1, v2):
- # return (rfloat.copysign(v1[0], v2[0]),
- # rfloat.copysign(v1[1], v2[1]))
- @complex_unary_op
- def sign(self, v):
- '''
- sign of complex number could be either the point closest to the unit circle
- or {-1,0,1}, for compatability with numpy we choose the latter
- '''
- if rfloat.isnan(v[0]) or rfloat.isnan(v[1]):
- return rfloat.NAN, 0
- if v[0] == 0.0:
- if v[1] == 0:
- return 0, 0
- if v[1] > 0:
- return 1, 0
- return -1, 0
- if v[0] > 0:
- return 1, 0
- return -1, 0
- def fmax(self, v1, v2):
- if self.ge(v1, v2) or self.isnan(v2):
- return v1
- return v2
- def fmin(self, v1, v2):
- if self.le(v1, v2) or self.isnan(v2):
- return v1
- return v2
- #@simple_binary_op
- #def fmod(self, v1, v2):
- # try:
- # return math.fmod(v1, v2)
- # except ValueError:
- # return rfloat.NAN
- @complex_unary_op
- def reciprocal(self, v):
- if rfloat.isinf(v[1]) and rfloat.isinf(v[0]):
- return rfloat.NAN, rfloat.NAN
- if rfloat.isinf(v[0]):
- return (rfloat.copysign(0., v[0]),
- rfloat.copysign(0., -v[1]))
- a2 = v[0]*v[0] + v[1]*v[1]
- try:
- return rcomplex.c_div((v[0], -v[1]), (a2, 0.))
- except ZeroDivisionError:
- return rfloat.NAN, rfloat.NAN
- @specialize.argtype(1)
- def round(self, v, decimals=0):
- ans = list(self.for_computation(self.unbox(v)))
- if rfloat.isfinite(ans[0]):
- ans[0] = rfloat.round_double(ans[0], decimals, half_even=True)
- if rfloat.isfinite(ans[1]):
- ans[1] = rfloat.round_double(ans[1], decimals, half_even=True)
- return self.box_complex(ans[0], ans[1])
- def rint(self, v):
- return self.round(v)
- # No floor, ceil, trunc in numpy for complex
- #@simple_unary_op
- #def floor(self, v):
- # return math.floor(v)
- #@simple_unary_op
- #def ceil(self, v):
- # return math.ceil(v)
- #@simple_unary_op
- #def trunc(self, v):
- # if v < 0:
- # return math.ceil(v)
- # else:
- # return math.floor(v)
- @complex_unary_op
- def exp(self, v):
- if rfloat.isinf(v[1]):
- if rfloat.isinf(v[0]):
- if v[0] < 0:
- return 0., 0.
- return rfloat.INFINITY, rfloat.NAN
- elif (rfloat.isfinite(v[0]) or \
- (rfloat.isinf(v[0]) and v[0] > 0)):
- return rfloat.NAN, rfloat.NAN
- try:
- return rcomplex.c_exp(*v)
- except OverflowError:
- if v[1] == 0:
- return rfloat.INFINITY, 0.0
- return rfloat.INFINITY, rfloat.NAN
- @complex_unary_op
- def exp2(self, v):
- try:
- return rcomplex.c_pow((2,0), v)
- except OverflowError:
- return rfloat.INFINITY, rfloat.NAN
- except ValueError:
- return rfloat.NAN, rfloat.NAN
- @complex_unary_op
- def expm1(self, v):
- # duplicate exp() so in the future it will be easier
- # to implement seterr
- if rfloat.isinf(v[1]):
- if rfloat.isinf(v[0]):
- if v[0] < 0:
- return -1., 0.
- return rfloat.NAN, rfloat.NAN
- elif (rfloat.isfinite(v[0]) or \
- (rfloat.isinf(v[0]) and v[0] > 0)):
- return rfloat.NAN, rfloat.NAN
- try:
- res = rcomplex.c_exp(*v)
- res = (res[0]-1, res[1])
- return res
- except OverflowError:
- if v[1] == 0:
- return rfloat.INFINITY, 0.0
- return rfloat.INFINITY, rfloat.NAN
- @complex_unary_op
- def sin(self, v):
- if rfloat.isinf(v[0]):
- if v[1] == 0.:
- return rfloat.NAN, 0.
- if rfloat.isfinite(v[1]):
- return rfloat.NAN, rfloat.NAN
- elif not rfloat.isnan(v[1]):
- return rfloat.NAN, rfloat.INFINITY
- return rcomplex.c_sin(*v)
- @complex_unary_op
- def cos(self, v):
- if rfloat.isinf(v[0]):
- if v[1] == 0.:
- return rfloat.NAN, 0.0
- if rfloat.isfinite(v[1]):
- return rfloat.NAN, rfloat.NAN
- elif not rfloat.isnan(v[1]):
- return rfloat.INFINITY, rfloat.NAN
- return rcomplex.c_cos(*v)
- @complex_unary_op
- def tan(self, v):
- if rfloat.isinf(v[0]) and rfloat.isfinite(v[1]):
- return rfloat.NAN, rfloat.NAN
- return rcomplex.c_tan(*v)
- @complex_unary_op
- def arcsin(self, v):
- return rcomplex.c_asin(*v)
- @complex_unary_op
- def arccos(self, v):
- return rcomplex.c_acos(*v)
- @complex_unary_op
- def arctan(self, v):
- if v[0] == 0 and (v[1] == 1 or v[1] == -1):
- #This is the place to print a "runtime warning"
- return rfloat.NAN, math.copysign(rfloat.INFINITY, v[1])
- return rcomplex.c_atan(*v)
- #@complex_binary_op
- #def arctan2(self, v1, v2):
- # return rcomplex.c_atan2(v1, v2)
- @complex_unary_op
- def sinh(self, v):
- if rfloat.isinf(v[1]):
- if rfloat.isfinite(v[0]):
- if v[0] == 0.0:
- return 0.0, rfloat.NAN
- return rfloat.NAN, rfloat.NAN
- elif not rfloat.isnan(v[0]):
- return rfloat.INFINITY, rfloat.NAN
- return rcomplex.c_sinh(*v)
- @complex_unary_op
- def cosh(self, v):
- if rfloat.isinf(v[1]):
- if rfloat.isfinite(v[0]):
- if v[0] == 0.0:
- return rfloat.NAN, 0.0
- return rfloat.NAN, rfloat.NAN
- elif not rfloat.isnan(v[0]):
- return rfloat.INFINITY, rfloat.NAN
- return rcomplex.c_cosh(*v)
- @complex_unary_op
- def tanh(self, v):
- if rfloat.isinf(v[1]) and rfloat.isfinite(v[0]):
- return rfloat.NAN, rfloat.NAN
- return rcomplex.c_tanh(*v)
- @complex_unary_op
- def arcsinh(self, v):
- return rcomplex.c_asinh(*v)
- @complex_unary_op
- def arccosh(self, v):
- return rcomplex.c_acosh(*v)
- @complex_unary_op
- def arctanh(self, v):
- if v[1] == 0 and (v[0] == 1.0 or v[0] == -1.0):
- return (math.copysign(rfloat.INFINITY, v[0]),
- math.copysign(0., v[1]))
- return rcomplex.c_atanh(*v)
- @complex_unary_op
- def sqrt(self, v):
- return rcomplex.c_sqrt(*v)
- @complex_unary_op
- def square(self, v):
- return rcomplex.c_mul(v,v)
- @raw_unary_op
- def isfinite(self, v):
- return rfloat.isfinite(v[0]) and rfloat.isfinite(v[1])
- #@simple_unary_op
- #def radians(self, v):
- # return v * degToRad
- #deg2rad = radians
- #@simple_unary_op
- #def degrees(self, v):
- # return v / degToRad
- @complex_unary_op
- def log(self, v):
- try:
- return rcomplex.c_log(*v)
- except ValueError:
- return -rfloat.INFINITY, math.atan2(v[1], v[0])
- @complex_unary_op
- def log2(self, v):
- try:
- r = rcomplex.c_log(*v)
- except ValueError:
- r = -rfloat.INFINITY, math.atan2(v[1], v[0])
- return r[0] / log2, r[1] / log2
- @complex_unary_op
- def log10(self, v):
- try:
- return rcomplex.c_log10(*v)
- except ValueError:
- return -rfloat.INFINITY, math.atan2(v[1], v[0]) / log10
- @complex_unary_op
- def log1p(self, v):
- try:
- return rcomplex.c_log(v[0] + 1, v[1])
- except OverflowError:
- return -rfloat.INFINITY, 0
- except ValueError:
- return rfloat.NAN, rfloat.NAN
- class Complex64(ComplexFloating, BaseType):
- T = rffi.FLOAT
- num = NPY.CFLOAT
- kind = NPY.COMPLEXLTR
- char = NPY.CFLOATLTR
- BoxType = boxes.W_Complex64Box
- ComponentBoxType = boxes.W_Float32Box
- ComponentType = Float32
- class Complex128(ComplexFloating, BaseType):
- T = rffi.DOUBLE
- num = NPY.CDOUBLE
- kind = NPY.COMPLEXLTR
- char = NPY.CDOUBLELTR
- BoxType = boxes.W_Complex128Box
- ComponentBoxType = boxes.W_Float64Box
- ComponentType = Float64
- if boxes.long_double_size == 8:
- class FloatLong(Float, BaseType):
- T = rffi.DOUBLE
- num = NPY.LONGDOUBLE
- kind = NPY.FLOATINGLTR
- char = NPY.LONGDOUBLELTR
- BoxType = boxes.W_FloatLongBox
- format_code = "d"
- class ComplexLong(ComplexFloating, BaseType):
- T = rffi.DOUBLE
- num = NPY.CLONGDOUBLE
- kind = NPY.COMPLEXLTR
- char = NPY.CLONGDOUBLELTR
- BoxType = boxes.W_ComplexLongBox
- ComponentBoxType = boxes.W_FloatLongBox
- ComponentType = FloatLong
- elif boxes.long_double_size in (12, 16):
- class FloatLong(Float, BaseType):
- T = rffi.LONGDOUBLE
- num = NPY.LONGDOUBLE
- kind = NPY.FLOATINGLTR
- char = NPY.LONGDOUBLELTR
- BoxType = boxes.W_FloatLongBox
- def runpack_str(self, space, s, native):
- assert len(s) == boxes.long_double_size
- fval = self.box(unpack_float80(s, native_is_bigendian))
- if not native:
- fval = self.byteswap(fval)
- return fval
- def byteswap…
Large files files are truncated, but you can click here to view the full file