@@ -91,6 +91,7 @@ PyArray_SetNumericOps(PyObject *dict)
91
91
SET (sqrt );
92
92
SET (cbrt );
93
93
SET (negative );
94
+ SET (positive );
94
95
SET (absolute );
95
96
SET (invert );
96
97
SET (left_shift );
@@ -143,6 +144,7 @@ PyArray_GetNumericOps(void)
143
144
GET (_ones_like );
144
145
GET (sqrt );
145
146
GET (negative );
147
+ GET (positive );
146
148
GET (absolute );
147
149
GET (invert );
148
150
GET (left_shift );
@@ -453,9 +455,14 @@ is_scalar_with_conversion(PyObject *o2, double* out_exponent)
453
455
return NPY_NOSCALAR ;
454
456
}
455
457
456
- /* optimize float array or complex array to a scalar power */
457
- static PyObject *
458
- fast_scalar_power (PyArrayObject * a1 , PyObject * o2 , int inplace )
458
+ /*
459
+ * optimize float array or complex array to a scalar power
460
+ * returns 0 on success, -1 if no optimization is possible
461
+ * the result is in value (can be NULL if an error occurred)
462
+ */
463
+ static int
464
+ fast_scalar_power (PyArrayObject * a1 , PyObject * o2 , int inplace ,
465
+ PyObject * * value )
459
466
{
460
467
double exponent ;
461
468
NPY_SCALARKIND kind ; /* NPY_NOSCALAR is not scalar */
@@ -464,17 +471,7 @@ fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace)
464
471
PyObject * fastop = NULL ;
465
472
if (PyArray_ISFLOAT (a1 ) || PyArray_ISCOMPLEX (a1 )) {
466
473
if (exponent == 1.0 ) {
467
- /* we have to do this one special, as the
468
- "copy" method of array objects isn't set
469
- up early enough to be added
470
- by PyArray_SetNumericOps.
471
- */
472
- if (inplace ) {
473
- Py_INCREF (a1 );
474
- return (PyObject * )a1 ;
475
- } else {
476
- return PyArray_Copy (a1 );
477
- }
474
+ fastop = n_ops .positive ;
478
475
}
479
476
else if (exponent == -1.0 ) {
480
477
fastop = n_ops .reciprocal ;
@@ -489,15 +486,16 @@ fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace)
489
486
fastop = n_ops .square ;
490
487
}
491
488
else {
492
- return NULL ;
489
+ return -1 ;
493
490
}
494
491
495
492
if (inplace || can_elide_temp_unary (a1 )) {
496
- return PyArray_GenericInplaceUnaryFunction (a1 , fastop );
493
+ * value = PyArray_GenericInplaceUnaryFunction (a1 , fastop );
497
494
}
498
495
else {
499
- return PyArray_GenericUnaryFunction (a1 , fastop );
496
+ * value = PyArray_GenericUnaryFunction (a1 , fastop );
500
497
}
498
+ return 0 ;
501
499
}
502
500
/* Because this is called with all arrays, we need to
503
501
* change the output if the kind of the scalar is different
@@ -507,36 +505,35 @@ fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace)
507
505
else if (exponent == 2.0 ) {
508
506
fastop = n_ops .square ;
509
507
if (inplace ) {
510
- return PyArray_GenericInplaceUnaryFunction (a1 , fastop );
508
+ * value = PyArray_GenericInplaceUnaryFunction (a1 , fastop );
511
509
}
512
510
else {
513
511
/* We only special-case the FLOAT_SCALAR and integer types */
514
512
if (kind == NPY_FLOAT_SCALAR && PyArray_ISINTEGER (a1 )) {
515
- PyObject * res ;
516
513
PyArray_Descr * dtype = PyArray_DescrFromType (NPY_DOUBLE );
517
514
a1 = (PyArrayObject * )PyArray_CastToType (a1 , dtype ,
518
515
PyArray_ISFORTRAN (a1 ));
519
- if (a1 == NULL ) {
520
- return NULL ;
516
+ if (a1 != NULL ) {
517
+ /* cast always creates a new array */
518
+ * value = PyArray_GenericInplaceUnaryFunction (a1 , fastop );
519
+ Py_DECREF (a1 );
521
520
}
522
- /* cast always creates a new array */
523
- res = PyArray_GenericInplaceUnaryFunction (a1 , fastop );
524
- Py_DECREF (a1 );
525
- return res ;
526
521
}
527
522
else {
528
- return PyArray_GenericUnaryFunction (a1 , fastop );
523
+ * value = PyArray_GenericUnaryFunction (a1 , fastop );
529
524
}
530
525
}
526
+ return 0 ;
531
527
}
532
528
}
533
- return NULL ;
529
+ /* no fast operation found */
530
+ return -1 ;
534
531
}
535
532
536
533
static PyObject *
537
534
array_power (PyArrayObject * a1 , PyObject * o2 , PyObject * modulo )
538
535
{
539
- PyObject * value ;
536
+ PyObject * value = NULL ;
540
537
541
538
if (modulo != Py_None ) {
542
539
/* modular exponentiation is not implemented (gh-8804) */
@@ -545,8 +542,7 @@ array_power(PyArrayObject *a1, PyObject *o2, PyObject *modulo)
545
542
}
546
543
547
544
BINOP_GIVE_UP_IF_NEEDED (a1 , o2 , nb_power , array_power );
548
- value = fast_scalar_power (a1 , o2 , 0 );
549
- if (!value ) {
545
+ if (fast_scalar_power (a1 , o2 , 0 , & value ) != 0 ) {
550
546
value = PyArray_GenericBinaryFunction (a1 , o2 , n_ops .power );
551
547
}
552
548
return value ;
@@ -686,12 +682,11 @@ static PyObject *
686
682
array_inplace_power (PyArrayObject * a1 , PyObject * o2 , PyObject * NPY_UNUSED (modulo ))
687
683
{
688
684
/* modulo is ignored! */
689
- PyObject * value ;
685
+ PyObject * value = NULL ;
690
686
691
687
INPLACE_GIVE_UP_IF_NEEDED (
692
688
a1 , o2 , nb_inplace_power , array_inplace_power );
693
- value = fast_scalar_power (a1 , o2 , 1 );
694
- if (!value ) {
689
+ if (fast_scalar_power (a1 , o2 , 1 , & value ) != 0 ) {
695
690
value = PyArray_GenericInplaceBinaryFunction (a1 , o2 , n_ops .power );
696
691
}
697
692
return value ;
0 commit comments