LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
ufunctors.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008, 2009, 2010 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 
24 #ifndef NDARRAY_SWIG_ufunctors_h_INCLUDED
25 #define NDARRAY_SWIG_ufunctors_h_INCLUDED
26 
32 #include "ndarray/swig/numpy.h"
33 
34 namespace ndarray {
35 
36 template <typename TUnaryFunctor,
37  typename TArgument=typename TUnaryFunctor::argument_type,
38  typename TResult=typename TUnaryFunctor::result_type>
40 
41  static PyObject* _call_(TUnaryFunctor const& self, PyObject* input, PyObject* output) {
42  PyObject* input_array = PyArray_FROM_OTF(input,detail::NumpyTraits<TArgument>::getCode(),
43  NPY_ALIGNED);
44  if (input_array == NULL) return NULL;
45  PyObject* output_array;
46  if (output == NULL || output == Py_None) {
47  output_array = PyArray_SimpleNew(PyArray_NDIM(input_array),
48  PyArray_DIMS(input_array),
50  } else {
51  output_array = PyArray_FROM_OTF(output,detail::NumpyTraits<TResult>::getCode(),
52  NPY_ALIGNED | NPY_WRITEABLE | NPY_UPDATEIFCOPY);
53  }
54  if (output_array == NULL) {
55  Py_DECREF(input_array);
56  return NULL;
57  }
58  PyObject* iter = PyArray_MultiIterNew(2,input_array,output_array);
59  if (iter == NULL) {
60  Py_DECREF(input_array);
61  Py_DECREF(output_array);
62  return NULL;
63  }
64  int size = ((PyArrayMultiIterObject*)(iter))->size;
65  while (size--) {
66  TArgument* arg = (TArgument*)PyArray_MultiIter_DATA(iter,0);
67  TResult* res = (TResult*)PyArray_MultiIter_DATA(iter,1);
68  *res = self(*arg);
69  PyArray_MultiIter_NEXT(iter);
70  }
71  Py_DECREF(input_array);
72  Py_DECREF(iter);
73  return PyArray_Return(reinterpret_cast<PyArrayObject*>(output_array));
74  }
75 
76 };
77 
78 
79 template <typename TBinaryFunctor,
80  typename TArgument1=typename TBinaryFunctor::first_argument_type,
81  typename TArgument2=typename TBinaryFunctor::second_argument_type,
82  typename TResult=typename TBinaryFunctor::result_type>
84 
85  static PyObject* _call_(TBinaryFunctor const& self, PyObject* input1, PyObject* input2,
86  PyObject* output) {
87  PyObject* input1_array = PyArray_FROM_OTF(input1,detail::NumpyTraits<TArgument1>::getCode(),
88  NPY_ALIGNED);
89  PyObject* input2_array = PyArray_FROM_OTF(input2,detail::NumpyTraits<TArgument1>::getCode(),
90  NPY_ALIGNED);
91  if (input1_array == NULL || input2_array == NULL) {
92  Py_XDECREF(input1_array);
93  Py_XDECREF(input2_array);
94  return NULL;
95  }
96  PyObject* output_array;
97  if (output == NULL || output == Py_None) {
98  PyObject* tmp = PyArray_MultiIterNew(2,input1_array,input2_array);
99  if (tmp == NULL) {
100  Py_XDECREF(input1_array);
101  Py_XDECREF(input2_array);
102  return NULL;
103  }
104  PyArrayMultiIterObject* tmp_iter = (PyArrayMultiIterObject*)tmp;
105  output_array = PyArray_SimpleNew(tmp_iter->nd,tmp_iter->dimensions,
107  Py_DECREF(tmp);
108  } else {
109  output_array = PyArray_FROM_OTF(output,detail::NumpyTraits<TResult>::getCode(),
110  NPY_ALIGNED | NPY_WRITEABLE | NPY_UPDATEIFCOPY);
111  }
112  if (output_array == NULL) {
113  Py_DECREF(input1_array);
114  Py_DECREF(input2_array);
115  return NULL;
116  }
117  PyObject* iter = PyArray_MultiIterNew(3,input1_array,input2_array,output_array);
118  if (iter == NULL) {
119  Py_DECREF(input1_array);
120  Py_DECREF(input2_array);
121  Py_DECREF(output_array);
122  return NULL;
123  }
124  int size = ((PyArrayMultiIterObject*)(iter))->size;
125  while (size--) {
126  TArgument1* arg1 = (TArgument1*)PyArray_MultiIter_DATA(iter,0);
127  TArgument2* arg2 = (TArgument2*)PyArray_MultiIter_DATA(iter,1);
128  TResult* res = (TResult*)PyArray_MultiIter_DATA(iter,2);
129  *res = self(*arg1,*arg2);
130  PyArray_MultiIter_NEXT(iter);
131  }
132  Py_DECREF(input1_array);
133  Py_DECREF(input2_array);
134  Py_DECREF(iter);
135  return PyArray_Return(reinterpret_cast<PyArrayObject*>(output_array));
136  }
137 
138 };
139 
140 } // namespace ndarray
141 
142 #endif // !NDARRAY_SWIG_ufunctors_h_INCLUDED
int iter
Python C-API conversions between ndarray and numpy.
static PyObject * _call_(TUnaryFunctor const &self, PyObject *input, PyObject *output)
Definition: ufunctors.h:41
static PyObject * _call_(TBinaryFunctor const &self, PyObject *input1, PyObject *input2, PyObject *output)
Definition: ufunctors.h:85