| 2228 | } |
| 2229 | |
| 2230 | static PyObject * |
| 2231 | execute_real_forward(PyObject *a1, double fct) |
| 2232 | { |
| 2233 | rfft_plan plan=NULL; |
| 2234 | int fail = 0; |
| 2235 | npy_intp tdim[NPY_MAXDIMS]; |
| 2236 | |
| 2237 | PyArrayObject *data = (PyArrayObject *)PyArray_FromAny(a1, |
| 2238 | PyArray_DescrFromType(NPY_DOUBLE), 1, 0, |
| 2239 | NPY_ARRAY_DEFAULT | NPY_ARRAY_ENSUREARRAY | NPY_ARRAY_FORCECAST, |
| 2240 | NULL); |
| 2241 | if (!data) return NULL; |
| 2242 | |
| 2243 | int ndim = PyArray_NDIM(data); |
| 2244 | const npy_intp *odim = PyArray_DIMS(data); |
| 2245 | int npts = odim[ndim - 1]; |
| 2246 | for (int d=0; d<ndim-1; ++d) |
| 2247 | tdim[d] = odim[d]; |
| 2248 | tdim[ndim-1] = npts/2 + 1; |
| 2249 | PyArrayObject *ret = (PyArrayObject *)PyArray_Empty(ndim, |
| 2250 | tdim, PyArray_DescrFromType(NPY_CDOUBLE), 0); |
| 2251 | if (!ret) fail=1; |
| 2252 | if (!fail) { |
| 2253 | int rstep = PyArray_DIM(ret, PyArray_NDIM(ret) - 1)*2; |
| 2254 | |
| 2255 | int nrepeats = PyArray_SIZE(data)/npts; |
| 2256 | double *rptr = (double *)PyArray_DATA(ret), |
| 2257 | *dptr = (double *)PyArray_DATA(data); |
| 2258 | |
| 2259 | Py_BEGIN_ALLOW_THREADS; |
| 2260 | plan = make_rfft_plan(npts); |
| 2261 | if (!plan) fail=1; |
| 2262 | if (!fail) |
| 2263 | for (int i = 0; i < nrepeats; i++) { |
| 2264 | rptr[rstep-1] = 0.0; |
| 2265 | memcpy((char *)(rptr+1), dptr, npts*sizeof(double)); |
| 2266 | if (rfft_forward(plan, rptr+1, fct)!=0) {fail=1; break;} |
| 2267 | rptr[0] = rptr[1]; |
| 2268 | rptr[1] = 0.0; |
| 2269 | rptr += rstep; |
| 2270 | dptr += npts; |
| 2271 | } |
| 2272 | if (plan) destroy_rfft_plan(plan); |
| 2273 | Py_END_ALLOW_THREADS; |
| 2274 | } |
| 2275 | if (fail) { |
| 2276 | Py_XDECREF(data); |
| 2277 | Py_XDECREF(ret); |
| 2278 | return PyErr_NoMemory(); |
| 2279 | } |
| 2280 | Py_DECREF(data); |
| 2281 | return (PyObject *)ret; |
| 2282 | } |
| 2283 | static PyObject * |
| 2284 | execute_real_backward(PyObject *a1, double fct) |
| 2285 | { |
no test coverage detected