int @G_makeplan(int type, int dim, int64_t* nmodes, int iflag, int ntr, double eps, finufft_plan* plan, finufft_opts* opts)

  Make a plan to perform one or more general transforms.

  Under the hood, for type 1 and 2, this does FFTW planning and kernel Fourier
  transform precomputation. For type 3, this does very little, since the FFT
  sizes are not yet known.

Inputs:
     type   type of transform (1,2, or 3)
     dim    spatial dimension (1,2, or 3)
     nmodes if type is 1 or 2, numbers of Fourier modes (length dim array),
            ie, {N1} in 1D, {N1,N2} in 2D, or {N1,N2,N3} in 3D.
            If type is 3, it is unused.
@f
@nt
@e
@o

  Outputs:
     plan   plan object (under the hood this is a pointer to another struct)
@r

  Notes:
     * All available threads are planned by default (but see opts.nthreads)
     * The vectorized (many vector) plan, ie ntrans>1, can be much faster
       than repeated calls with the same nonuniform points.
       Note that here the I/O data ordering is stacked rather than interleaved.
     * For more details about the fields in the opts pointer, see opts.rst


int @G_setpts(finufft_plan plan, int64_t M, double* x, double* y, double* z, int64_t N, double* s, double* t, double* z)

  Input nonuniform points with coordinates x (and possibly y, and possibly z),
  and, if type 3, nonuniform frequency target coordinates s (and possibly t,
  and possibly u), into an existing plan. If type is 1 or 2 then the last four
  arguments are ignored. Unused dimensions are ignored.

  Under the hood, for type 1 or 2, this routine bin-sorts the points (storing
  just the permutation rather than new copies of the coordinates). For type
  3 it also bin-sorts the frequencies, chooses two levels of grid sizes, then
  plans the inner type 2 call (interpolation and FFTW).

  Inputs:
     M      number of nonuniform spatial points (used by all types)
     x      nonuniform point x-coordinates (length M real array)
     y      if dim>1, nonuniform point y-coordinates (length M real array),
            ignored otherwise
     z      if dim>2, nonuniform point z-coordinates (length M real array),
            ignored otherwise
     N      number of nonuniform frequency targets (type 3 only, ignored
            otherwise)
     s      nonuniform frequency x-coordinates (length N real array)
     t      if dim>1, nonuniform frequency y-coordinates (length N real array),
            ignored otherwise
     u      if dim>2, nonuniform frequency z-coordinates (length N real array),
            ignored otherwise

  Input/Outputs:
     plan   plan object

  Outputs:
@r

  Notes:
    * The coordinates in x (and if nonempty, y and z) can be any real numbers.
      For type 1 and 2 transforms, their definitions imply that that the
      result is invariant to adding any multiple of 2pi to these coordinates.
      (Internally, each coordinate is folded to [-pi,pi); as usual for
      periodic functions, rounding errors are inevitable if much larger values
      are input.) For type 1 these coordinates are "sources", whereas for type
      2, they are "targets".
      For type 3 the coordinates are "sources", and the "frequency targets"
      s (and if nonempty, t and u) may also be any real numbers; the only
      restriction for type 3 is that the product of source and target domain
      sizes is not too large (it controls the internal fine grid size).
    * The coordinates pointed to by any used arrays x, y, z, s, t, u must
      not be changed between this call and the below execute call!


int @G_execute(finufft_plan plan, complex<double>* c, complex<double>* f)

  Perform one or more NUFFT transforms using previously entered nonuniform
  points and an existing plan. To summarize, this maps
    type 1: c -> f
    type 2: f -> c      
    type 3: c -> f

  Inputs:
       plan   plan object

  Input/Outputs:
       c      For types 1 and 3, the input strengths at the nonuniform point
              sources (size M*ntr complex array).
              If type 2, the output values at the nonuniform point targets
              (size M*ntr complex array).
       f      If type 1, the output Fourier mode coefficients (size N1*ntr or
              N1*N2*ntr or N1*N2*N3*ntr complex array, when dim = 1, 2, or 3
              respectively).
              If type 2, the input Fourier mode coefficients (size N1*ntr or
              N1*N2*ntr or N1*N2*N3*ntr complex array, when dim = 1, 2, or 3
              respectively).
              If type 3, the output values at the nonuniform frequency targets
              (size N*ntr complex array).
              
  Outputs:
@r

  Notes:
    * The contents of the arrays x, y, z, s, t, u must not have changed since
      the finufft_setpts call that read them. The execution rereads them
      (this way of doing business saves RAM).
    * f and c are contiguous Fortran-style arrays with the transform number,
      if ntr>1, being the "slowest" (outer) dimension.


int @G_destroy(finufft_plan plan)

  Deallocate a plan object. This must be used upon clean-up, or before reusing
  a plan in another call to finufft_makeplan.

  Inputs/Outputs:
       plan   plan object

  Outputs:
@r
