PageRenderTime 245ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/module/micronumpy/types.py

https://bitbucket.org/pypy/pypy/
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
  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(self, w_v):
  1521. value = self.unbox(w_v)
  1522. result = StringBuilder(10)
  1523. pack_float80(result, value, 10, not native_is_bigendian)
  1524. return self.box(unpack_float80(result.build(), native_is_bigendian))
  1525. class ComplexLong(ComplexFloating, BaseType):
  1526. T = rffi.LONGDOUBLE
  1527. num = NPY.CLONGDOUBLE
  1528. kind = NPY.COMPLEXLTR
  1529. char = NPY.CLONGDOUBLELTR
  1530. BoxType = boxes.W_ComplexLongBox
  1531. ComponentBoxType = boxes.W_FloatLongBox
  1532. ComponentType = FloatLong
  1533. _all_objs_for_tests = [] # for tests
  1534. class ObjectType(Primitive, BaseType):
  1535. T = lltype.Signed
  1536. num = NPY.OBJECT
  1537. kind = NPY.OBJECTLTR
  1538. char = NPY.OBJECTLTR
  1539. BoxType = boxes.W_ObjectBox
  1540. def get_element_size(self):
  1541. return rffi.sizeof(lltype.Signed)
  1542. def coerce(self, space, dtype, w_item):
  1543. if isinstance(w_item, boxes.W_ObjectBox):
  1544. return w_item
  1545. return boxes.W_ObjectBox(w_item)
  1546. def coerce_subtype(self, space, w_subtype, w_item):
  1547. # return the item itself
  1548. return self.unbox(self.box(w_item))
  1549. def store(self, arr, i, offset, box, native):
  1550. if arr.gcstruct is V_OBJECTSTORE:
  1551. raise oefmt(self.space.w_NotImplementedError,
  1552. "cannot store object in array with no gc hook")
  1553. self._write(arr.storage, i, offset, self.unbox(box),
  1554. arr.gcstruct)
  1555. def read(self, arr, i, offset, dtype):
  1556. if arr.gcstruct is V_OBJECTSTORE:
  1557. raise oefmt(self.space.w_NotImplementedError,
  1558. "cannot read object from array with no gc hook")
  1559. return self.box(self._read(arr.storage, i, offset))
  1560. def byteswap(self, w_v):
  1561. return w_v
  1562. @jit.dont_look_inside
  1563. def _write(self, storage, i, offset, w_obj, gcstruct):
  1564. # no GC anywhere in this function!
  1565. if we_are_translated():
  1566. from rpython.rlib import rgc
  1567. rgc.ll_writebarrier(gcstruct)
  1568. value = rffi.cast(lltype.Signed, cast_instance_to_gcref(w_obj))
  1569. else:
  1570. value = len(_all_objs_for_tests)
  1571. _all_objs_for_tests.append(w_obj)
  1572. raw_storage_setitem_unaligned(storage, i + offset, value)
  1573. @jit.dont_look_inside
  1574. def _read(self, storage, i, offset, native=True):
  1575. res = raw_storage_getitem_unaligned(self.T, storage, i + offset)
  1576. if we_are_translated():
  1577. gcref = rffi.cast(llmemory.GCREF, res)
  1578. w_obj = cast_gcref_to_instance(W_Root, gcref)
  1579. else:
  1580. w_obj = _all_objs_for_tests[res]
  1581. return w_obj
  1582. def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
  1583. value = self.unbox(box)
  1584. for i in xrange(start, stop, width):
  1585. self._write(storage, i, offset, value, gcstruct)
  1586. def unbox(self, box):
  1587. if isinstance(box, self.BoxType):
  1588. return box.w_obj
  1589. else:
  1590. raise oefmt(self.space.w_NotImplementedError,
  1591. "object dtype cannot unbox %s", str(box))
  1592. @specialize.argtype(1)
  1593. def box(self, w_obj):
  1594. if isinstance(w_obj, W_Root):
  1595. pass
  1596. elif isinstance(w_obj, bool):
  1597. w_obj = self.space.newbool(w_obj)
  1598. elif isinstance(w_obj, int):
  1599. w_obj = self.space.newint(w_obj)
  1600. elif isinstance(w_obj, lltype.Number):
  1601. w_obj = self.space.newint(w_obj)
  1602. elif isinstance(w_obj, float):
  1603. w_obj = self.space.newfloat(w_obj)
  1604. elif w_obj is None:
  1605. w_obj = self.space.w_None
  1606. else:
  1607. raise oefmt(self.space.w_NotImplementedError,
  1608. "cannot create object array/scalar from lltype")
  1609. return self.BoxType(w_obj)
  1610. @specialize.argtype(1, 2)
  1611. def box_complex(self, real, imag):
  1612. if isinstance(real, rffi.r_singlefloat):
  1613. real = rffi.cast(rffi.DOUBLE, real)
  1614. if isinstance(imag, rffi.r_singlefloat):
  1615. imag = rffi.cast(rffi.DOUBLE, imag)
  1616. w_obj = self.space.newcomplex(real, imag)
  1617. return self.BoxType(w_obj)
  1618. def str_format(self, box, add_quotes=True):
  1619. if not add_quotes:
  1620. as_str = self.space.str_w(self.space.repr(self.unbox(box)))
  1621. as_strl = len(as_str) - 1
  1622. if as_strl>1 and as_str[0] == "'" and as_str[as_strl] == "'":
  1623. as_str = as_str[1:as_strl]
  1624. return as_str
  1625. return self.space.str_w(self.space.repr(self.unbox(box)))
  1626. def runpack_str(self, space, s, native):
  1627. raise oefmt(space.w_NotImplementedError,
  1628. "fromstring not implemented for object type")
  1629. def to_builtin_type(self, space, box):
  1630. assert isinstance(box, self.BoxType)
  1631. return box.w_obj
  1632. @staticmethod
  1633. def for_computation(v):
  1634. return v
  1635. @raw_binary_op
  1636. def eq(self, v1, v2):
  1637. return self.space.eq_w(v1, v2)
  1638. @simple_binary_op
  1639. def max(self, v1, v2):
  1640. if self.space.is_true(self.space.ge(v1, v2)):
  1641. return v1
  1642. return v2
  1643. @simple_binary_op
  1644. def min(self, v1, v2):
  1645. if self.space.is_true(self.space.le(v1, v2)):
  1646. return v1
  1647. return v2
  1648. @raw_binary_op
  1649. def argmax(self, v1, v2):
  1650. if self.space.is_true(self.space.ge(v1, v2)):
  1651. return True
  1652. return False
  1653. @raw_binary_op
  1654. def argmin(self, v1, v2):
  1655. if self.space.is_true(self.space.le(v1, v2)):
  1656. return True
  1657. return False
  1658. @raw_unary_op
  1659. def bool(self,v):
  1660. return self._obool(v)
  1661. def _obool(self, v):
  1662. if self.space.is_true(v):
  1663. return True
  1664. return False
  1665. @raw_binary_op
  1666. def logical_and(self, v1, v2):
  1667. if self._obool(v1):
  1668. return self.box(v2)
  1669. return self.box(v1)
  1670. @raw_binary_op
  1671. def logical_or(self, v1, v2):
  1672. if self._obool(v1):
  1673. return self.box(v1)
  1674. return self.box(v2)
  1675. @raw_unary_op
  1676. def logical_not(self, v):
  1677. return not self._obool(v)
  1678. @raw_binary_op
  1679. def logical_xor(self, v1, v2):
  1680. a = self._obool(v1)
  1681. b = self._obool(v2)
  1682. return (not b and a) or (not a and b)
  1683. @simple_binary_op
  1684. def bitwise_and(self, v1, v2):
  1685. return self.space.and_(v1, v2)
  1686. @simple_binary_op
  1687. def bitwise_or(self, v1, v2):
  1688. return self.space.or_(v1, v2)
  1689. @simple_binary_op
  1690. def bitwise_xor(self, v1, v2):
  1691. return self.space.xor(v1, v2)
  1692. @simple_binary_op
  1693. def pow(self, v1, v2):
  1694. return self.space.pow(v1, v2, self.space.wrap(1))
  1695. @simple_unary_op
  1696. def reciprocal(self, v1):
  1697. return self.space.div(self.space.wrap(1.0), v1)
  1698. @simple_unary_op
  1699. def sign(self, v):
  1700. zero = self.space.wrap(0)
  1701. one = self.space.wrap(1)
  1702. m_one = self.space.wrap(-1)
  1703. if self.space.is_true(self.space.gt(v, zero)):
  1704. return one
  1705. elif self.space.is_true(self.space.lt(v, zero)):
  1706. return m_one
  1707. else:
  1708. return zero
  1709. @simple_unary_op
  1710. def real(self, v):
  1711. return v
  1712. @simple_unary_op
  1713. def imag(self, v):
  1714. return 0
  1715. @simple_unary_op
  1716. def square(self, v):
  1717. return self.space.mul(v, v)
  1718. @raw_binary_op
  1719. def le(self, v1, v2):
  1720. return self.space.bool_w(self.space.le(v1, v2))
  1721. @raw_binary_op
  1722. def ge(self, v1, v2):
  1723. return self.space.bool_w(self.space.ge(v1, v2))
  1724. @raw_binary_op
  1725. def lt(self, v1, v2):
  1726. return self.space.bool_w(self.space.lt(v1, v2))
  1727. @raw_binary_op
  1728. def gt(self, v1, v2):
  1729. return self.space.bool_w(self.space.gt(v1, v2))
  1730. @raw_binary_op
  1731. def ne(self, v1, v2):
  1732. return self.space.bool_w(self.space.ne(v1, v2))
  1733. def add_attributeerr_op(cls, op):
  1734. def func(self, *args):
  1735. raise oefmt(self.space.w_AttributeError,
  1736. "%s", op)
  1737. func.__name__ = 'object_' + op
  1738. setattr(cls, op, func)
  1739. def add_unsupported_op(cls, op):
  1740. def func(self, *args):
  1741. raise oefmt(self.space.w_TypeError,
  1742. "ufunc '%s' not supported for input types", op)
  1743. func.__name__ = 'object_' + op
  1744. setattr(cls, op, func)
  1745. def add_unary_op(cls, op, method):
  1746. @simple_unary_op
  1747. def func(self, w_v):
  1748. space = self.space
  1749. w_impl = space.lookup(w_v, method)
  1750. if w_impl is None:
  1751. raise oefmt(space.w_AttributeError, 'unknown op "%s" on object' % op)
  1752. return space.get_and_call_function(w_impl, w_v)
  1753. func.__name__ = 'object_' + op
  1754. setattr(cls, op, func)
  1755. def add_space_unary_op(cls, op):
  1756. @simple_unary_op
  1757. def func(self, v):
  1758. return getattr(self.space, op)(v)
  1759. func.__name__ = 'object_' + op
  1760. setattr(cls, op, func)
  1761. def add_space_binary_op(cls, op):
  1762. @simple_binary_op
  1763. def func(self, v1, v2):
  1764. return getattr(self.space, op)(v1, v2)
  1765. func.__name__ = 'object_' + op
  1766. setattr(cls, op, func)
  1767. for op in ('copysign', 'isfinite', 'isinf', 'isnan', 'logaddexp', 'logaddexp2',
  1768. 'signbit'):
  1769. add_unsupported_op(ObjectType, op)
  1770. for op in ('arctan2', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan',
  1771. 'arctanh', 'ceil', 'floor', 'cos', 'sin', 'tan', 'cosh', 'sinh',
  1772. 'tanh', 'radians', 'degrees', 'exp','exp2', 'expm1', 'fabs',
  1773. 'log', 'log10', 'log1p', 'log2', 'sqrt', 'trunc'):
  1774. add_attributeerr_op(ObjectType, op)
  1775. for op in ('abs', 'neg', 'pos', 'invert'):
  1776. add_space_unary_op(ObjectType, op)
  1777. for op, method in (('conj', 'descr_conjugate'), ('rint', 'descr_rint')):
  1778. add_unary_op(ObjectType, op, method)
  1779. for op in ('add', 'floordiv', 'div', 'mod', 'mul', 'sub', 'lshift', 'rshift'):
  1780. add_space_binary_op(ObjectType, op)
  1781. ObjectType.fmax = ObjectType.max
  1782. ObjectType.fmin = ObjectType.min
  1783. ObjectType.fmod = ObjectType.mod
  1784. class FlexibleType(BaseType):
  1785. def get_element_size(self):
  1786. return rffi.sizeof(self.T)
  1787. def to_str(self, item):
  1788. return item.raw_str()
  1789. def str_unary_op(func):
  1790. specialize.argtype(1)(func)
  1791. @functools.wraps(func)
  1792. def dispatcher(self, v1):
  1793. return func(self, self.to_str(v1))
  1794. return dispatcher
  1795. def str_binary_op(func):
  1796. specialize.argtype(1, 2)(func)
  1797. @functools.wraps(func)
  1798. def dispatcher(self, v1, v2):
  1799. return func(self,
  1800. self.to_str(v1),
  1801. self.to_str(v2)
  1802. )
  1803. return dispatcher
  1804. class StringType(FlexibleType):
  1805. T = lltype.Char
  1806. num = NPY.STRING
  1807. kind = NPY.STRINGLTR
  1808. char = NPY.STRINGLTR
  1809. @jit.unroll_safe
  1810. def coerce(self, space, dtype, w_item):
  1811. if isinstance(w_item, boxes.W_StringBox):
  1812. return w_item
  1813. if w_item is None:
  1814. w_item = space.wrap('')
  1815. arg = space.str_w(space.str(w_item))
  1816. arr = VoidBoxStorage(dtype.elsize, dtype)
  1817. with arr as storage:
  1818. j = min(len(arg), dtype.elsize)
  1819. for i in range(j):
  1820. storage[i] = arg[i]
  1821. for j in range(j, dtype.elsize):
  1822. storage[j] = '\x00'
  1823. return boxes.W_StringBox(arr, 0, arr.dtype)
  1824. def store(self, arr, i, offset, box, native):
  1825. assert isinstance(box, boxes.W_StringBox)
  1826. size = min(arr.dtype.elsize - offset, box.arr.size - box.ofs)
  1827. with arr as storage:
  1828. return self._store(storage, i, offset, box, size)
  1829. @jit.unroll_safe
  1830. def _store(self, storage, i, offset, box, size):
  1831. assert isinstance(box, boxes.W_StringBox)
  1832. with box.arr as box_storage:
  1833. for k in range(size):
  1834. storage[k + offset + i] = box_storage[k + box.ofs]
  1835. def read(self, arr, i, offset, dtype):
  1836. return boxes.W_StringBox(arr, i + offset, dtype)
  1837. def str_format(self, item, add_quotes=True):
  1838. builder = StringBuilder()
  1839. if add_quotes:
  1840. builder.append("'")
  1841. builder.append(self.to_str(item))
  1842. if add_quotes:
  1843. builder.append("'")
  1844. return builder.build()
  1845. # XXX move the rest of this to base class when UnicodeType is supported
  1846. def to_builtin_type(self, space, box):
  1847. return space.wrap(self.to_str(box))
  1848. @str_binary_op
  1849. def eq(self, v1, v2):
  1850. return v1 == v2
  1851. @str_binary_op
  1852. def ne(self, v1, v2):
  1853. return v1 != v2
  1854. @str_binary_op
  1855. def lt(self, v1, v2):
  1856. return v1 < v2
  1857. @str_binary_op
  1858. def le(self, v1, v2):
  1859. return v1 <= v2
  1860. @str_binary_op
  1861. def gt(self, v1, v2):
  1862. return v1 > v2
  1863. @str_binary_op
  1864. def ge(self, v1, v2):
  1865. return v1 >= v2
  1866. @str_binary_op
  1867. def logical_and(self, v1, v2):
  1868. if bool(v1) and bool(v2):
  1869. return Bool._True
  1870. return Bool._False
  1871. @str_binary_op
  1872. def logical_or(self, v1, v2):
  1873. if bool(v1) or bool(v2):
  1874. return Bool._True
  1875. return Bool._False
  1876. @str_unary_op
  1877. def logical_not(self, v):
  1878. return not bool(v)
  1879. @str_binary_op
  1880. def logical_xor(self, v1, v2):
  1881. a = bool(v1)
  1882. b = bool(v2)
  1883. return (not b and a) or (not a and b)
  1884. def bool(self, v):
  1885. return bool(self.to_str(v))
  1886. def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
  1887. for i in xrange(start, stop, width):
  1888. self._store(storage, i, offset, box, width)
  1889. class UnicodeType(FlexibleType):
  1890. T = lltype.UniChar
  1891. num = NPY.UNICODE
  1892. kind = NPY.UNICODELTR
  1893. char = NPY.UNICODELTR
  1894. def get_element_size(self):
  1895. return 4 # always UTF-32
  1896. @jit.unroll_safe
  1897. def coerce(self, space, dtype, w_item):
  1898. if isinstance(w_item, boxes.W_UnicodeBox):
  1899. return w_item
  1900. if isinstance(w_item, boxes.W_ObjectBox):
  1901. value = space.unicode_w(space.unicode_from_object(w_item.w_obj))
  1902. else:
  1903. value = space.unicode_w(space.unicode_from_object(w_item))
  1904. return boxes.W_UnicodeBox(value)
  1905. def store(self, arr, i, offset, box, native):
  1906. assert isinstance(box, boxes.W_UnicodeBox)
  1907. value = box._value
  1908. with arr as storage:
  1909. self._store(storage, i, offset, box, arr.dtype.elsize)
  1910. @jit.unroll_safe
  1911. def _store(self, storage, i, offset, box, width):
  1912. size = min(width // 4, len(box._value))
  1913. for k in range(size):
  1914. index = i + offset + 4*k
  1915. data = rffi.cast(Int32.T, ord(box._value[k]))
  1916. raw_storage_setitem_unaligned(storage, index, data)
  1917. # zero out the remaining memory
  1918. for index in range(size * 4 + i + offset, width):
  1919. data = rffi.cast(Int8.T, 0)
  1920. raw_storage_setitem_unaligned(storage, index, data)
  1921. def read(self, arr, i, offset, dtype):
  1922. if dtype is None:
  1923. dtype = arr.dtype
  1924. size = dtype.elsize // 4
  1925. builder = UnicodeBuilder(size)
  1926. with arr as storage:
  1927. for k in range(size):
  1928. index = i + offset + 4*k
  1929. codepoint = raw_storage_getitem_unaligned(
  1930. Int32.T, arr.storage, index)
  1931. char = unichr(codepoint)
  1932. if char == u'\0':
  1933. break
  1934. builder.append(char)
  1935. return boxes.W_UnicodeBox(builder.build())
  1936. def str_format(self, item, add_quotes=True):
  1937. assert isinstance(item, boxes.W_UnicodeBox)
  1938. if add_quotes:
  1939. w_unicode = self.to_builtin_type(self.space, item)
  1940. return self.space.str_w(self.space.repr(w_unicode))
  1941. else:
  1942. # Same as W_UnicodeBox.descr_repr() but without quotes and prefix
  1943. from rpython.rlib.runicode import unicode_encode_unicode_escape
  1944. return unicode_encode_unicode_escape(item._value,
  1945. len(item._value), 'strict')
  1946. def to_builtin_type(self, space, box):
  1947. assert isinstance(box, boxes.W_UnicodeBox)
  1948. return space.wrap(box._value)
  1949. def eq(self, v1, v2):
  1950. assert isinstance(v1, boxes.W_UnicodeBox)
  1951. assert isinstance(v2, boxes.W_UnicodeBox)
  1952. return v1._value == v2._value
  1953. def ne(self, v1, v2):
  1954. assert isinstance(v1, boxes.W_UnicodeBox)
  1955. assert isinstance(v2, boxes.W_UnicodeBox)
  1956. return v1._value != v2._value
  1957. def lt(self, v1, v2):
  1958. assert isinstance(v1, boxes.W_UnicodeBox)
  1959. assert isinstance(v2, boxes.W_UnicodeBox)
  1960. return v1._value < v2._value
  1961. def le(self, v1, v2):
  1962. assert isinstance(v1, boxes.W_UnicodeBox)
  1963. assert isinstance(v2, boxes.W_UnicodeBox)
  1964. return v1._value <= v2._value
  1965. def gt(self, v1, v2):
  1966. assert isinstance(v1, boxes.W_UnicodeBox)
  1967. assert isinstance(v2, boxes.W_UnicodeBox)
  1968. return v1._value > v2._value
  1969. def ge(self, v1, v2):
  1970. assert isinstance(v1, boxes.W_UnicodeBox)
  1971. assert isinstance(v2, boxes.W_UnicodeBox)
  1972. return v1._value >= v2._value
  1973. def logical_and(self, v1, v2):
  1974. assert isinstance(v1, boxes.W_UnicodeBox)
  1975. assert isinstance(v2, boxes.W_UnicodeBox)
  1976. if bool(v1) and bool(v2):
  1977. return Bool._True
  1978. return Bool._False
  1979. def logical_or(self, v1, v2):
  1980. assert isinstance(v1, boxes.W_UnicodeBox)
  1981. assert isinstance(v2, boxes.W_UnicodeBox)
  1982. if bool(v1) or bool(v2):
  1983. return Bool._True
  1984. return Bool._False
  1985. def logical_not(self, v):
  1986. assert isinstance(v, boxes.W_UnicodeBox)
  1987. return not bool(v)
  1988. def logical_xor(self, v1, v2):
  1989. assert isinstance(v1, boxes.W_UnicodeBox)
  1990. assert isinstance(v2, boxes.W_UnicodeBox)
  1991. a = bool(v1)
  1992. b = bool(v2)
  1993. return (not b and a) or (not a and b)
  1994. def bool(self, v):
  1995. assert isinstance(v, boxes.W_UnicodeBox)
  1996. return bool(v._value)
  1997. def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
  1998. assert isinstance(box, boxes.W_UnicodeBox)
  1999. for i in xrange(start, stop, width):
  2000. self._store(storage, i, offset, box, width)
  2001. class VoidType(FlexibleType):
  2002. T = lltype.Char
  2003. num = NPY.VOID
  2004. kind = NPY.VOIDLTR
  2005. char = NPY.VOIDLTR
  2006. def _coerce(self, space, arr, ofs, dtype, w_items, shape):
  2007. # TODO: Make sure the shape and the array match
  2008. from pypy.module.micronumpy.descriptor import W_Dtype
  2009. if w_items is None:
  2010. items_w = [None] * shape[0]
  2011. elif support.issequence_w(space, w_items):
  2012. items_w = space.fixedview(w_items)
  2013. else:
  2014. items_w = [w_items] * shape[0]
  2015. subdtype = dtype.subdtype
  2016. assert isinstance(subdtype, W_Dtype)
  2017. itemtype = subdtype.itemtype
  2018. if len(shape) <= 1:
  2019. for i in range(len(items_w)):
  2020. w_box = subdtype.coerce(space, items_w[i])
  2021. subdtype.store(arr, 0, ofs, w_box)
  2022. ofs += itemtype.get_element_size()
  2023. else:
  2024. for w_item in items_w:
  2025. size = 1
  2026. for dimension in shape[1:]:
  2027. size *= dimension
  2028. size *= itemtype.get_element_size()
  2029. self._coerce(space, arr, ofs, dtype, w_item, shape[1:])
  2030. ofs += size
  2031. def coerce(self, space, dtype, w_items):
  2032. if dtype.is_record():
  2033. # the dtype is a union of a void and a record,
  2034. return record_coerce(self, space, dtype, w_items)
  2035. arr = VoidBoxStorage(dtype.elsize, dtype)
  2036. self._coerce(space, arr, 0, dtype, w_items, dtype.shape)
  2037. return boxes.W_VoidBox(arr, 0, dtype)
  2038. @jit.unroll_safe
  2039. def store(self, arr, i, offset, box, native):
  2040. assert isinstance(box, boxes.W_VoidBox)
  2041. assert box.dtype is box.arr.dtype
  2042. with arr as arr_storage, box.arr as box_storage:
  2043. for k in range(box.arr.dtype.elsize):
  2044. arr_storage[i + k + offset] = box_storage[k + box.ofs]
  2045. def readarray(self, arr, i, offset, dtype=None):
  2046. from pypy.module.micronumpy.base import W_NDimArray
  2047. if dtype is None:
  2048. dtype = arr.dtype
  2049. strides, backstrides = calc_strides(dtype.shape, dtype.subdtype,
  2050. arr.order)
  2051. implementation = SliceArray(i + offset, strides, backstrides,
  2052. dtype.shape, arr, W_NDimArray(arr),
  2053. dtype.subdtype)
  2054. return W_NDimArray(implementation)
  2055. def read(self, arr, i, offset, dtype):
  2056. return boxes.W_VoidBox(arr, i + offset, dtype)
  2057. @jit.unroll_safe
  2058. def str_format(self, box, add_quotes=True):
  2059. assert isinstance(box, boxes.W_VoidBox)
  2060. arr = self.readarray(box.arr, box.ofs, 0, box.dtype)
  2061. return arr.dump_data(prefix='', suffix='')
  2062. def to_builtin_type(self, space, item):
  2063. ''' From the documentation of ndarray.item():
  2064. "Void arrays return a buffer object for item(),
  2065. unless fields are defined, in which case a tuple is returned."
  2066. '''
  2067. assert isinstance(item, boxes.W_VoidBox)
  2068. dt = item.arr.dtype
  2069. ret_unwrapped = []
  2070. for name in dt.names:
  2071. ofs, dtype = dt.fields[name[0]]
  2072. # XXX: code duplication with W_VoidBox.descr_getitem()
  2073. if isinstance(dtype.itemtype, VoidType):
  2074. read_val = dtype.itemtype.readarray(item.arr, ofs, 0, dtype)
  2075. else:
  2076. read_val = dtype.read(item.arr, ofs, 0)
  2077. if isinstance (read_val, boxes.W_StringBox):
  2078. # StringType returns a str
  2079. read_val = space.wrap(dtype.itemtype.to_str(read_val))
  2080. ret_unwrapped = ret_unwrapped + [read_val,]
  2081. if len(ret_unwrapped) == 0:
  2082. raise oefmt(space.w_NotImplementedError,
  2083. "item() for Void aray with no fields not implemented")
  2084. return space.newtuple(ret_unwrapped)
  2085. class CharType(StringType):
  2086. char = NPY.CHARLTR
  2087. def record_coerce(typ, space, dtype, w_item):
  2088. from pypy.module.micronumpy.base import W_NDimArray
  2089. if isinstance(w_item, boxes.W_VoidBox):
  2090. if dtype == w_item.dtype:
  2091. return w_item
  2092. else:
  2093. # match up the field names
  2094. items_w = [None] * len(dtype.names)
  2095. for i in range(len(dtype.names)):
  2096. name = dtype.names[i]
  2097. if name in w_item.dtype.names:
  2098. items_w[i] = w_item.descr_getitem(space, space.wrap(name[0]))
  2099. elif w_item is not None:
  2100. if space.isinstance_w(w_item, space.w_tuple):
  2101. if len(dtype.names) != space.len_w(w_item):
  2102. raise oefmt(space.w_ValueError,
  2103. "size of tuple must match number of fields.")
  2104. items_w = space.fixedview(w_item)
  2105. elif isinstance(w_item, W_NDimArray) and w_item.is_scalar():
  2106. items_w = space.fixedview(w_item.get_scalar_value())
  2107. elif space.isinstance_w(w_item, space.w_list):
  2108. raise oefmt(space.w_TypeError,
  2109. "expected a readable buffer object")
  2110. else:
  2111. # XXX support initializing from readable buffers
  2112. items_w = [w_item] * len(dtype.names)
  2113. else:
  2114. items_w = [None] * len(dtype.fields)
  2115. arr = VoidBoxStorage(dtype.elsize, dtype)
  2116. for i in range(len(dtype.names)):
  2117. ofs, subdtype = dtype.fields[dtype.names[i][0]]
  2118. try:
  2119. w_box = subdtype.coerce(space, items_w[i])
  2120. except IndexError:
  2121. w_box = subdtype.coerce(space, None)
  2122. subdtype.store(arr, 0, ofs, w_box)
  2123. return boxes.W_VoidBox(arr, 0, dtype)
  2124. class RecordType(FlexibleType):
  2125. T = lltype.Char
  2126. num = NPY.VOID
  2127. kind = NPY.VOIDLTR
  2128. char = NPY.VOIDLTR
  2129. def read(self, arr, i, offset, dtype):
  2130. return boxes.W_VoidBox(arr, i + offset, dtype)
  2131. @jit.unroll_safe
  2132. def coerce(self, space, dtype, w_item):
  2133. return record_coerce(self, space, dtype, w_item)
  2134. def runpack_str(self, space, s, native):
  2135. raise oefmt(space.w_NotImplementedError,
  2136. "fromstring not implemented for record types")
  2137. def store(self, arr, i, offset, box, native):
  2138. assert isinstance(box, boxes.W_VoidBox)
  2139. with arr as storage:
  2140. self._store(storage, i, offset, box, box.dtype.elsize)
  2141. @jit.unroll_safe
  2142. def _store(self, storage, i, ofs, box, size):
  2143. with box.arr as box_storage:
  2144. for k in range(size):
  2145. storage[k + i + ofs] = box_storage[k + box.ofs]
  2146. def fill(self, storage, width, native, box, start, stop, offset, gcstruct):
  2147. assert isinstance(box, boxes.W_VoidBox)
  2148. assert width == box.dtype.elsize
  2149. for i in xrange(start, stop, width):
  2150. self._store(storage, i, offset, box, width)
  2151. def byteswap(self, w_v):
  2152. # XXX implement
  2153. return w_v
  2154. def to_builtin_type(self, space, box):
  2155. assert isinstance(box, boxes.W_VoidBox)
  2156. items = []
  2157. dtype = box.dtype
  2158. for name in dtype.names:
  2159. ofs, subdtype = dtype.fields[name[0]]
  2160. subbox = subdtype.read(box.arr, box.ofs, ofs)
  2161. items.append(subdtype.itemtype.to_builtin_type(space, subbox))
  2162. return space.newtuple(items)
  2163. @jit.unroll_safe
  2164. def str_format(self, box, add_quotes=True):
  2165. assert isinstance(box, boxes.W_VoidBox)
  2166. pieces = ["("]
  2167. first = True
  2168. for name in box.dtype.names:
  2169. ofs, subdtype = box.dtype.fields[name[0]]
  2170. if first:
  2171. first = False
  2172. else:
  2173. pieces.append(", ")
  2174. val = subdtype.read(box.arr, box.ofs, ofs)
  2175. tp = subdtype.itemtype
  2176. pieces.append(tp.str_format(val, add_quotes=add_quotes))
  2177. pieces.append(")")
  2178. return "".join(pieces)
  2179. def eq(self, v1, v2):
  2180. assert isinstance(v1, boxes.W_VoidBox)
  2181. assert isinstance(v2, boxes.W_VoidBox)
  2182. s1 = v1.dtype.elsize
  2183. s2 = v2.dtype.elsize
  2184. assert s1 == s2
  2185. with v1.arr as v1_storage, v2.arr as v2_storage:
  2186. for i in range(s1):
  2187. if v1_storage[v1.ofs + i] != v2_storage[v2.ofs + i]:
  2188. return False
  2189. return True
  2190. def ne(self, v1, v2):
  2191. return not self.eq(v1, v2)
  2192. for tp in [Int32, Int64]:
  2193. if tp.T == lltype.Signed:
  2194. IntP = tp
  2195. break
  2196. for tp in [UInt32, UInt64]:
  2197. if tp.T == lltype.Unsigned:
  2198. UIntP = tp
  2199. break
  2200. del tp
  2201. all_float_types = []
  2202. float_types = []
  2203. all_int_types = []
  2204. int_types = []
  2205. all_complex_types = []
  2206. complex_types = []
  2207. _REQ_STRLEN = [0, 3, 5, 10, 10, 20, 20, 20, 20] # data for can_cast_to()
  2208. def _setup():
  2209. # compute alignment
  2210. for tp in globals().values():
  2211. if isinstance(tp, type) and hasattr(tp, 'T'):
  2212. tp.alignment = widen(clibffi.cast_type_to_ffitype(tp.T).c_alignment)
  2213. if issubclass(tp, Float):
  2214. all_float_types.append((tp, 'float'))
  2215. float_types.append(tp)
  2216. if issubclass(tp, Integer):
  2217. all_int_types.append((tp, 'int'))
  2218. int_types.append(tp)
  2219. elsize = tp(ObjSpace()).get_element_size()
  2220. tp.strlen = _REQ_STRLEN[elsize]
  2221. if tp.kind == NPY.SIGNEDLTR:
  2222. tp.strlen += 1
  2223. if issubclass(tp, ComplexFloating):
  2224. all_complex_types.append((tp, 'complex'))
  2225. complex_types.append(tp)
  2226. for l in [float_types, int_types, complex_types]:
  2227. l.sort(key=lambda tp: tp.num)
  2228. _setup()
  2229. del _setup
  2230. number_types = int_types + float_types + complex_types
  2231. all_types = [Bool] + number_types + [ObjectType, StringType, UnicodeType, VoidType]
  2232. _int_types = [(Int8, UInt8), (Int16, UInt16), (Int32, UInt32),
  2233. (Int64, UInt64), (Long, ULong)]
  2234. for Int_t, UInt_t in _int_types:
  2235. Int_t.Unsigned = UInt_t
  2236. UInt_t.Signed = Int_t
  2237. size = rffi.sizeof(Int_t.T)
  2238. Int_t.min_value = rffi.cast(Int_t.T, -1) << (8*size - 1)
  2239. Int_t.max_value = ~Int_t.min_value
  2240. UInt_t.max_value = ~rffi.cast(UInt_t.T, 0)
  2241. signed_types = [Int8, Int16, Int32, Int64, Long]
  2242. def make_integer_min_dtype(Int_t, UInt_t):
  2243. smaller_types = [tp for tp in signed_types
  2244. if rffi.sizeof(tp.T) < rffi.sizeof(Int_t.T)]
  2245. smaller_types = unrolling_iterable(
  2246. [(tp, tp.Unsigned) for tp in smaller_types])
  2247. def min_dtype(self):
  2248. value = rffi.cast(UInt64.T, self.value)
  2249. for Small, USmall in smaller_types:
  2250. signed_max = rffi.cast(UInt64.T, Small.max_value)
  2251. unsigned_max = rffi.cast(UInt64.T, USmall.max_value)
  2252. if value <= unsigned_max:
  2253. if value <= signed_max:
  2254. return Small.num, USmall.num
  2255. else:
  2256. return USmall.num, USmall.num
  2257. if value <= rffi.cast(UInt64.T, Int_t.max_value):
  2258. return Int_t.num, UInt_t.num
  2259. else:
  2260. return UInt_t.num, UInt_t.num
  2261. UInt_t.BoxType.min_dtype = min_dtype
  2262. def min_dtype(self):
  2263. value = rffi.cast(Int64.T, self.value)
  2264. if value >= 0:
  2265. for Small, USmall in smaller_types:
  2266. signed_max = rffi.cast(Int64.T, Small.max_value)
  2267. unsigned_max = rffi.cast(Int64.T, USmall.max_value)
  2268. if value <= unsigned_max:
  2269. if value <= signed_max:
  2270. return Small.num, USmall.num
  2271. else:
  2272. return USmall.num, USmall.num
  2273. return Int_t.num, UInt_t.num
  2274. else:
  2275. for Small, USmall in smaller_types:
  2276. signed_min = rffi.cast(Int64.T, Small.min_value)
  2277. if value >= signed_min:
  2278. return Small.num, Small.num
  2279. return Int_t.num, Int_t.num
  2280. Int_t.BoxType.min_dtype = min_dtype
  2281. for Int_t in signed_types:
  2282. UInt_t = Int_t.Unsigned
  2283. make_integer_min_dtype(Int_t, UInt_t)
  2284. smaller_float_types = {
  2285. Float16: [], Float32: [Float16], Float64: [Float16, Float32],
  2286. FloatLong: [Float16, Float32, Float64]}
  2287. def make_float_min_dtype(Float_t):
  2288. smaller_types = unrolling_iterable(smaller_float_types[Float_t])
  2289. smallest_type = Float16
  2290. def min_dtype(self):
  2291. value = float(self.value)
  2292. if not rfloat.isfinite(value):
  2293. tp = smallest_type
  2294. else:
  2295. for SmallFloat in smaller_types:
  2296. if -SmallFloat.max_value < value < SmallFloat.max_value:
  2297. tp = SmallFloat
  2298. break
  2299. else:
  2300. tp = Float_t
  2301. return tp.num, tp.num
  2302. Float_t.BoxType.min_dtype = min_dtype
  2303. for Float_t in float_types:
  2304. make_float_min_dtype(Float_t)
  2305. smaller_complex_types = {
  2306. Complex64: [], Complex128: [Complex64],
  2307. ComplexLong: [Complex64, Complex128]}
  2308. def make_complex_min_dtype(Complex_t):
  2309. smaller_types = unrolling_iterable(smaller_complex_types[Complex_t])
  2310. def min_dtype(self):
  2311. real, imag = float(self.real), float(self.imag)
  2312. for CSmall in smaller_types:
  2313. max_value = CSmall.ComponentType.max_value
  2314. if -max_value < real < max_value and -max_value < imag < max_value:
  2315. tp = CSmall
  2316. break
  2317. else:
  2318. tp = Complex_t
  2319. return tp.num, tp.num
  2320. Complex_t.BoxType.min_dtype = min_dtype
  2321. for Complex_t in complex_types:
  2322. make_complex_min_dtype(Complex_t)
  2323. def min_dtype(self):
  2324. return Bool.num, Bool.num
  2325. Bool.BoxType.min_dtype = min_dtype