Author: Matti Picus <[email protected]>
Branch:
Changeset: r62534:f1b95506732f
Date: 2013-03-19 17:52 -0700
http://bitbucket.org/pypy/pypy/changeset/f1b95506732f/
Log: merge scalar_get_set which adds get_, set_, imag, real for scalar
arrays
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py
b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -82,6 +82,10 @@
return SliceArray(self.start, strides, backstrides,
self.get_shape(), self, orig_array)
+ def set_real(self, space, orig_array, w_value):
+ tmp = self.get_real(orig_array)
+ tmp.setslice(space, convert_to_array(space, w_value))
+
def get_imag(self, orig_array):
strides = self.get_strides()
backstrides = self.get_backstrides()
@@ -98,6 +102,10 @@
impl.fill(self.dtype.box(0))
return impl
+ def set_imag(self, space, orig_array, w_value):
+ tmp = self.get_imag(orig_array)
+ tmp.setslice(space, convert_to_array(space, w_value))
+
# -------------------- applevel get/setitem -----------------------
@jit.unroll_safe
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py
b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -1,6 +1,6 @@
from pypy.module.micronumpy.arrayimpl import base
-from pypy.module.micronumpy.base import W_NDimArray
+from pypy.module.micronumpy.base import W_NDimArray, convert_to_array
from pypy.module.micronumpy import support
from pypy.interpreter.error import OperationError
@@ -38,6 +38,9 @@
def get_strides(self):
return []
+ def get_backstrides(self):
+ return []
+
def create_iter(self, shape=None, backward_broadcast=False):
return ScalarIterator(self)
@@ -58,6 +61,62 @@
def transpose(self, _):
return self
+ def get_real(self, orig_array):
+ if self.dtype.is_complex_type():
+ scalar = Scalar(self.dtype.float_type)
+ scalar.value = self.value.convert_real_to(scalar.dtype)
+ return scalar
+ return self
+
+ def set_real(self, space, orig_array, w_val):
+ w_arr = convert_to_array(space, w_val)
+ dtype = self.dtype.float_type or self.dtype
+ if len(w_arr.get_shape()) > 0:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "could not broadcast input array from shape " +
+ "(%s) into shape ()" % (
+ ','.join([str(x) for x in w_arr.get_shape()],))))
+ if self.dtype.is_complex_type():
+ #imag = dtype.itemtype.unbox(self.value.convert_imag_to(dtype))
+ #val = dtype.itemtype.unbox(w_arr.get_scalar_value().
+ # convert_to(dtype))
+ #self.value = self.dtype.box_complex(val, imag)
+ self.value =
self.dtype.itemtype.composite(w_arr.get_scalar_value().convert_to(dtype),
+ self.value.convert_imag_to(dtype))
+ else:
+ self.value = w_arr.get_scalar_value()
+
+ def get_imag(self, orig_array):
+ if self.dtype.is_complex_type():
+ scalar = Scalar(self.dtype.float_type)
+ scalar.value = self.value.convert_imag_to(scalar.dtype)
+ return scalar
+ scalar = Scalar(self.dtype)
+ if self.dtype.is_flexible_type():
+ scalar.value = self.value
+ else:
+ scalar.value = scalar.dtype.itemtype.box(0)
+ return scalar
+
+ def set_imag(self, space, orig_array, w_val):
+ #Only called on complex dtype
+ assert self.dtype.is_complex_type()
+ w_arr = convert_to_array(space, w_val)
+ dtype = self.dtype.float_type
+ if len(w_arr.get_shape()) > 0:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "could not broadcast input array from shape " +
+ "(%s) into shape ()" % (
+ ','.join([str(x) for x in w_arr.get_shape()],))))
+ #real = dtype.itemtype.unbox(self.value.convert_real_to(dtype))
+ #val = dtype.itemtype.unbox(w_arr.get_scalar_value().
+ # convert_to(dtype))
+ #self.value = self.dtype.box_complex(real, val)
+ self.value = self.dtype.itemtype.composite(
+ self.value.convert_real_to(dtype),
+ w_arr.get_scalar_value(),
+ )
+
def descr_getitem(self, space, _, w_idx):
raise OperationError(space.w_IndexError,
space.wrap("scalars cannot be indexed"))
diff --git a/pypy/module/micronumpy/interp_dtype.py
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -71,7 +71,6 @@
def box_complex(self, real, imag):
return self.itemtype.box_complex(real, imag)
-
def coerce(self, space, w_item):
return self.itemtype.coerce(space, self, w_item)
diff --git a/pypy/module/micronumpy/interp_numarray.py
b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -272,16 +272,14 @@
def descr_set_real(self, space, w_value):
# copy (broadcast) values into self
- tmp = self.implementation.get_real(self)
- tmp.setslice(space, convert_to_array(space, w_value))
+ self.implementation.set_real(space, self, w_value)
def descr_set_imag(self, space, w_value):
# if possible, copy (broadcast) values into self
if not self.get_dtype().is_complex_type():
raise OperationError(space.w_TypeError,
space.wrap('array does not have imaginary part to set'))
- tmp = self.implementation.get_imag(self)
- tmp.setslice(space, convert_to_array(space, w_value))
+ self.implementation.set_imag(space, self, w_value)
def descr_reshape(self, space, args_w):
"""reshape(...)
diff --git a/pypy/module/micronumpy/test/test_complex.py
b/pypy/module/micronumpy/test/test_complex.py
--- a/pypy/module/micronumpy/test/test_complex.py
+++ b/pypy/module/micronumpy/test/test_complex.py
@@ -140,25 +140,25 @@
def test_fmax(self):
from numpypy import fmax, array
nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'),
float('-inf')
- a = array((complex(ninf, 10), complex(10, ninf),
+ a = array((complex(ninf, 10), complex(10, ninf),
complex( inf, 10), complex(10, inf),
5+5j, 5-5j, -5+5j, -5-5j,
0+5j, 0-5j, 5, -5,
complex(nan, 0), complex(0, nan)), dtype = complex)
b = [ninf]*a.size
- res = [a[0 ], a[1 ], a[2 ], a[3 ],
+ res = [a[0 ], a[1 ], a[2 ], a[3 ],
a[4 ], a[5 ], a[6 ], a[7 ],
a[8 ], a[9 ], a[10], a[11],
b[12], b[13]]
assert (fmax(a, b) == res).all()
b = [inf]*a.size
- res = [b[0 ], b[1 ], a[2 ], b[3 ],
+ res = [b[0 ], b[1 ], a[2 ], b[3 ],
b[4 ], b[5 ], b[6 ], b[7 ],
b[8 ], b[9 ], b[10], b[11],
b[12], b[13]]
assert (fmax(a, b) == res).all()
b = [0]*a.size
- res = [b[0 ], a[1 ], a[2 ], a[3 ],
+ res = [b[0 ], a[1 ], a[2 ], a[3 ],
a[4 ], a[5 ], b[6 ], b[7 ],
a[8 ], b[9 ], a[10], b[11],
b[12], b[13]]
@@ -167,25 +167,25 @@
def test_fmin(self):
from numpypy import fmin, array
nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'),
float('-inf')
- a = array((complex(ninf, 10), complex(10, ninf),
+ a = array((complex(ninf, 10), complex(10, ninf),
complex( inf, 10), complex(10, inf),
5+5j, 5-5j, -5+5j, -5-5j,
0+5j, 0-5j, 5, -5,
complex(nan, 0), complex(0, nan)), dtype = complex)
b = [inf]*a.size
- res = [a[0 ], a[1 ], b[2 ], a[3 ],
+ res = [a[0 ], a[1 ], b[2 ], a[3 ],
a[4 ], a[5 ], a[6 ], a[7 ],
a[8 ], a[9 ], a[10], a[11],
b[12], b[13]]
assert (fmin(a, b) == res).all()
b = [ninf]*a.size
- res = [b[0 ], b[1 ], b[2 ], b[3 ],
+ res = [b[0 ], b[1 ], b[2 ], b[3 ],
b[4 ], b[5 ], b[6 ], b[7 ],
b[8 ], b[9 ], b[10], b[11],
b[12], b[13]]
assert (fmin(a, b) == res).all()
b = [0]*a.size
- res = [a[0 ], b[1 ], b[2 ], b[3 ],
+ res = [a[0 ], b[1 ], b[2 ], b[3 ],
b[4 ], b[5 ], a[6 ], a[7 ],
b[8 ], a[9 ], b[10], a[11],
b[12], b[13]]
@@ -205,17 +205,17 @@
pass # no longdouble yet
inf = float('inf')
nan = float('nan')
- #complex
- orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j,
- complex(inf, 3), complex(inf, -3), complex(inf, -inf),
+ #complex
+ orig = [2.+4.j, -2.+4.j, 2.-4.j, -2.-4.j,
+ complex(inf, 3), complex(inf, -3), complex(inf, -inf),
complex(nan, 3), 0+0j, 0-0j]
a2 = 2.**2 + 4.**2
r = 2. / a2
i = 4. / a2
cnan = complex(nan, nan)
- expected = [complex(r, -i), complex(-r, -i), complex(r, i),
- complex(-r, i),
- -0j, 0j, cnan,
+ expected = [complex(r, -i), complex(-r, -i), complex(r, i),
+ complex(-r, i),
+ -0j, 0j, cnan,
cnan, cnan, cnan]
for c, rel_err in c_and_relerr:
actual = reciprocal(array([orig], dtype=c))
@@ -225,7 +225,7 @@
def test_floorceiltrunc(self):
from numpypy import array, floor, ceil, trunc
- a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)])
+ a = array([ complex(-1.4, -1.4), complex(-1.5, -1.5)])
raises(TypeError, floor, a)
raises(TypeError, ceil, a)
raises(TypeError, trunc, a)
@@ -270,11 +270,11 @@
(c,a[i], b[i], res)
# cast untranslated boxed results to float,
# does no harm when translated
- t1 = float(res[0])
- t2 = float(b[i].real)
+ t1 = float(res[0])
+ t2 = float(b[i].real)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
- t1 = float(res[1])
- t2 = float(b[i].imag)
+ t1 = float(res[1])
+ t2 = float(b[i].imag)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
def test_expm1(self):
@@ -310,11 +310,11 @@
(c,a[i], b[i], res)
# cast untranslated boxed results to float,
# does no harm when translated
- t1 = float(res.real)
- t2 = float(b[i].real)
+ t1 = float(res.real)
+ t2 = float(b[i].real)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
- t1 = float(res.imag)
- t2 = float(b[i].imag)
+ t1 = float(res.imag)
+ t2 = float(b[i].imag)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
def test_not_complex(self):
@@ -330,16 +330,16 @@
raises(TypeError, logaddexp, complex(1, 1), complex(3, 3))
raises(TypeError, logaddexp2, complex(1, 1), complex(3, 3))
raises(TypeError, arctan2, complex(1, 1), complex(3, 3))
- raises (TypeError, fmod, complex(90,90), 3)
+ raises (TypeError, fmod, complex(90,90), 3)
def test_isnan_isinf(self):
from numpypy import isnan, isinf, array
- assert (isnan(array([0.2+2j, complex(float('inf'),0),
+ assert (isnan(array([0.2+2j, complex(float('inf'),0),
complex(0,float('inf')), complex(0,float('nan')),
complex(float('nan'), 0)], dtype=complex)) == \
[False, False, False, True, True]).all()
- assert (isinf(array([0.2+2j, complex(float('inf'),0),
+ assert (isinf(array([0.2+2j, complex(float('inf'),0),
complex(0,float('inf')), complex(0,float('nan')),
complex(float('nan'), 0)], dtype=complex)) == \
[False, True, True, False, False]).all()
@@ -374,7 +374,7 @@
b = power(a, p)
for i in range(len(a)):
try:
- r = self.c_pow((float(a[i].real), float(a[i].imag)),
+ r = self.c_pow((float(a[i].real), float(a[i].imag)),
(float(p.real), float(p.imag)))
except ZeroDivisionError:
r = (nan, nan)
@@ -384,10 +384,10 @@
r = (nan, nan)
msg = 'result of %r(%r)**%r got %r expected %r\n ' % \
(c,a[i], p, b[i], r)
- t1 = float(r[0])
- t2 = float(b[i].real)
+ t1 = float(r[0])
+ t2 = float(b[i].real)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
- t1 = float(r[1])
+ t1 = float(r[1])
t2 = float(b[i].imag)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
@@ -445,11 +445,11 @@
(c,a[i], b[i], res)
# cast untranslated boxed results to float,
# does no harm when translated
- t1 = float(res.real)
- t2 = float(b[i].real)
+ t1 = float(res.real)
+ t2 = float(b[i].real)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
- t1 = float(res.imag)
- t2 = float(b[i].imag)
+ t1 = float(res.imag)
+ t2 = float(b[i].imag)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
for c,rel_err in ((complex128, 2e-15), (complex64, 1e-7)):
b = log1p(array(a,dtype=c))
@@ -465,11 +465,11 @@
(c,a[i], b[i], res)
# cast untranslated boxed results to float,
# does no harm when translated
- t1 = float(res.real)
- t2 = float(b[i].real)
+ t1 = float(res.real)
+ t2 = float(b[i].real)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
- t1 = float(res.imag)
- t2 = float(b[i].imag)
+ t1 = float(res.imag)
+ t2 = float(b[i].imag)
self.rAlmostEqual(t1, t2, rel_err=rel_err, msg=msg)
def test_logical_ops(self):
@@ -520,7 +520,26 @@
assert imag(0.0) == 0.0
a = array([complex(3.0, 4.0)])
b = a.real
+ b[0] = 1024
+ assert a[0].real == 1024
assert b.dtype == dtype(float)
+ a = array(complex(3.0, 4.0))
+ b = a.real
+ assert b == array(3)
+ a.real = 1024
+ assert a.real == 1024
+ assert a.imag == array(4)
+ assert b.dtype == dtype(float)
+ a = array(4.0)
+ b = a.imag
+ assert b == 0
+ assert b.dtype == dtype(float)
+ raises(TypeError, 'a.imag = 1024')
+ raises(ValueError, 'a.real = [1, 3]')
+ a = array('abc')
+ assert str(a.real) == 'abc'
+ # numpy imag for flexible types returns self
+ assert str(a.imag) == 'abc'
for complex_ in complex_dtypes:
O = complex(0, 0)
@@ -547,12 +566,12 @@
assert add(c1, c2) == complex_(complex(4, 6))
assert add(c1, c2) == complex(4, 6)
-
+
assert sub(c0, c0) == sub(c1, c1) == 0
assert sub(c1, c2) == complex(-2, -2)
assert negative(complex(1,1)) == complex(-1, -1)
assert negative(complex(0, 0)) == 0
-
+
assert multiply(1, c1) == c1
assert multiply(2, c2) == complex(6, 8)
@@ -610,7 +629,7 @@
for complex_, abs_err, testcases in (\
(np.complex128, 5e-323, self.testcases128),
- # (np.complex64, 5e-32, self.testcases64),
+ # (np.complex64, 5e-32, self.testcases64),
):
for id, fn, ar, ai, er, ei, flags in testcases:
arg = complex_(complex(ar, ai))
@@ -648,7 +667,7 @@
) % (id, fn, complex_, ar, ai,
expected[0], expected[1],
actual[0], actual[1])
-
+
# since rAlmostEqual is a wrapped function,
# convert arguments to avoid boxed values
rAlmostEqual(float(expected[0]), float(actual[0]),
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -1150,6 +1150,14 @@
return rfloat.NAN, rfloat.NAN
return rfloat.INFINITY, rfloat.INFINITY
+ @specialize.argtype(1)
+ def composite(self, v1, v2):
+ assert isinstance(v1, self.ComponentBoxType)
+ assert isinstance(v2, self.ComponentBoxType)
+ real = v1.value
+ imag = v2.value
+ return self.box_complex(real, imag)
+
@complex_unary_op
def pos(self, v):
return v
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit