diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2018-11-16 18:16:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-16 18:16:53 +0100 |
commit | 12b3e3f548556630bc77f4fdcc23dc670b4e6a78 (patch) | |
tree | 106e8b52bf7d0e67315ada36c9a7ea78e852d7b3 | |
parent | 7c938b42a797111d6fc1d4442ee93e6839f3dee4 (diff) | |
parent | 831e311422ecf574669f06a25aa02a567a8ff243 (diff) | |
download | cython-12b3e3f548556630bc77f4fdcc23dc670b4e6a78.tar.gz |
Merge pull request #2709 from serge-sans-paille/fix/pythran-power
Fix/pythran power
-rw-r--r-- | Cython/Compiler/ExprNodes.py | 19 | ||||
-rw-r--r-- | Cython/Compiler/Pythran.py | 9 | ||||
-rw-r--r-- | tests/run/numpy_pythran_unit.pyx | 10 |
3 files changed, 30 insertions, 8 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 2c7e025b8..b60d405f1 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -11115,12 +11115,19 @@ class BinopNode(ExprNode): if self.type.is_pythran_expr: code.putln("// Pythran binop") code.putln("__Pyx_call_destructor(%s);" % self.result()) - code.putln("new (&%s) decltype(%s){%s %s %s};" % ( - self.result(), - self.result(), - self.operand1.pythran_result(), - self.operator, - self.operand2.pythran_result())) + if self.operator == '**': + code.putln("new (&%s) decltype(%s){pythonic::numpy::functor::power{}(%s, %s)};" % ( + self.result(), + self.result(), + self.operand1.pythran_result(), + self.operand2.pythran_result())) + else: + code.putln("new (&%s) decltype(%s){%s %s %s};" % ( + self.result(), + self.result(), + self.operand1.pythran_result(), + self.operator, + self.operand2.pythran_result())) elif self.operand1.type.is_pyobject: function = self.py_operation_function(code) if self.operator == '**': diff --git a/Cython/Compiler/Pythran.py b/Cython/Compiler/Pythran.py index 056985cd1..fc8195696 100644 --- a/Cython/Compiler/Pythran.py +++ b/Cython/Compiler/Pythran.py @@ -60,8 +60,12 @@ def type_remove_ref(ty): def pythran_binop_type(op, tA, tB): - return "decltype(std::declval<%s>() %s std::declval<%s>())" % ( - pythran_type(tA), op, pythran_type(tB)) + if op == '**': + return 'decltype(pythonic::numpy::functor::power{}(std::declval<%s>(), std::declval<%s>()))' % ( + pythran_type(tA), pythran_type(tB)) + else: + return "decltype(std::declval<%s>() %s std::declval<%s>())" % ( + pythran_type(tA), op, pythran_type(tB)) def pythran_unaryop_type(op, type_): @@ -209,6 +213,7 @@ def include_pythran_generic(env): env.add_include_file("pythonic/python/core.hpp") env.add_include_file("pythonic/types/bool.hpp") env.add_include_file("pythonic/types/ndarray.hpp") + env.add_include_file("pythonic/numpy/power.hpp") env.add_include_file("<new>") # for placement new for i in (8, 16, 32, 64): diff --git a/tests/run/numpy_pythran_unit.pyx b/tests/run/numpy_pythran_unit.pyx index 3992233b0..4637e66c6 100644 --- a/tests/run/numpy_pythran_unit.pyx +++ b/tests/run/numpy_pythran_unit.pyx @@ -13,3 +13,13 @@ def trigo(np.ndarray[double, ndim=1] angles): array([ 1., -1., 1.]) """ return np.cos(angles) + +def power(np.ndarray[double, ndim=1] values): + + """ + >>> a = np.array([0., 1., 2.]) + >>> res = power(a) + >>> res[0], res[1], res[2] + (0.0, 1.0, 8.0) + """ + return values ** 3 |