/pypy/module/micronumpy/types.py

https://bitbucket.org/pypy/pypy/ · Python · 2755 lines · 2262 code · 392 blank · 101 comment · 404 complexity · 75df483c3a37a08bd4fcca7f701324e8 MD5 · raw file

Large files are truncated click here to view the full file

  1. import functools
  2. import math
  3. from rpython.rlib.unroll import unrolling_iterable
  4. from pypy.interpreter.error import OperationError, oefmt
  5. from pypy.objspace.std.floatobject import float2string
  6. from pypy.objspace.std.complexobject import str_format
  7. from pypy.interpreter.baseobjspace import W_Root, ObjSpace
  8. from rpython.rlib import clibffi, jit, rfloat, rcomplex
  9. from rpython.rlib.objectmodel import specialize, we_are_translated
  10. from rpython.rlib.rarithmetic import widen, byteswap, r_ulonglong, \
  11. most_neg_value_of, LONG_BIT
  12. from rpython.rlib.rawstorage import (alloc_raw_storage,
  13. raw_storage_getitem_unaligned, raw_storage_setitem_unaligned)
  14. from rpython.rlib.rstring import StringBuilder, UnicodeBuilder
  15. from rpython.rlib.rstruct.ieee import (float_pack, float_unpack, unpack_float,
  16. pack_float80, unpack_float80)
  17. from rpython.rlib.rstruct.nativefmttable import native_is_bigendian
  18. from rpython.rlib.rstruct.runpack import runpack
  19. from rpython.rtyper.annlowlevel import cast_instance_to_gcref,\
  20. cast_gcref_to_instance
  21. from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
  22. from rpython.tool.sourcetools import func_with_new_name
  23. from pypy.module.micronumpy import boxes, support
  24. from pypy.module.micronumpy.concrete import SliceArray, VoidBoxStorage, V_OBJECTSTORE
  25. from pypy.module.micronumpy.strides import calc_strides
  26. from . import constants as NPY
  27. degToRad = math.pi / 180.0
  28. log2 = math.log(2)
  29. log2e = 1. / log2
  30. log10 = math.log(10)
  31. '''
  32. if not we_are_translated():
  33. _raw_storage_setitem_unaligned = raw_storage_setitem_unaligned
  34. _raw_storage_getitem_unaligned = raw_storage_getitem_unaligned
  35. def raw_storage_setitem_unaligned(storage, offset, value):
  36. assert offset >=0
  37. try:
  38. assert offset < storage._obj.getlength()
  39. except AttributeError:
  40. pass
  41. return _raw_storage_setitem_unaligned(storage, offset, value)
  42. def raw_storage_getitem_unaligned(T, storage, offset):
  43. assert offset >=0
  44. try:
  45. assert offset < storage._obj.getlength()
  46. except AttributeError:
  47. pass
  48. return _raw_storage_getitem_unaligned(T, storage, offset)
  49. '''
  50. def simple_unary_op(func):
  51. specialize.argtype(1)(func)
  52. @functools.wraps(func)
  53. def dispatcher(self, v):
  54. return self.box(
  55. func(
  56. self,
  57. self.for_computation(self.unbox(v)),
  58. )
  59. )
  60. return dispatcher
  61. def complex_unary_op(func):
  62. specialize.argtype(1)(func)
  63. @functools.wraps(func)
  64. def dispatcher(self, v):
  65. return self.box_complex(
  66. *func(
  67. self,
  68. self.for_computation(self.unbox(v))
  69. )
  70. )
  71. return dispatcher
  72. def complex_to_real_unary_op(func):
  73. specialize.argtype(1)(func)
  74. @functools.wraps(func)
  75. def dispatcher(self, v):
  76. return self.box_component(
  77. func(
  78. self,
  79. self.for_computation(self.unbox(v))
  80. )
  81. )
  82. return dispatcher
  83. def raw_unary_op(func):
  84. specialize.argtype(1)(func)
  85. @functools.wraps(func)
  86. def dispatcher(self, v):
  87. return func(
  88. self,
  89. self.for_computation(self.unbox(v))
  90. )
  91. return dispatcher
  92. def simple_binary_op(func):
  93. specialize.argtype(1, 2)(func)
  94. @functools.wraps(func)
  95. def dispatcher(self, v1, v2):
  96. return self.box(
  97. func(
  98. self,
  99. self.for_computation(self.unbox(v1)),
  100. self.for_computation(self.unbox(v2)),
  101. )
  102. )
  103. return dispatcher
  104. def complex_binary_op(func):
  105. specialize.argtype(1, 2)(func)
  106. @functools.wraps(func)
  107. def dispatcher(self, v1, v2):
  108. return self.box_complex(
  109. *func(
  110. self,
  111. self.for_computation(self.unbox(v1)),
  112. self.for_computation(self.unbox(v2)),
  113. )
  114. )
  115. return dispatcher
  116. def raw_binary_op(func):
  117. specialize.argtype(1, 2)(func)
  118. @functools.wraps(func)
  119. def dispatcher(self, v1, v2):
  120. return func(self,
  121. self.for_computation(self.unbox(v1)),
  122. self.for_computation(self.unbox(v2))
  123. )
  124. return dispatcher
  125. class BaseType(object):
  126. _immutable_fields_ = ['space']
  127. strlen = 0 # chars needed to print any possible value of the type
  128. def __init__(self, space):
  129. assert isinstance(space, ObjSpace)
  130. self.space = space
  131. def __repr__(self):
  132. return self.__class__.__name__
  133. def malloc(self, size, zero=True):
  134. if zero:
  135. return alloc_raw_storage(size, track_allocation=False, zero=True)
  136. else:
  137. return alloc_raw_storage(size, track_allocation=False, zero=False)
  138. @classmethod
  139. def basesize(cls):
  140. return rffi.sizeof(cls.T)
  141. class Primitive(object):
  142. _mixin_ = True
  143. def get_element_size(self):
  144. return rffi.sizeof(self.T)
  145. @specialize.argtype(1)
  146. def box(self, value):
  147. return self.BoxType(rffi.cast(self.T, value))
  148. @specialize.argtype(1, 2)
  149. def box_complex(self, real, imag):
  150. #XXX this is the place to display a warning
  151. return self.box(real)
  152. def box_raw_data(self, data):
  153. # For pickle
  154. array = rffi.cast(rffi.CArrayPtr(self.T), data)
  155. return self.box(array[0])
  156. def unbox(self, box):
  157. if isinstance(box, self.BoxType):
  158. return box.value
  159. elif isinstance(box, boxes.W_ObjectBox):
  160. return self._coerce(self.space, box).value
  161. else:
  162. raise oefmt(self.space.w_NotImplementedError,
  163. "%s dtype cannot unbox %s", str(self), str(box))
  164. def coerce(self, space, dtype, w_item):
  165. if isinstance(w_item, self.BoxType):
  166. return w_item
  167. return self.coerce_subtype(space, space.gettypefor(self.BoxType), w_item)
  168. def coerce_subtype(self, space, w_subtype, w_item):
  169. # XXX: ugly
  170. w_obj = space.allocate_instance(self.BoxType, w_subtype)
  171. assert isinstance(w_obj, self.BoxType)
  172. w_obj.__init__(self._coerce(space, w_item).value)
  173. return w_obj
  174. def to_builtin_type(self, space, box):
  175. return space.wrap(self.for_computation(self.unbox(box)))
  176. def _coerce(self, space, w_item):
  177. raise NotImplementedError
  178. def default_fromstring(self, space):
  179. raise NotImplementedError
  180. def _read(self, storage, i, offset, native):
  181. res = raw_storage_getitem_unaligned(self.T, storage, i + offset)
  182. if not native:
  183. res = byteswap(res)
  184. return res
  185. def _write(self, storage, i, offset, value, native):
  186. if not native:
  187. value = byteswap(value)
  188. raw_storage_setitem_unaligned(storage, i + offset, value)
  189. def read(self, arr, i, offset, dtype):
  190. with arr as storage:
  191. return self.box(self._read(storage, i, offset, dtype.is_native()))
  192. def read_bool(self, arr, i, offset, dtype):
  193. with arr as storage:
  194. return bool(self.for_computation(
  195. self._read(storage, i, offset, dtype.is_native())))
  196. def store(self, arr, i, offset, box, native):
  197. with arr as storage:
  198. self._write(storage, i, offset, self.unbox(box), native)
  199. def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
  200. value = self.unbox(box)
  201. for i in xrange(start, stop, width):
  202. self._write(storage, i, offset, value, native)
  203. def runpack_str(self, space, s, native):
  204. v = rffi.cast(self.T, runpack(self.format_code, s))
  205. if not native:
  206. v = byteswap(v)
  207. return self.box(v)
  208. @simple_binary_op
  209. def add(self, v1, v2):
  210. return v1 + v2
  211. @simple_binary_op
  212. def sub(self, v1, v2):
  213. return v1 - v2
  214. @simple_binary_op
  215. def mul(self, v1, v2):
  216. return v1 * v2
  217. @simple_unary_op
  218. def pos(self, v):
  219. return +v
  220. @simple_unary_op
  221. def neg(self, v):
  222. return -v
  223. def byteswap(self, w_v):
  224. # no for_computation here
  225. return self.box(byteswap(self.unbox(w_v)))
  226. @simple_unary_op
  227. def conj(self, v):
  228. return v
  229. @simple_unary_op
  230. def real(self, v):
  231. return v
  232. @simple_unary_op
  233. def imag(self, v):
  234. return 0
  235. @simple_unary_op
  236. def abs(self, v):
  237. return abs(v)
  238. @raw_unary_op
  239. def isnan(self, v):
  240. return False
  241. @raw_unary_op
  242. def isinf(self, v):
  243. return False
  244. @raw_binary_op
  245. def eq(self, v1, v2):
  246. return v1 == v2
  247. @raw_binary_op
  248. def ne(self, v1, v2):
  249. return v1 != v2
  250. @raw_binary_op
  251. def lt(self, v1, v2):
  252. return v1 < v2
  253. @raw_binary_op
  254. def le(self, v1, v2):
  255. return v1 <= v2
  256. @raw_binary_op
  257. def gt(self, v1, v2):
  258. return v1 > v2
  259. @raw_binary_op
  260. def ge(self, v1, v2):
  261. return v1 >= v2
  262. @raw_binary_op
  263. def logical_and(self, v1, v2):
  264. if bool(v1) and bool(v2):
  265. return Bool._True
  266. return Bool._False
  267. @raw_binary_op
  268. def logical_or(self, v1, v2):
  269. if bool(v1) or bool(v2):
  270. return Bool._True
  271. return Bool._False
  272. @raw_unary_op
  273. def logical_not(self, v):
  274. return not bool(v)
  275. @raw_binary_op
  276. def logical_xor(self, v1, v2):
  277. a = bool(v1)
  278. b = bool(v2)
  279. return (not b and a) or (not a and b)
  280. @raw_unary_op
  281. def bool(self, v):
  282. return bool(v)
  283. @simple_binary_op
  284. def max(self, v1, v2):
  285. return max(v1, v2)
  286. @simple_binary_op
  287. def min(self, v1, v2):
  288. return min(v1, v2)
  289. @raw_binary_op
  290. def argmax(self, v1, v2):
  291. return v1 >= v2
  292. @raw_binary_op
  293. def argmin(self, v1, v2):
  294. return v1 <= v2
  295. @raw_unary_op
  296. def rint(self, v):
  297. float64 = Float64(self.space)
  298. return float64.rint(float64.box(v))
  299. class Bool(BaseType, Primitive):
  300. T = lltype.Bool
  301. num = NPY.BOOL
  302. kind = NPY.GENBOOLLTR
  303. char = NPY.BOOLLTR
  304. BoxType = boxes.W_BoolBox
  305. format_code = "?"
  306. strlen = 5 # "False"
  307. _True = BoxType(True)
  308. _False = BoxType(False)
  309. @specialize.argtype(1)
  310. def box(self, value):
  311. boolean = rffi.cast(self.T, value)
  312. if boolean:
  313. return self._True
  314. else:
  315. return self._False
  316. @specialize.argtype(1, 2)
  317. def box_complex(self, real, imag):
  318. box = Primitive.box(self, real)
  319. if box.value:
  320. return self._True
  321. box = Primitive.box(self, imag)
  322. if box.value:
  323. return self._True
  324. return self._False
  325. def coerce_subtype(self, space, w_subtype, w_item):
  326. # Doesn't return subclasses so it can return the constants.
  327. return self._coerce(space, w_item)
  328. def _coerce(self, space, w_item):
  329. if space.is_none(w_item):
  330. return self.box(False)
  331. return self.box(space.is_true(w_item))
  332. def to_builtin_type(self, space, w_item):
  333. return space.wrap(self.unbox(w_item))
  334. def str_format(self, box, add_quotes=True):
  335. return "True" if self.unbox(box) else "False"
  336. @staticmethod
  337. def for_computation(v):
  338. return int(v)
  339. def default_fromstring(self, space):
  340. return self.box(True)
  341. @simple_binary_op
  342. def lshift(self, v1, v2):
  343. return v1 << v2
  344. @simple_binary_op
  345. def rshift(self, v1, v2):
  346. return v1 >> v2
  347. @simple_binary_op
  348. def bitwise_and(self, v1, v2):
  349. return v1 & v2
  350. @simple_binary_op
  351. def bitwise_or(self, v1, v2):
  352. return v1 | v2
  353. @simple_binary_op
  354. def bitwise_xor(self, v1, v2):
  355. return v1 ^ v2
  356. @simple_unary_op
  357. def invert(self, v):
  358. return not v
  359. @raw_unary_op
  360. def isfinite(self, v):
  361. return True
  362. @raw_unary_op
  363. def signbit(self, v):
  364. return False
  365. @simple_unary_op
  366. def reciprocal(self, v):
  367. if v:
  368. return 1
  369. return 0
  370. @specialize.argtype(1)
  371. def round(self, v, decimals=0):
  372. if decimals == 0:
  373. return Float64(self.space).box(self.unbox(v))
  374. # numpy 1.10 compatibility
  375. raise oefmt(self.space.w_TypeError, "ufunc casting failure")
  376. class Integer(Primitive):
  377. _mixin_ = True
  378. signed = True
  379. def _base_coerce(self, space, w_item):
  380. if w_item is None:
  381. return self.box(0)
  382. return self.box(space.int_w(space.call_function(space.w_int, w_item)))
  383. def _coerce(self, space, w_item):
  384. return self._base_coerce(space, w_item)
  385. def str_format(self, box, add_quotes=True):
  386. return str(self.for_computation(self.unbox(box)))
  387. @staticmethod
  388. def for_computation(v):
  389. return widen(v)
  390. def default_fromstring(self, space):
  391. return self.box(0)
  392. @specialize.argtype(1, 2)
  393. def div(self, b1, b2):
  394. v1 = self.for_computation(self.unbox(b1))
  395. v2 = self.for_computation(self.unbox(b2))
  396. if v2 == 0:
  397. return self.box(0)
  398. if (self.T is rffi.SIGNEDCHAR or self.T is rffi.SHORT or self.T is rffi.INT or
  399. self.T is rffi.LONG or self.T is rffi.LONGLONG):
  400. if v2 == -1 and v1 == self.for_computation(most_neg_value_of(self.T)):
  401. return self.box(0)
  402. return self.box(v1 / v2)
  403. @specialize.argtype(1, 2)
  404. def floordiv(self, b1, b2):
  405. v1 = self.for_computation(self.unbox(b1))
  406. v2 = self.for_computation(self.unbox(b2))
  407. if v2 == 0:
  408. return self.box(0)
  409. if (self.T is rffi.SIGNEDCHAR or self.T is rffi.SHORT or self.T is rffi.INT or
  410. self.T is rffi.LONG or self.T is rffi.LONGLONG):
  411. if v2 == -1 and v1 == self.for_computation(most_neg_value_of(self.T)):
  412. return self.box(0)
  413. return self.box(v1 / v2)
  414. @simple_binary_op
  415. def mod(self, v1, v2):
  416. return v1 % v2
  417. @simple_binary_op
  418. @jit.look_inside_iff(lambda self, v1, v2: jit.isconstant(v2))
  419. def pow(self, v1, v2):
  420. if v2 < 0:
  421. return 0
  422. res = 1
  423. while v2 > 0:
  424. if v2 & 1:
  425. res *= v1
  426. v2 >>= 1
  427. if v2 == 0:
  428. break
  429. v1 *= v1
  430. return res
  431. @simple_binary_op
  432. def lshift(self, v1, v2):
  433. return v1 << v2
  434. @simple_binary_op
  435. def rshift(self, v1, v2):
  436. return v1 >> v2
  437. @simple_unary_op
  438. def sign(self, v):
  439. if v > 0:
  440. return 1
  441. elif v < 0:
  442. return -1
  443. else:
  444. assert v == 0
  445. return 0
  446. @raw_unary_op
  447. def isfinite(self, v):
  448. return True
  449. @raw_unary_op
  450. def isnan(self, v):
  451. return False
  452. @raw_unary_op
  453. def isinf(self, v):
  454. return False
  455. @simple_binary_op
  456. def bitwise_and(self, v1, v2):
  457. return v1 & v2
  458. @simple_binary_op
  459. def bitwise_or(self, v1, v2):
  460. return v1 | v2
  461. @simple_binary_op
  462. def bitwise_xor(self, v1, v2):
  463. return v1 ^ v2
  464. @simple_unary_op
  465. def invert(self, v):
  466. return ~v
  467. @specialize.argtype(1)
  468. def reciprocal(self, v):
  469. raw = self.for_computation(self.unbox(v))
  470. ans = 0
  471. if raw == 0:
  472. # XXX good place to warn
  473. if self.T is rffi.INT or self.T is rffi.LONG or self.T is rffi.LONGLONG:
  474. ans = most_neg_value_of(self.T)
  475. elif abs(raw) == 1:
  476. ans = raw
  477. return self.box(ans)
  478. @specialize.argtype(1)
  479. def round(self, v, decimals=0):
  480. raw = self.for_computation(self.unbox(v))
  481. if decimals < 0:
  482. # No ** in rpython
  483. factor = 1
  484. for i in xrange(-decimals):
  485. factor *=10
  486. #int does floor division, we want toward zero
  487. if raw < 0:
  488. ans = - (-raw / factor * factor)
  489. else:
  490. ans = raw / factor * factor
  491. else:
  492. ans = raw
  493. return self.box(ans)
  494. @raw_unary_op
  495. def signbit(self, v):
  496. return v < 0
  497. class Int8(BaseType, Integer):
  498. T = rffi.SIGNEDCHAR
  499. num = NPY.BYTE
  500. kind = NPY.SIGNEDLTR
  501. char = NPY.BYTELTR
  502. BoxType = boxes.W_Int8Box
  503. format_code = "b"
  504. class UInt8(BaseType, Integer):
  505. T = rffi.UCHAR
  506. num = NPY.UBYTE
  507. kind = NPY.UNSIGNEDLTR
  508. char = NPY.UBYTELTR
  509. BoxType = boxes.W_UInt8Box
  510. format_code = "B"
  511. signed = False
  512. class Int16(BaseType, Integer):
  513. T = rffi.SHORT
  514. num = NPY.SHORT
  515. kind = NPY.SIGNEDLTR
  516. char = NPY.SHORTLTR
  517. BoxType = boxes.W_Int16Box
  518. format_code = "h"
  519. class UInt16(BaseType, Integer):
  520. T = rffi.USHORT
  521. num = NPY.USHORT
  522. kind = NPY.UNSIGNEDLTR
  523. char = NPY.USHORTLTR
  524. BoxType = boxes.W_UInt16Box
  525. format_code = "H"
  526. signed = False
  527. class Int32(BaseType, Integer):
  528. T = rffi.INT
  529. num = NPY.INT
  530. kind = NPY.SIGNEDLTR
  531. char = NPY.INTLTR
  532. BoxType = boxes.W_Int32Box
  533. format_code = "i"
  534. class UInt32(BaseType, Integer):
  535. T = rffi.UINT
  536. num = NPY.UINT
  537. kind = NPY.UNSIGNEDLTR
  538. char = NPY.UINTLTR
  539. BoxType = boxes.W_UInt32Box
  540. format_code = "I"
  541. signed = False
  542. def _int64_coerce(self, space, w_item):
  543. try:
  544. return self._base_coerce(space, w_item)
  545. except OperationError as e:
  546. if not e.match(space, space.w_OverflowError):
  547. raise
  548. bigint = space.bigint_w(w_item)
  549. try:
  550. value = bigint.tolonglong()
  551. except OverflowError:
  552. raise OperationError(space.w_OverflowError, space.w_None)
  553. return self.box(value)
  554. class Int64(BaseType, Integer):
  555. T = rffi.LONGLONG
  556. num = NPY.LONGLONG
  557. kind = NPY.SIGNEDLTR
  558. char = NPY.LONGLONGLTR
  559. BoxType = boxes.W_Int64Box
  560. format_code = "q"
  561. if LONG_BIT == 32:
  562. _coerce = func_with_new_name(_int64_coerce, '_coerce')
  563. def _uint64_coerce(self, space, w_item):
  564. try:
  565. return self._base_coerce(space, w_item)
  566. except OperationError as e:
  567. if not e.match(space, space.w_OverflowError):
  568. raise
  569. bigint = space.bigint_w(w_item)
  570. try:
  571. value = bigint.toulonglong()
  572. except OverflowError:
  573. raise OperationError(space.w_OverflowError, space.w_None)
  574. return self.box(value)
  575. class UInt64(BaseType, Integer):
  576. T = rffi.ULONGLONG
  577. num = NPY.ULONGLONG
  578. kind = NPY.UNSIGNEDLTR
  579. char = NPY.ULONGLONGLTR
  580. BoxType = boxes.W_UInt64Box
  581. format_code = "Q"
  582. signed = False
  583. _coerce = func_with_new_name(_uint64_coerce, '_coerce')
  584. class Long(BaseType, Integer):
  585. T = rffi.LONG
  586. num = NPY.LONG
  587. kind = NPY.SIGNEDLTR
  588. char = NPY.LONGLTR
  589. BoxType = boxes.W_LongBox
  590. format_code = "l"
  591. def _ulong_coerce(self, space, w_item):
  592. try:
  593. return self._base_coerce(space, w_item)
  594. except OperationError as e:
  595. if not e.match(space, space.w_OverflowError):
  596. raise
  597. bigint = space.bigint_w(w_item)
  598. try:
  599. value = bigint.touint()
  600. except OverflowError:
  601. raise OperationError(space.w_OverflowError, space.w_None)
  602. return self.box(value)
  603. class ULong(BaseType, Integer):
  604. T = rffi.ULONG
  605. num = NPY.ULONG
  606. kind = NPY.UNSIGNEDLTR
  607. char = NPY.ULONGLTR
  608. BoxType = boxes.W_ULongBox
  609. format_code = "L"
  610. signed = False
  611. _coerce = func_with_new_name(_ulong_coerce, '_coerce')
  612. class Float(Primitive):
  613. _mixin_ = True
  614. strlen = 32
  615. def _coerce(self, space, w_item):
  616. if w_item is None:
  617. return self.box(0.0)
  618. if space.is_none(w_item):
  619. return self.box(rfloat.NAN)
  620. return self.box(space.float_w(space.call_function(space.w_float, w_item)))
  621. def str_format(self, box, add_quotes=True):
  622. return float2string(self.for_computation(self.unbox(box)), "g",
  623. rfloat.DTSF_STR_PRECISION)
  624. @staticmethod
  625. def for_computation(v):
  626. return float(v)
  627. def default_fromstring(self, space):
  628. return self.box(-1.0)
  629. @simple_binary_op
  630. def div(self, v1, v2):
  631. try:
  632. return v1 / v2
  633. except ZeroDivisionError:
  634. if v1 == v2 == 0.0:
  635. return rfloat.NAN
  636. return rfloat.copysign(rfloat.INFINITY, v1 * v2)
  637. @simple_binary_op
  638. def floordiv(self, v1, v2):
  639. try:
  640. return math.floor(v1 / v2)
  641. except ZeroDivisionError:
  642. if v1 == v2 == 0.0:
  643. return rfloat.NAN
  644. return rfloat.copysign(rfloat.INFINITY, v1 * v2)
  645. @simple_binary_op
  646. def mod(self, v1, v2):
  647. # partial copy of pypy.objspace.std.floatobject.W_FloatObject.descr_mod
  648. if v2 == 0.0:
  649. return rfloat.NAN
  650. mod = math.fmod(v1, v2)
  651. if mod:
  652. # ensure the remainder has the same sign as the denominator
  653. if (v2 < 0.0) != (mod < 0.0):
  654. mod += v2
  655. else:
  656. # the remainder is zero, and in the presence of signed zeroes
  657. # fmod returns different results across platforms; ensure
  658. # it has the same sign as the denominator; we'd like to do
  659. # "mod = v2 * 0.0", but that may get optimized away
  660. mod = rfloat.copysign(0.0, v2)
  661. return mod
  662. @simple_binary_op
  663. def pow(self, v1, v2):
  664. try:
  665. return math.pow(v1, v2)
  666. except ValueError:
  667. return rfloat.NAN
  668. except OverflowError:
  669. if math.modf(v2)[0] == 0 and math.modf(v2 / 2)[0] != 0:
  670. # Odd integer powers result in the same sign as the base
  671. return rfloat.copysign(rfloat.INFINITY, v1)
  672. return rfloat.INFINITY
  673. @simple_binary_op
  674. def copysign(self, v1, v2):
  675. return math.copysign(v1, v2)
  676. @simple_unary_op
  677. def sign(self, v):
  678. if v == 0.0:
  679. return 0.0
  680. if rfloat.isnan(v):
  681. return rfloat.NAN
  682. return rfloat.copysign(1.0, v)
  683. @raw_unary_op
  684. def signbit(self, v):
  685. return rfloat.copysign(1.0, v) < 0.0
  686. @simple_unary_op
  687. def fabs(self, v):
  688. return math.fabs(v)
  689. @simple_binary_op
  690. def max(self, v1, v2):
  691. return v1 if v1 >= v2 or rfloat.isnan(v1) else v2
  692. @simple_binary_op
  693. def min(self, v1, v2):
  694. return v1 if v1 <= v2 or rfloat.isnan(v1) else v2
  695. @raw_binary_op
  696. def argmax(self, v1, v2):
  697. return v1 >= v2 or rfloat.isnan(v1)
  698. @raw_binary_op
  699. def argmin(self, v1, v2):
  700. return v1 <= v2 or rfloat.isnan(v1)
  701. @simple_binary_op
  702. def fmax(self, v1, v2):
  703. return v1 if v1 >= v2 or rfloat.isnan(v2) else v2
  704. @simple_binary_op
  705. def fmin(self, v1, v2):
  706. return v1 if v1 <= v2 or rfloat.isnan(v2) else v2
  707. @simple_binary_op
  708. def fmod(self, v1, v2):
  709. try:
  710. return math.fmod(v1, v2)
  711. except ValueError:
  712. return rfloat.NAN
  713. @simple_unary_op
  714. def reciprocal(self, v):
  715. if v == 0.0:
  716. return rfloat.copysign(rfloat.INFINITY, v)
  717. return 1.0 / v
  718. @simple_unary_op
  719. def floor(self, v):
  720. return math.floor(v)
  721. @simple_unary_op
  722. def ceil(self, v):
  723. return math.ceil(v)
  724. @specialize.argtype(1)
  725. def round(self, v, decimals=0):
  726. raw = self.for_computation(self.unbox(v))
  727. if rfloat.isinf(raw):
  728. return v
  729. elif rfloat.isnan(raw):
  730. return v
  731. ans = rfloat.round_double(raw, decimals, half_even=True)
  732. return self.box(ans)
  733. @simple_unary_op
  734. def trunc(self, v):
  735. if v < 0:
  736. return math.ceil(v)
  737. else:
  738. return math.floor(v)
  739. @simple_unary_op
  740. def exp(self, v):
  741. try:
  742. return math.exp(v)
  743. except OverflowError:
  744. return rfloat.INFINITY
  745. @simple_unary_op
  746. def exp2(self, v):
  747. try:
  748. return math.pow(2, v)
  749. except OverflowError:
  750. return rfloat.INFINITY
  751. @simple_unary_op
  752. def expm1(self, v):
  753. try:
  754. return rfloat.expm1(v)
  755. except OverflowError:
  756. return rfloat.INFINITY
  757. @simple_unary_op
  758. def sin(self, v):
  759. return math.sin(v)
  760. @simple_unary_op
  761. def cos(self, v):
  762. return math.cos(v)
  763. @simple_unary_op
  764. def tan(self, v):
  765. return math.tan(v)
  766. @simple_unary_op
  767. def arcsin(self, v):
  768. if not -1.0 <= v <= 1.0:
  769. return rfloat.NAN
  770. return math.asin(v)
  771. @simple_unary_op
  772. def arccos(self, v):
  773. if not -1.0 <= v <= 1.0:
  774. return rfloat.NAN
  775. return math.acos(v)
  776. @simple_unary_op
  777. def arctan(self, v):
  778. return math.atan(v)
  779. @simple_binary_op
  780. def arctan2(self, v1, v2):
  781. return math.atan2(v1, v2)
  782. @simple_unary_op
  783. def sinh(self, v):
  784. return math.sinh(v)
  785. @simple_unary_op
  786. def cosh(self, v):
  787. return math.cosh(v)
  788. @simple_unary_op
  789. def tanh(self, v):
  790. return math.tanh(v)
  791. @simple_unary_op
  792. def arcsinh(self, v):
  793. return math.asinh(v)
  794. @simple_unary_op
  795. def arccosh(self, v):
  796. if v < 1.0:
  797. return rfloat.NAN
  798. return math.acosh(v)
  799. @simple_unary_op
  800. def arctanh(self, v):
  801. if v == 1.0 or v == -1.0:
  802. return math.copysign(rfloat.INFINITY, v)
  803. if not -1.0 < v < 1.0:
  804. return rfloat.NAN
  805. return math.atanh(v)
  806. @simple_unary_op
  807. def sqrt(self, v):
  808. try:
  809. return math.sqrt(v)
  810. except ValueError:
  811. return rfloat.NAN
  812. @simple_unary_op
  813. def square(self, v):
  814. return v*v
  815. @raw_unary_op
  816. def isnan(self, v):
  817. return rfloat.isnan(v)
  818. @raw_unary_op
  819. def isinf(self, v):
  820. return rfloat.isinf(v)
  821. @raw_unary_op
  822. def isfinite(self, v):
  823. return rfloat.isfinite(v)
  824. @simple_unary_op
  825. def radians(self, v):
  826. return v * degToRad
  827. deg2rad = radians
  828. @simple_unary_op
  829. def degrees(self, v):
  830. return v / degToRad
  831. @simple_unary_op
  832. def log(self, v):
  833. try:
  834. return math.log(v)
  835. except ValueError:
  836. if v == 0.0:
  837. # CPython raises ValueError here, so we have to check
  838. # the value to find the correct numpy return value
  839. return -rfloat.INFINITY
  840. return rfloat.NAN
  841. @simple_unary_op
  842. def log2(self, v):
  843. try:
  844. return math.log(v) / log2
  845. except ValueError:
  846. if v == 0.0:
  847. # CPython raises ValueError here, so we have to check
  848. # the value to find the correct numpy return value
  849. return -rfloat.INFINITY
  850. return rfloat.NAN
  851. @simple_unary_op
  852. def log10(self, v):
  853. try:
  854. return math.log10(v)
  855. except ValueError:
  856. if v == 0.0:
  857. # CPython raises ValueError here, so we have to check
  858. # the value to find the correct numpy return value
  859. return -rfloat.INFINITY
  860. return rfloat.NAN
  861. @simple_unary_op
  862. def log1p(self, v):
  863. try:
  864. return rfloat.log1p(v)
  865. except OverflowError:
  866. return -rfloat.INFINITY
  867. except ValueError:
  868. return rfloat.NAN
  869. @simple_binary_op
  870. def logaddexp(self, v1, v2):
  871. tmp = v1 - v2
  872. if tmp > 0:
  873. return v1 + rfloat.log1p(math.exp(-tmp))
  874. elif tmp <= 0:
  875. return v2 + rfloat.log1p(math.exp(tmp))
  876. else:
  877. return v1 + v2
  878. def npy_log2_1p(self, v):
  879. return log2e * rfloat.log1p(v)
  880. @simple_binary_op
  881. def logaddexp2(self, v1, v2):
  882. tmp = v1 - v2
  883. if tmp > 0:
  884. return v1 + self.npy_log2_1p(math.pow(2, -tmp))
  885. if tmp <= 0:
  886. return v2 + self.npy_log2_1p(math.pow(2, tmp))
  887. else:
  888. return v1 + v2
  889. @simple_unary_op
  890. def rint(self, v):
  891. x = float(v)
  892. if rfloat.isfinite(x):
  893. import math
  894. y = math.floor(x)
  895. r = x - y
  896. if r > 0.5:
  897. y += 1.0
  898. if r == 0.5:
  899. r = y - 2.0 * math.floor(0.5 * y)
  900. if r == 1.0:
  901. y += 1.0
  902. return y
  903. else:
  904. return x
  905. class Float16(Float, BaseType):
  906. _STORAGE_T = rffi.USHORT
  907. T = rffi.SHORT
  908. num = NPY.HALF
  909. kind = NPY.FLOATINGLTR
  910. char = NPY.HALFLTR
  911. BoxType = boxes.W_Float16Box
  912. max_value = 65000.
  913. @specialize.argtype(1)
  914. def box(self, value):
  915. return self.BoxType(rffi.cast(rffi.DOUBLE, value))
  916. def runpack_str(self, space, s, native):
  917. assert len(s) == 2
  918. fval = self.box(unpack_float(s, native_is_bigendian))
  919. if not native:
  920. fval = self.byteswap(fval)
  921. return fval
  922. def default_fromstring(self, space):
  923. return self.box(-1.0)
  924. def byteswap(self, w_v):
  925. value = self.unbox(w_v)
  926. hbits = float_pack(value, 2)
  927. swapped = byteswap(rffi.cast(self._STORAGE_T, hbits))
  928. return self.box(float_unpack(r_ulonglong(swapped), 2))
  929. def _read(self, storage, i, offset, native):
  930. hbits = raw_storage_getitem_unaligned(self._STORAGE_T, storage, i + offset)
  931. if not native:
  932. hbits = byteswap(hbits)
  933. return float_unpack(r_ulonglong(hbits), 2)
  934. def _write(self, storage, i, offset, value, native):
  935. try:
  936. hbits = float_pack(value, 2)
  937. except OverflowError:
  938. hbits = float_pack(rfloat.INFINITY, 2)
  939. hbits = rffi.cast(self._STORAGE_T, hbits)
  940. if not native:
  941. hbits = byteswap(hbits)
  942. raw_storage_setitem_unaligned(storage, i + offset, hbits)
  943. class Float32(Float, BaseType):
  944. T = rffi.FLOAT
  945. num = NPY.FLOAT
  946. kind = NPY.FLOATINGLTR
  947. char = NPY.FLOATLTR
  948. BoxType = boxes.W_Float32Box
  949. format_code = "f"
  950. max_value = 3.4e38
  951. class Float64(Float, BaseType):
  952. T = rffi.DOUBLE
  953. num = NPY.DOUBLE
  954. kind = NPY.FLOATINGLTR
  955. char = NPY.DOUBLELTR
  956. BoxType = boxes.W_Float64Box
  957. format_code = "d"
  958. max_value = 1.7e308
  959. class ComplexFloating(object):
  960. _mixin_ = True
  961. strlen = 64
  962. def _coerce(self, space, w_item):
  963. if w_item is None:
  964. return self.box_complex(0.0, 0.0)
  965. if space.is_none(w_item):
  966. return self.box_complex(rfloat.NAN, rfloat.NAN)
  967. w_item = space.call_function(space.w_complex, w_item)
  968. real, imag = space.unpackcomplex(w_item)
  969. return self.box_complex(real, imag)
  970. def coerce(self, space, dtype, w_item):
  971. if isinstance(w_item, self.BoxType):
  972. return w_item
  973. return self.coerce_subtype(space, space.gettypefor(self.BoxType), w_item)
  974. def coerce_subtype(self, space, w_subtype, w_item):
  975. w_tmpobj = self._coerce(space, w_item)
  976. w_obj = space.allocate_instance(self.BoxType, w_subtype)
  977. assert isinstance(w_obj, self.BoxType)
  978. w_obj.__init__(w_tmpobj.real, w_tmpobj.imag)
  979. return w_obj
  980. def str_format(self, box, add_quotes=True):
  981. real, imag = self.for_computation(self.unbox(box))
  982. imag_str = str_format(imag)
  983. if not rfloat.isfinite(imag):
  984. imag_str += '*'
  985. imag_str += 'j'
  986. # (0+2j) => 2j
  987. if real == 0 and math.copysign(1, real) == 1:
  988. return imag_str
  989. real_str = str_format(real)
  990. op = '+' if imag >= 0 or rfloat.isnan(imag) else ''
  991. return ''.join(['(', real_str, op, imag_str, ')'])
  992. def runpack_str(self, space, s, native):
  993. comp = self.ComponentBoxType._get_dtype(space)
  994. l = len(s) // 2
  995. real = comp.runpack_str(space, s[:l])
  996. imag = comp.runpack_str(space, s[l:])
  997. if not native:
  998. real = comp.itemtype.byteswap(real)
  999. imag = comp.itemtype.byteswap(imag)
  1000. return self.composite(real, imag)
  1001. @staticmethod
  1002. def for_computation(v):
  1003. return float(v[0]), float(v[1])
  1004. @raw_unary_op
  1005. def _to_builtin_type(self, v):
  1006. return v
  1007. def to_builtin_type(self, space, box):
  1008. real, imag = self.for_computation(self.unbox(box))
  1009. return space.newcomplex(real, imag)
  1010. def bool(self, v):
  1011. real, imag = self.for_computation(self.unbox(v))
  1012. return bool(real) or bool(imag)
  1013. def read_bool(self, arr, i, offset, dtype):
  1014. with arr as storage:
  1015. v = self.for_computation(
  1016. self._read(storage, i, offset, dtype.is_native()))
  1017. return bool(v[0]) or bool(v[1])
  1018. def get_element_size(self):
  1019. return 2 * rffi.sizeof(self.T)
  1020. def byteswap(self, w_v):
  1021. real, imag = self.unbox(w_v)
  1022. return self.box_complex(byteswap(real), byteswap(imag))
  1023. @specialize.argtype(1)
  1024. def box(self, value):
  1025. return self.BoxType(
  1026. rffi.cast(self.T, value),
  1027. rffi.cast(self.T, 0.0))
  1028. @specialize.argtype(1)
  1029. def box_component(self, value):
  1030. return self.ComponentBoxType(
  1031. rffi.cast(self.T, value))
  1032. @specialize.argtype(1, 2)
  1033. def box_complex(self, real, imag):
  1034. return self.BoxType(
  1035. rffi.cast(self.T, real),
  1036. rffi.cast(self.T, imag))
  1037. def box_raw_data(self, data):
  1038. # For pickle
  1039. array = rffi.cast(rffi.CArrayPtr(self.T), data)
  1040. return self.box_complex(array[0], array[1])
  1041. def composite(self, v1, v2):
  1042. assert isinstance(v1, self.ComponentBoxType)
  1043. assert isinstance(v2, self.ComponentBoxType)
  1044. real = v1.value
  1045. imag = v2.value
  1046. return self.box_complex(real, imag)
  1047. def unbox(self, box):
  1048. if isinstance(box, self.BoxType):
  1049. return box.real, box.imag
  1050. elif isinstance(box, boxes.W_ObjectBox):
  1051. retval = self._coerce(self.space, box)
  1052. return retval.real, retval.imag
  1053. else:
  1054. raise oefmt(self.space.w_NotImplementedError,
  1055. "%s dtype cannot unbox %s", str(self), str(box))
  1056. def _read(self, storage, i, offset, native):
  1057. real = raw_storage_getitem_unaligned(self.T, storage, i + offset)
  1058. imag = raw_storage_getitem_unaligned(self.T, storage, i + offset + rffi.sizeof(self.T))
  1059. if not native:
  1060. real = byteswap(real)
  1061. imag = byteswap(imag)
  1062. return real, imag
  1063. def read(self, arr, i, offset, dtype):
  1064. with arr as storage:
  1065. real, imag = self._read(storage, i, offset, dtype.is_native())
  1066. return self.box_complex(real, imag)
  1067. def _write(self, storage, i, offset, value, native):
  1068. real, imag = value
  1069. if not native:
  1070. real = byteswap(real)
  1071. imag = byteswap(imag)
  1072. raw_storage_setitem_unaligned(storage, i + offset, real)
  1073. raw_storage_setitem_unaligned(storage, i + offset + rffi.sizeof(self.T), imag)
  1074. def store(self, arr, i, offset, box, native):
  1075. with arr as storage:
  1076. self._write(storage, i, offset, self.unbox(box), native)
  1077. def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
  1078. value = self.unbox(box)
  1079. for i in xrange(start, stop, width):
  1080. self._write(storage, i, offset, value, native)
  1081. @complex_binary_op
  1082. def add(self, v1, v2):
  1083. return rcomplex.c_add(v1, v2)
  1084. @complex_binary_op
  1085. def sub(self, v1, v2):
  1086. return rcomplex.c_sub(v1, v2)
  1087. @complex_binary_op
  1088. def mul(self, v1, v2):
  1089. return rcomplex.c_mul(v1, v2)
  1090. @complex_binary_op
  1091. def div(self, v1, v2):
  1092. try:
  1093. return rcomplex.c_div(v1, v2)
  1094. except ZeroDivisionError:
  1095. if rcomplex.c_abs(*v1) == 0 or \
  1096. (rfloat.isnan(v1[0]) and rfloat.isnan(v1[1])):
  1097. return rfloat.NAN, rfloat.NAN
  1098. return rfloat.INFINITY, rfloat.INFINITY
  1099. @complex_unary_op
  1100. def pos(self, v):
  1101. return v
  1102. @complex_unary_op
  1103. def neg(self, v):
  1104. return -v[0], -v[1]
  1105. @complex_unary_op
  1106. def conj(self, v):
  1107. return v[0], -v[1]
  1108. @complex_to_real_unary_op
  1109. def real(self, v):
  1110. return v[0]
  1111. @complex_to_real_unary_op
  1112. def imag(self, v):
  1113. return v[1]
  1114. @complex_to_real_unary_op
  1115. def abs(self, v):
  1116. try:
  1117. return rcomplex.c_abs(v[0], v[1])
  1118. except OverflowError:
  1119. # warning ...
  1120. return rfloat.INFINITY
  1121. @raw_unary_op
  1122. def isnan(self, v):
  1123. '''a complex number is nan if one of the parts is nan'''
  1124. return rfloat.isnan(v[0]) or rfloat.isnan(v[1])
  1125. @raw_unary_op
  1126. def isinf(self, v):
  1127. '''a complex number is inf if one of the parts is inf'''
  1128. return rfloat.isinf(v[0]) or rfloat.isinf(v[1])
  1129. def _eq(self, v1, v2):
  1130. return v1[0] == v2[0] and v1[1] == v2[1]
  1131. @raw_binary_op
  1132. def eq(self, v1, v2):
  1133. #compare the parts, so nan == nan is False
  1134. return self._eq(v1, v2)
  1135. @raw_binary_op
  1136. def ne(self, v1, v2):
  1137. return not self._eq(v1, v2)
  1138. def _lt(self, v1, v2):
  1139. (r1, i1), (r2, i2) = v1, v2
  1140. if r1 < r2 and not rfloat.isnan(i1) and not rfloat.isnan(i2):
  1141. return True
  1142. if r1 == r2 and i1 < i2:
  1143. return True
  1144. return False
  1145. @raw_binary_op
  1146. def lt(self, v1, v2):
  1147. return self._lt(v1, v2)
  1148. @raw_binary_op
  1149. def le(self, v1, v2):
  1150. return self._lt(v1, v2) or self._eq(v1, v2)
  1151. @raw_binary_op
  1152. def gt(self, v1, v2):
  1153. return self._lt(v2, v1)
  1154. @raw_binary_op
  1155. def ge(self, v1, v2):
  1156. return self._lt(v2, v1) or self._eq(v2, v1)
  1157. def _cbool(self, v):
  1158. return bool(v[0]) or bool(v[1])
  1159. @raw_binary_op
  1160. def logical_and(self, v1, v2):
  1161. if self._cbool(v1) and self._cbool(v2):
  1162. return Bool._True
  1163. return Bool._False
  1164. @raw_binary_op
  1165. def logical_or(self, v1, v2):
  1166. if self._cbool(v1) or self._cbool(v2):
  1167. return Bool._True
  1168. return Bool._False
  1169. @raw_unary_op
  1170. def logical_not(self, v):
  1171. return not self._cbool(v)
  1172. @raw_binary_op
  1173. def logical_xor(self, v1, v2):
  1174. a = self._cbool(v1)
  1175. b = self._cbool(v2)
  1176. return (not b and a) or (not a and b)
  1177. def min(self, v1, v2):
  1178. if self.le(v1, v2) or self.isnan(v1):
  1179. return v1
  1180. return v2
  1181. def max(self, v1, v2):
  1182. if self.ge(v1, v2) or self.isnan(v1):
  1183. return v1
  1184. return v2
  1185. def argmin(self, v1, v2):
  1186. if self.le(v1, v2) or self.isnan(v1):
  1187. return True
  1188. return False
  1189. def argmax(self, v1, v2):
  1190. if self.ge(v1, v2) or self.isnan(v1):
  1191. return True
  1192. return False
  1193. @complex_binary_op
  1194. def floordiv(self, v1, v2):
  1195. (r1, i1), (r2, i2) = v1, v2
  1196. if r2 < 0:
  1197. abs_r2 = -r2
  1198. else:
  1199. abs_r2 = r2
  1200. if i2 < 0:
  1201. abs_i2 = -i2
  1202. else:
  1203. abs_i2 = i2
  1204. if abs_r2 >= abs_i2:
  1205. if abs_r2 == 0.0:
  1206. return rfloat.NAN, 0.
  1207. else:
  1208. ratio = i2 / r2
  1209. denom = r2 + i2 * ratio
  1210. rr = (r1 + i1 * ratio) / denom
  1211. elif rfloat.isnan(r2):
  1212. rr = rfloat.NAN
  1213. else:
  1214. ratio = r2 / i2
  1215. denom = r2 * ratio + i2
  1216. assert i2 != 0.0
  1217. rr = (r1 * ratio + i1) / denom
  1218. return math.floor(rr), 0.
  1219. #complex mod does not exist in numpy
  1220. #@simple_binary_op
  1221. #def mod(self, v1, v2):
  1222. # return math.fmod(v1, v2)
  1223. def pow(self, v1, v2):
  1224. y = self.for_computation(self.unbox(v2))
  1225. if y[1] == 0:
  1226. if y[0] == 0:
  1227. return self.box_complex(1, 0)
  1228. if y[0] == 1:
  1229. return v1
  1230. if y[0] == 2:
  1231. return self.mul(v1, v1)
  1232. x = self.for_computation(self.unbox(v1))
  1233. if x[0] == 0 and x[1] == 0:
  1234. if y[0] > 0 and y[1] == 0:
  1235. return self.box_complex(0, 0)
  1236. return self.box_complex(rfloat.NAN, rfloat.NAN)
  1237. b = self.for_computation(self.unbox(self.log(v1)))
  1238. return self.exp(self.box_complex(b[0] * y[0] - b[1] * y[1],
  1239. b[0] * y[1] + b[1] * y[0]))
  1240. #complex copysign does not exist in numpy
  1241. #@complex_binary_op
  1242. #def copysign(self, v1, v2):
  1243. # return (rfloat.copysign(v1[0], v2[0]),
  1244. # rfloat.copysign(v1[1], v2[1]))
  1245. @complex_unary_op
  1246. def sign(self, v):
  1247. '''
  1248. sign of complex number could be either the point closest to the unit circle
  1249. or {-1,0,1}, for compatability with numpy we choose the latter
  1250. '''
  1251. if rfloat.isnan(v[0]) or rfloat.isnan(v[1]):
  1252. return rfloat.NAN, 0
  1253. if v[0] == 0.0:
  1254. if v[1] == 0:
  1255. return 0, 0
  1256. if v[1] > 0:
  1257. return 1, 0
  1258. return -1, 0
  1259. if v[0] > 0:
  1260. return 1, 0
  1261. return -1, 0
  1262. def fmax(self, v1, v2):
  1263. if self.ge(v1, v2) or self.isnan(v2):
  1264. return v1
  1265. return v2
  1266. def fmin(self, v1, v2):
  1267. if self.le(v1, v2) or self.isnan(v2):
  1268. return v1
  1269. return v2
  1270. #@simple_binary_op
  1271. #def fmod(self, v1, v2):
  1272. # try:
  1273. # return math.fmod(v1, v2)
  1274. # except ValueError:
  1275. # return rfloat.NAN
  1276. @complex_unary_op
  1277. def reciprocal(self, v):
  1278. if rfloat.isinf(v[1]) and rfloat.isinf(v[0]):
  1279. return rfloat.NAN, rfloat.NAN
  1280. if rfloat.isinf(v[0]):
  1281. return (rfloat.copysign(0., v[0]),
  1282. rfloat.copysign(0., -v[1]))
  1283. a2 = v[0]*v[0] + v[1]*v[1]
  1284. try:
  1285. return rcomplex.c_div((v[0], -v[1]), (a2, 0.))
  1286. except ZeroDivisionError:
  1287. return rfloat.NAN, rfloat.NAN
  1288. @specialize.argtype(1)
  1289. def round(self, v, decimals=0):
  1290. ans = list(self.for_computation(self.unbox(v)))
  1291. if rfloat.isfinite(ans[0]):
  1292. ans[0] = rfloat.round_double(ans[0], decimals, half_even=True)
  1293. if rfloat.isfinite(ans[1]):
  1294. ans[1] = rfloat.round_double(ans[1], decimals, half_even=True)
  1295. return self.box_complex(ans[0], ans[1])
  1296. def rint(self, v):
  1297. return self.round(v)
  1298. # No floor, ceil, trunc in numpy for complex
  1299. #@simple_unary_op
  1300. #def floor(self, v):
  1301. # return math.floor(v)
  1302. #@simple_unary_op
  1303. #def ceil(self, v):
  1304. # return math.ceil(v)
  1305. #@simple_unary_op
  1306. #def trunc(self, v):
  1307. # if v < 0:
  1308. # return math.ceil(v)
  1309. # else:
  1310. # return math.floor(v)
  1311. @complex_unary_op
  1312. def exp(self, v):
  1313. if rfloat.isinf(v[1]):
  1314. if rfloat.isinf(v[0]):
  1315. if v[0] < 0:
  1316. return 0., 0.
  1317. return rfloat.INFINITY, rfloat.NAN
  1318. elif (rfloat.isfinite(v[0]) or \
  1319. (rfloat.isinf(v[0]) and v[0] > 0)):
  1320. return rfloat.NAN, rfloat.NAN
  1321. try:
  1322. return rcomplex.c_exp(*v)
  1323. except OverflowError:
  1324. if v[1] == 0:
  1325. return rfloat.INFINITY, 0.0
  1326. return rfloat.INFINITY, rfloat.NAN
  1327. @complex_unary_op
  1328. def exp2(self, v):
  1329. try:
  1330. return rcomplex.c_pow((2,0), v)
  1331. except OverflowError:
  1332. return rfloat.INFINITY, rfloat.NAN
  1333. except ValueError:
  1334. return rfloat.NAN, rfloat.NAN
  1335. @complex_unary_op
  1336. def expm1(self, v):
  1337. # duplicate exp() so in the future it will be easier
  1338. # to implement seterr
  1339. if rfloat.isinf(v[1]):
  1340. if rfloat.isinf(v[0]):
  1341. if v[0] < 0:
  1342. return -1., 0.
  1343. return rfloat.NAN, rfloat.NAN
  1344. elif (rfloat.isfinite(v[0]) or \
  1345. (rfloat.isinf(v[0]) and v[0] > 0)):
  1346. return rfloat.NAN, rfloat.NAN
  1347. try:
  1348. res = rcomplex.c_exp(*v)
  1349. res = (res[0]-1, res[1])
  1350. return res
  1351. except OverflowError:
  1352. if v[1] == 0:
  1353. return rfloat.INFINITY, 0.0
  1354. return rfloat.INFINITY, rfloat.NAN
  1355. @complex_unary_op
  1356. def sin(self, v):
  1357. if rfloat.isinf(v[0]):
  1358. if v[1] == 0.:
  1359. return rfloat.NAN, 0.
  1360. if rfloat.isfinite(v[1]):
  1361. return rfloat.NAN, rfloat.NAN
  1362. elif not rfloat.isnan(v[1]):
  1363. return rfloat.NAN, rfloat.INFINITY
  1364. return rcomplex.c_sin(*v)
  1365. @complex_unary_op
  1366. def cos(self, v):
  1367. if rfloat.isinf(v[0]):
  1368. if v[1] == 0.:
  1369. return rfloat.NAN, 0.0
  1370. if rfloat.isfinite(v[1]):
  1371. return rfloat.NAN, rfloat.NAN
  1372. elif not rfloat.isnan(v[1]):
  1373. return rfloat.INFINITY, rfloat.NAN
  1374. return rcomplex.c_cos(*v)
  1375. @complex_unary_op
  1376. def tan(self, v):
  1377. if rfloat.isinf(v[0]) and rfloat.isfinite(v[1]):
  1378. return rfloat.NAN, rfloat.NAN
  1379. return rcomplex.c_tan(*v)
  1380. @complex_unary_op
  1381. def arcsin(self, v):
  1382. return rcomplex.c_asin(*v)
  1383. @complex_unary_op
  1384. def arccos(self, v):
  1385. return rcomplex.c_acos(*v)
  1386. @complex_unary_op
  1387. def arctan(self, v):
  1388. if v[0] == 0 and (v[1] == 1 or v[1] == -1):
  1389. #This is the place to print a "runtime warning"
  1390. return rfloat.NAN, math.copysign(rfloat.INFINITY, v[1])
  1391. return rcomplex.c_atan(*v)
  1392. #@complex_binary_op
  1393. #def arctan2(self, v1, v2):
  1394. # return rcomplex.c_atan2(v1, v2)
  1395. @complex_unary_op
  1396. def sinh(self, v):
  1397. if rfloat.isinf(v[1]):
  1398. if rfloat.isfinite(v[0]):
  1399. if v[0] == 0.0:
  1400. return 0.0, rfloat.NAN
  1401. return rfloat.NAN, rfloat.NAN
  1402. elif not rfloat.isnan(v[0]):
  1403. return rfloat.INFINITY, rfloat.NAN
  1404. return rcomplex.c_sinh(*v)
  1405. @complex_unary_op
  1406. def cosh(self, v):
  1407. if rfloat.isinf(v[1]):
  1408. if rfloat.isfinite(v[0]):
  1409. if v[0] == 0.0:
  1410. return rfloat.NAN, 0.0
  1411. return rfloat.NAN, rfloat.NAN
  1412. elif not rfloat.isnan(v[0]):
  1413. return rfloat.INFINITY, rfloat.NAN
  1414. return rcomplex.c_cosh(*v)
  1415. @complex_unary_op
  1416. def tanh(self, v):
  1417. if rfloat.isinf(v[1]) and rfloat.isfinite(v[0]):
  1418. return rfloat.NAN, rfloat.NAN
  1419. return rcomplex.c_tanh(*v)
  1420. @complex_unary_op
  1421. def arcsinh(self, v):
  1422. return rcomplex.c_asinh(*v)
  1423. @complex_unary_op
  1424. def arccosh(self, v):
  1425. return rcomplex.c_acosh(*v)
  1426. @complex_unary_op
  1427. def arctanh(self, v):
  1428. if v[1] == 0 and (v[0] == 1.0 or v[0] == -1.0):
  1429. return (math.copysign(rfloat.INFINITY, v[0]),
  1430. math.copysign(0., v[1]))
  1431. return rcomplex.c_atanh(*v)
  1432. @complex_unary_op
  1433. def sqrt(self, v):
  1434. return rcomplex.c_sqrt(*v)
  1435. @complex_unary_op
  1436. def square(self, v):
  1437. return rcomplex.c_mul(v,v)
  1438. @raw_unary_op
  1439. def isfinite(self, v):
  1440. return rfloat.isfinite(v[0]) and rfloat.isfinite(v[1])
  1441. #@simple_unary_op
  1442. #def radians(self, v):
  1443. # return v * degToRad
  1444. #deg2rad = radians
  1445. #@simple_unary_op
  1446. #def degrees(self, v):
  1447. # return v / degToRad
  1448. @complex_unary_op
  1449. def log(self, v):
  1450. try:
  1451. return rcomplex.c_log(*v)
  1452. except ValueError:
  1453. return -rfloat.INFINITY, math.atan2(v[1], v[0])
  1454. @complex_unary_op
  1455. def log2(self, v):
  1456. try:
  1457. r = rcomplex.c_log(*v)
  1458. except ValueError:
  1459. r = -rfloat.INFINITY, math.atan2(v[1], v[0])
  1460. return r[0] / log2, r[1] / log2
  1461. @complex_unary_op
  1462. def log10(self, v):
  1463. try:
  1464. return rcomplex.c_log10(*v)
  1465. except ValueError:
  1466. return -rfloat.INFINITY, math.atan2(v[1], v[0]) / log10
  1467. @complex_unary_op
  1468. def log1p(self, v):
  1469. try:
  1470. return rcomplex.c_log(v[0] + 1, v[1])
  1471. except OverflowError:
  1472. return -rfloat.INFINITY, 0
  1473. except ValueError:
  1474. return rfloat.NAN, rfloat.NAN
  1475. class Complex64(ComplexFloating, BaseType):
  1476. T = rffi.FLOAT
  1477. num = NPY.CFLOAT
  1478. kind = NPY.COMPLEXLTR
  1479. char = NPY.CFLOATLTR
  1480. BoxType = boxes.W_Complex64Box
  1481. ComponentBoxType = boxes.W_Float32Box
  1482. ComponentType = Float32
  1483. class Complex128(ComplexFloating, BaseType):
  1484. T = rffi.DOUBLE
  1485. num = NPY.CDOUBLE
  1486. kind = NPY.COMPLEXLTR
  1487. char = NPY.CDOUBLELTR
  1488. BoxType = boxes.W_Complex128Box
  1489. ComponentBoxType = boxes.W_Float64Box
  1490. ComponentType = Float64
  1491. if boxes.long_double_size == 8:
  1492. class FloatLong(Float, BaseType):
  1493. T = rffi.DOUBLE
  1494. num = NPY.LONGDOUBLE
  1495. kind = NPY.FLOATINGLTR
  1496. char = NPY.LONGDOUBLELTR
  1497. BoxType = boxes.W_FloatLongBox
  1498. format_code = "d"
  1499. class ComplexLong(ComplexFloating, BaseType):
  1500. T = rffi.DOUBLE
  1501. num = NPY.CLONGDOUBLE
  1502. kind = NPY.COMPLEXLTR
  1503. char = NPY.CLONGDOUBLELTR
  1504. BoxType = boxes.W_ComplexLongBox
  1505. ComponentBoxType = boxes.W_FloatLongBox
  1506. ComponentType = FloatLong
  1507. elif boxes.long_double_size in (12, 16):
  1508. class FloatLong(Float, BaseType):
  1509. T = rffi.LONGDOUBLE
  1510. num = NPY.LONGDOUBLE
  1511. kind = NPY.FLOATINGLTR
  1512. char = NPY.LONGDOUBLELTR
  1513. BoxType = boxes.W_FloatLongBox
  1514. def runpack_str(self, space, s, native):
  1515. assert len(s) == boxes.long_double_size
  1516. fval = self.box(unpack_float80(s, native_is_bigendian))
  1517. if not native:
  1518. fval = self.byteswap(fval)
  1519. return fval
  1520. def byteswap