diff --git a/bench_nd.py b/bench_nd.py
index ab391751ddd601eb5872a5cee4cf68e4450e1575..72dae6b5d62eeea8d18c68506224a7972f01884e 100644
--- a/bench_nd.py
+++ b/bench_nd.py
@@ -23,10 +23,10 @@ def bench_nd_fftn(ndim, nmax, ntry, tp, nrepeat, filename=""):
         tmin_pp=1e38
         for i in range(nrepeat):
             t0=time()
-            b=pypocketfft.fftn(a,nthreads=nthreads)
+            b=pypocketfft.c2c(a,nthreads=nthreads, forward=True)
             t1=time()
             tmin_pp = min(tmin_pp,t1-t0)
-        a2=pypocketfft.ifftn(b,inorm=2)
+        a2=pypocketfft.c2c(b,inorm=2, forward=False)
         assert(_l2error(a,a2)<(2.5e-15 if tp=='c16' else 6e-7))
         res.append(tmin_pp/tmin_np)
     plt.title("t(pypocketfft / numpy 1.17), {}D, {}, max_extent={}".format(ndim, str(tp), nmax))
diff --git a/pypocketfft.cc b/pypocketfft.cc
index 5fd02369f946afd7a3e834dc27c95c2fa427ed09..1328de906581ac21dc79b1ba0ac7808d390c5bfb 100644
--- a/pypocketfft.cc
+++ b/pypocketfft.cc
@@ -23,7 +23,8 @@
 namespace {
 
 using namespace std;
-using namespace pocketfft;
+using pocketfft::shape_t;
+using pocketfft::stride_t;
 
 namespace py = pybind11;
 
@@ -104,8 +105,8 @@ template<typename T> T norm_fct(int inorm, const shape_t &shape,
   return norm_fct<T>(inorm, N);
   }
 
-template<typename T> py::array xfftn_internal(const py::array &in,
-  const shape_t &axes, int inorm, bool inplace, bool fwd, size_t nthreads)
+template<typename T> py::array c2c_internal(const py::array &in,
+  const shape_t &axes, bool forward, int inorm, bool inplace, size_t nthreads)
   {
   auto dims(copy_shape(in));
   py::array res = inplace ? in : py::array_t<complex<T>>(dims);
@@ -116,13 +117,13 @@ template<typename T> py::array xfftn_internal(const py::array &in,
   {
   py::gil_scoped_release release;
   T fct = norm_fct<T>(inorm, dims, axes);
-  c2c(dims, s_in, s_out, axes, fwd, d_in, d_out, fct, nthreads);
+  pocketfft::c2c(dims, s_in, s_out, axes, forward, d_in, d_out, fct, nthreads);
   }
   return res;
   }
 
-template<typename T> py::array sym_rfftn_internal(const py::array &in,
-  const shape_t &axes, int inorm, bool fwd, size_t nthreads)
+template<typename T> py::array c2c_sym_internal(const py::array &in,
+  const shape_t &axes, bool forward, int inorm, size_t nthreads)
   {
   auto dims(copy_shape(in));
   py::array res = py::array_t<complex<T>>(dims);
@@ -133,7 +134,7 @@ template<typename T> py::array sym_rfftn_internal(const py::array &in,
   {
   py::gil_scoped_release release;
   T fct = norm_fct<T>(inorm, dims, axes);
-  r2c(dims, s_in, s_out, axes, fwd, d_in, d_out, fct, nthreads);
+  pocketfft::r2c(dims, s_in, s_out, axes, forward, d_in, d_out, fct, nthreads);
   // now fill in second half
   using namespace pocketfft::detail;
   ndarr<complex<T>> ares(res.mutable_data(), dims, s_out);
@@ -148,28 +149,20 @@ template<typename T> py::array sym_rfftn_internal(const py::array &in,
   return res;
   }
 
-py::array xfftn(const py::array &a, py::object axes, int inorm,
-  bool inplace, bool fwd, size_t nthreads)
+py::array c2c(const py::array &a, py::object axes, bool forward, int inorm,
+  bool inplace, size_t nthreads)
   {
   if (a.dtype().kind() == 'c')
-    DISPATCH(a, c128, c64, clong, xfftn_internal, (a, makeaxes(a, axes), inorm,
-             inplace, fwd, nthreads))
+    DISPATCH(a, c128, c64, clong, c2c_internal, (a, makeaxes(a, axes), forward,
+             inorm, inplace, nthreads))
 
   if (inplace) throw runtime_error("cannot do this operation in-place");
-  DISPATCH(a, f64, f32, flong, sym_rfftn_internal, (a, makeaxes(a, axes), inorm,
-           fwd, nthreads))
+  DISPATCH(a, f64, f32, flong, c2c_sym_internal, (a, makeaxes(a, axes), forward,
+           inorm, nthreads))
   }
 
-py::array fftn(const py::array &a, py::object axes, int inorm, bool inplace,
-  size_t nthreads)
-  { return xfftn(a, axes, inorm, inplace, true, nthreads); }
-
-py::array ifftn(const py::array &a, py::object axes, int inorm,
-  bool inplace, size_t nthreads)
-  { return xfftn(a, axes, inorm, inplace, false, nthreads); }
-
-template<typename T> py::array rfftn_internal(const py::array &in,
-  py::object axes_, int inorm, size_t nthreads)
+template<typename T> py::array r2c_internal(const py::array &in,
+  py::object axes_, bool forward, int inorm, size_t nthreads)
   {
   auto axes = makeaxes(in, axes_);
   auto dims_in(copy_shape(in)), dims_out(dims_in);
@@ -182,20 +175,23 @@ template<typename T> py::array rfftn_internal(const py::array &in,
   {
   py::gil_scoped_release release;
   T fct = norm_fct<T>(inorm, dims_in, axes);
-  r2c(dims_in, s_in, s_out, axes, true, d_in, d_out, fct, nthreads);
+  pocketfft::r2c(dims_in, s_in, s_out, axes, forward, d_in, d_out, fct, nthreads);
   }
   return res;
   }
 
-py::array rfftn(const py::array &in, py::object axes_, int inorm,
+py::array r2c(const py::array &in, py::object axes_, bool forward, int inorm,
   size_t nthreads)
   {
-  DISPATCH(in, f64, f32, flong, rfftn_internal, (in, axes_, inorm, nthreads))
+  DISPATCH(in, f64, f32, flong, r2c_internal, (in, axes_, forward, inorm,
+    nthreads))
   }
 
-template<typename T> py::array xrfft_scipy(const py::array &in,
-  size_t axis, int inorm, bool inplace, bool fwd, size_t nthreads)
+template<typename T> py::array r2r_fftpack_internal(const py::array &in,
+  py::object axes_, bool input_halfcomplex, bool forward, int inorm,
+  bool inplace, size_t nthreads)
   {
+  auto axes = makeaxes(in, axes_);
   auto dims(copy_shape(in));
   py::array res = inplace ? in : py::array_t<T>(dims);
   auto s_in=copy_strides(in);
@@ -204,27 +200,23 @@ template<typename T> py::array xrfft_scipy(const py::array &in,
   auto d_out=reinterpret_cast<T *>(res.mutable_data());
   {
   py::gil_scoped_release release;
-  T fct = norm_fct<T>(inorm, dims[axis]);
-  r2r_fftpack(dims, s_in, s_out, {axis}, fwd, fwd, d_in, d_out, fct, nthreads);
+  T fct = norm_fct<T>(inorm, dims, axes);
+  pocketfft::r2r_fftpack(dims, s_in, s_out, axes, !input_halfcomplex, forward, d_in, d_out,
+    fct, nthreads);
   }
   return res;
   }
 
-py::array rfft_scipy(const py::array &in, size_t axis, int inorm,
-  bool inplace, size_t nthreads)
+py::array r2r_fftpack(const py::array &in, py::object axes_,
+  bool input_halfcomplex, bool forward, int inorm, bool inplace,
+  size_t nthreads)
   {
-  DISPATCH(in, f64, f32, flong, xrfft_scipy, (in, axis, inorm, inplace, true,
-    nthreads))
+  DISPATCH(in, f64, f32, flong, r2r_fftpack_internal, (in, axes_,
+    input_halfcomplex, forward, inorm, inplace, nthreads))
   }
 
-py::array irfft_scipy(const py::array &in, size_t axis, int inorm,
-  bool inplace, size_t nthreads)
-  {
-  DISPATCH(in, f64, f32, flong, xrfft_scipy, (in, axis, inorm, inplace, false,
-    nthreads))
-  }
-template<typename T> py::array irfftn_internal(const py::array &in,
-  py::object axes_, size_t lastsize, int inorm, size_t nthreads)
+template<typename T> py::array c2r_internal(const py::array &in,
+  py::object axes_, size_t lastsize, bool forward, int inorm, size_t nthreads)
   {
   auto axes = makeaxes(in, axes_);
   size_t axis = axes.back();
@@ -241,16 +233,16 @@ template<typename T> py::array irfftn_internal(const py::array &in,
   {
   py::gil_scoped_release release;
   T fct = norm_fct<T>(inorm, dims_out, axes);
-  c2r(dims_out, s_in, s_out, axes, false, d_in, d_out, fct, nthreads);
+  pocketfft::c2r(dims_out, s_in, s_out, axes, forward, d_in, d_out, fct, nthreads);
   }
   return res;
   }
 
-py::array irfftn(const py::array &in, py::object axes_, size_t lastsize,
-  int inorm, size_t nthreads)
+py::array c2r(const py::array &in, py::object axes_, size_t lastsize,
+  bool forward, int inorm, size_t nthreads)
   {
-  DISPATCH(in, c128, c64, clong, irfftn_internal, (in, axes_, lastsize, inorm,
-    nthreads))
+  DISPATCH(in, c128, c64, clong, c2r_internal, (in, axes_, lastsize, forward,
+    inorm, nthreads))
   }
 
 template<typename T> py::array hartley_internal(const py::array &in,
@@ -266,7 +258,7 @@ template<typename T> py::array hartley_internal(const py::array &in,
   {
   py::gil_scoped_release release;
   T fct = norm_fct<T>(inorm, dims, axes);
-  r2r_hartley(dims, s_in, s_out, axes, d_in, d_out, fct, nthreads);
+  pocketfft::r2r_hartley(dims, s_in, s_out, axes, d_in, d_out, fct, nthreads);
   }
   return res;
   }
@@ -312,7 +304,7 @@ py::array mycomplex2hartley(const py::array &in,
 py::array hartley2(const py::array &in, py::object axes_, int inorm,
   bool inplace, size_t nthreads)
   {
-  return mycomplex2hartley(in, rfftn(in, axes_, inorm, nthreads), axes_,
+  return mycomplex2hartley(in, r2c(in, axes_, true, inorm, nthreads), axes_,
     inplace);
   }
 
@@ -328,8 +320,7 @@ vector instructions for faster execution if these are supported by the CPU and
 were enabled during compilation.
 )""";
 
-const char *fftn_DS = R"""(
-Performs a forward complex FFT.
+const char *c2c_DS = R"""(Performs a complex FFT.
 
 Parameters
 ----------
@@ -339,6 +330,8 @@ a : numpy.ndarray (any complex or real type)
 axes : list of integers
     The axes along which the FFT is carried out.
     If not set, all axes will be transformed.
+forward : bool
+    If `True`, a negative sign is used in the exponent, else a positive one.
 inorm : int
     Normalization type
       0 : no normalization
@@ -360,38 +353,7 @@ np.ndarray (same shape as `a`, complex type with same accuracy as `a`)
     The transformed data.
 )""";
 
-const char *ifftn_DS = R"""(Performs a backward complex FFT.
-
-Parameters
-----------
-a : numpy.ndarray (any complex or real type)
-    The input data. If its type is real, a more efficient real-to-complex
-    transform will be used.
-axes : list of integers
-    The axes along which the FFT is carried out.
-    If not set, all axes will be transformed.
-inorm : int
-    Normalization type
-      0 : no normalization
-      1 : divide by sqrt(N)
-      2 : divide by N
-    where N is the product of the lengths of the transformed axes.
-inplace : bool
-    if False, returns the result in a new array and leaves the input unchanged.
-    if True, stores the result in the input array and returns a handle to it.
-    NOTE: if `a` is real-valued and `inplace` is `True`, an exception will be
-    raised!
-nthreads : int
-    Number of threads to use. If 0, use the system default (typically governed
-    by the `OMP_NUM_THREADS` environment variable).
-
-Returns
--------
-np.ndarray (same shape as `a`, complex type with same accuracy as `a`)
-    The transformed data
-)""";
-
-const char *rfftn_DS = R"""(Performs a forward real-valued FFT.
+const char *r2c_DS = R"""(Performs an FFT whose input is strictly real.
 
 Parameters
 ----------
@@ -400,6 +362,8 @@ a : numpy.ndarray (any real type)
 axes : list of integers
     The axes along which the FFT is carried out.
     If not set, all axes will be transformed in ascending order.
+forward : bool
+    If `True`, a negative sign is used in the exponent, else a positive one.
 inorm : int
     Normalization type
       0 : no normalization
@@ -418,36 +382,7 @@ np.ndarray (complex type with same accuracy as `a`)
     was n on input, it is n//2+1 on output.
 )""";
 
-const char *rfft_scipy_DS = R"""(Performs a forward real-valued FFT.
-
-Parameters
-----------
-a : numpy.ndarray (any real type)
-    The input data
-axis : int
-    The axis along which the FFT is carried out.
-inorm : int
-    Normalization type
-      0 : no normalization
-      1 : divide by sqrt(N)
-      2 : divide by N
-    where N is the length of `axis`.
-inplace : bool
-    if False, returns the result in a new array and leaves the input unchanged.
-    if True, stores the result in the input array and returns a handle to it.
-nthreads : int
-    Number of threads to use. If 0, use the system default (typically governed
-    by the `OMP_NUM_THREADS` environment variable).
-
-Returns
--------
-np.ndarray (same shape and data type as `a`)
-    The transformed data. The shape is identical to that of the input array.
-    Along the transformed axis, values are arranged in
-    FFTPACK half-complex order, i.e. `a[0].re, a[1].re, a[1].im, a[2].re ...`.
-)""";
-
-const char *irfftn_DS = R"""(Performs a backward real-valued FFT.
+const char *c2r_DS = R"""(Performs an FFT whose output is strictly real.
 
 Parameters
 ----------
@@ -458,6 +393,8 @@ axes : list of integers
     If not set, all axes will be transformed in ascending order.
 lastsize : the output size of the last axis to be transformed.
     If the corresponding input axis has size n, this can be 2*n-2 or 2*n-1.
+forward : bool
+    If `True`, a negative sign is used in the exponent, else a positive one.
 inorm : int
     Normalization type
       0 : no normalization
@@ -476,15 +413,20 @@ np.ndarray (real type with same accuracy as `a`)
     entries.
 )""";
 
-const char *irfft_scipy_DS = R"""(Performs a backward real-valued FFT.
+const char *r2r_fftpack_DS = R"""(Performs a real-valued FFT using the FFTPACK storage scheme.
 
 Parameters
 ----------
 a : numpy.ndarray (any real type)
-    The input data. Along the transformed axis, values are expected in
-    FFTPACK half-complex order, i.e. `a[0].re, a[1].re, a[1].im, a[2].re ...`.
-axis : int
-    The axis along which the FFT is carried out.
+    The input data
+axes : list of integers
+    The axes along which the FFT is carried out.
+    If not set, all axes will be transformed.
+input_halfcomplex : bool
+    if True, the transform will go from halfcomplex to real format, else in
+    the other direction
+forward : bool
+    If `True`, a negative sign is used in the exponent, else a positive one.
 inorm : int
     Normalization type
       0 : no normalization
@@ -542,18 +484,15 @@ PYBIND11_MODULE(pypocketfft, m)
   using namespace pybind11::literals;
 
   m.doc() = pypocketfft_DS;
-  m.def("fftn",&fftn, fftn_DS, "a"_a, "axes"_a=py::none(), "inorm"_a=0,
-    "inplace"_a=false, "nthreads"_a=1);
-  m.def("ifftn",&ifftn, ifftn_DS, "a"_a, "axes"_a=py::none(), "inorm"_a=0,
-    "inplace"_a=false, "nthreads"_a=1);
-  m.def("rfftn",&rfftn, rfftn_DS, "a"_a, "axes"_a=py::none(), "inorm"_a=0,
-    "nthreads"_a=1);
-  m.def("rfft_scipy",&rfft_scipy, rfft_scipy_DS, "a"_a, "axis"_a, "inorm"_a=0,
-    "inplace"_a=false, "nthreads"_a=1);
-  m.def("irfftn",&irfftn, irfftn_DS, "a"_a, "axes"_a=py::none(), "lastsize"_a=0,
-    "inorm"_a=0, "nthreads"_a=1);
-  m.def("irfft_scipy",&irfft_scipy, irfft_scipy_DS, "a"_a, "axis"_a,
+  m.def("c2c",&c2c, c2c_DS, "a"_a, "axes"_a=py::none(), "forward"_a=true,
     "inorm"_a=0, "inplace"_a=false, "nthreads"_a=1);
+  m.def("r2c",&r2c, r2c_DS, "a"_a, "axes"_a=py::none(), "forward"_a=true,
+    "inorm"_a=0, "nthreads"_a=1);
+  m.def("c2r",&c2r, c2r_DS, "a"_a, "axes"_a=py::none(), "lastsize"_a=0,
+    "forward"_a=true, "inorm"_a=0, "nthreads"_a=1);
+  m.def("r2r_fftpack",&r2r_fftpack, r2r_fftpack_DS, "a"_a, "axes"_a,
+    "input_halfcomplex"_a, "forward"_a, "inorm"_a=0, "inplace"_a=false,
+    "nthreads"_a=1);
   m.def("hartley",&hartley, hartley_DS, "a"_a, "axes"_a=py::none(), "inorm"_a=0,
     "inplace"_a=false, "nthreads"_a=1);
   m.def("hartley2",&hartley2, "a"_a, "axes"_a=py::none(), "inorm"_a=0,
diff --git a/stress.py b/stress.py
index 15dd47097a1ca4197036ed88beb3841259dede8d..cc62775573ee7303ead4ff1ab16f0767217d4df6 100644
--- a/stress.py
+++ b/stress.py
@@ -4,6 +4,31 @@ import pypocketfft
 def _l2error(a,b):
     return np.sqrt(np.sum(np.abs(a-b)**2)/np.sum(np.abs(a)**2))
 
+def fftn(a, axes=None, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.c2c(a, axes=axes, forward=True, inorm=inorm,
+                           inplace=inplace, nthreads=nthreads)
+
+def ifftn(a, axes=None, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.c2c(a, axes=axes, forward=False, inorm=inorm,
+                           inplace=inplace, nthreads=nthreads)
+
+def rfftn(a, axes=None, inorm=0, nthreads=1):
+    return pypocketfft.r2c(a, axes=axes, forward=True, inorm=inorm,
+                           nthreads=nthreads)
+
+def irfftn(a, axes=None, lastsize=0, inorm=0, nthreads=1):
+    return pypocketfft.c2r(a, axes=axes, lastsize=lastsize,forward=False,
+                           inorm=inorm, nthreads=nthreads)
+
+def rfft_scipy(a, axis, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.r2r_fftpack(a, axes=(axis,), input_halfcomplex=False,
+                                   forward=True, inorm=inorm, inplace=inplace,
+                                   nthreads=nthreads)
+def irfft_scipy(a, axis, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.r2r_fftpack(a, axes=(axis,), input_halfcomplex=True,
+                                   forward=False, inorm=inorm, inplace=inplace,
+                                   nthreads=nthreads)
+
 nthreads=0
 cmaxerr=0.
 fmaxerr=0.
@@ -22,32 +47,32 @@ def test():
     axes = axes[:nax]
     lastsize = shape[axes[-1]]
     a=np.random.rand(*shape)-0.5 + 1j*np.random.rand(*shape)-0.5j
-    b=pypocketfft.ifftn(pypocketfft.fftn(a,axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
+    b=ifftn(fftn(a,axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
     err = _l2error(a,b)
     if err > cmaxerr:
         cmaxerr = err
         print("cmaxerr:", cmaxerr, shape, axes)
-    b=pypocketfft.ifftn(pypocketfft.fftn(a.real,axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
+    b=ifftn(fftn(a.real,axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
     err = _l2error(a.real,b)
     if err > cmaxerr:
         cmaxerr = err
         print("cmaxerr:", cmaxerr, shape, axes)
-    b=pypocketfft.fftn(pypocketfft.ifftn(a.real,axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
+    b=fftn(ifftn(a.real,axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
     err = _l2error(a.real,b)
     if err > cmaxerr:
         cmaxerr = err
         print("cmaxerr:", cmaxerr, shape, axes)
-    b=pypocketfft.irfftn(pypocketfft.rfftn(a.real,axes=axes,nthreads=nthreads),axes=axes,inorm=2,lastsize=lastsize,nthreads=nthreads)
+    b=irfftn(rfftn(a.real,axes=axes,nthreads=nthreads),axes=axes,inorm=2,lastsize=lastsize,nthreads=nthreads)
     err = _l2error(a.real,b)
     if err > fmaxerr:
         fmaxerr = err
         print("fmaxerr:", fmaxerr, shape, axes)
-    b=pypocketfft.ifftn(pypocketfft.fftn(a.astype(np.complex64),axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
+    b=ifftn(fftn(a.astype(np.complex64),axes=axes,nthreads=nthreads),axes=axes,inorm=2,nthreads=nthreads)
     err = _l2error(a.astype(np.complex64),b)
     if err > cmaxerrf:
         cmaxerrf = err
         print("cmaxerrf:", cmaxerrf, shape, axes)
-    b=pypocketfft.irfftn(pypocketfft.rfftn(a.real.astype(np.float32),axes=axes,nthreads=nthreads),axes=axes,inorm=2,lastsize=lastsize,nthreads=nthreads)
+    b=irfftn(rfftn(a.real.astype(np.float32),axes=axes,nthreads=nthreads),axes=axes,inorm=2,lastsize=lastsize,nthreads=nthreads)
     err = _l2error(a.real.astype(np.float32),b)
     if err > fmaxerrf:
         fmaxerrf = err
diff --git a/test.py b/test.py
index b788e60e4e2c1b72d0068b9da4b8719b8e177e94..9abea597367f83df99d2e3613eefa4805a524639 100644
--- a/test.py
+++ b/test.py
@@ -15,77 +15,101 @@ len1D=range(1,2048)
 def _l2error(a,b):
     return np.sqrt(np.sum(np.abs(a-b)**2)/np.sum(np.abs(a)**2))
 
+def fftn(a, axes=None, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.c2c(a, axes=axes, forward=True, inorm=inorm,
+                           inplace=inplace, nthreads=nthreads)
+
+def ifftn(a, axes=None, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.c2c(a, axes=axes, forward=False, inorm=inorm,
+                           inplace=inplace, nthreads=nthreads)
+
+def rfftn(a, axes=None, inorm=0, nthreads=1):
+    return pypocketfft.r2c(a, axes=axes, forward=True, inorm=inorm,
+                           nthreads=nthreads)
+
+def irfftn(a, axes=None, lastsize=0, inorm=0, nthreads=1):
+    return pypocketfft.c2r(a, axes=axes, lastsize=lastsize,forward=False,
+                           inorm=inorm, nthreads=nthreads)
+
+def rfft_scipy(a, axis, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.r2r_fftpack(a, axes=(axis,), input_halfcomplex=False,
+                                   forward=True, inorm=inorm, inplace=inplace,
+                                   nthreads=nthreads)
+def irfft_scipy(a, axis, inorm=0, inplace=False, nthreads=1):
+    return pypocketfft.r2r_fftpack(a, axes=(axis,), input_halfcomplex=True,
+                                   forward=False, inorm=inorm, inplace=inplace,
+                                   nthreads=nthreads)
 @pmp("len", len1D)
 @pmp("inorm", [0,1,2])
 def test1D(len, inorm):
     a=np.random.rand(len)-0.5 + 1j*np.random.rand(len)-0.5j
     b=a.astype(np.complex64)
     c=a.astype(np.complex256)
-    assert_(_l2error(a, pypocketfft.ifftn(pypocketfft.fftn(c,inorm=inorm), inorm=2-inorm))<1e-18)
-    assert_(_l2error(a, pypocketfft.ifftn(pypocketfft.fftn(a,inorm=inorm), inorm=2-inorm))<1.5e-15)
-    assert_(_l2error(a.real, pypocketfft.ifftn(pypocketfft.fftn(a.real,inorm=inorm), inorm=2-inorm))<1.5e-15)
-    assert_(_l2error(a.real, pypocketfft.fftn(pypocketfft.ifftn(a.real,inorm=inorm), inorm=2-inorm))<1.5e-15)
-    assert_(_l2error(a.real, pypocketfft.irfftn(pypocketfft.rfftn(a.real,inorm=inorm), inorm=2-inorm,lastsize=len))<1.5e-15)
+    assert_(_l2error(a, ifftn(fftn(c,inorm=inorm), inorm=2-inorm))<1e-18)
+    assert_(_l2error(a, ifftn(fftn(a,inorm=inorm), inorm=2-inorm))<1.5e-15)
+    assert_(_l2error(a.real, ifftn(fftn(a.real,inorm=inorm), inorm=2-inorm))<1.5e-15)
+    assert_(_l2error(a.real, fftn(ifftn(a.real,inorm=inorm), inorm=2-inorm))<1.5e-15)
+    assert_(_l2error(a.real, irfftn(rfftn(a.real,inorm=inorm), inorm=2-inorm,lastsize=len))<1.5e-15)
     tmp=a.copy()
-    assert_ (pypocketfft.ifftn(pypocketfft.fftn(tmp, inplace=True, inorm=inorm), inplace=True, inorm=2-inorm) is tmp)
+    assert_ (ifftn(fftn(tmp, inplace=True, inorm=inorm), inplace=True, inorm=2-inorm) is tmp)
     assert_(_l2error(tmp, a)<1.5e-15)
-    assert_(_l2error(b, pypocketfft.ifftn(pypocketfft.fftn(b, inorm=inorm), inorm=2-inorm))<6e-7)
-    assert_(_l2error(b.real, pypocketfft.ifftn(pypocketfft.fftn(b.real,inorm=inorm), inorm=2-inorm))<6e-7)
-    assert_(_l2error(b.real, pypocketfft.fftn(pypocketfft.ifftn(b.real,inorm=inorm), inorm=2-inorm))<6e-7)
-    assert_(_l2error(b.real, pypocketfft.irfftn(pypocketfft.rfftn(b.real, inorm=inorm), lastsize=len, inorm=2-inorm))<6e-7)
+    assert_(_l2error(b, ifftn(fftn(b, inorm=inorm), inorm=2-inorm))<6e-7)
+    assert_(_l2error(b.real, ifftn(fftn(b.real,inorm=inorm), inorm=2-inorm))<6e-7)
+    assert_(_l2error(b.real, fftn(ifftn(b.real,inorm=inorm), inorm=2-inorm))<6e-7)
+    assert_(_l2error(b.real, irfftn(rfftn(b.real, inorm=inorm), lastsize=len, inorm=2-inorm))<6e-7)
     tmp=b.copy()
-    assert_ (pypocketfft.ifftn(pypocketfft.fftn(tmp, inplace=True, inorm=inorm), inplace=True, inorm=2-inorm) is tmp)
+    assert_ (ifftn(fftn(tmp, inplace=True, inorm=inorm), inplace=True, inorm=2-inorm) is tmp)
     assert_(_l2error(tmp, b)<6e-7)
 
 @pmp("shp", shapes)
 @pmp("nthreads", (0,1,2))
 def test_fftn(shp, nthreads):
     a=np.random.rand(*shp)-0.5 + 1j*np.random.rand(*shp)-0.5j
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a), pypocketfft.fftn(a, nthreads=nthreads))<1e-15)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a), fftn(a, nthreads=nthreads))<1e-15)
     a=a.astype(np.complex64)
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a), pypocketfft.fftn(a, nthreads=nthreads))<5e-7)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a), fftn(a, nthreads=nthreads))<5e-7)
 
 @pmp("shp", shapes2D)
 @pmp("axes", ((0,),(1,),(0,1),(1,0)))
 def test_fftn2D(shp, axes):
     a=np.random.rand(*shp)-0.5 + 1j*np.random.rand(*shp)-0.5j
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a, axes=axes), pypocketfft.fftn(a, axes=axes))<1e-15)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a, axes=axes), fftn(a, axes=axes))<1e-15)
     a=a.astype(np.complex64)
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a, axes=axes), pypocketfft.fftn(a, axes=axes))<5e-7)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.fftn(a, axes=axes), fftn(a, axes=axes))<5e-7)
 
 @pmp("shp", shapes)
 def test_rfftn(shp):
     a=np.random.rand(*shp)-0.5
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a), pypocketfft.rfftn(a))<1e-15)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a), rfftn(a))<1e-15)
     a=a.astype(np.float32)
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a), pypocketfft.rfftn(a))<5e-7)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a), rfftn(a))<5e-7)
 
 @pmp("shp", shapes)
 def test_rfft_scipy(shp):
     for i in range(len(shp)):
         a=np.random.rand(*shp)-0.5
-        assert_(_l2error(pyfftw.interfaces.scipy_fftpack.rfft(a,axis=i), pypocketfft.rfft_scipy(a,axis=i))<1e-15)
-        assert_(_l2error(pyfftw.interfaces.scipy_fftpack.irfft(a,axis=i), pypocketfft.irfft_scipy(a,axis=i,inorm=2))<1e-15)
+        assert_(_l2error(pyfftw.interfaces.scipy_fftpack.rfft(a,axis=i), rfft_scipy(a,axis=i))<1e-15)
+        assert_(_l2error(pyfftw.interfaces.scipy_fftpack.irfft(a,axis=i), irfft_scipy(a,axis=i,inorm=2))<1e-15)
 
 @pmp("shp", shapes2D)
 @pmp("axes", ((0,),(1,),(0,1),(1,0)))
 def test_rfftn2D(shp, axes):
     a=np.random.rand(*shp)-0.5
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a, axes=axes), pypocketfft.rfftn(a, axes=axes))<1e-15)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a, axes=axes), rfftn(a, axes=axes))<1e-15)
     a=a.astype(np.float32)
-    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a, axes=axes), pypocketfft.rfftn(a, axes=axes))<5e-7)
+    assert_(_l2error(pyfftw.interfaces.numpy_fft.rfftn(a, axes=axes), rfftn(a, axes=axes))<5e-7)
 
 @pmp("shp", shapes)
 def test_identity(shp):
     a=np.random.rand(*shp)-0.5 + 1j*np.random.rand(*shp)-0.5j
-    assert_(_l2error(pypocketfft.ifftn(pypocketfft.fftn(a),inorm=2), a)<1.5e-15)
-    assert_(_l2error(pypocketfft.ifftn(pypocketfft.fftn(a.real),inorm=2), a.real)<1.5e-15)
-    assert_(_l2error(pypocketfft.fftn(pypocketfft.ifftn(a.real),inorm=2), a.real)<1.5e-15)
+    assert_(_l2error(ifftn(fftn(a),inorm=2), a)<1.5e-15)
+    assert_(_l2error(ifftn(fftn(a.real),inorm=2), a.real)<1.5e-15)
+    assert_(_l2error(fftn(ifftn(a.real),inorm=2), a.real)<1.5e-15)
     tmp=a.copy()
-    assert_ (pypocketfft.ifftn(pypocketfft.fftn(tmp, inplace=True), inorm=2, inplace=True) is tmp)
+    assert_ (ifftn(fftn(tmp, inplace=True), inorm=2, inplace=True) is tmp)
     assert_(_l2error(tmp, a)<1.5e-15)
     a=a.astype(np.complex64)
-    assert_(_l2error(pypocketfft.ifftn(pypocketfft.fftn(a),inorm=2), a)<6e-7)
+    assert_(_l2error(ifftn(fftn(a),inorm=2), a)<6e-7)
 
 @pmp("shp", shapes)
 def test_identity_r(shp):
@@ -93,20 +117,20 @@ def test_identity_r(shp):
     b=a.astype(np.float32)
     for ax in range(a.ndim):
         n = a.shape[ax]
-        assert_(_l2error(pypocketfft.irfftn(pypocketfft.rfftn(a,(ax,)),(ax,),lastsize=n,inorm=2), a)<1e-15)
-        assert_(_l2error(pypocketfft.irfftn(pypocketfft.rfftn(b,(ax,)),(ax,),lastsize=n,inorm=2), b)<5e-7)
+        assert_(_l2error(irfftn(rfftn(a,(ax,)),(ax,),lastsize=n,inorm=2), a)<1e-15)
+        assert_(_l2error(irfftn(rfftn(b,(ax,)),(ax,),lastsize=n,inorm=2), b)<5e-7)
 
 @pmp("shp", shapes)
 def test_identity_r2(shp):
     a=np.random.rand(*shp)-0.5 + 1j*np.random.rand(*shp)-0.5j
-    a=pypocketfft.rfftn(pypocketfft.irfftn(a))
-    assert_(_l2error(pypocketfft.rfftn(pypocketfft.irfftn(a),inorm=2), a)<1e-15)
+    a=rfftn(irfftn(a))
+    assert_(_l2error(rfftn(irfftn(a),inorm=2), a)<1e-15)
 
 @pmp("shp", shapes2D+shapes3D)
 def test_hartley2(shp):
     a=np.random.rand(*shp)-0.5
     v1 = pypocketfft.hartley2(a)
-    v2 = pypocketfft.fftn(a.astype(np.complex128))
+    v2 = fftn(a.astype(np.complex128))
     v2 = v2.real+v2.imag
     assert_(_l2error(v1, v2)<1e-15)