package nxm.sys.libm;

import nxm.sys.inc.DataTypes;
import nxm.sys.inc.MidasReference;
import nxm.sys.lib.Convert;
import nxm.sys.lib.Data;
import nxm.sys.lib.DataFile;
import nxm.sys.lib.MidasException;
import nxm.sys.lib.Native;
import nxm.sys.lib.Shell;

/**
  Class to handle Fast Fourier Transform functions.
  This uses native routines where possible.

  @author Jeff Schoen
*/
public class Fft extends Operator {

  private static final boolean USE_NATIVE = true; // Set to false when debugging this library only

  /** REAL FFT Flag      */ public static final int REAL      = 0x00000001;
  /** COMPLEX FFT Flag   */ public static final int COMPLEX   = 0x00000002;
  /** FORWARD FFT Flag   */ public static final int FORWARD   = 0x00000008;
  /** INVERSE FFT Flag   */ public static final int INVERSE   = 0x00000010;
  /** PACKED FFT Flag    */ public static final int PACKED    = 0x00000020;
  /** UNPACKED FFT Flag  */ public static final int UNPACKED  = 0x00000040;
  /** NONYQUIST FFT Flag */ public static final int NONYQUIST = 0x00000080;
  /** SCALE FFT Flag     */ public static final int SCALE     = 0x00000100;
  /** INITPLANS FFT Flag */ public static final int INITPLANS = 0x10000000;
  /** FREEPLANS FFT Flag */ public static final int FREEPLANS = 0x20000000;
  /** VALIDPLAN FFT Flag */ public static final int VALIDPLAN = 0x40000000;

  private static final int  FFT_RADIX_MIN       = 2;
  private static final int  FFT_RADIX_MAX       = 32;

   /* FFT Configuration and Processing Flags */
  private static final int  FFT_FLAGS_NULL      = 0x00000000;
  private static final int  FFT_FLAGS_REAL      = 0x00000001;
  private static final int  FFT_FLAGS_COMPLEX   = 0x00000002;
  private static final int  FFT_FLAGS_FORWARD   = 0x00000008;
  private static final int  FFT_FLAGS_INVERSE   = 0x00000010;
  private static final int  FFT_FLAGS_PACKED    = 0x00000020;
  private static final int  FFT_FLAGS_UNPACKED  = 0x00000040;
  private static final int  FFT_FLAGS_NONYQUIST = 0x00000080;
  private static final int  FFT_FLAGS_SCALE     = 0x00000100;
  private static final int  FFT_FLAGS_INITPLANS = 0x10000000;
  private static final int  FFT_FLAGS_FREEPLANS = 0x20000000;
  private static final int  FFT_FLAGS_VALIDPLAN = 0x40000000;
  private static final int  FFT_FLAGS_OUTOFMEM  = 0x80000000;


 private static final int[][] radix_decomp_profile =
         { {  2,    0, 2147483647, 2147483647 },
           {  3,    0, 2147483647, 2147483647 },
           {  4,    0, 2147483647, 2147483647 },
           {  5,    0, 2147483647, 2147483647 },
           {  8,    0, 2147483647, 2147483647 },
           { 16, 4000, 2147483647,          1 },
           { 32,    0,          0,          0 } };

  private static final double twopi = 2.0 * Math.PI;   // 6.2831853071795864769252867665590057683943388);

  /** Indicates whether the native FFT library has been loaded properly. */
  private static boolean loaded = Shell.loadLibrary ("sys","libm","Fft");

  /** Variable used by the native library to maintain information between the
      init and work methods.  This should only be manipulated by the native routines.  */
  private long     planp;
  private int      fflags;
  private int      size,dir,nc,logn;
  private double[] twd,rtwd;
  private float[]  twf,rtwf;
  private DataFile hcbi,hcbo;
  private boolean  useNative;
  private boolean  useCuda;

  /** Fft Default Constructor */
  public Fft () {
  }

  /** Initialize the instance to handle data of the given size and using the specified flags.
   *  @param size     FFT size
   *  @param fftFlags FFT flags
   */
  public Fft (int size, int fftFlags) {
    init(size,fftFlags);
  }

  @Override
  public int validate (char type, int n, int mode) {
    switch (mode) {
      case SC: n=n/2; break;
      case CC: break;
      default: n=NOSUPPORT;
    } return n;
  }

  /** Performs an inplace FFT of the data contained in buf.  Buf is expected
      to be an array of floats or doubles.
      @param buf  array of floats or double on which to perform an in place FFT
      @param size FFT size
      @param flag FFT flags
   */
  public static void process (Object buf, int size, int flag) {
    //System.out.format("process: flag %i\n", flag );
    boolean useNative = Native.useMath && loaded && USE_NATIVE;
    if (useNative) processNative( buf, size, flag);
    else new Fft(size, flag).work( buf );
  }

  private static native void processNative (Object buf, int size, int flag);

  private static native long initPlan (int size, int flag);
  private static native void workPlan (long planp, Object buf);
  private static native long freePlan (long planp);

  private static native long initPlanCU (int size, int flag);
  private static native void workPlanCU (long planp, Object buf);
  private static native long freePlanCU (long planp);

  /** Calls {@link #process(Object, int, int)} to perform an inplace FFT
      @param a    original Data buffer array
      @param b    new array buffer to be copied to if not equal to array a
      @param size FFT size
      @param mode FFT flag
      @return true
   */
  public boolean XX (float[] a, float[] b, int size, int mode) {
    if (a!=b) System.arraycopy (a,0, b,0, size);
    process (b,size,mode);
    return true;
  }

  /** Checks whether or not the FFT size is invalid
      @param size  FFT size
      @param flags FFT flags
      @return valid FFT size
   */
  public static int validSize (int size, int flags) {
    for (;;) {
       try {
         new Fft(size,flags); // this throws Exception if size is invalid
         return size;
       } catch (MidasException me) { size++; }
    }
  }

  /** Initializes the instance to operate on data of the given size with the
      specified flags.  If the native FFT library has been loaded, this method
      will invoke the appropriate initialization methods on that library,
      setting planp in the process.
      @param size     FFT size
      @param fftFlags FFT flags
   */
  public void init (int size, int fftFlags) {
    this.fflags = fftFlags;
    this.size   = size;
    if ((fftFlags&COMPLEX)!=0) nc=size; else nc=size/2;
    if ((fftFlags&INVERSE)!=0) dir=-1;  else dir=1;
    useNative = Native.useMath && loaded && USE_NATIVE;
    useCuda = useNative && Native.useCuda; // need extra checks for supported Radix
    //System.out.format( "useNative %b, useCuda %b\n", useNative, useCuda );
    if (useNative) planp = useCuda? initPlanCU(size,fftFlags) : initPlan(size,fftFlags);
    else planp = init_internal();
    if (planp==0) throw new MidasException("Problem initializing FFT plan: size="+size+" flags="+fftFlags);
  }

  /** Set input debug file
      @param ref Midas Reference
      @param filename name of DataFile within the Midas Reference
   */
  public void setDebugFileIn (Object ref, String filename) {
    hcbi = new DataFile();
    if (ref instanceof MidasReference) {
      hcbi.init((MidasReference) ref,filename,"2000","SF",0);
    } else {
      hcbi.init(Convert.ref2Midas(ref),filename,"2000","SF",0);
    }
    hcbi.setSubSize(size);
    hcbi.setSize(1);
    hcbi.open(DataFile.OUTPUT);
  }

  /** Set output debug file
      @param ref Midas Reference
      @param filename name of DataFile within the Midas Reference
   */
  public void setDebugFileOut (Object ref, String filename) {
    hcbo = new DataFile();
    if (ref instanceof MidasReference) {
      hcbo.init((MidasReference) ref,filename,"2000","CF",0);
    } else {
      hcbo.init(Convert.ref2Midas(ref),filename,"2000","CF",0);
    }
    hcbo.setSubSize(nc);
    hcbo.setSize(1);
    hcbo.open(DataFile.OUTPUT);
  }


  /** Performs the FFT operation on the data that is contained within the
      specified buffer. The buf object is expected to be an array of floats
      or doubles and the result is computed in place within the buf.
      @param buf buffer holding the data on which to perform the FFT
  */
  public void work (Object buf) {
    //System.out.println( "In Fft.work(buf)" );
    if (hcbi!=null) hcbi.write(Convert.o2ba(buf),0,size*4);
    if (useNative) {
      //System.out.println( "Fft.work(buf): useNative");
      if (useCuda) workPlanCU(planp,buf);
      else         workPlan(planp,buf);
    }
    else if (buf instanceof float[]) {
      //System.out.println( "Fft.work(buf): useJava");
      fft_work( (float[])buf);
    }
    else if (buf instanceof double[]) {
      //System.out.println( "Fft.work(buf): useJava");
      fft_work( (double[])buf);
    }
    else if (buf instanceof byte[]) {
      //System.out.println( "Fft.work(buf): useJava");
      // fix for BUG 1182 - TUNER;DSP produces zero values from Web Start
      // assumes byte[] is float - Fft.c (native) makes same assumption
      byte[]  bbuf = (byte[]) buf;
      float[] fbuf = new float[bbuf.length / 4];
      Convert.bb2ja(bbuf, 0, DataTypes.FLOAT, fbuf, 0, DataTypes.FLOAT, fbuf.length);
      fft_work(fbuf);
      Convert.ja2bb(fbuf, 0, DataTypes.FLOAT, bbuf, 0, DataTypes.FLOAT, fbuf.length);
    }
    if (hcbo!=null) hcbo.write(Convert.o2ba(buf),0,nc*8);
  }


  /** Perform the FFT operation on the given data.  The contents of the data
      object are cast to the buffer type and the results are inserted into
      the Data object.
      @param data the data on which to perform the FFT
  */
  public void work (Data data) {
    //System.out.println("Fft.work(data)");
    if (hcbi!=null) hcbi.write(data.buf,0,size*4);
    if (useNative) {
      //System.out.println("Fft.work(data) useNative");
      if (useCuda) workPlanCU(planp,data.buf);
      else {
        //System.out.println( "planp");
        //System.out.print( planp );
        //System.out.println( "" );

        workPlan(planp,data.buf);

      }
      float[] buf = data.castF(true);
      data.uncast(buf,true);
    }
    else {
      //System.out.println( "Fft.work(buf): useJava");
      float[] buf = data.castF(true); // double precision not supported yet
      fft_work (buf);
      data.uncast(buf,true);
    }
    if (hcbo!=null) hcbo.write(data.buf,0,nc*8);
  }

  /** Perform rotation on Data buffer based on SF or CF NeXtMidas data types
      Calls {@link #rotateSF(float[])} for SF and {@link #rotateCF(float[])} for CF
      @param data Data object containing buffer to be rotated
   */
  public void rotate (Data data) {
    float[] buf = data.castF(true);
    if (data.spa==1) rotateSF (buf);
    if (data.spa==2) rotateCF (buf);
    data.uncast(buf,true);
  }

  /** Reverse rotation on Data buffer based on SF or CF NeXtMidas data types
      Calls {@link #shiftLeftSF(float[], int)} for SF or {@link #shiftLeftCF(float[], int)} for CF
      @param data Data object containing buffer to be unrotated
      @param nrot elements will be shifted by this many elements
   */
  public void unrotate( Data data, int nrot ) {
    float[] buf = data.castF(true);
    if (data.spa==1) shiftLeftSF (buf, nrot);
    if (data.spa==2) shiftLeftCF (buf, nrot);
    data.uncast(buf,true);
  }

  /** Performs rotation on Data buffer from Data object with SF mode
      @param buf Data buffer to be rotated
   */
  public void rotateSF (float[] buf) {
    int i=0, j=0, k=size/2+1;
    float a=buf[j++];
    float b=buf[j++];
    for (;k<size;) {
      buf[i++] = buf[k];
      buf[k++] = buf[j++];
    }
    buf[i++]=a;
    buf[i++]=b;
  }

  /** Performs rotation on Data buffer from Data object with SF mode
      @param buf Data buffer to be rotated
   */
  public void rotateCF (float[] buf) {
    int i=0, j=0, k=size+2;
    float ar=buf[j++],ai=buf[j++];
    float br=buf[j++],bi=buf[j++];
    for (;k<size*2;) {
      buf[i++] = buf[k];   buf[i++] = buf[k+1];
      buf[k++] = buf[j++]; buf[k++] = buf[j++];
    }
    buf[i++]=ar; buf[i++]=ai;
    buf[i++]=br; buf[i++]=bi;
  }

  /** Shifts elements in a data buffer from a Data object with SF mode to the left
      @param buf    Data buffer to be shifted
      @param amount elements are shifted by this many elements
   */
  public void shiftLeftSF (float[] buf, int amount ) {
    int i=size-1, j=size-1, k = amount - 1;
    /*
    System.out.println( "Before SF shift");
    int temp = 4;
    for( int loopc = 0; loopc < temp; loopc++ ) {
      System.out.format("%f\n", buf[loopc]);
    }
    int i=temp-1, j=temp-1, k = amount - 1;
    */
    float a=buf[j--];
    float b=buf[j--];
    for (;k>=0;) {
      buf[i--] = buf[k];
      buf[k--] = buf[j--];
    }
    buf[i--]=a;
    buf[i--]=b;
    /*
    System.out.println( "After SF Shift.");
    for( int loopc = 0; loopc < temp; loopc++ ) {
      System.out.format("%f\n", buf[loopc]);
    }
    */
  }

  /** Shifts elements in a data buffer from a Data object with CF mode to the left
      @param buf    Data buffer to be shifted
      @param amount elements are shifted by this many elements
   */
  public void shiftLeftCF (float[] buf, int amount) {
    int i=size*2-1, j=size*2-1, k=amount*2-1;
    /*int temp = 4;
    int i=temp*2-1, j=temp*2-1, k=amount*2-1;
    System.out.println( "BeforeCFShift");
    for( int loopc = 0; loopc < temp*2; loopc++ ) {
      System.out.format("%f\n", buf[loopc]);
    }
    */
    float ar=buf[j--],ai=buf[j--];
    float br=buf[j--],bi=buf[j--];
    for (;k>=0;) {
      buf[i--] = buf[k];   buf[i--] = buf[k-1];
      buf[k--] = buf[j--]; buf[k--] = buf[j--];
    }
    buf[i--]=ar; buf[i--]=ai;
    buf[i--]=br; buf[i--]=bi;
    /*
    System.out.println( "After CF SHift");
    for( int loopc = 0; loopc < temp*2; loopc++ ) {
      System.out.format("%f\n", buf[loopc]);
    }
    */
  }

  /** close debug DataFiles and free CPU resources ?? */
  public void free() {
    if (hcbi!=null) hcbi.close();
    if (hcbo!=null) hcbo.close();
    if (useNative) {
      if (planp != 0L) { planp = useCuda? freePlanCU(planp) : freePlan(planp); }
    }
  }

  /** Return the number of inputs that this operation operates on. */
  public int getInputs() { return 1; }


  /** Return the number of outputs that this operation returns. */
  public int getOutputs() { return 1; }


  /*
   * JMM 3/12/2008 - Replaced Java FFT code with ported C code
   * =========================================================
   *
   * Apart from changes to eliminate C pointers and to improve the efficiency
   * of array indexing without pointers, the code closely follows the
   * design and structure of the C equivalent.
   *
   * SEE comments in libm/libnmfft.c for authors, references, etc.
   */


/*
-----------------------------------------------------------------------
  FUNCTION:
    init_internal()

  SYNOPSIS:
    void init_internal ()

  ARGUMENTS:
    None

  PURPOSE:
    Creates and validates an FFT plan for subsequent execution
    by the function fft_work().

  REVISIONS:
    05/05/00 	rdh 	baseline
-----------------------------------------------------------------------
*/
    private int     planFlags;              /* Copy of calling flags        */
    private int     planValidflag;          /* Is plan valid?               */
    private int     planScale;              /* Scale FFT for correctness    */
    private int     planSize;               /* Complex FFT size             */
    private int     planType;               /* FFT type (real/complex)      */
    private int     planDirection;          /* Forward/Inverse FFT          */
    private int     planPacking;            /* Type of packing/unpack       */
    private int     planRadixevenodd;       /* Even/odd number radix passes */
    private int     planRadixgeneric;       /* Generic Radix Pass ID        */
    private int     planRadixcount;         /* Total known radix passes     */
    private int[]   planRadixpassid;        /* Specific radix pass ID's     */
    private int[]   planRadixpasscnt;       /* Specific radix pass cnts     */
    private float[] planRdxgen_t;           /* Generic Radix t-vector       */
    private float[] planRdxgen_w;           /* Generic radix w-matrix       */
    private float[] planTwidtable;          /* Radix pass twiddle table     */
    private float[] planWorkbuf;            /* Working buffer               */


    private long init_internal() {
 /* Local variables */
    int ii, jj;
    int nsize, lclflags;
    int mradixid[]  = new int[FFT_RADIX_MAX+1];
    int mradixcnt[] = new int[FFT_RADIX_MAX+1];
    //System.out.println( "init_internal.");
 /* Initialize plan */
    planFlags        = FFT_FLAGS_NULL;
    planValidflag    = FFT_FLAGS_NULL;
    planScale        = FFT_FLAGS_NULL;
    planSize         = this.size;
    planType         = FFT_FLAGS_COMPLEX;
    planDirection    = FFT_FLAGS_FORWARD;
    planPacking      = FFT_FLAGS_PACKED;
    planRadixevenodd = 0;
    planRadixgeneric = 0;
    planRadixcount   = 0;
    planRdxgen_t     = null;
    planRdxgen_w     = null;
    planTwidtable    = null;
    planWorkbuf      = null;
    planRadixpassid  = new int[FFT_RADIX_MAX+1];
    planRadixpasscnt = new int[FFT_RADIX_MAX+1];

    for (ii=0; ii<(FFT_RADIX_MAX+1); ii++) {
      planRadixpassid[ii]  = 0;
      planRadixpasscnt[ii] = 0;
    }

 /* Create plan based on flags */
    planFlags = this.fflags;
    lclflags  = this.fflags;

    if ((lclflags & FFT_FLAGS_REAL) == FFT_FLAGS_REAL)
      planType = FFT_FLAGS_REAL;

    if ((lclflags & FFT_FLAGS_COMPLEX) == FFT_FLAGS_COMPLEX)
      planType = FFT_FLAGS_COMPLEX;

    if ((lclflags & FFT_FLAGS_FORWARD) == FFT_FLAGS_FORWARD)
      planDirection = FFT_FLAGS_FORWARD;

    if ((lclflags & FFT_FLAGS_INVERSE) == FFT_FLAGS_INVERSE)
      planDirection = FFT_FLAGS_INVERSE;
    //System.out.format( "init_internal plan direction: %d\n", planDirection );
    if ((lclflags & FFT_FLAGS_PACKED) == FFT_FLAGS_PACKED)
      planPacking = FFT_FLAGS_PACKED;

    if ((lclflags & FFT_FLAGS_UNPACKED) == FFT_FLAGS_UNPACKED)
      planPacking = FFT_FLAGS_UNPACKED;

    if ((lclflags & FFT_FLAGS_NONYQUIST) == FFT_FLAGS_NONYQUIST)
      planPacking = FFT_FLAGS_NONYQUIST;

    if ((lclflags & FFT_FLAGS_SCALE) == FFT_FLAGS_SCALE)
      planScale = FFT_FLAGS_SCALE;

 /* Check for invalid combinations of flags */
    if (planType == FFT_FLAGS_COMPLEX) planPacking = FFT_FLAGS_PACKED;


 /* Attempt to factor the plan into available radix routines */
    nsize = (this.size > 0) ? (this.size) : 0;
    if (planType == FFT_FLAGS_REAL) {
      if (fft_checkradix(nsize,FFT_FLAGS_REAL) >= 0) {
        nsize /= 2;
        planSize = nsize;
        fft_genradix(nsize);
        planValidflag = FFT_FLAGS_VALIDPLAN;
      }
      else {
        nsize = 0;
        planSize = nsize;
        planValidflag = FFT_FLAGS_NULL;
      }
    }
    else {
      if (fft_checkradix(nsize,FFT_FLAGS_COMPLEX) >= 0) {
        nsize = this.size;
        planSize = nsize;
        fft_genradix(nsize);
        planValidflag = FFT_FLAGS_VALIDPLAN;
      }
      else {
        nsize = 0;
        planSize = nsize;
        planValidflag = FFT_FLAGS_NULL;
      }
    }

    if (planValidflag == FFT_FLAGS_VALIDPLAN) {
      for (ii=0; ii<(FFT_RADIX_MAX+1); ii++){
        mradixid[ii]  = planRadixpassid[ii];
	mradixcnt[ii] = planRadixpasscnt[ii];
      }
      for (ii=0; ii<(FFT_RADIX_MAX+1); ii++){
        planRadixpassid[ii]  = 0;
	planRadixpasscnt[ii] = 0;
      }
      jj = 0;
      planRadixcount = 0;
      for (ii=0; ii<(FFT_RADIX_MAX+1); ii++){
        if (mradixcnt[ii] != 0) {
	  planRadixcount       = planRadixcount + 1;
          planRadixpassid[jj]  = mradixid[ii];
	  planRadixpasscnt[jj] = mradixcnt[ii];
          planRadixevenodd     += mradixcnt[ii];
	  jj ++;
	}
      }
      if (planRadixgeneric != 0) planRadixevenodd += 1;
      planRadixevenodd = intmod(planRadixevenodd,2);
    }
    else {
      planRadixgeneric = 0;
      planRadixcount   = 0;
      for (ii=0; ii<(FFT_RADIX_MAX+1); ii++){
        planRadixpassid[ii]  = 0;
        planRadixpasscnt[ii] = 0;
      }
    }

 /* Allocate twiddle factor table and working buffer */
    if (planValidflag == FFT_FLAGS_VALIDPLAN) {
      nsize = (planType == FFT_FLAGS_COMPLEX) ? planSize : 2*(planSize);
      planTwidtable = new float[nsize*2 + 8];
      planWorkbuf   = new float[nsize*2 + 8];
      fft_gen_twiddle(planTwidtable,nsize,planType);
    }

 /* Allocate DFT matrix and t-vector buffers if a generic pass is required */
    if ((planValidflag == FFT_FLAGS_VALIDPLAN)&&(planRadixgeneric > 0)) {
      nsize = planRadixgeneric;
      planRdxgen_t = new float[nsize*2];
      planRdxgen_w = new float[nsize*nsize*2];
      fft_generic_matrix(nsize,planRdxgen_w);
    }

    return (planValidflag == FFT_FLAGS_VALIDPLAN)? 1:0;
}

/*
-----------------------------------------------------------------------
  FUNCTION:
    fft_work()

  SYNOPSIS:
    void fft_work(float[] a)

  ARGUMENTS:
    float[] a   --- input/output vector of data to perform FFT/IFFT on

  PURPOSE:
    Executes an FFT plan to perform either a real or complex FFT on the
    specified data buffer

  REVISIONS:
    05/05/00 	rdh	baseline
    09/12/01 	rdh	modified to use "radixevenodd" to eliminate "memcpy"

  NOTE(JMM): Use of "radixevenodd" implies that sometimes the initial pass will
             be performed in-memory, whereas the comments associated with the
             butterfly code below indicate not-in-memory.  Cursory analysis of
             some of the code suggest that the butterflies might be OK as
             in-memory passes, but I hereby flag this as a concern
-----------------------------------------------------------------------
*/

void fft_work(float[] a)
{
  //System.out.println( "fft_work()");

/* Local variables */
    int      ii, jj;
    int      partProd;
    int      iradix;
    int      iradixcnt;
    boolean  srcIsInput;
    boolean  destIsInput;

 /* Check input size */
    if (planSize < 2) return;

 /* Determine initial source and destination */
    srcIsInput  = true;
    destIsInput = (planRadixevenodd != 0);  // if odd # passes,  first pass in-place

    //System.out.format( "planDirection: %d\n", planDirection );
    //System.out.format( "FFTINVERSE: %d\n", FFT_FLAGS_INVERSE );

 /* Pack the data if forward real FFT */
    if ((planType == FFT_FLAGS_REAL) && (planDirection == FFT_FLAGS_INVERSE))
        fft_pack(a, planTwidtable, planSize, planDirection, planPacking);

 /* Execute the Radix-M passes */
    partProd = planSize;
    if (planRadixgeneric != 0) {
        partProd /= planRadixgeneric;
        radixpass_generic(srcIsInput  ? a : planWorkbuf,
                          destIsInput ? a : planWorkbuf,
                          planTwidtable, planSize, partProd, planDirection,
			  planRadixgeneric, planRdxgen_t, planRdxgen_w);
        if (destIsInput) {
            srcIsInput  = true;
            destIsInput = false;
        } else {
            srcIsInput  = false;
            destIsInput = true;
        }
    }

    for (ii=(planRadixcount-1); ii>=0; ii--) {
        iradix    = (planRadixpassid[ii] > 0) ? planRadixpassid[ii] : 1;
        iradixcnt = planRadixpasscnt[ii];
        for (jj=iradixcnt; jj > 0; jj--) {
            partProd /= iradix;

            switch (iradix) {
                case 2:
                  radixpass_2(srcIsInput  ? a : planWorkbuf,
                              destIsInput ? a : planWorkbuf,
                              planTwidtable, planSize, partProd, planDirection);
                  /* swap (or adjust) source and destination */
                  if (destIsInput) { // previous pass was input or work -> input
                      srcIsInput  = true;   // next pass is input -> work
                      destIsInput = false;
                  } else {          // previous pass was input -> work
                      srcIsInput  = false;  // next pass is work -> input
                      destIsInput = true;
                  }
                break;
            case 3:
                  radixpass_3(srcIsInput  ? a : planWorkbuf,
                              destIsInput ? a : planWorkbuf,
                              planTwidtable, planSize, partProd, planDirection);
                  /* swap (or adjust) source and destination */
                  if (destIsInput) { // previous pass was input or work -> input
                      srcIsInput  = true;   // next pass is input -> work
                      destIsInput = false;
                  } else {          // previous pass was input -> work
                      srcIsInput  = false;  // next pass is work -> input
                      destIsInput = true;
                  }
                break;
            case 4:
                  radixpass_4(srcIsInput  ? a : planWorkbuf,
                              destIsInput ? a : planWorkbuf,
                              planTwidtable, planSize, partProd, planDirection);
                  /* swap (or adjust) source and destination */
                  if (destIsInput) { // previous pass was input or work -> input
                      srcIsInput  = true;   // next pass is input -> work
                      destIsInput = false;
                  } else {          // previous pass was input -> work
                      srcIsInput  = false;  // next pass is work -> input
                      destIsInput = true;
                  }
                break;
            case 5:
                  radixpass_5(srcIsInput  ? a : planWorkbuf,
                              destIsInput ? a : planWorkbuf,
                              planTwidtable, planSize, partProd, planDirection);
                  /* swap (or adjust) source and destination */
                  if (destIsInput) { // previous pass was input or work -> input
                      srcIsInput  = true;   // next pass is input -> work
                      destIsInput = false;
                  } else {          // previous pass was input -> work
                      srcIsInput  = false;  // next pass is work -> input
                      destIsInput = true;
                  }
                break;
            case 8:
                  radixpass_8(srcIsInput  ? a : planWorkbuf,
                              destIsInput ? a : planWorkbuf,
                              planTwidtable, planSize, partProd, planDirection);
                  /* swap (or adjust) source and destination */
                  if (destIsInput) { // previous pass was input or work -> input
                      srcIsInput  = true;   // next pass is input -> work
                      destIsInput = false;
                  } else {          // previous pass was input -> work
                      srcIsInput  = false;  // next pass is work -> input
                      destIsInput = true;
                  }
                break;
            case 16:
                  radixpass_16(srcIsInput  ? a : planWorkbuf,
                               destIsInput ? a : planWorkbuf,
                               planTwidtable, planSize, partProd, planDirection);
                  /* swap (or adjust) source and destination */
                  if (destIsInput) { // previous pass was input or work -> input
                      srcIsInput  = true;   // next pass is input -> work
                      destIsInput = false;
                  } else {          // previous pass was input -> work
                      srcIsInput  = false;  // next pass is work -> input
                      destIsInput = true;
                  }
                break;
            case 32:
                  radixpass_32(srcIsInput  ? a : planWorkbuf,
                               destIsInput ? a : planWorkbuf,
                               planTwidtable, planSize, partProd, planDirection);
                  /* swap (or adjust) source and destination */
                  if (destIsInput) { // previous pass was input or work -> input
                      srcIsInput  = true;   // next pass is input -> work
                      destIsInput = false;
                  } else {          // previous pass was input -> work
                      srcIsInput  = false;  // next pass is work -> input
                      destIsInput = true;
                  }
                break;
            default:        // nothing to do here...
            }
        }
    }

 /* Unpack the data if inverse real FFT */
    if ((planType == FFT_FLAGS_REAL) && (planDirection == FFT_FLAGS_FORWARD))
        fft_pack(a, planTwidtable, planSize, planDirection, planPacking);

 /* Perform any required operations on the output data buffer */
    if (planScale == FFT_FLAGS_SCALE)
        fft_func_scale(a, planSize, planDirection, planType, planPacking);

    return;
}


/*
-----------------------------------------------------------------------

  UTILITIES:
    intmod()    --- integer modulus function

  REVISIONS:

-----------------------------------------------------------------------
*/

int intmod(int iarg, int idiv)
{
    return ((idiv != 0) ? (iarg % idiv) : (-1));
}

/*
-----------------------------------------------------------------------

  FUNCTION:
    fft_genradix()

  SYNOPSIS:
    void fft_genradix(int)

  ARGUMENTS:
    int nsize --- FFT size to factor

  PURPOSE:
    Computes the Radix pass factorization of a complex FFT size
    with biases for RISC/non-RISC platforms. Any residual is assigned
    to a single-pass generic radix butterfly.

  REVISIONS:
    04/25/00 	rdh	added conditional compile for RISC/non-RISC
    05/01/00 	rdh	changed calling to use FFT_Plan for generic
                          radix support
    08/17/01 	rdh	modified to use "profiles" for various machines

-----------------------------------------------------------------------
*/

void fft_genradix(int nsize)
{
 /* Local variables */
    int ii, ip;

  /* Initialize results */
     nsize = (planSize > 0) ? (planSize) : 0;
     planRadixgeneric = 0;
     for (ii=0; ii<(FFT_RADIX_MAX+1); ii++) {
        planRadixpassid[ii]  = ii;
        planRadixpasscnt[ii] = 0;
     }

  /* Factor the FFT size using architecture dependencies */
    for (ii=FFT_RADIX_MAX; ii>=2; ii--) {
        for (ip=0; ip<7; ip++) {
            /* Check for valid radix size, max FFT size, min FFT size */
            if ((ii     == radix_decomp_profile[ip][0]) &&
                (nsize  >  radix_decomp_profile[ip][1]) &&
                (nsize  <  radix_decomp_profile[ip][2])) {
           /* Check for completed factorization and max radixpass count */
                while( (nsize>1) &&
                       (intmod(nsize,ii) == 0) &&
                       (planRadixpasscnt[ii] < radix_decomp_profile[ip][3]) ) {
                    planRadixpasscnt[ii] = planRadixpasscnt[ii]+1;
                    nsize /= ii;
                }
            }
        }
     }

  /* Any leftover must be processed by a radix_generic pass */
     if (nsize != 1) {
       planRadixgeneric = nsize;
       nsize = 1;
     }

  /* Determine return status */
     if(nsize != 1) {
        planRadixgeneric = 0;
        for (ii=0; ii<(FFT_RADIX_MAX+1); ii++) {
           planRadixpassid[ii]  = ii;
           planRadixpasscnt[ii] = 0;
        }
     }

     return;
}


/*
-----------------------------------------------------------------------

  FUNCTION:
    fft_checkradix()

  SYNOPSIS:
    int fft_checkradix(int n, int flags)

  ARGUMENTS:
    int n     --- FFT size to factor
    int flags --- FFT parameter flags (real/complex/etc.)

  RETURN:
    (int)  1 --- FFT size/type can be efficiently computed (factored)
    (int)  0 --- FFT size/type can be computed inefficiently
    (int) -1 --- requested FFT size/type cannot be computed by
                       this library

  PURPOSE:
    Can be called prior to doing a call to nm_fft() to determine
    whether a desired FFT size can be efficiently computed by the
    available radix passes.

  REVISIONS:
    02/15/01 	rdh	baseline

-----------------------------------------------------------------------
*/

int fft_checkradix(int n, int fftFlags)
{
  int lclflags;
  int nfft;
  int irtn;

  /* Initialize the local plan fields */
     lclflags = fftFlags;
     planRadixgeneric = 0;

  /* Check for even number of points in Real FFT size */
     nfft = n;
     irtn = 1;
     if ((lclflags & FFT_FLAGS_REAL) == FFT_FLAGS_REAL)
       nfft = (intmod(n,2) == 0) ? (n/2) : (0);

  /* Factor the FFT size into available radix passes */
     if (nfft > 0)
       fft_genradix(nfft);
     else
       irtn = -1;

  /* Check the return status */
     if (planRadixgeneric > 0)
       irtn = (planRadixgeneric > 101) ? (-1) : (0);

  /* Stupid check */
     if (n < 1) irtn = -1;

  return (irtn);
}


/*
-----------------------------------------------------------------------
  FUNCTION:
    fft_gen_twiddle()

  SYNOPSIS:
    void fft_gen_twiddle(float[] t, int n, int rcflag)

  ARGUMENTS:
    float[] twids  --- complex output vector of twiddle factors
    int     n      --- size of complex input vector
    int     rcflag --- real/complex FFT type flag

  PURPOSE:
    Generate the twiddle factor table for use by the
    RADIX-M and packing functions.

  REVISIONS:
    04/20/00 	rdh	baseline conversion from FPS routine
    04/21/00 	rdh	changed phase argument to double for precision
-----------------------------------------------------------------------
*/

void fft_gen_twiddle(float[] twids, int n, int rcflag)
{
/* Local variables */
    int ii, nfft, nfft2;
    double radphas, rnfft;

 /* Initialize FFT size */
    if (n < 1) return;
    nfft  = n;
    nfft2 = (rcflag == FFT_FLAGS_REAL) ? (nfft/2) : 0;
    rnfft = 1.0/(double)nfft;

 /* Create twiddle table for complex and real FFT */
    for(ii=nfft-1; ii>=nfft2; ii--) {
        radphas = twopi * ((double)ii) * rnfft;
        twids[ii*2  ] = (float)Math.cos(radphas);
        twids[ii*2+1] = (float)Math.sin(radphas);
    }

    if (rcflag == FFT_FLAGS_REAL) {                 /* Real FFT    */
        for(ii=nfft2-1; ii>=0; ii--) {
            radphas = 2.0 * twopi * ((double)ii) * rnfft;
            twids[ii*2  ] = (float)Math.cos(radphas);
            twids[ii*2+1] = (float)Math.sin(radphas);
        }
    }

    return;
}


/*
-----------------------------------------------------------------------
  FUNCTION:
    fft_generic_matrix()

  SYNOPSIS:
    void fft_generic_matrix(int size, float[] matrix)

  ARGUMENTS:
    int     size   --- size of DFT matrix to create
    float[] matrix --- complex DFT matrix elements

  PURPOSE:
    Creates the DFT kernel matrix for radixpass_generic() to use.
    This matrix is required when no available fast radixpass can
    be found by the planner factorization, fft_genradix().

  REVISIONS:
    05/01/00 	rdh	baseline
-----------------------------------------------------------------------
*/

void fft_generic_matrix(int size, float[] matrix)
{
/* Local variables */
    int    irow,icol,idx;
    double dn, dtwid, dftarg;

 /* Create the DFT matrix */
    dn    = (double) size;
    dtwid = (size > 0) ? (twopi/dn) : 0;
    for (irow=0; irow<size; irow++) {
      for (icol=0; icol<size; icol++) {
        dftarg = dtwid * intmod(irow*icol, size);
	idx    = irow*size + icol;
	matrix[idx*2  ] =  (float)Math.cos(dftarg);
	matrix[idx*2+1] = -1.0F*(float)Math.sin(dftarg);
      }
    }

    return;
}


/*
-----------------------------------------------------------------------
  FUNCTION:
    radixpass_M()

  SYNOPSIS:
    void radixpass_M(const float *a, float *c, const float *t,
                     int n, int la, int dirflag)

  ARGUMENTS:
    float *a       --- complex input vector treated as real array
    float *c       --- complex output vector treated as real array
    float *t       --- complex twiddle vector treated as real array
    int  n        --- size of complex input/output/twiddle vectors
    int  la       --- partial product of remaining radix passes
    int  dirflag  --- FFT direction (forward/inverse)

  PURPOSE:
    To perform a forward/inverse not-in-place Radix-M complex
    butterfly pass for use in FFT algorithms.

  DESCRIPTION:
       These routines perform a single forward/inverse, not-in-place
       Radix-M FFT pass on the complex input vector A.  Forward
       (negative exponent version) Radix-M complex butterflies are
       performed on sets of M input points using decimation in time.
       The algorithm is self-sorting and does not require bit reversing.
       The complex exponential twiddle factor vector used by the routines
       should have been generated by a call to "fft_gen_twiddle". The
       The LA calling parameter is the partial product of the radices
       remaining to be completed after the current pass.

  REVISIONS:
    04/20/00 	rdh	baseline conversion from FPS routine
    04/21/00 	rdh	changed phase argument to double for precision
    01/04/01    rdh	massive overhaul to use pointers and Wang's
                          kernel operations
-----------------------------------------------------------------------
*/

void radixpass_2(float[] in, float[] out, float[] twids,
                 int size, int la, int dirflag)
{
/* Constants */
    final int RADIXSIZE = 2;

/* Local variables */
    int   kk, ll, mm;
    int   istep, ispan, ospan;
    float o00_re;
    float o00_im;
    float xreg_re, xreg_im;
    float t00_re, t01_re;
    float t00_im, t01_im;

 /* Verify parameters */
    if (size < RADIXSIZE || la < 1) return;

 /* Initialize pointers */
    ospan = 2*size/RADIXSIZE;
    ispan = la;
    mm    = ospan/ispan;

/* Process the data */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[kk*ispan];
                o00_im = twids[kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) {     // The fundamental forward pass RADIX 2 kernel
                   t00_re  = in[ispan*(istep+0)+ll];
                   t00_im  = in[ispan*(istep+0)+ll+1];
                   xreg_re = in[ispan*(istep+2)+ll];
                   xreg_im = in[ispan*(istep+2)+ll+1];
                   t01_re  = o00_re*xreg_re + o00_im*xreg_im;
                   t01_im  = o00_re*xreg_im - o00_im*xreg_re;

                   out[kk*ispan+ll]         = t00_re + t01_re;
                   out[kk*ispan+ll+1]       = t00_im + t01_im;
                   out[kk*ispan+ospan+ll  ] = t00_re - t01_re;
                   out[kk*ispan+ospan+ll+1] = t00_im - t01_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) { // The fundamental forward pass RADIX 2 kernel
               t00_re = in[ll];
               t00_im = in[ll+1];
               t01_re = in[ispan*2+ll];
               t01_im = in[ispan*2+ll+1];

               out[ll]         = t00_re + t01_re;
               out[ll+1]       = t00_im + t01_im;
               out[ospan+ll]   = t00_re - t01_re;
               out[ospan+ll+1] = t00_im - t01_im;
            }
	}
	break;

      default:                                         /* Inverse Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[kk*ispan];
                o00_im = twids[kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 2 kernel */
                   t00_re  = in[ispan*(istep+0)+ll];
                   t00_im  = in[ispan*(istep+0)+ll+1];
                   xreg_re = in[ispan*(istep+2)+ll];
                   xreg_im = in[ispan*(istep+2)+ll+1];
                   t01_re  = o00_re*xreg_re - o00_im*xreg_im;
                   t01_im  = o00_re*xreg_im + o00_im*xreg_re;

                   out[kk*ispan+ll]         = t00_re + t01_re;
                   out[kk*ispan+ll+1]       = t00_im + t01_im;
                   out[kk*ispan+ospan+ll  ] = t00_re - t01_re;
                   out[kk*ispan+ospan+ll+1] = t00_im - t01_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 2 kernel */
               t00_re = in[ll];
               t00_im = in[ll+1];
               t01_re = in[ispan*2+ll];
               t01_im = in[ispan*2+ll+1];

               out[ll]         = t00_re + t01_re;
               out[ll+1]       = t00_im + t01_im;
               out[ospan+ll]   = t00_re - t01_re;
               out[ospan+ll+1] = t00_im - t01_im;
            }
	}
	break;
    }

    return;
}


/*-----------------------------------------------------------------------*/

void radixpass_3(float[] in, float[] out,  float[] twids,
                 int size, int la, int dirflag)
{
/* Constants */
    final int   RADIXSIZE = 3;
    final float s1        = -1.500000000000000000000000000000000000000000000F;
    final float s2        =  0.866025403784438646763723170752936183471402627F;

/* Local variables */
    int   kk, ll, mm;
    int   istep, ispan, ospan;
    float o00_re, o01_re;
    float o00_im, o01_im;
    float t01_re, t02_re;
    float t01_im, t02_im;
    float xreg_re, xreg_im;
    float x00a_re, x00a_im, x00b_re, x00b_im;
    float x01a_re, x01a_im, x01b_re, x01b_im;
    float x02a_re, x02a_im;

/* Verify parameters */
    if (size < RADIXSIZE || la < 1) return;

 /* Initialize constants */
    ospan = 2*size/RADIXSIZE;
    ispan = la;
    mm    = ospan/ispan;

 /* Process the data */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        if (ispan != ospan/2) {
          for (kk=0; kk<mm; kk+=2) {
            o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
            o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
            istep  = kk*RADIXSIZE;

            for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental forward pass RADIX 3 kernel */
                xreg_re = in[ispan*(istep+2)+ll];
                xreg_im = in[ispan*(istep+2)+ll+1];
                t01_re  = o00_re*xreg_re + o00_im*xreg_im;
                t01_im  = o00_re*xreg_im - o00_im*xreg_re;
                xreg_re = in[ispan*(istep+4)+ll];
                xreg_im = in[ispan*(istep+4)+ll+1];
                t02_re  = o01_re*xreg_re + o01_im*xreg_im;
                t02_im  = o01_re*xreg_im - o01_im*xreg_re;
                x01a_re = t02_re + t01_re;
                x02a_re = t02_re - t01_re;
                x02a_re *= s2;
                x01a_im = t01_im + t02_im;
                x02a_im = t01_im - t02_im;
                x02a_im *= s2;
                x00a_re = in[ispan*(istep+0)+ll];
                x00b_re = x00a_re + x01a_re;
                out[kk*ispan+ll] = x00b_re;
                x00a_im = in[ispan*(istep+0)+ll+1];
                x00b_im = x00a_im + x01a_im;
                out[kk*ispan+ll+1] = x00b_im;
                x01b_im = x00b_im + s1*x01a_im;
                x01b_re = x00b_re + s1*x01a_re;
                out[kk*ispan+ospan+ll  ]   = x01b_re + x02a_im;
                out[kk*ispan+ospan+ll+1]   = x01b_im + x02a_re;
                out[kk*ispan+ospan*2+ll  ] = x01b_re - x02a_im;
                out[kk*ispan+ospan*2+ll+1] = x01b_im - x02a_re;
            }
          }
        }
        else {
          for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental forward pass RADIX 3 kernel */
                t01_re  = in[ispan*2+ll];
                t01_im  = in[ispan*2+ll+1];
                t02_re  = in[ispan*4+ll];
                t02_im  = in[ispan*4+ll+1];
                x01a_re = t02_re + t01_re;
                x02a_re = t02_re - t01_re;
                x02a_re *= s2;
                x01a_im = t01_im + t02_im;
                x02a_im = t01_im - t02_im;
                x02a_im *= s2;
                x00a_re = in[ll];
                x00b_re = x00a_re + x01a_re;
                out[ll] = x00b_re;
                x00a_im = in[ll+1];
                x00b_im = x00a_im + x01a_im;
                out[ll+1] = x00b_im;
                x01b_im = x00b_im + s1*x01a_im;
                x01b_re = x00b_re + s1*x01a_re;
                out[ospan+ll]     = x01b_re + x02a_im;
                out[ospan+ll+1]   = x01b_im + x02a_re;
                out[ospan*2+ll]   = x01b_re - x02a_im;
                out[ospan*2+ll+1] = x01b_im - x02a_re;
          }
        }
        break;

      default:                                         /* Inverse Pass */
        if (ispan != ospan/2) {
          for (kk=0; kk<mm; kk+=2) {
            o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
            o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
            istep  = kk*RADIXSIZE;
            for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 3 kernel */
                xreg_re = in[ispan*(istep+2)+ll];
                xreg_im = in[ispan*(istep+2)+ll+1];
                t01_re  = o00_re*xreg_re - o00_im*xreg_im;
                t01_im  = o00_re*xreg_im + o00_im*xreg_re;
                xreg_re = in[ispan*(istep+4)+ll];
                xreg_im = in[ispan*(istep+4)+ll+1];
                t02_re  = o01_re*xreg_re - o01_im*xreg_im;
                t02_im  = o01_re*xreg_im + o01_im*xreg_re;
                x01a_re = t02_re + t01_re;
                x02a_re = t02_re - t01_re;
                x02a_re *= s2;
                x01a_im = t01_im + t02_im;
                x02a_im = t01_im - t02_im;
                x02a_im *= s2;
                x00a_re = in[ispan*(istep+0)+ll];
                x00b_re = x00a_re + x01a_re;
                out[kk*ispan+ll] = x00b_re;
                x00a_im = in[ispan*(istep+0)+ll+1];
                x00b_im = x00a_im + x01a_im;
                out[kk*ispan+ll+1] = x00b_im;
                x01b_im = x00b_im + s1*x01a_im;
                x01b_re = x00b_re + s1*x01a_re;
                out[kk*ispan+ospan+ll]     = x01b_re - x02a_im;
                out[kk*ispan+ospan+ll+1]   = x01b_im - x02a_re;
                out[kk*ispan+2*ospan+ll]   = x01b_re + x02a_im;
                out[kk*ispan+2*ospan+ll+1] = x01b_im + x02a_re;
            }
          }
        }
        else {
          for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 3 kernel */
                t01_re  = in[2*ispan+ll];
                t01_im  = in[2*ispan+ll+1];
                t02_re  = in[4*ispan+ll];
                t02_im  = in[4*ispan+ll+1];
                x01a_re = t02_re + t01_re;
                x02a_re = t02_re - t01_re;
                x02a_re *= s2;
                x01a_im = t01_im + t02_im;
                x02a_im = t01_im - t02_im;
                x02a_im *= s2;
                x00a_re = in[ll];
                x00b_re = x00a_re + x01a_re;
                out[ll] = x00b_re;
                x00a_im = in[ll+1];
                x00b_im = x00a_im + x01a_im;
                out[ll+1] = x00b_im;
                x01b_im = x00b_im + s1*x01a_im;
                x01b_re = x00b_re + s1*x01a_re;
                out[ospan+ll]     = x01b_re - x02a_im;
                out[ospan+ll+1]   = x01b_im - x02a_re;
                out[ospan*2+ll]   = x01b_re + x02a_im;
                out[ospan*2+ll+1] = x01b_im + x02a_re;
          }
        }
        break;
    }

    return;
}






/*-----------------------------------------------------------------------*/

void radixpass_4(float[] in, float[] out, float[] twids,
                 int size, int la, int dirflag)
{
/* Constants */
    final int RADIXSIZE = 4;

/* Local variables */
    int   kk, ll, mm;
    int   istep, ispan, ospan;
    float o00_re, o01_re, o02_re;
    float o00_im, o01_im, o02_im;
    float t00_re, t01_re, t02_re, t03_re;
    float t00_im, t01_im, t02_im, t03_im;
    float xreg_re, xreg_im;
    float x00a_re, x00a_im;
    float x01a_re, x01a_im;
    float x02a_re, x02a_im;
    float x03a_re, x03a_im;

 /* Verify parameters */
    if (size < RADIXSIZE || la < 1) return;

 /* Initialize pointers */
    ospan = 2*size/RADIXSIZE;
    ispan = la;
    mm    = ospan/ispan;

 /* Process the data */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
                o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];  o02_im = twids[3*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re  = in[ispan*(istep+0)+ll];
                   t00_im  = in[ispan*(istep+0)+ll+1];
                   xreg_re = in[ispan*(istep+2)+ll];
                   xreg_im = in[ispan*(istep+2)+ll+1];
                   t01_re  = o00_re*xreg_re + o00_im*xreg_im;
                   t01_im  = o00_re*xreg_im - o00_im*xreg_re;
                   xreg_re = in[ispan*(istep+4)+ll];
                   xreg_im = in[ispan*(istep+4)+ll+1];
                   t02_re  = o01_re*xreg_re + o01_im*xreg_im;
                   t02_im  = o01_re*xreg_im - o01_im*xreg_re;
                   xreg_re = in[ispan*(istep+6)+ll];
                   xreg_im = in[ispan*(istep+6)+ll+1];
                   t03_re  = o02_re*xreg_re + o02_im*xreg_im;
                   t03_im  = o02_re*xreg_im - o02_im*xreg_re;

                   x00a_re = t00_re + t02_re;
                   x02a_re = t00_re - t02_re;
                   x00a_im = t00_im + t02_im;
                   x02a_im = t00_im - t02_im;
                   x01a_re = t01_re + t03_re;
                   x03a_re = t01_re - t03_re;
                   x01a_im = t01_im + t03_im;
                   x03a_im = t01_im - t03_im;

                   out[kk*ispan+ll]           = x00a_re + x01a_re;
                   out[kk*ispan+ll+1]         = x00a_im + x01a_im;
                   out[kk*ispan+ospan+ll]     = x02a_re + x03a_im;
                   out[kk*ispan+ospan+ll+1]   = x02a_im - x03a_re;
                   out[kk*ispan+2*ospan+ll]   = x00a_re - x01a_re;
                   out[kk*ispan+2*ospan+ll+1] = x00a_im - x01a_im;
                   out[kk*ispan+3*ospan+ll]   = x02a_re - x03a_im;
                   out[kk*ispan+3*ospan+ll+1] = x02a_im + x03a_re;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) {
               t00_re  = in[ll];
               t00_im  = in[ll+1];
               t01_re  = in[2*ispan+ll];
               t01_im  = in[2*ispan+ll+1];
               t02_re  = in[4*ispan+ll];
               t02_im  = in[4*ispan+ll+1];
               t03_re  = in[6*ispan+ll];
               t03_im  = in[6*ispan+ll+1];

               x00a_re = t00_re + t02_re;
               x02a_re = t00_re - t02_re;
               x00a_im = t00_im + t02_im;
               x02a_im = t00_im - t02_im;
               x01a_re = t01_re + t03_re;
               x03a_re = t01_re - t03_re;
               x01a_im = t01_im + t03_im;
               x03a_im = t01_im - t03_im;

               out[ll]           = x00a_re + x01a_re;
               out[ll+1]         = x00a_im + x01a_im;
               out[ospan+ll]     = x02a_re + x03a_im;
               out[ospan+ll+1]   = x02a_im - x03a_re;
               out[2*ospan+ll]   = x00a_re - x01a_re;
               out[2*ospan+ll+1] = x00a_im - x01a_im;
               out[3*ospan+ll]   = x02a_re - x03a_im;
               out[3*ospan+ll+1] = x02a_im + x03a_re;
            }
	}
    	break;

      default:                                         /* Inverse Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
                o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];  o02_im = twids[3*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re  = in[ispan*(istep+0)+ll];
                   t00_im  = in[ispan*(istep+0)+ll+1];
                   xreg_re = in[ispan*(istep+2)+ll];
                   xreg_im = in[ispan*(istep+2)+ll+1];
                   t01_re  = o00_re*xreg_re - o00_im*xreg_im;
                   t01_im  = o00_re*xreg_im + o00_im*xreg_re;
                   xreg_re = in[ispan*(istep+4)+ll];
                   xreg_im = in[ispan*(istep+4)+ll+1];
                   t02_re  = o01_re*xreg_re - o01_im*xreg_im;
                   t02_im  = o01_re*xreg_im + o01_im*xreg_re;
                   xreg_re = in[ispan*(istep+6)+ll];
                   xreg_im = in[ispan*(istep+6)+ll+1];
                   t03_re  = o02_re*xreg_re - o02_im*xreg_im;
                   t03_im  = o02_re*xreg_im + o02_im*xreg_re;

                   x00a_re = t00_re + t02_re;
                   x02a_re = t00_re - t02_re;
                   x00a_im = t00_im + t02_im;
                   x02a_im = t00_im - t02_im;
                   x01a_re = t01_re + t03_re;
                   x03a_re = t01_re - t03_re;
                   x01a_im = t01_im + t03_im;
                   x03a_im = t01_im - t03_im;

                   out[kk*ispan+ll]           = x00a_re + x01a_re;
                   out[kk*ispan+ll+1]         = x00a_im + x01a_im;
                   out[kk*ispan+ospan+ll]     = x02a_re - x03a_im;
                   out[kk*ispan+ospan+ll+1]   = x02a_im + x03a_re;
                   out[kk*ispan+2*ospan+ll]   = x00a_re - x01a_re;
                   out[kk*ispan+2*ospan+ll+1] = x00a_im - x01a_im;
                   out[kk*ispan+3*ospan+ll]   = x02a_re + x03a_im;
                   out[kk*ispan+3*ospan+ll+1] = x02a_im - x03a_re;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) {
               t00_re  = in[ll];
               t00_im  = in[ll+1];
               t01_re  = in[2*ispan+ll];
               t01_im  = in[2*ispan+ll+1];
               t02_re  = in[4*ispan+ll];
               t02_im  = in[4*ispan+ll+1];
               t03_re  = in[6*ispan+ll];
               t03_im  = in[6*ispan+ll+1];

               x00a_re = t00_re + t02_re;
               x02a_re = t00_re - t02_re;
               x00a_im = t00_im + t02_im;
               x02a_im = t00_im - t02_im;
               x01a_re = t01_re + t03_re;
               x03a_re = t01_re - t03_re;
               x01a_im = t01_im + t03_im;
               x03a_im = t01_im - t03_im;

               out[ll]           = x00a_re + x01a_re;
               out[ll+1]         = x00a_im + x01a_im;
               out[ospan+ll]     = x02a_re - x03a_im;
               out[ospan+ll+1]   = x02a_im + x03a_re;
               out[2*ospan+ll]   = x00a_re - x01a_re;
               out[2*ospan+ll+1] = x00a_im - x01a_im;
               out[3*ospan+ll]   = x02a_re + x03a_im;
               out[3*ospan+ll+1] = x02a_im - x03a_re;
            }
	}
	break;
    }

    return;
}




void radixpass_5(float[] in, float[] out, float[] twids,
                 int size, int la, int dirflag)
{
/* Constants */
    final int   RADIXSIZE = 5;
    final float s1        = -1.250000000000000000000000000000000000000000000F;
    final float s2        = +0.559016994374947424102293417182819058860154590F;
    final float s3        = +0.951056516295153572116439333379382143405698634F;
    final float s4        = +0.618033988749895013548041333706350997090339661F;

/* Local variables */
    int   kk,ll,mm;
    int   istep,ispan,ospan;
    float o00_re,o01_re,o02_re,o03_re;
    float o00_im,o01_im,o02_im,o03_im;
    float t01_re,t02_re,t03_re,t04_re;
    float t01_im,t02_im,t03_im,t04_im;
    float xreg_re,xreg_im;
    float x00a_re,x00a_im;
    float x01a_re,x01a_im,x01b_re,x01b_im,x01c_re,x01c_im;
    float x02a_re,x02a_im,x02b_re,x02b_im,x02c_re,x02c_im;
    float x03a_re,x03a_im,x03b_re,x03b_im,x03c_re,x03c_im;
    float x04a_re,x04a_im,x04b_re,x04b_im,x04c_re,x04c_im;

 /* Verify parameters */
    if (size < RADIXSIZE || la < 1) return;

 /* Initialize pointers */
    ospan = 2*size/RADIXSIZE;
    ispan = la;
    mm    = ospan/ispan;

 /* Process the data */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        if (ispan != ospan/2) {
          for (kk=0; kk<mm; kk+=2) {
            o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
            o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
            o02_re = twids[3*kk*ispan];  o02_im = twids[3*kk*ispan+1];
            o03_re = twids[4*kk*ispan];  o03_im = twids[4*kk*ispan+1];
            istep  = kk*RADIXSIZE;

            for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental forward pass RADIX 5 kernel */
                xreg_re = in[ispan*(istep+2)+ll];
                xreg_im = in[ispan*(istep+2)+ll+1];
                t01_re  = o00_re*xreg_re + o00_im*xreg_im;
                t01_im  = o00_re*xreg_im - o00_im*xreg_re;
                xreg_re = in[ispan*(istep+8)+ll];
                xreg_im = in[ispan*(istep+8)+ll+1];
                t04_re  = o03_re*xreg_re + o03_im*xreg_im;
                t04_im  = o03_re*xreg_im - o03_im*xreg_re;
                x01a_re = t01_re + t04_re;
                x04a_re = t01_re - t04_re;
                x01a_im = t01_im + t04_im;
                x04a_im = t01_im - t04_im;
                xreg_re = in[ispan*(istep+4)+ll];
                xreg_im = in[ispan*(istep+4)+ll+1];
                t02_re  = o01_re*xreg_re + o01_im*xreg_im;
                t02_im  = o01_re*xreg_im - o01_im*xreg_re;
                xreg_re = in[ispan*(istep+6)+ll];
                xreg_im = in[ispan*(istep+6)+ll+1];
                t03_re  = o02_re*xreg_re + o02_im*xreg_im;
                t03_im  = o02_re*xreg_im - o02_im*xreg_re;
                x02a_re = t02_re + t03_re;
                x03a_re = t02_re - t03_re;
                x02a_im = t02_im + t03_im;
                x03a_im = t02_im - t03_im;
                xreg_re = in[ispan*(istep+0)+ll];
                x02b_re = x01a_re - x02a_re;
                x01b_re = x01a_re + x02a_re;
                x00a_re = xreg_re + x01b_re;
                out[kk*ispan+ll] = x00a_re;
                xreg_im = in[ispan*(istep+0)+ll+1];
                x02b_im = x01a_im - x02a_im;
                x01b_im = x01a_im + x02a_im;
                x00a_im = xreg_im + x01b_im;
                out[kk*ispan+ll+1] = x00a_im;
                x01b_re = s1*x01b_re + x00a_re;
                x02b_re = s2*x02b_re;
                x01c_re = x01b_re + x02b_re;
                x02c_re = x01b_re - x02b_re;
                x01b_im = s1*x01b_im + x00a_im;
                x02b_im = s2*x02b_im;
                x01c_im = x01b_im + x02b_im;
                x02c_im = x01b_im - x02b_im;
                x03b_re = s3*x03a_im;
                x04b_re = s3*x04a_im;
                x03c_re = s4*x04b_re - x03b_re;
                x04c_re = s4*x03b_re + x04b_re;
                x03b_im = s3*x03a_re;
                x04b_im = s3*x04a_re;
                x03c_im = s4*x04b_im - x03b_im;
                x04c_im = s4*x03b_im + x04b_im;
                out[kk*ispan+ospan+ll]     = x01c_re + x04c_re;
                out[kk*ispan+ospan+ll+1]   = x01c_im - x04c_im;
                out[kk*ispan+ospan*2+ll]   = x02c_re + x03c_re;
                out[kk*ispan+ospan*2+ll+1] = x02c_im - x03c_im;
                out[kk*ispan+ospan*3+ll]   = x02c_re - x03c_re;
                out[kk*ispan+ospan*3+ll+1] = x02c_im + x03c_im;
                out[kk*ispan+ospan*4+ll]   = x01c_re - x04c_re;
                out[kk*ispan+ospan*4+ll+1] = x01c_im + x04c_im;
            }
          }
        }
        else {
          for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental forward pass RADIX 5 kernel */
                t01_re  = in[ispan*2+ll];
                t01_im  = in[ispan*2+ll+1];
                t04_re  = in[ispan*8+ll];
                t04_im  = in[ispan*8+ll+1];
                x01a_re = t01_re + t04_re;
                x04a_re = t01_re - t04_re;
                x01a_im = t01_im + t04_im;
                x04a_im = t01_im - t04_im;
                t02_re  = in[ispan*4+ll];
                t02_im  = in[ispan*4+ll+1];
                t03_re  = in[ispan*6+ll];
                t03_im  = in[ispan*6+ll+1];
                x02a_re = t02_re + t03_re;
                x03a_re = t02_re - t03_re;
                x02a_im = t02_im + t03_im;
                x03a_im = t02_im - t03_im;
                xreg_re = in[ll];
                x02b_re = x01a_re - x02a_re;
                x01b_re = x01a_re + x02a_re;
                x00a_re = xreg_re + x01b_re;
                out[ll] = x00a_re;
                xreg_im = in[ll+1];
                x02b_im = x01a_im - x02a_im;
                x01b_im = x01a_im + x02a_im;
                x00a_im = xreg_im + x01b_im;
                out[ll+1] = x00a_im;
                x01b_re = s1*x01b_re + x00a_re;
                x02b_re = s2*x02b_re;
                x01c_re = x01b_re + x02b_re;
                x02c_re = x01b_re - x02b_re;
                x01b_im = s1*x01b_im + x00a_im;
                x02b_im = s2*x02b_im;
                x01c_im = x01b_im + x02b_im;
                x02c_im = x01b_im - x02b_im;
                x03b_re = s3*x03a_im;
                x04b_re = s3*x04a_im;
                x03c_re = s4*x04b_re - x03b_re;
                x04c_re = s4*x03b_re + x04b_re;
                x03b_im = s3*x03a_re;
                x04b_im = s3*x04a_re;
                x03c_im = s4*x04b_im - x03b_im;
                x04c_im = s4*x03b_im + x04b_im;
                out[ospan+ll]     = x01c_re + x04c_re;
                out[ospan+ll+1]   = x01c_im - x04c_im;
                out[ospan*2+ll]   = x02c_re + x03c_re;
                out[ospan*2+ll+1] = x02c_im - x03c_im;
                out[ospan*3+ll]   = x02c_re - x03c_re;
                out[ospan*3+ll+1] = x02c_im + x03c_im;
                out[ospan*4+ll]   = x01c_re - x04c_re;
                out[ospan*4+ll+1] = x01c_im + x04c_im;
          }
        }
        break;

      default:                                         /* Inverse Pass */
        if (ispan != ospan/2) {
          for (kk=0; kk<mm; kk+=2) {
            o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
            o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
            o02_re = twids[3*kk*ispan];  o02_im = twids[3*kk*ispan+1];
            o03_re = twids[4*kk*ispan];  o03_im = twids[4*kk*ispan+1];
            istep  = kk*RADIXSIZE;

            for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 5 kernel */
                xreg_re = in[ispan*(istep+2)+ll];
                xreg_im = in[ispan*(istep+2)+ll+1];
                t01_re  = o00_re*xreg_re - o00_im*xreg_im;
                t01_im  = o00_re*xreg_im + o00_im*xreg_re;
                xreg_re = in[ispan*(istep+8)+ll];
                xreg_im = in[ispan*(istep+8)+ll+1];
                t04_re  = o03_re*xreg_re - o03_im*xreg_im;
                t04_im  = o03_re*xreg_im + o03_im*xreg_re;
                x01a_re = t01_re + t04_re;
                x04a_re = t01_re - t04_re;
                x01a_im = t01_im + t04_im;
                x04a_im = t01_im - t04_im;
                xreg_re = in[ispan*(istep+4)+ll];
                xreg_im = in[ispan*(istep+4)+ll+1];
                t02_re  = o01_re*xreg_re - o01_im*xreg_im;
                t02_im  = o01_re*xreg_im + o01_im*xreg_re;
                xreg_re = in[ispan*(istep+6)+ll];
                xreg_im = in[ispan*(istep+6)+ll+1];
                t03_re  = o02_re*xreg_re - o02_im*xreg_im;
                t03_im  = o02_re*xreg_im + o02_im*xreg_re;
                x02a_re = t02_re + t03_re;
                x03a_re = t02_re - t03_re;
                x02a_im = t02_im + t03_im;
                x03a_im = t02_im - t03_im;
                xreg_re = in[ispan*(istep+0)+ll];
                x02b_re = x01a_re - x02a_re;
                x01b_re = x01a_re + x02a_re;
                x00a_re = xreg_re + x01b_re;
                out[kk*ispan+ll] = x00a_re;
                xreg_im = in[ispan*(istep+0)+ll+1];
                x02b_im = x01a_im - x02a_im;
                x01b_im = x01a_im + x02a_im;
                x00a_im = xreg_im + x01b_im;
                out[kk*ispan+ll+1] = x00a_im;
                x01b_re = s1*x01b_re + x00a_re;
                x02b_re = s2*x02b_re;
                x01c_re = x01b_re + x02b_re;
                x02c_re = x01b_re - x02b_re;
                x01b_im = s1*x01b_im + x00a_im;
                x02b_im = s2*x02b_im;
                x01c_im = x01b_im + x02b_im;
                x02c_im = x01b_im - x02b_im;
                x03b_re = s3*x03a_im;
                x04b_re = s3*x04a_im;
                x03c_re = s4*x04b_re - x03b_re;
                x04c_re = s4*x03b_re + x04b_re;
                x03b_im = s3*x03a_re;
                x04b_im = s3*x04a_re;
                x03c_im = s4*x04b_im - x03b_im;
                x04c_im = s4*x03b_im + x04b_im;
                out[kk*ispan+ospan+ll]     = x01c_re - x04c_re;
                out[kk*ispan+ospan+ll+1]   = x01c_im + x04c_im;
                out[kk*ispan+ospan*2+ll]   = x02c_re - x03c_re;
                out[kk*ispan+ospan*2+ll+1] = x02c_im + x03c_im;
                out[kk*ispan+ospan*3+ll]   = x02c_re + x03c_re;
                out[kk*ispan+ospan*3+ll+1] = x02c_im - x03c_im;
                out[kk*ispan+ospan*4+ll]   = x01c_re + x04c_re;
                out[kk*ispan+ospan*4+ll+1] = x01c_im - x04c_im;
            }
          }
        }
        else {
          for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 5 kernel */
                t01_re  = in[ispan*2+ll];
                t01_im  = in[ispan*2+ll+1];
                t04_re  = in[ispan*8+ll];
                t04_im  = in[ispan*8+ll+1];
                x01a_re = t01_re + t04_re;
                x04a_re = t01_re - t04_re;
                x01a_im = t01_im + t04_im;
                x04a_im = t01_im - t04_im;
                t02_re  = in[ispan*4+ll];
                t02_im  = in[ispan*4+ll+1];
                t03_re  = in[ispan*6+ll];
                t03_im  = in[ispan*6+ll+1];
                x02a_re = t02_re + t03_re;
                x03a_re = t02_re - t03_re;
                x02a_im = t02_im + t03_im;
                x03a_im = t02_im - t03_im;
                xreg_re = in[ll];
                x02b_re = x01a_re - x02a_re;
                x01b_re = x01a_re + x02a_re;
                x00a_re = xreg_re + x01b_re;
                out[ll] = x00a_re;
                xreg_im = in[ll+1];
                x02b_im = x01a_im - x02a_im;
                x01b_im = x01a_im + x02a_im;
                x00a_im = xreg_im + x01b_im;
                out[ll+1] = x00a_im;
                x01b_re = s1*x01b_re + x00a_re;
                x02b_re = s2*x02b_re;
                x01c_re = x01b_re + x02b_re;
                x02c_re = x01b_re - x02b_re;
                x01b_im = s1*x01b_im + x00a_im;
                x02b_im = s2*x02b_im;
                x01c_im = x01b_im + x02b_im;
                x02c_im = x01b_im - x02b_im;
                x03b_re = s3*x03a_im;
                x04b_re = s3*x04a_im;
                x03c_re = s4*x04b_re - x03b_re;
                x04c_re = s4*x03b_re + x04b_re;
                x03b_im = s3*x03a_re;
                x04b_im = s3*x04a_re;
                x03c_im = s4*x04b_im - x03b_im;
                x04c_im = s4*x03b_im + x04b_im;
                out[ospan+ll]     = x01c_re - x04c_re;
                out[ospan+ll+1]   = x01c_im + x04c_im;
                out[ospan*2+ll]   = x02c_re - x03c_re;
                out[ospan*2+ll+1] = x02c_im + x03c_im;
                out[ospan*3+ll]   = x02c_re + x03c_re;
                out[ospan*3+ll+1] = x02c_im - x03c_im;
                out[ospan*4+ll]   = x01c_re + x04c_re;
                out[ospan*4+ll+1] = x01c_im - x04c_im;
          }
        }
        break;
    }

    return;
}


void radixpass_8(float[] in, float[] out, float[] twids,
                   int size, int la, int dirflag)
{
/* Constants */
    final int   RADIXSIZE = 8;
    final float s1        = +0.707106781186547524400844362104849039284835938F;

/* Local variables */
    int   kk, ll, mm;
    int   istep, ispan, ospan;
    float o00_re, o01_re, o02_re, o03_re, o04_re, o05_re, o06_re;
    float o00_im, o01_im, o02_im, o03_im, o04_im, o05_im, o06_im;
    float t00_re, t01_re, t02_re, t03_re, t04_re, t05_re, t06_re, t07_re;
    float t00_im, t01_im, t02_im, t03_im, t04_im, t05_im, t06_im, t07_im;
    float xreg_re, xreg_im;
    float x00a_re, x00a_im, x00b_re, x00b_im;
    float x01a_re, x01a_im, x01b_re, x01b_im;
    float x02a_re, x02a_im, x02b_re, x02b_im;
    float x03a_re, x03a_im, x03b_re, x03b_im;
    float x04a_re, x04a_im, x04b_re, x04b_im;
    float x05a_re, x05a_im, x05b_re, x05b_im, x05c_re, x05c_im, x05d_re, x05d_im;
    float x06a_re, x06a_im, x06b_re, x06b_im;
    float x07a_re, x07a_im, x07b_re, x07b_im, x07c_re, x07c_im, x07d_re, x07d_im;

 /* Verify parameters */
    if (size < RADIXSIZE || la < 1) return;

 /* Initialize pointers */
    ospan = 2*size/RADIXSIZE;
    ispan = la;
    mm    = ospan/ispan;

 /* Process the data */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
                o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];  o02_im = twids[3*kk*ispan+1];
                o03_re = twids[4*kk*ispan];  o03_im = twids[4*kk*ispan+1];
                o04_re = twids[5*kk*ispan];  o04_im = twids[5*kk*ispan+1];
                o05_re = twids[6*kk*ispan];  o05_im = twids[6*kk*ispan+1];
                o06_re = twids[7*kk*ispan];  o06_im = twids[7*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental forward pass RADIX 8 kernel */
                   t00_re  = in[ispan*(istep+0)+ll];
                   t00_im  = in[ispan*(istep+0)+ll+1];
                   xreg_re = in[ispan*(istep+2)+ll];
                   xreg_im = in[ispan*(istep+2)+ll+1];
                   t01_re  = o00_re*xreg_re + o00_im*xreg_im;
                   t01_im  = o00_re*xreg_im - o00_im*xreg_re;
                   xreg_re = in[ispan*(istep+4)+ll];
                   xreg_im = in[ispan*(istep+4)+ll+1];
                   t02_re  = o01_re*xreg_re + o01_im*xreg_im;
                   t02_im  = o01_re*xreg_im - o01_im*xreg_re;
                   xreg_re = in[ispan*(istep+6)+ll];
                   xreg_im = in[ispan*(istep+6)+ll+1];
                   t03_re  = o02_re*xreg_re + o02_im*xreg_im;
                   t03_im  = o02_re*xreg_im - o02_im*xreg_re;
                   xreg_re = in[ispan*(istep+8)+ll];
                   xreg_im = in[ispan*(istep+8)+ll+1];
                   t04_re  = o03_re*xreg_re + o03_im*xreg_im;
                   t04_im  = o03_re*xreg_im - o03_im*xreg_re;
                   xreg_re = in[ispan*(istep+10)+ll];
                   xreg_im = in[ispan*(istep+10)+ll+1];
                   t05_re  = o04_re*xreg_re + o04_im*xreg_im;
                   t05_im  = o04_re*xreg_im - o04_im*xreg_re;
                   xreg_re = in[ispan*(istep+12)+ll];
                   xreg_im = in[ispan*(istep+12)+ll+1];
                   t06_re  = o05_re*xreg_re + o05_im*xreg_im;
                   t06_im  = o05_re*xreg_im - o05_im*xreg_re;
                   xreg_re = in[ispan*(istep+14)+ll];
                   xreg_im = in[ispan*(istep+14)+ll+1];
                   t07_re  = o06_re*xreg_re + o06_im*xreg_im;
                   t07_im  = o06_re*xreg_im - o06_im*xreg_re;

                   x04a_re = t00_re - t04_re;
                   x00a_re = t00_re + t04_re;
                   x02a_re = t02_re + t06_re;
                   x06a_re = t02_re - t06_re;
                   x00b_re = x00a_re + x02a_re;
                   x02b_re = x00a_re - x02a_re;
                   x04a_im = t00_im - t04_im;
                   x00a_im = t00_im + t04_im;
                   x02a_im = t02_im + t06_im;
                   x06a_im = t02_im - t06_im;
                   x00b_im = x00a_im + x02a_im;
                   x02b_im = x00a_im - x02a_im;
                   x05a_re = t01_re - t05_re;
                   x01a_re = t01_re + t05_re;
                   x03a_re = t03_re + t07_re;
                   x07a_re = t03_re - t07_re;
                   x01b_re = x01a_re + x03a_re;
                   x03b_re = x01a_re - x03a_re;
                   x05a_im = t01_im - t05_im;
                   x01a_im = t01_im + t05_im;
                   x03a_im = t03_im + t07_im;
                   x07a_im = t03_im - t07_im;
                   x01b_im = x01a_im + x03a_im;
                   x03b_im = x01a_im - x03a_im;

                   out[kk*ispan+0*ospan+ll]   = x00b_re + x01b_re;
                   out[kk*ispan+0*ospan+ll+1] = x00b_im + x01b_im;
                   out[kk*ispan+4*ospan+ll]   = x00b_re - x01b_re;
                   out[kk*ispan+4*ospan+ll+1] = x00b_im - x01b_im;
                   out[kk*ispan+2*ospan+ll]   = x02b_re + x03b_im;
                   out[kk*ispan+2*ospan+ll+1] = x02b_im - x03b_re;
                   out[kk*ispan+6*ospan+ll]   = x02b_re - x03b_im;
                   out[kk*ispan+6*ospan+ll+1] = x02b_im + x03b_re;

                   x07b_re = x05a_re + x07a_re;
                   x05b_re = x05a_re - x07a_re;
                   x07b_im = x05a_im + x07a_im;
                   x05b_im = x05a_im - x07a_im;
                   x05c_re = s1*x05b_re;
                   x04b_re = x04a_re + x05c_re;
                   x05d_re = x04a_re - x05c_re;
                   x05c_im = s1*x05b_im;
                   x04b_im = x04a_im + x05c_im;
                   x05d_im = x04a_im - x05c_im;
                   x07c_re = s1*x07b_im;
                   x06b_re = x06a_im + x07c_re;
                   x07d_re = x06a_im - x07c_re;
                   x07c_im = s1*x07b_re;
                   x06b_im = x06a_re + x07c_im;
                   x07d_im = x07c_im - x06a_re;

                   out[kk*ispan+1*ospan+ll]   = x04b_re + x06b_re;
                   out[kk*ispan+1*ospan+ll+1] = x04b_im - x06b_im;
                   out[kk*ispan+7*ospan+ll]   = x04b_re - x06b_re;
                   out[kk*ispan+7*ospan+ll+1] = x04b_im + x06b_im;
                   out[kk*ispan+3*ospan+ll]   = x05d_re - x07d_re;
                   out[kk*ispan+3*ospan+ll+1] = x05d_im - x07d_im;
                   out[kk*ispan+5*ospan+ll]   = x05d_re + x07d_re;
                   out[kk*ispan+5*ospan+ll+1] = x05d_im + x07d_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental forward pass RADIX 8 kernel */
               t00_re = in[0*ispan+ll];
               t00_im = in[0*ispan+ll+1];
               t01_re = in[2*ispan+ll];
               t01_im = in[2*ispan+ll+1];
               t02_re = in[4*ispan+ll];
               t02_im = in[4*ispan+ll+1];
               t03_re = in[6*ispan+ll];
               t03_im = in[6*ispan+ll+1];
               t04_re = in[8*ispan+ll];
               t04_im = in[8*ispan+ll+1];
               t05_re = in[10*ispan+ll];
               t05_im = in[10*ispan+ll+1];
               t06_re = in[12*ispan+ll];
               t06_im = in[12*ispan+ll+1];
               t07_re = in[14*ispan+ll];
               t07_im = in[14*ispan+ll+1];

               x04a_re = t00_re - t04_re;
               x00a_re = t00_re + t04_re;
               x02a_re = t02_re + t06_re;
               x06a_re = t02_re - t06_re;
               x00b_re = x00a_re + x02a_re;
               x02b_re = x00a_re - x02a_re;
               x04a_im = t00_im - t04_im;
               x00a_im = t00_im + t04_im;
               x02a_im = t02_im + t06_im;
               x06a_im = t02_im - t06_im;
               x00b_im = x00a_im + x02a_im;
               x02b_im = x00a_im - x02a_im;
               x05a_re = t01_re - t05_re;
               x01a_re = t01_re + t05_re;
               x03a_re = t03_re + t07_re;
               x07a_re = t03_re - t07_re;
               x01b_re = x01a_re + x03a_re;
               x03b_re = x01a_re - x03a_re;
               x05a_im = t01_im - t05_im;
               x01a_im = t01_im + t05_im;
               x03a_im = t03_im + t07_im;
               x07a_im = t03_im - t07_im;
               x01b_im = x01a_im + x03a_im;
               x03b_im = x01a_im - x03a_im;

               out[0*ospan+ll]   = x00b_re + x01b_re;
               out[0*ospan+ll+1] = x00b_im + x01b_im;
               out[4*ospan+ll]   = x00b_re - x01b_re;
               out[4*ospan+ll+1] = x00b_im - x01b_im;
               out[2*ospan+ll]   = x02b_re + x03b_im;
               out[2*ospan+ll+1] = x02b_im - x03b_re;
               out[6*ospan+ll]   = x02b_re - x03b_im;
               out[6*ospan+ll+1] = x02b_im + x03b_re;

               x07b_re = x05a_re + x07a_re;
               x05b_re = x05a_re - x07a_re;
               x07b_im = x05a_im + x07a_im;
               x05b_im = x05a_im - x07a_im;
               x05c_re = s1*x05b_re;
               x04b_re = x04a_re + x05c_re;
               x05d_re = x04a_re - x05c_re;
               x05c_im = s1*x05b_im;
               x04b_im = x04a_im + x05c_im;
               x05d_im = x04a_im - x05c_im;
               x07c_re = s1*x07b_im;
               x06b_re = x06a_im + x07c_re;
               x07d_re = x06a_im - x07c_re;
               x07c_im = s1*x07b_re;
               x06b_im = x06a_re + x07c_im;
               x07d_im = x07c_im - x06a_re;

               out[1*ospan+ll]   = x04b_re + x06b_re;
               out[1*ospan+ll+1] = x04b_im - x06b_im;
               out[7*ospan+ll]   = x04b_re - x06b_re;
               out[7*ospan+ll+1] = x04b_im + x06b_im;
               out[3*ospan+ll]   = x05d_re - x07d_re;
               out[3*ospan+ll+1] = x05d_im - x07d_im;
               out[5*ospan+ll]   = x05d_re + x07d_re;
               out[5*ospan+ll+1] = x05d_im + x07d_im;
            }
	}
	break;

      default:                                         /* Inverse Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[kk*ispan];    o00_im = twids[kk*ispan+1];
                o01_re = twids[2*kk*ispan];  o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];  o02_im = twids[3*kk*ispan+1];
                o03_re = twids[4*kk*ispan];  o03_im = twids[4*kk*ispan+1];
                o04_re = twids[5*kk*ispan];  o04_im = twids[5*kk*ispan+1];
                o05_re = twids[6*kk*ispan];  o05_im = twids[6*kk*ispan+1];
                o06_re = twids[7*kk*ispan];  o06_im = twids[7*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 8 kernel */
                   t00_re  = in[ispan*(istep+0)+ll];
                   t00_im  = in[ispan*(istep+0)+ll+1];
                   xreg_re = in[ispan*(istep+2)+ll];
                   xreg_im = in[ispan*(istep+2)+ll+1];
                   t01_re  = o00_re*xreg_re - o00_im*xreg_im;
                   t01_im  = o00_re*xreg_im + o00_im*xreg_re;
                   xreg_re = in[ispan*(istep+4)+ll];
                   xreg_im = in[ispan*(istep+4)+ll+1];
                   t02_re  = o01_re*xreg_re - o01_im*xreg_im;
                   t02_im  = o01_re*xreg_im + o01_im*xreg_re;
                   xreg_re = in[ispan*(istep+6)+ll];
                   xreg_im = in[ispan*(istep+6)+ll+1];
                   t03_re  = o02_re*xreg_re - o02_im*xreg_im;
                   t03_im  = o02_re*xreg_im + o02_im*xreg_re;
                   xreg_re = in[ispan*(istep+8)+ll];
                   xreg_im = in[ispan*(istep+8)+ll+1];
                   t04_re  = o03_re*xreg_re - o03_im*xreg_im;
                   t04_im  = o03_re*xreg_im + o03_im*xreg_re;
                   xreg_re = in[ispan*(istep+10)+ll];
                   xreg_im = in[ispan*(istep+10)+ll+1];
                   t05_re  = o04_re*xreg_re - o04_im*xreg_im;
                   t05_im  = o04_re*xreg_im + o04_im*xreg_re;
                   xreg_re = in[ispan*(istep+12)+ll];
                   xreg_im = in[ispan*(istep+12)+ll+1];
                   t06_re  = o05_re*xreg_re - o05_im*xreg_im;
                   t06_im  = o05_re*xreg_im + o05_im*xreg_re;
                   xreg_re = in[ispan*(istep+14)+ll];
                   xreg_im = in[ispan*(istep+14)+ll+1];
                   t07_re  = o06_re*xreg_re - o06_im*xreg_im;
                   t07_im  = o06_re*xreg_im + o06_im*xreg_re;

                   x04a_re = t00_re - t04_re;
                   x00a_re = t00_re + t04_re;
                   x02a_re = t02_re + t06_re;
                   x06a_re = t02_re - t06_re;
                   x00b_re = x00a_re + x02a_re;
                   x02b_re = x00a_re - x02a_re;
                   x04a_im = t00_im - t04_im;
                   x00a_im = t00_im + t04_im;
                   x02a_im = t02_im + t06_im;
                   x06a_im = t02_im - t06_im;
                   x00b_im = x00a_im + x02a_im;
                   x02b_im = x00a_im - x02a_im;
                   x05a_re = t01_re - t05_re;
                   x01a_re = t01_re + t05_re;
                   x03a_re = t03_re + t07_re;
                   x07a_re = t03_re - t07_re;
                   x01b_re = x01a_re + x03a_re;
                   x03b_re = x01a_re - x03a_re;
                   x05a_im = t01_im - t05_im;
                   x01a_im = t01_im + t05_im;
                   x03a_im = t03_im + t07_im;
                   x07a_im = t03_im - t07_im;
                   x01b_im = x01a_im + x03a_im;
                   x03b_im = x01a_im - x03a_im;

                   out[kk*ispan+0*ospan+ll]   = x00b_re + x01b_re;
                   out[kk*ispan+0*ospan+ll+1] = x00b_im + x01b_im;
                   out[kk*ispan+4*ospan+ll]   = x00b_re - x01b_re;
                   out[kk*ispan+4*ospan+ll+1] = x00b_im - x01b_im;
                   out[kk*ispan+2*ospan+ll]   = x02b_re - x03b_im;
                   out[kk*ispan+2*ospan+ll+1] = x02b_im + x03b_re;
                   out[kk*ispan+6*ospan+ll]   = x02b_re + x03b_im;
                   out[kk*ispan+6*ospan+ll+1] = x02b_im - x03b_re;

                   x07b_re = x05a_re + x07a_re;
                   x05b_re = x05a_re - x07a_re;
                   x07b_im = x05a_im + x07a_im;
                   x05b_im = x05a_im - x07a_im;
                   x05c_re = s1*x05b_re;
                   x04b_re = x04a_re + x05c_re;
                   x05d_re = x04a_re - x05c_re;
                   x05c_im = s1*x05b_im;
                   x04b_im = x04a_im + x05c_im;
                   x05d_im = x04a_im - x05c_im;
                   x07c_re = s1*x07b_im;
                   x06b_re = x06a_im + x07c_re;
                   x07d_re = x06a_im - x07c_re;
                   x07c_im = s1*x07b_re;
                   x06b_im = x06a_re + x07c_im;
                   x07d_im = x07c_im - x06a_re;

                   out[kk*ispan+1*ospan+ll]   = x04b_re - x06b_re;
                   out[kk*ispan+1*ospan+ll+1] = x04b_im + x06b_im;
                   out[kk*ispan+7*ospan+ll]   = x04b_re + x06b_re;
                   out[kk*ispan+7*ospan+ll+1] = x04b_im - x06b_im;
                   out[kk*ispan+3*ospan+ll]   = x05d_re + x07d_re;
                   out[kk*ispan+3*ospan+ll+1] = x05d_im + x07d_im;
                   out[kk*ispan+5*ospan+ll]   = x05d_re - x07d_re;
                   out[kk*ispan+5*ospan+ll+1] = x05d_im - x07d_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) { /* The fundamental inverse pass RADIX 8 kernel */
               t00_re = in[0*ispan+ll];
               t00_im = in[0*ispan+ll+1];
               t01_re = in[2*ispan+ll];
               t01_im = in[2*ispan+ll+1];
               t02_re = in[4*ispan+ll];
               t02_im = in[4*ispan+ll+1];
               t03_re = in[6*ispan+ll];
               t03_im = in[6*ispan+ll+1];
               t04_re = in[8*ispan+ll];
               t04_im = in[8*ispan+ll+1];
               t05_re = in[10*ispan+ll];
               t05_im = in[10*ispan+ll+1];
               t06_re = in[12*ispan+ll];
               t06_im = in[12*ispan+ll+1];
               t07_re = in[14*ispan+ll];
               t07_im = in[14*ispan+ll+1];

               x04a_re = t00_re - t04_re;
               x00a_re = t00_re + t04_re;
               x02a_re = t02_re + t06_re;
               x06a_re = t02_re - t06_re;
               x00b_re = x00a_re + x02a_re;
               x02b_re = x00a_re - x02a_re;
               x04a_im = t00_im - t04_im;
               x00a_im = t00_im + t04_im;
               x02a_im = t02_im + t06_im;
               x06a_im = t02_im - t06_im;
               x00b_im = x00a_im + x02a_im;
               x02b_im = x00a_im - x02a_im;
               x05a_re = t01_re - t05_re;
               x01a_re = t01_re + t05_re;
               x03a_re = t03_re + t07_re;
               x07a_re = t03_re - t07_re;
               x01b_re = x01a_re + x03a_re;
               x03b_re = x01a_re - x03a_re;
               x05a_im = t01_im - t05_im;
               x01a_im = t01_im + t05_im;
               x03a_im = t03_im + t07_im;
               x07a_im = t03_im - t07_im;
               x01b_im = x01a_im + x03a_im;
               x03b_im = x01a_im - x03a_im;

               out[0*ospan+ll]   = x00b_re + x01b_re;
               out[0*ospan+ll+1] = x00b_im + x01b_im;
               out[4*ospan+ll]   = x00b_re - x01b_re;
               out[4*ospan+ll+1] = x00b_im - x01b_im;
               out[2*ospan+ll]   = x02b_re - x03b_im;
               out[2*ospan+ll+1] = x02b_im + x03b_re;
               out[6*ospan+ll]   = x02b_re + x03b_im;
               out[6*ospan+ll+1] = x02b_im - x03b_re;

               x07b_re = x05a_re + x07a_re;
               x05b_re = x05a_re - x07a_re;
               x07b_im = x05a_im + x07a_im;
               x05b_im = x05a_im - x07a_im;
               x05c_re = s1*x05b_re;
               x04b_re = x04a_re + x05c_re;
               x05d_re = x04a_re - x05c_re;
               x05c_im = s1*x05b_im;
               x04b_im = x04a_im + x05c_im;
               x05d_im = x04a_im - x05c_im;
               x07c_re = s1*x07b_im;
               x06b_re = x06a_im + x07c_re;
               x07d_re = x06a_im - x07c_re;
               x07c_im = s1*x07b_re;
               x06b_im = x06a_re + x07c_im;
               x07d_im = x07c_im - x06a_re;

               out[1*ospan+ll]   = x04b_re - x06b_re;
               out[1*ospan+ll+1] = x04b_im + x06b_im;
               out[7*ospan+ll]   = x04b_re + x06b_re;
               out[7*ospan+ll+1] = x04b_im - x06b_im;
               out[3*ospan+ll]   = x05d_re + x07d_re;
               out[3*ospan+ll+1] = x05d_im + x07d_im;
               out[5*ospan+ll]   = x05d_re - x07d_re;
               out[5*ospan+ll+1] = x05d_im - x07d_im;
            }
	}
	break;
    }

    return;
}


void radixpass_16(float[] in, float[] out, float[] twids,
                   int size, int la, int dirflag)
{
/* Constants */
    final int   RADIXSIZE = 16;
    final float s1        = 0.707106781186547524400844362104849039284835938689F;
    final float s2        = 1.414213562373095048801688724209698078569671875377F;
    final float s3        = 0.923879532511286756128183189396788286822416626864F;
    final float s4        = 0.382683432365089771728459984030398866761344562486F;

/* Local variables */
    int   kk, ll, mm;
    int   istep, ispan, ospan;
    float o00_re, o01_re, o02_re, o03_re, o04_re, o05_re, o06_re, o07_re;
    float o00_im, o01_im, o02_im, o03_im, o04_im, o05_im, o06_im, o07_im;
    float o08_re, o09_re, o10_re, o11_re, o12_re, o13_re, o14_re;
    float o08_im, o09_im, o10_im, o11_im, o12_im, o13_im, o14_im;
    float t00_re, t01_re, t02_re, t03_re, t04_re, t05_re, t06_re, t07_re;
    float t00_im, t01_im, t02_im, t03_im, t04_im, t05_im, t06_im, t07_im;
    float t08_re, t09_re, t10_re, t11_re, t12_re, t13_re, t14_re, t15_re;
    float t08_im, t09_im, t10_im, t11_im, t12_im, t13_im, t14_im, t15_im;
    float x00a_re, x00a_im, x00b_re, x00b_im, x00c_re, x00c_im;
    float x01a_re, x01a_im, x01b_re, x01b_im, x01c_re, x01c_im;
    float x02a_re, x02a_im, x02b_re, x02b_im, x02c_re, x02c_im;
    float x03a_re, x03a_im, x03b_re, x03b_im, x03c_re, x03c_im;
    float x04a_re, x04a_im, x04b_re, x04b_im, x04c_re, x04c_im;
    float x05a_re, x05a_im, x05b_re, x05b_im, x05c_re, x05c_im;
    float x05d_re, x05d_im, x05e_re, x05e_im;
    float x06a_re, x06a_im, x06b_re, x06b_im, x06c_re, x06c_im;
    float x07a_re, x07a_im, x07b_re, x07b_im, x07c_re, x07c_im;
    float x07d_re, x07d_im, x07e_re, x07e_im;
    float x08a_re, x08a_im, x08b_re, x08b_im, x08c_re, x08c_im;
    float x09a_re, x09a_im, x09b_re, x09b_im, x09c_re, x09c_im;
    float x09d_re, x09d_im, x09e_re, x09e_im, x09f_re, x09f_im;
    float x10a_re, x10a_im, x10b_re, x10b_im, x10c_re, x10c_im;
    float x10d_re, x10d_im, x10e_re, x10e_im;
    float x11a_re, x11a_im, x11b_re, x11b_im, x11c_re, x11c_im;
    float x11d_re, x11d_im, x11e_re, x11e_im, x11f_re, x11f_im;
    float x12a_re, x12a_im, x12b_re, x12b_im, x12c_re, x12c_im;
    float x13a_re, x13a_im, x13b_re, x13b_im, x13c_re, x13c_im;
    float x13d_re, x13d_im, x13e_re, x13e_im;
    float x14a_re, x14a_im, x14b_re, x14b_im, x14c_re, x14c_im;
    float x14d_re, x14d_im, x14e_re, x14e_im;
    float x15a_re, x15a_im, x15b_re, x15b_im, x15c_re, x15c_im;
    float x15d_re, x15d_im, x15e_re, x15e_im, x15f_re, x15f_im;

 /* Verify parameters */
    if (size < RADIXSIZE || la < 1) return;

 /* Initialize pointers */
    ospan = 2*size/RADIXSIZE;
    ispan = la;
    mm    = ospan/ispan;

 /* Process the data */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[1*kk*ispan];   o00_im = twids[1*kk*ispan];
                o01_re = twids[2*kk*ispan];   o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];   o02_im = twids[3*kk*ispan+1];
                o03_re = twids[4*kk*ispan];   o03_im = twids[4*kk*ispan+1];
                o04_re = twids[5*kk*ispan];   o04_im = twids[5*kk*ispan+1];
                o05_re = twids[6*kk*ispan];   o05_im = twids[6*kk*ispan+1];
                o06_re = twids[7*kk*ispan];   o06_im = twids[7*kk*ispan+1];
                o07_re = twids[8*kk*ispan];   o07_im = twids[8*kk*ispan+1];
                o08_re = twids[9*kk*ispan];   o08_im = twids[9*kk*ispan+1];
                o09_re = twids[10*kk*ispan];  o09_im = twids[10*kk*ispan+1];
                o10_re = twids[11*kk*ispan];  o10_im = twids[11*kk*ispan+1];
                o11_re = twids[12*kk*ispan];  o11_im = twids[12*kk*ispan+1];
                o12_re = twids[13*kk*ispan];  o12_im = twids[13*kk*ispan+1];
                o13_re = twids[14*kk*ispan];  o13_im = twids[14*kk*ispan+1];
                o14_re = twids[15*kk*ispan];  o14_im = twids[15*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[ispan*(istep+0)+ll];
                   t00_im = in[ispan*(istep+0)+ll+1];
                   t01_re = o00_re*in[ispan*(istep+2)+ll]    + o00_im*in[ispan*(istep+2)+ll+1];
                   t01_im = o00_re*in[ispan*(istep+2)+ll+1]  - o00_im*in[ispan*(istep+2)+ll];
                   t02_re = o01_re*in[ispan*(istep+4)+ll]    + o01_im*in[ispan*(istep+4)+ll+1];
                   t02_im = o01_re*in[ispan*(istep+4)+ll+1]  - o01_im*in[ispan*(istep+4)+ll];
                   t03_re = o02_re*in[ispan*(istep+6)+ll]    + o02_im*in[ispan*(istep+6)+ll+1];
                   t03_im = o02_re*in[ispan*(istep+6)+ll+1]  - o02_im*in[ispan*(istep+6)+ll];
                   t04_re = o03_re*in[ispan*(istep+8)+ll]    + o03_im*in[ispan*(istep+8)+ll+1];
                   t04_im = o03_re*in[ispan*(istep+8)+ll+1]  - o03_im*in[ispan*(istep+8)+ll];
                   t05_re = o04_re*in[ispan*(istep+10)+ll]   + o04_im*in[ispan*(istep+10)+ll+1];
                   t05_im = o04_re*in[ispan*(istep+10)+ll+1] - o04_im*in[ispan*(istep+10)+ll];
                   t06_re = o05_re*in[ispan*(istep+12)+ll]   + o05_im*in[ispan*(istep+12)+ll+1];
                   t06_im = o05_re*in[ispan*(istep+12)+ll+1] - o05_im*in[ispan*(istep+12)+ll];
                   t07_re = o06_re*in[ispan*(istep+14)+ll]   + o06_im*in[ispan*(istep+14)+ll+1];
                   t07_im = o06_re*in[ispan*(istep+14)+ll+1] - o06_im*in[ispan*(istep+14)+ll];
                   t08_re = o07_re*in[ispan*(istep+16)+ll]   + o07_im*in[ispan*(istep+16)+ll+1];
                   t08_im = o07_re*in[ispan*(istep+16)+ll+1] - o07_im*in[ispan*(istep+16)+ll];
                   t09_re = o08_re*in[ispan*(istep+18)+ll]   + o08_im*in[ispan*(istep+18)+ll+1];
                   t09_im = o08_re*in[ispan*(istep+18)+ll+1] - o08_im*in[ispan*(istep+18)+ll];
                   t10_re = o09_re*in[ispan*(istep+20)+ll]   + o09_im*in[ispan*(istep+20)+ll+1];
                   t10_im = o09_re*in[ispan*(istep+20)+ll+1] - o09_im*in[ispan*(istep+20)+ll];
                   t11_re = o10_re*in[ispan*(istep+22)+ll]   + o10_im*in[ispan*(istep+22)+ll+1];
                   t11_im = o10_re*in[ispan*(istep+22)+ll+1] - o10_im*in[ispan*(istep+22)+ll];
                   t12_re = o11_re*in[ispan*(istep+24)+ll]   + o11_im*in[ispan*(istep+24)+ll+1];
                   t12_im = o11_re*in[ispan*(istep+24)+ll+1] - o11_im*in[ispan*(istep+24)+ll];
                   t13_re = o12_re*in[ispan*(istep+26)+ll]   + o12_im*in[ispan*(istep+26)+ll+1];
                   t13_im = o12_re*in[ispan*(istep+26)+ll+1] - o12_im*in[ispan*(istep+26)+ll];
                   t14_re = o13_re*in[ispan*(istep+28)+ll]   + o13_im*in[ispan*(istep+28)+ll+1];
                   t14_im = o13_re*in[ispan*(istep+28)+ll+1] - o13_im*in[ispan*(istep+28)+ll];
                   t15_re = o14_re*in[ispan*(istep+30)+ll]   + o14_im*in[ispan*(istep+30)+ll+1];
                   t15_im = o14_re*in[ispan*(istep+30)+ll+1] - o14_im*in[ispan*(istep+30)+ll];

                   x00c_re = t00_re + t08_re;
                   x08c_re = t00_re - t08_re;
                   x00c_im = t00_im + t08_im;
                   x08c_im = t00_im - t08_im;
                   x02c_re = t02_re + t10_re;
                   x10e_re = t02_re - t10_re;
                   x02c_im = t02_im + t10_im;
                   x10e_im = t02_im - t10_im;
                   x04c_re = t04_re + t12_re;
                   x12c_re = t04_re - t12_re;
                   x04c_im = t04_im + t12_im;
                   x12c_im = t04_im - t12_im;
                   x06c_re = t06_re + t14_re;
                   x14e_re = t06_re - t14_re;
                   x06c_im = t06_im + t14_im;
                   x14e_im = t06_im - t14_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = t01_re + t09_re;
                   x09f_re = t01_re - t09_re;
                   x01c_im = t01_im + t09_im;
                   x09f_im = t01_im - t09_im;
                   x03c_re = t03_re + t11_re;
                   x11f_re = t03_re - t11_re;
                   x03c_im = t03_im + t11_im;
                   x11f_im = t03_im - t11_im;
                   x05e_re = t05_re + t13_re;
                   x13e_re = t05_re - t13_re;
                   x05e_im = t05_im + t13_im;
                   x13e_im = t05_im - t13_im;
                   x07e_re = t07_re + t15_re;
                   x15f_re = t07_re - t15_re;
                   x07e_im = t07_im + t15_im;
                   x15f_im = t07_im - t15_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[kk*ispan+0*ospan+ll]    = x00a_re + x01a_re;
                   out[kk*ispan+0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[kk*ispan+8*ospan+ll]    = x00a_re - x01a_re;
                   out[kk*ispan+8*ospan+ll+1]  = x00a_im - x01a_im;
                   out[kk*ispan+4*ospan+ll]    = x02a_re + x03a_im;
                   out[kk*ispan+4*ospan+ll+1]  = x02a_im - x03a_re;
                   out[kk*ispan+12*ospan+ll]   = x02a_re - x03a_im;
                   out[kk*ispan+12*ospan+ll+1] = x02a_im + x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[kk*ispan+2*ospan+ll]    = x04a_re + x06a_re;
                   out[kk*ispan+2*ospan+ll+1]  = x04a_im - x06a_im;
                   out[kk*ispan+14*ospan+ll]   = x04a_re - x06a_re;
                   out[kk*ispan+14*ospan+ll+1] = x04a_im + x06a_im;
                   out[kk*ispan+6*ospan+ll]    = x05a_re - x07a_re;
                   out[kk*ispan+6*ospan+ll+1]  = x05a_im + x07a_im;
                   out[kk*ispan+10*ospan+ll]   = x05a_re + x07a_re;
                   out[kk*ispan+10*ospan+ll+1] = x05a_im - x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[kk*ispan+1*ospan+ll]    = x08a_re + x12a_re;
                   out[kk*ispan+1*ospan+ll+1]  = x08a_im + x12a_im;
                   out[kk*ispan+15*ospan+ll]   = x08a_re - x12a_re;
                   out[kk*ispan+15*ospan+ll+1] = x08a_im - x12a_im;
                   out[kk*ispan+7*ospan+ll]    = x09a_re - x13a_re;
                   out[kk*ispan+7*ospan+ll+1]  = x09a_im - x13a_im;
                   out[kk*ispan+9*ospan+ll]    = x09a_re + x13a_re;
                   out[kk*ispan+9*ospan+ll+1]  = x09a_im + x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[kk*ispan+3*ospan+ll]    = x10a_re - x14a_re;
                   out[kk*ispan+3*ospan+ll+1]  = x10a_im - x14a_im;
                   out[kk*ispan+13*ospan+ll]   = x10a_re + x14a_re;
                   out[kk*ispan+13*ospan+ll+1] = x10a_im + x14a_im;
                   out[kk*ispan+5*ospan+ll]    = x11a_re + x15a_re;
                   out[kk*ispan+5*ospan+ll+1]  = x11a_im + x15a_im;
                   out[kk*ispan+11*ospan+ll]   = x11a_re - x15a_re;
                   out[kk*ispan+11*ospan+ll+1] = x11a_im - x15a_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[0*ispan+ll];
                   t00_im = in[0*ispan+ll+1];
                   t01_re = in[2*ispan+ll];
                   t01_im = in[2*ispan+ll+1];
                   t02_re = in[4*ispan+ll];
                   t02_im = in[4*ispan+ll+1];
                   t03_re = in[6*ispan+ll];
                   t03_im = in[6*ispan+ll+1];
                   t04_re = in[8*ispan+ll];
                   t04_im = in[8*ispan+ll+1];
                   t05_re = in[10*ispan+ll];
                   t05_im = in[10*ispan+ll+1];
                   t06_re = in[12*ispan+ll];
                   t06_im = in[12*ispan+ll+1];
                   t07_re = in[14*ispan+ll];
                   t07_im = in[14*ispan+ll+1];
                   t08_re = in[16*ispan+ll];
                   t08_im = in[16*ispan+ll+1];
                   t09_re = in[18*ispan+ll];
                   t09_im = in[18*ispan+ll+1];
                   t10_re = in[20*ispan+ll];
                   t10_im = in[20*ispan+ll+1];
                   t11_re = in[22*ispan+ll];
                   t11_im = in[22*ispan+ll+1];
                   t12_re = in[24*ispan+ll];
                   t12_im = in[24*ispan+ll+1];
                   t13_re = in[26*ispan+ll];
                   t13_im = in[26*ispan+ll+1];
                   t14_re = in[28*ispan+ll];
                   t14_im = in[28*ispan+ll+1];
                   t15_re = in[30*ispan+ll];
                   t15_im = in[30*ispan+ll+1];

                   x00c_re = t00_re + t08_re;
                   x08c_re = t00_re - t08_re;
                   x00c_im = t00_im + t08_im;
                   x08c_im = t00_im - t08_im;
                   x02c_re = t02_re + t10_re;
                   x10e_re = t02_re - t10_re;
                   x02c_im = t02_im + t10_im;
                   x10e_im = t02_im - t10_im;
                   x04c_re = t04_re + t12_re;
                   x12c_re = t04_re - t12_re;
                   x04c_im = t04_im + t12_im;
                   x12c_im = t04_im - t12_im;
                   x06c_re = t06_re + t14_re;
                   x14e_re = t06_re - t14_re;
                   x06c_im = t06_im + t14_im;
                   x14e_im = t06_im - t14_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = t01_re + t09_re;
                   x09f_re = t01_re - t09_re;
                   x01c_im = t01_im + t09_im;
                   x09f_im = t01_im - t09_im;
                   x03c_re = t03_re + t11_re;
                   x11f_re = t03_re - t11_re;
                   x03c_im = t03_im + t11_im;
                   x11f_im = t03_im - t11_im;
                   x05e_re = t05_re + t13_re;
                   x13e_re = t05_re - t13_re;
                   x05e_im = t05_im + t13_im;
                   x13e_im = t05_im - t13_im;
                   x07e_re = t07_re + t15_re;
                   x15f_re = t07_re - t15_re;
                   x07e_im = t07_im + t15_im;
                   x15f_im = t07_im - t15_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[0*ospan+ll]    = x00a_re + x01a_re;
                   out[0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[8*ospan+ll]    = x00a_re - x01a_re;
                   out[8*ospan+ll+1]  = x00a_im - x01a_im;
                   out[4*ospan+ll]    = x02a_re + x03a_im;
                   out[4*ospan+ll+1]  = x02a_im - x03a_re;
                   out[12*ospan+ll]   = x02a_re - x03a_im;
                   out[12*ospan+ll+1] = x02a_im + x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[2*ospan+ll]    = x04a_re + x06a_re;
                   out[2*ospan+ll+1]  = x04a_im - x06a_im;
                   out[14*ospan+ll]   = x04a_re - x06a_re;
                   out[14*ospan+ll+1] = x04a_im + x06a_im;
                   out[6*ospan+ll]    = x05a_re - x07a_re;
                   out[6*ospan+ll+1]  = x05a_im + x07a_im;
                   out[10*ospan+ll]   = x05a_re + x07a_re;
                   out[10*ospan+ll+1] = x05a_im - x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[1*ospan+ll]    = x08a_re + x12a_re;
                   out[1*ospan+ll+1]  = x08a_im + x12a_im;
                   out[15*ospan+ll]   = x08a_re - x12a_re;
                   out[15*ospan+ll+1] = x08a_im - x12a_im;
                   out[7*ospan+ll]    = x09a_re - x13a_re;
                   out[7*ospan+ll+1]  = x09a_im - x13a_im;
                   out[9*ospan+ll]    = x09a_re + x13a_re;
                   out[9*ospan+ll+1]  = x09a_im + x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[3*ospan+ll]    = x10a_re - x14a_re;
                   out[3*ospan+ll+1]  = x10a_im - x14a_im;
                   out[13*ospan+ll]   = x10a_re + x14a_re;
                   out[13*ospan+ll+1] = x10a_im + x14a_im;
                   out[5*ospan+ll]    = x11a_re + x15a_re;
                   out[5*ospan+ll+1]  = x11a_im + x15a_im;
                   out[11*ospan+ll]   = x11a_re - x15a_re;
                   out[11*ospan+ll+1] = x11a_im - x15a_im;
            }
	}

	break;

      default:                                         /* Inverse Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[1*kk*ispan];   o00_im = twids[1*kk*ispan+1];
                o01_re = twids[2*kk*ispan];   o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];   o02_im = twids[3*kk*ispan+1];
                o03_re = twids[4*kk*ispan];   o03_im = twids[4*kk*ispan+1];
                o04_re = twids[5*kk*ispan];   o04_im = twids[5*kk*ispan+1];
                o05_re = twids[6*kk*ispan];   o05_im = twids[6*kk*ispan+1];
                o06_re = twids[7*kk*ispan];   o06_im = twids[7*kk*ispan+1];
                o07_re = twids[8*kk*ispan];   o07_im = twids[8*kk*ispan+1];
                o08_re = twids[9*kk*ispan];   o08_im = twids[9*kk*ispan+1];
                o09_re = twids[10*kk*ispan];  o09_im = twids[10*kk*ispan+1];
                o10_re = twids[11*kk*ispan];  o10_im = twids[11*kk*ispan+1];
                o11_re = twids[12*kk*ispan];  o11_im = twids[12*kk*ispan+1];
                o12_re = twids[13*kk*ispan];  o12_im = twids[13*kk*ispan+1];
                o13_re = twids[14*kk*ispan];  o13_im = twids[14*kk*ispan+1];
                o14_re = twids[15*kk*ispan];  o14_im = twids[15*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[ispan*(istep+0)+ll];
                   t00_im = in[ispan*(istep+0)+ll+1];
                   t01_re = o00_re*in[ispan*(istep+2)+ll]     - o00_im*in[ispan*(istep+2)+ll+1];
                   t01_im = o00_re*in[ispan*(istep+2)+ll+1]   + o00_im*in[ispan*(istep+2)+ll];
                   t02_re = o01_re*in[ispan*(istep+4)+ll]     - o01_im*in[ispan*(istep+4)+ll+1];
                   t02_im = o01_re*in[ispan*(istep+4)+ll+1]   + o01_im*in[ispan*(istep+4)+ll];
                   t03_re = o02_re*in[ispan*(istep+6)+ll]     - o02_im*in[ispan*(istep+6)+ll+1];
                   t03_im = o02_re*in[ispan*(istep+6)+ll+1]   + o02_im*in[ispan*(istep+6)+ll];
                   t04_re = o03_re*in[ispan*(istep+8)+ll]     - o03_im*in[ispan*(istep+8)+ll+1];
                   t04_im = o03_re*in[ispan*(istep+8)+ll+1]   + o03_im*in[ispan*(istep+8)+ll];
                   t05_re = o04_re*in[ispan*(istep+10)+ll]    - o04_im*in[ispan*(istep+10)+ll+1];
                   t05_im = o04_re*in[ispan*(istep+10)+ll+1]  + o04_im*in[ispan*(istep+10)+ll];
                   t06_re = o05_re*in[ispan*(istep+12)+ll]    - o05_im*in[ispan*(istep+12)+ll+1];
                   t06_im = o05_re*in[ispan*(istep+12)+ll+1]  + o05_im*in[ispan*(istep+12)+ll];
                   t07_re = o06_re*in[ispan*(istep+14)+ll]    - o06_im*in[ispan*(istep+14)+ll+1];
                   t07_im = o06_re*in[ispan*(istep+14)+ll+1]  + o06_im*in[ispan*(istep+14)+ll];
                   t08_re = o07_re*in[ispan*(istep+16)+ll]    - o07_im*in[ispan*(istep+16)+ll+1];
                   t08_im = o07_re*in[ispan*(istep+16)+ll+1]  + o07_im*in[ispan*(istep+16)+ll];
                   t09_re = o08_re*in[ispan*(istep+18)+ll]    - o08_im*in[ispan*(istep+18)+ll+1];
                   t09_im = o08_re*in[ispan*(istep+18)+ll+1]  + o08_im*in[ispan*(istep+18)+ll];
                   t10_re = o09_re*in[ispan*(istep+20)+ll]    - o09_im*in[ispan*(istep+20)+ll+1];
                   t10_im = o09_re*in[ispan*(istep+20)+ll+1]  + o09_im*in[ispan*(istep+20)+ll];
                   t11_re = o10_re*in[ispan*(istep+22)+ll]    - o10_im*in[ispan*(istep+22)+ll+1];
                   t11_im = o10_re*in[ispan*(istep+22)+ll+1]  + o10_im*in[ispan*(istep+22)+ll];
                   t12_re = o11_re*in[ispan*(istep+24)+ll]    - o11_im*in[ispan*(istep+24)+ll+1];
                   t12_im = o11_re*in[ispan*(istep+24)+ll+1]  + o11_im*in[ispan*(istep+24)+ll];
                   t13_re = o12_re*in[ispan*(istep+26)+ll]    - o12_im*in[ispan*(istep+26)+ll+1];
                   t13_im = o12_re*in[ispan*(istep+26)+ll+1]  + o12_im*in[ispan*(istep+26)+ll];
                   t14_re = o13_re*in[ispan*(istep+28)+ll]    - o13_im*in[ispan*(istep+28)+ll+1];
                   t14_im = o13_re*in[ispan*(istep+28)+ll+1]  + o13_im*in[ispan*(istep+28)+ll];
                   t15_re = o14_re*in[ispan*(istep+30)+ll]    - o14_im*in[ispan*(istep+30)+ll+1];
                   t15_im = o14_re*in[ispan*(istep+30)+ll+1]  + o14_im*in[ispan*(istep+30)+ll];

                   x00c_re = t00_re + t08_re;
                   x08c_re = t00_re - t08_re;
                   x00c_im = t00_im + t08_im;
                   x08c_im = t00_im - t08_im;
                   x02c_re = t02_re + t10_re;
                   x10e_re = t02_re - t10_re;
                   x02c_im = t02_im + t10_im;
                   x10e_im = t02_im - t10_im;
                   x04c_re = t04_re + t12_re;
                   x12c_re = t04_re - t12_re;
                   x04c_im = t04_im + t12_im;
                   x12c_im = t04_im - t12_im;
                   x06c_re = t06_re + t14_re;
                   x14e_re = t06_re - t14_re;
                   x06c_im = t06_im + t14_im;
                   x14e_im = t06_im - t14_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = t01_re + t09_re;
                   x09f_re = t01_re - t09_re;
                   x01c_im = t01_im + t09_im;
                   x09f_im = t01_im - t09_im;
                   x03c_re = t03_re + t11_re;
                   x11f_re = t03_re - t11_re;
                   x03c_im = t03_im + t11_im;
                   x11f_im = t03_im - t11_im;
                   x05e_re = t05_re + t13_re;
                   x13e_re = t05_re - t13_re;
                   x05e_im = t05_im + t13_im;
                   x13e_im = t05_im - t13_im;
                   x07e_re = t07_re + t15_re;
                   x15f_re = t07_re - t15_re;
                   x07e_im = t07_im + t15_im;
                   x15f_im = t07_im - t15_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[kk*ispan+0*ospan+ll]    = x00a_re + x01a_re;
                   out[kk*ispan+0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[kk*ispan+8*ospan+ll]    = x00a_re - x01a_re;
                   out[kk*ispan+8*ospan+ll+1]  = x00a_im - x01a_im;
                   out[kk*ispan+4*ospan+ll]    = x02a_re - x03a_im;
                   out[kk*ispan+4*ospan+ll+1]  = x02a_im + x03a_re;
                   out[kk*ispan+12*ospan+ll]   = x02a_re + x03a_im;
                   out[kk*ispan+12*ospan+ll+1] = x02a_im - x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[kk*ispan+2*ospan+ll]    = x04a_re - x06a_re;
                   out[kk*ispan+2*ospan+ll+1]  = x04a_im + x06a_im;
                   out[kk*ispan+14*ospan+ll]   = x04a_re + x06a_re;
                   out[kk*ispan+14*ospan+ll+1] = x04a_im - x06a_im;
                   out[kk*ispan+6*ospan+ll]    = x05a_re + x07a_re;
                   out[kk*ispan+6*ospan+ll+1]  = x05a_im - x07a_im;
                   out[kk*ispan+10*ospan+ll]   = x05a_re - x07a_re;
                   out[kk*ispan+10*ospan+ll+1] = x05a_im + x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[kk*ispan+1*ospan+ll]    = x08a_re - x12a_re;
                   out[kk*ispan+1*ospan+ll+1]  = x08a_im - x12a_im;
                   out[kk*ispan+15*ospan+ll]   = x08a_re + x12a_re;
                   out[kk*ispan+15*ospan+ll+1] = x08a_im + x12a_im;
                   out[kk*ispan+7*ospan+ll]    = x09a_re + x13a_re;
                   out[kk*ispan+7*ospan+ll+1]  = x09a_im + x13a_im;
                   out[kk*ispan+9*ospan+ll]    = x09a_re - x13a_re;
                   out[kk*ispan+9*ospan+ll+1]  = x09a_im - x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[kk*ispan+3*ospan+ll]    = x10a_re + x14a_re;
                   out[kk*ispan+3*ospan+ll+1]  = x10a_im + x14a_im;
                   out[kk*ispan+13*ospan+ll]   = x10a_re - x14a_re;
                   out[kk*ispan+13*ospan+ll+1] = x10a_im - x14a_im;
                   out[kk*ispan+5*ospan+ll]    = x11a_re - x15a_re;
                   out[kk*ispan+5*ospan+ll+1]  = x11a_im - x15a_im;
                   out[kk*ispan+11*ospan+ll]   = x11a_re + x15a_re;
                   out[kk*ispan+11*ospan+ll+1] = x11a_im + x15a_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[0*ispan+ll];
                   t00_im = in[0*ispan+ll+1];
                   t01_re = in[2*ispan+ll];
                   t01_im = in[2*ispan+ll+1];
                   t02_re = in[4*ispan+ll];
                   t02_im = in[4*ispan+ll+1];
                   t03_re = in[6*ispan+ll];
                   t03_im = in[6*ispan+ll+1];
                   t04_re = in[8*ispan+ll];
                   t04_im = in[8*ispan+ll+1];
                   t05_re = in[10*ispan+ll];
                   t05_im = in[10*ispan+ll+1];
                   t06_re = in[12*ispan+ll];
                   t06_im = in[12*ispan+ll+1];
                   t07_re = in[14*ispan+ll];
                   t07_im = in[14*ispan+ll+1];
                   t08_re = in[16*ispan+ll];
                   t08_im = in[16*ispan+ll+1];
                   t09_re = in[18*ispan+ll];
                   t09_im = in[18*ispan+ll+1];
                   t10_re = in[20*ispan+ll];
                   t10_im = in[20*ispan+ll+1];
                   t11_re = in[22*ispan+ll];
                   t11_im = in[22*ispan+ll+1];
                   t12_re = in[24*ispan+ll];
                   t12_im = in[24*ispan+ll+1];
                   t13_re = in[26*ispan+ll];
                   t13_im = in[26*ispan+ll+1];
                   t14_re = in[28*ispan+ll];
                   t14_im = in[28*ispan+ll+1];
                   t15_re = in[30*ispan+ll];
                   t15_im = in[30*ispan+ll+1];

                   x00c_re = t00_re + t08_re;
                   x08c_re = t00_re - t08_re;
                   x00c_im = t00_im + t08_im;
                   x08c_im = t00_im - t08_im;
                   x02c_re = t02_re + t10_re;
                   x10e_re = t02_re - t10_re;
                   x02c_im = t02_im + t10_im;
                   x10e_im = t02_im - t10_im;
                   x04c_re = t04_re + t12_re;
                   x12c_re = t04_re - t12_re;
                   x04c_im = t04_im + t12_im;
                   x12c_im = t04_im - t12_im;
                   x06c_re = t06_re + t14_re;
                   x14e_re = t06_re - t14_re;
                   x06c_im = t06_im + t14_im;
                   x14e_im = t06_im - t14_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = t01_re + t09_re;
                   x09f_re = t01_re - t09_re;
                   x01c_im = t01_im + t09_im;
                   x09f_im = t01_im - t09_im;
                   x03c_re = t03_re + t11_re;
                   x11f_re = t03_re - t11_re;
                   x03c_im = t03_im + t11_im;
                   x11f_im = t03_im - t11_im;
                   x05e_re = t05_re + t13_re;
                   x13e_re = t05_re - t13_re;
                   x05e_im = t05_im + t13_im;
                   x13e_im = t05_im - t13_im;
                   x07e_re = t07_re + t15_re;
                   x15f_re = t07_re - t15_re;
                   x07e_im = t07_im + t15_im;
                   x15f_im = t07_im - t15_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[0*ospan+ll]    = x00a_re + x01a_re;
                   out[0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[8*ospan+ll]    = x00a_re - x01a_re;
                   out[8*ospan+ll+1]  = x00a_im - x01a_im;
                   out[4*ospan+ll]    = x02a_re - x03a_im;
                   out[4*ospan+ll+1]  = x02a_im + x03a_re;
                   out[12*ospan+ll]   = x02a_re + x03a_im;
                   out[12*ospan+ll+1] = x02a_im - x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[2*ospan+ll]    = x04a_re - x06a_re;
                   out[2*ospan+ll+1]  = x04a_im + x06a_im;
                   out[14*ospan+ll]   = x04a_re + x06a_re;
                   out[14*ospan+ll+1] = x04a_im - x06a_im;
                   out[6*ospan+ll]    = x05a_re + x07a_re;
                   out[6*ospan+ll+1]  = x05a_im - x07a_im;
                   out[10*ospan+ll]   = x05a_re - x07a_re;
                   out[10*ospan+ll+1] = x05a_im + x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[1*ospan+ll]    = x08a_re - x12a_re;
                   out[1*ospan+ll+1]  = x08a_im - x12a_im;
                   out[15*ospan+ll]   = x08a_re + x12a_re;
                   out[15*ospan+ll+1] = x08a_im + x12a_im;
                   out[7*ospan+ll]    = x09a_re + x13a_re;
                   out[7*ospan+ll+1]  = x09a_im + x13a_im;
                   out[9*ospan+ll]    = x09a_re - x13a_re;
                   out[9*ospan+ll+1]  = x09a_im - x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[3*ospan+ll]    = x10a_re + x14a_re;
                   out[3*ospan+ll+1]  = x10a_im + x14a_im;
                   out[13*ospan+ll]   = x10a_re - x14a_re;
                   out[13*ospan+ll+1] = x10a_im - x14a_im;
                   out[5*ospan+ll]    = x11a_re - x15a_re;
                   out[5*ospan+ll+1]  = x11a_im - x15a_im;
                   out[11*ospan+ll]   = x11a_re + x15a_re;
                   out[11*ospan+ll+1] = x11a_im + x15a_im;
            }
	}

	break;
    }

    return;
}


void radixpass_32(float[] in, float[] out, float[] twids,
                   int size, int la, int dirflag)
{
/* Constants */
    final int   RADIXSIZE = 32;
    final float s1        = 0.707106781186547524400844362104849039284835938689F;
    final float s2        = 1.414213562373095048801688724209698078569671875377F;
    final float s3        = 0.923879532511286756128183189396788286822416626864F;
    final float s4        = 0.382683432365089771728459984030398866761344562486F;
    final float s5        = 1.847759065022573512256366378793576573644833252727F;
    final float s6        = 0.765366864730179543456919968060797733522689125971F;
    final float s7        = 0.980785280403230449126182236134239036973933731893F;
    final float s8        = 0.195090322016128267848284868477022240927691618752F;
    final float s9        = 0.831469612302545237078788377617905756738560812987F;
    final float s10       = 0.555570233019602224742830813948532874374937191755F;

/* Local variables */
    int   kk, ll, mm;
    int   istep, ispan, ospan;
    float o00_re, o01_re, o02_re, o03_re, o04_re, o05_re, o06_re, o07_re;
    float o00_im, o01_im, o02_im, o03_im, o04_im, o05_im, o06_im, o07_im;
    float o08_re, o09_re, o10_re, o11_re, o12_re, o13_re, o14_re, o15_re;
    float o08_im, o09_im, o10_im, o11_im, o12_im, o13_im, o14_im, o15_im;
    float o16_re, o17_re, o18_re, o19_re, o20_re, o21_re, o22_re, o23_re;
    float o16_im, o17_im, o18_im, o19_im, o20_im, o21_im, o22_im, o23_im;
    float o24_re, o25_re, o26_re, o27_re, o28_re, o29_re, o30_re;
    float o24_im, o25_im, o26_im, o27_im, o28_im, o29_im, o30_im;
    float t00_re, t01_re, t02_re, t03_re, t04_re, t05_re, t06_re, t07_re;
    float t00_im, t01_im, t02_im, t03_im, t04_im, t05_im, t06_im, t07_im;
    float t08_re, t09_re, t10_re, t11_re, t12_re, t13_re, t14_re, t15_re;
    float t08_im, t09_im, t10_im, t11_im, t12_im, t13_im, t14_im, t15_im;
    float t16_re, t17_re, t18_re, t19_re, t20_re, t21_re, t22_re, t23_re;
    float t16_im, t17_im, t18_im, t19_im, t20_im, t21_im, t22_im, t23_im;
    float t24_re, t25_re, t26_re, t27_re, t28_re, t29_re, t30_re, t31_re;
    float t24_im, t25_im, t26_im, t27_im, t28_im, t29_im, t30_im, t31_im;
    float x00z_re, x00z_im, x00a_re, x00a_im, x00b_re, x00b_im, x00c_re, x00c_im;
    float x01z_re, x01z_im, x01a_re, x01a_im, x01b_re, x01b_im, x01c_re, x01c_im;
    float x02z_re, x02z_im, x02a_re, x02a_im, x02b_re, x02b_im, x02c_re, x02c_im;
    float x03z_re, x03z_im, x03a_re, x03a_im, x03b_re, x03b_im, x03c_re, x03c_im;
    float x04z_re, x04z_im, x04a_re, x04a_im, x04b_re, x04b_im, x04c_re, x04c_im;
    float x05z_re, x05z_im, x05a_re, x05a_im, x05b_re, x05b_im, x05c_re, x05c_im;
    float x05d_re, x05d_im, x05e_re, x05e_im;
    float x06z_re, x06z_im, x06a_re, x06a_im, x06b_re, x06b_im, x06c_re, x06c_im;
    float x07z_re, x07z_im, x07a_re, x07a_im, x07b_re, x07b_im, x07c_re, x07c_im;
    float x07d_re, x07d_im, x07e_re, x07e_im;
    float x08z_re, x08z_im, x08a_re, x08a_im, x08b_re, x08b_im, x08c_re, x08c_im;
    float x09z_re, x09z_im, x09a_re, x09a_im, x09b_re, x09b_im, x09c_re, x09c_im;
    float x09d_re, x09d_im, x09e_re, x09e_im, x09f_re, x09f_im;
    float x10z_re, x10z_im, x10a_re, x10a_im, x10b_re, x10b_im, x10c_re, x10c_im;
    float x10d_re, x10d_im, x10e_re, x10e_im;
    float x11z_re, x11z_im, x11a_re, x11a_im, x11b_re, x11b_im, x11c_re, x11c_im;
    float x11d_re, x11d_im, x11e_re, x11e_im, x11f_re, x11f_im;
    float x12z_re, x12z_im, x12a_re, x12a_im, x12b_re, x12b_im, x12c_re, x12c_im;
    float x13z_re, x13z_im, x13a_re, x13a_im, x13b_re, x13b_im, x13c_re, x13c_im;
    float x13d_re, x13d_im, x13e_re, x13e_im;
    float x14z_re, x14z_im, x14a_re, x14a_im, x14b_re, x14b_im, x14c_re, x14c_im;
    float x14d_re, x14d_im, x14e_re, x14e_im;
    float x15z_re, x15z_im, x15a_re, x15a_im, x15b_re, x15b_im, x15c_re, x15c_im;
    float x15d_re, x15d_im, x15e_re, x15e_im, x15f_re, x15f_im;
    float x16z_re, x16z_im, x16a_re, x16a_im, x16b_re, x16b_im, x16c_re, x16c_im;
    float x17z_re, x17z_im, x17a_re, x17a_im, x17b_re, x17b_im, x17c_re, x17c_im;
    float x17d_re, x17d_im, x17e_re, x17e_im, x17f_re, x17f_im, x17g_re, x17g_im;
    float x18z_re, x18z_im, x18a_re, x18a_im, x18b_re, x18b_im, x18c_re, x18c_im;
    float x18d_re, x18d_im, x18e_re, x18e_im, x18f_re, x18f_im;
    float x19z_re, x19z_im, x19a_re, x19a_im, x19b_re, x19b_im, x19c_re, x19c_im;
    float x19d_re, x19d_im, x19e_re, x19e_im, x19f_re, x19f_im, x19g_re, x19g_im;
    float x20z_re, x20z_im, x20a_re, x20a_im, x20b_re, x20b_im, x20c_re, x20c_im;
    float x20d_re, x20d_im, x20e_re, x20e_im;
    float x21z_re, x21z_im, x21a_re, x21a_im, x21b_re, x21b_im, x21c_re, x21c_im;
    float x21d_re, x21d_im, x21e_re, x21e_im, x21f_re, x21f_im, x21g_re, x21g_im;
    float x22z_re, x22z_im, x22a_re, x22a_im, x22b_re, x22b_im, x22c_re, x22c_im;
    float x22d_re, x22d_im, x22e_re, x22e_im, x22f_re, x22f_im;
    float x23z_re, x23z_im, x23a_re, x23a_im, x23b_re, x23b_im, x23c_re, x23c_im;
    float x23d_re, x23d_im, x23e_re, x23e_im, x23f_re, x23f_im, x23g_re, x23g_im;
    float x24z_re, x24z_im, x24a_re, x24a_im, x24b_re, x24b_im, x24c_re, x24c_im;
    float x25z_re, x25z_im, x25a_re, x25a_im, x25b_re, x25b_im, x25c_re, x25c_im;
    float x25d_re, x25d_im, x25e_re, x25e_im, x25f_re, x25f_im, x25g_re, x25g_im;
    float x26z_re, x26z_im, x26a_re, x26a_im, x26b_re, x26b_im, x26c_re, x26c_im;
    float x26d_re, x26d_im, x26e_re, x26e_im, x26f_re, x26f_im;
    float x27z_re, x27z_im, x27a_re, x27a_im, x27b_re, x27b_im, x27c_re, x27c_im;
    float x27d_re, x27d_im, x27e_re, x27e_im, x27f_re, x27f_im, x27g_re, x27g_im;
    float x28z_re, x28z_im, x28a_re, x28a_im, x28b_re, x28b_im, x28c_re, x28c_im;
    float x28d_re, x28d_im, x28e_re, x28e_im;
    float x29z_re, x29z_im, x29a_re, x29a_im, x29b_re, x29b_im, x29c_re, x29c_im;
    float x29d_re, x29d_im, x29e_re, x29e_im, x29f_re, x29f_im, x29g_re, x29g_im;
    float x30z_re, x30z_im, x30a_re, x30a_im, x30b_re, x30b_im, x30c_re, x30c_im;
    float x30d_re, x30d_im, x30e_re, x30e_im, x30f_re, x30f_im;
    float x31z_re, x31z_im, x31a_re, x31a_im, x31b_re, x31b_im, x31c_re, x31c_im;
    float x31d_re, x31d_im, x31e_re, x31e_im, x31f_re, x31f_im, x31g_re, x31g_im;

 /* Verify parameters */
    if (size < RADIXSIZE || la < 1) return;

 /* Initialize pointers */
    ospan = 2*size/RADIXSIZE;
    ispan = la;
    mm    = ospan/ispan;

 /* Process the data */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[1*kk*ispan];   o00_im = twids[1*kk*ispan+1];
                o01_re = twids[2*kk*ispan];   o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];   o02_im = twids[3*kk*ispan+1];
                o03_re = twids[4*kk*ispan];   o03_im = twids[4*kk*ispan+1];
                o04_re = twids[5*kk*ispan];   o04_im = twids[5*kk*ispan+1];
                o05_re = twids[6*kk*ispan];   o05_im = twids[6*kk*ispan+1];
                o06_re = twids[7*kk*ispan];   o06_im = twids[7*kk*ispan+1];
                o07_re = twids[8*kk*ispan];   o07_im = twids[8*kk*ispan+1];
                o08_re = twids[9*kk*ispan];   o08_im = twids[9*kk*ispan+1];
                o09_re = twids[10*kk*ispan];  o09_im = twids[10*kk*ispan+1];
                o10_re = twids[11*kk*ispan];  o10_im = twids[11*kk*ispan+1];
                o11_re = twids[12*kk*ispan];  o11_im = twids[12*kk*ispan+1];
                o12_re = twids[13*kk*ispan];  o12_im = twids[13*kk*ispan+1];
                o13_re = twids[14*kk*ispan];  o13_im = twids[14*kk*ispan+1];
                o14_re = twids[15*kk*ispan];  o14_im = twids[15*kk*ispan+1];
                o15_re = twids[16*kk*ispan];  o15_im = twids[16*kk*ispan+1];
                o16_re = twids[17*kk*ispan];  o16_im = twids[17*kk*ispan+1];
                o17_re = twids[18*kk*ispan];  o17_im = twids[18*kk*ispan+1];
                o18_re = twids[19*kk*ispan];  o18_im = twids[19*kk*ispan+1];
                o19_re = twids[20*kk*ispan];  o19_im = twids[20*kk*ispan+1];
                o20_re = twids[21*kk*ispan];  o20_im = twids[21*kk*ispan+1];
                o21_re = twids[22*kk*ispan];  o21_im = twids[22*kk*ispan+1];
                o22_re = twids[23*kk*ispan];  o22_im = twids[23*kk*ispan+1];
                o23_re = twids[24*kk*ispan];  o23_im = twids[24*kk*ispan+1];
                o24_re = twids[25*kk*ispan];  o24_im = twids[25*kk*ispan+1];
                o25_re = twids[26*kk*ispan];  o25_im = twids[26*kk*ispan+1];
                o26_re = twids[27*kk*ispan];  o26_im = twids[27*kk*ispan+1];
                o27_re = twids[28*kk*ispan];  o27_im = twids[28*kk*ispan+1];
                o28_re = twids[29*kk*ispan];  o28_im = twids[29*kk*ispan+1];
                o29_re = twids[30*kk*ispan];  o29_im = twids[30*kk*ispan+1];
                o30_re = twids[31*kk*ispan];  o30_im = twids[31*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[ispan*(istep+0)+ll];
                   t00_im = in[ispan*(istep+0)+ll+1];
                   t01_re = o00_re*in[ispan*(istep+ 2)+ll]   + o00_im*in[ispan*(istep+ 2)+ll+1];
                   t01_im = o00_re*in[ispan*(istep+ 2)+ll+1] - o00_im*in[ispan*(istep+ 2)+ll];
                   t02_re = o01_re*in[ispan*(istep+ 4)+ll]   + o01_im*in[ispan*(istep+ 4)+ll+1];
                   t02_im = o01_re*in[ispan*(istep+ 4)+ll+1] - o01_im*in[ispan*(istep+ 4)+ll];
                   t03_re = o02_re*in[ispan*(istep+ 6)+ll]   + o02_im*in[ispan*(istep+ 6)+ll+1];
                   t03_im = o02_re*in[ispan*(istep+ 6)+ll+1] - o02_im*in[ispan*(istep+ 6)+ll];
                   t04_re = o03_re*in[ispan*(istep+ 8)+ll]   + o03_im*in[ispan*(istep+ 8)+ll+1];
                   t04_im = o03_re*in[ispan*(istep+ 8)+ll+1] - o03_im*in[ispan*(istep+ 8)+ll];
                   t05_re = o04_re*in[ispan*(istep+10)+ll]   + o04_im*in[ispan*(istep+10)+ll+1];
                   t05_im = o04_re*in[ispan*(istep+10)+ll+1] - o04_im*in[ispan*(istep+10)+ll];
                   t06_re = o05_re*in[ispan*(istep+12)+ll]   + o05_im*in[ispan*(istep+12)+ll+1];
                   t06_im = o05_re*in[ispan*(istep+12)+ll+1] - o05_im*in[ispan*(istep+12)+ll];
                   t07_re = o06_re*in[ispan*(istep+14)+ll]   + o06_im*in[ispan*(istep+14)+ll+1];
                   t07_im = o06_re*in[ispan*(istep+14)+ll+1] - o06_im*in[ispan*(istep+14)+ll];
                   t08_re = o07_re*in[ispan*(istep+16)+ll]   + o07_im*in[ispan*(istep+16)+ll+1];
                   t08_im = o07_re*in[ispan*(istep+16)+ll+1] - o07_im*in[ispan*(istep+16)+ll];
                   t09_re = o08_re*in[ispan*(istep+18)+ll]   + o08_im*in[ispan*(istep+18)+ll+1];
                   t09_im = o08_re*in[ispan*(istep+18)+ll+1] - o08_im*in[ispan*(istep+18)+ll];
                   t10_re = o09_re*in[ispan*(istep+20)+ll]   + o09_im*in[ispan*(istep+20)+ll+1];
                   t10_im = o09_re*in[ispan*(istep+20)+ll+1] - o09_im*in[ispan*(istep+20)+ll];
                   t11_re = o10_re*in[ispan*(istep+22)+ll]   + o10_im*in[ispan*(istep+22)+ll+1];
                   t11_im = o10_re*in[ispan*(istep+22)+ll+1] - o10_im*in[ispan*(istep+22)+ll];
                   t12_re = o11_re*in[ispan*(istep+24)+ll]   + o11_im*in[ispan*(istep+24)+ll+1];
                   t12_im = o11_re*in[ispan*(istep+24)+ll+1] - o11_im*in[ispan*(istep+24)+ll];
                   t13_re = o12_re*in[ispan*(istep+26)+ll]   + o12_im*in[ispan*(istep+26)+ll+1];
                   t13_im = o12_re*in[ispan*(istep+26)+ll+1] - o12_im*in[ispan*(istep+26)+ll];
                   t14_re = o13_re*in[ispan*(istep+28)+ll]   + o13_im*in[ispan*(istep+28)+ll+1];
                   t14_im = o13_re*in[ispan*(istep+28)+ll+1] - o13_im*in[ispan*(istep+28)+ll];
                   t15_re = o14_re*in[ispan*(istep+30)+ll]   + o14_im*in[ispan*(istep+30)+ll+1];
                   t15_im = o14_re*in[ispan*(istep+30)+ll+1] - o14_im*in[ispan*(istep+30)+ll];
                   t16_re = o15_re*in[ispan*(istep+32)+ll]   + o15_im*in[ispan*(istep+32)+ll+1];
                   t16_im = o15_re*in[ispan*(istep+32)+ll+1] - o15_im*in[ispan*(istep+32)+ll];
                   t17_re = o16_re*in[ispan*(istep+34)+ll]   + o16_im*in[ispan*(istep+34)+ll+1];
                   t17_im = o16_re*in[ispan*(istep+34)+ll+1] - o16_im*in[ispan*(istep+34)+ll];
                   t18_re = o17_re*in[ispan*(istep+36)+ll]   + o17_im*in[ispan*(istep+36)+ll+1];
                   t18_im = o17_re*in[ispan*(istep+36)+ll+1] - o17_im*in[ispan*(istep+36)+ll];
                   t19_re = o18_re*in[ispan*(istep+38)+ll]   + o18_im*in[ispan*(istep+38)+ll+1];
                   t19_im = o18_re*in[ispan*(istep+38)+ll+1] - o18_im*in[ispan*(istep+38)+ll];
                   t20_re = o19_re*in[ispan*(istep+40)+ll]   + o19_im*in[ispan*(istep+40)+ll+1];
                   t20_im = o19_re*in[ispan*(istep+40)+ll+1] - o19_im*in[ispan*(istep+40)+ll];
                   t21_re = o20_re*in[ispan*(istep+42)+ll]   + o20_im*in[ispan*(istep+42)+ll+1];
                   t21_im = o20_re*in[ispan*(istep+42)+ll+1] - o20_im*in[ispan*(istep+42)+ll];
                   t22_re = o21_re*in[ispan*(istep+44)+ll]   + o21_im*in[ispan*(istep+44)+ll+1];
                   t22_im = o21_re*in[ispan*(istep+44)+ll+1] - o21_im*in[ispan*(istep+44)+ll];
                   t23_re = o22_re*in[ispan*(istep+46)+ll]   + o22_im*in[ispan*(istep+46)+ll+1];
                   t23_im = o22_re*in[ispan*(istep+46)+ll+1] - o22_im*in[ispan*(istep+46)+ll];
                   t24_re = o23_re*in[ispan*(istep+48)+ll]   + o23_im*in[ispan*(istep+48)+ll+1];
                   t24_im = o23_re*in[ispan*(istep+48)+ll+1] - o23_im*in[ispan*(istep+48)+ll];
                   t25_re = o24_re*in[ispan*(istep+50)+ll]   + o24_im*in[ispan*(istep+50)+ll+1];
                   t25_im = o24_re*in[ispan*(istep+50)+ll+1] - o24_im*in[ispan*(istep+50)+ll];
                   t26_re = o25_re*in[ispan*(istep+52)+ll]   + o25_im*in[ispan*(istep+52)+ll+1];
                   t26_im = o25_re*in[ispan*(istep+52)+ll+1] - o25_im*in[ispan*(istep+52)+ll];
                   t27_re = o26_re*in[ispan*(istep+54)+ll]   + o26_im*in[ispan*(istep+54)+ll+1];
                   t27_im = o26_re*in[ispan*(istep+54)+ll+1] - o26_im*in[ispan*(istep+54)+ll];
                   t28_re = o27_re*in[ispan*(istep+56)+ll]   + o27_im*in[ispan*(istep+56)+ll+1];
                   t28_im = o27_re*in[ispan*(istep+56)+ll+1] - o27_im*in[ispan*(istep+56)+ll];
                   t29_re = o28_re*in[ispan*(istep+58)+ll]   + o28_im*in[ispan*(istep+58)+ll+1];
                   t29_im = o28_re*in[ispan*(istep+58)+ll+1] - o28_im*in[ispan*(istep+58)+ll];
                   t30_re = o29_re*in[ispan*(istep+60)+ll]   + o29_im*in[ispan*(istep+60)+ll+1];
                   t30_im = o29_re*in[ispan*(istep+60)+ll+1] - o29_im*in[ispan*(istep+60)+ll];
                   t31_re = o30_re*in[ispan*(istep+62)+ll]   + o30_im*in[ispan*(istep+62)+ll+1];
                   t31_im = o30_re*in[ispan*(istep+62)+ll+1] - o30_im*in[ispan*(istep+62)+ll];

                   x00z_re = t00_re + t16_re;
                   x16z_re = t00_re - t16_re;
                   x00z_im = t00_im + t16_im;
                   x16z_im = t00_im - t16_im;
                   x01z_re = t01_re + t17_re;
                   x17z_re = t01_re - t17_re;
                   x01z_im = t01_im + t17_im;
                   x17z_im = t01_im - t17_im;
                   x02z_re = t02_re + t18_re;
                   x18z_re = t02_re - t18_re;
                   x02z_im = t02_im + t18_im;
                   x18z_im = t02_im - t18_im;
                   x03z_re = t03_re + t19_re;
                   x19z_re = t03_re - t19_re;
                   x03z_im = t03_im + t19_im;
                   x19z_im = t03_im - t19_im;
                   x04z_re = t04_re + t20_re;
                   x20z_re = t04_re - t20_re;
                   x04z_im = t04_im + t20_im;
                   x20z_im = t04_im - t20_im;
                   x05z_re = t05_re + t21_re;
                   x21z_re = t05_re - t21_re;
                   x05z_im = t05_im + t21_im;
                   x21z_im = t05_im - t21_im;
                   x06z_re = t06_re + t22_re;
                   x22z_re = t06_re - t22_re;
                   x06z_im = t06_im + t22_im;
                   x22z_im = t06_im - t22_im;
                   x07z_re = t07_re + t23_re;
                   x23z_re = t07_re - t23_re;
                   x07z_im = t07_im + t23_im;
                   x23z_im = t07_im - t23_im;
                   x08z_re = t08_re + t24_re;
                   x24z_re = t08_re - t24_re;
                   x08z_im = t08_im + t24_im;
                   x24z_im = t08_im - t24_im;
                   x09z_re = t09_re + t25_re;
                   x25z_re = t09_re - t25_re;
                   x09z_im = t09_im + t25_im;
                   x25z_im = t09_im - t25_im;
                   x10z_re = t10_re + t26_re;
                   x26z_re = t10_re - t26_re;
                   x10z_im = t10_im + t26_im;
                   x26z_im = t10_im - t26_im;
                   x11z_re = t11_re + t27_re;
                   x27z_re = t11_re - t27_re;
                   x11z_im = t11_im + t27_im;
                   x27z_im = t11_im - t27_im;
                   x12z_re = t12_re + t28_re;
                   x28z_re = t12_re - t28_re;
                   x12z_im = t12_im + t28_im;
                   x28z_im = t12_im - t28_im;
                   x13z_re = t13_re + t29_re;
                   x29z_re = t13_re - t29_re;
                   x13z_im = t13_im + t29_im;
                   x29z_im = t13_im - t29_im;
                   x14z_re = t14_re + t30_re;
                   x30z_re = t14_re - t30_re;
                   x14z_im = t14_im + t30_im;
                   x30z_im = t14_im - t30_im;
                   x15z_re = t15_re + t31_re;
                   x31z_re = t15_re - t31_re;
                   x15z_im = t15_im + t31_im;
                   x31z_im = t15_im - t31_im;

                   x00c_re = x00z_re + x08z_re;
                   x08c_re = x00z_re - x08z_re;
                   x00c_im = x00z_im + x08z_im;
                   x08c_im = x00z_im - x08z_im;
                   x02c_re = x02z_re + x10z_re;
                   x10e_re = x02z_re - x10z_re;
                   x02c_im = x02z_im + x10z_im;
                   x10e_im = x02z_im - x10z_im;
                   x04c_re = x04z_re + x12z_re;
                   x12c_re = x04z_re - x12z_re;
                   x04c_im = x04z_im + x12z_im;
                   x12c_im = x04z_im - x12z_im;
                   x06c_re = x06z_re + x14z_re;
                   x14e_re = x06z_re - x14z_re;
                   x06c_im = x06z_im + x14z_im;
                   x14e_im = x06z_im - x14z_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = x01z_re + x09z_re;
                   x09f_re = x01z_re - x09z_re;
                   x01c_im = x01z_im + x09z_im;
                   x09f_im = x01z_im - x09z_im;
                   x03c_re = x03z_re + x11z_re;
                   x11f_re = x03z_re - x11z_re;
                   x03c_im = x03z_im + x11z_im;
                   x11f_im = x03z_im - x11z_im;
                   x05e_re = x05z_re + x13z_re;
                   x13e_re = x05z_re - x13z_re;
                   x05e_im = x05z_im + x13z_im;
                   x13e_im = x05z_im - x13z_im;
                   x07e_re = x07z_re + x15z_re;
                   x15f_re = x07z_re - x15z_re;
                   x07e_im = x07z_im + x15z_im;
                   x15f_im = x07z_im - x15z_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[kk*ispan+0*ospan+ll]    = x00a_re + x01a_re;
                   out[kk*ispan+0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[kk*ispan+16*ospan+ll]   = x00a_re - x01a_re;
                   out[kk*ispan+16*ospan+ll+1] = x00a_im - x01a_im;
                   out[kk*ispan+8*ospan+ll]    = x02a_re + x03a_im;
                   out[kk*ispan+8*ospan+ll+1]  = x02a_im - x03a_re;
                   out[kk*ispan+24*ospan+ll]   = x02a_re - x03a_im;
                   out[kk*ispan+24*ospan+ll+1] = x02a_im + x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[kk*ispan+4*ospan+ll]    = x04a_re + x06a_re;
                   out[kk*ispan+4*ospan+ll+1]  = x04a_im - x06a_im;
                   out[kk*ispan+28*ospan+ll]   = x04a_re - x06a_re;
                   out[kk*ispan+28*ospan+ll+1] = x04a_im + x06a_im;
                   out[kk*ispan+12*ospan+ll]   = x05a_re - x07a_re;
                   out[kk*ispan+12*ospan+ll+1] = x05a_im + x07a_im;
                   out[kk*ispan+20*ospan+ll]   = x05a_re + x07a_re;
                   out[kk*ispan+20*ospan+ll+1] = x05a_im - x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[kk*ispan+2*ospan+ll]    = x08a_re + x12a_re;
                   out[kk*ispan+2*ospan+ll+1]  = x08a_im + x12a_im;
                   out[kk*ispan+30*ospan+ll]   = x08a_re - x12a_re;
                   out[kk*ispan+30*ospan+ll+1] = x08a_im - x12a_im;
                   out[kk*ispan+14*ospan+ll]   = x09a_re - x13a_re;
                   out[kk*ispan+14*ospan+ll+1] = x09a_im - x13a_im;
                   out[kk*ispan+18*ospan+ll]   = x09a_re + x13a_re;
                   out[kk*ispan+18*ospan+ll+1] = x09a_im + x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[kk*ispan+6*ospan+ll]    = x10a_re - x14a_re;
                   out[kk*ispan+6*ospan+ll+1]  = x10a_im - x14a_im;
                   out[kk*ispan+26*ospan+ll]   = x10a_re + x14a_re;
                   out[kk*ispan+26*ospan+ll+1] = x10a_im + x14a_im;
                   out[kk*ispan+10*ospan+ll]   = x11a_re + x15a_re;
                   out[kk*ispan+10*ospan+ll+1] = x11a_im + x15a_im;
                   out[kk*ispan+22*ospan+ll]   = x11a_re - x15a_re;
                   out[kk*ispan+22*ospan+ll+1] = x11a_im - x15a_im;

                   x17g_re = x17z_re - x31z_re;
                   x31g_re = x17z_re + x31z_re;
                   x17g_im = x17z_im - x31z_im;
                   x31g_im = x17z_im + x31z_im;
                   x21g_re = x21z_re - x27z_re;
                   x27g_re = x21z_re + x27z_re;
                   x21g_im = x21z_im - x27z_im;
                   x27g_im = x21z_im + x27z_im;
                   x23g_re = x23z_re - x25z_re;
                   x25g_re = x23z_re + x25z_re;
                   x23g_im = x23z_im - x25z_im;
                   x25g_im = x23z_im + x25z_im;
                   x17f_re = x17g_re - x23g_re;
                   x21f_re = s2*x21g_re;
                   x17e_re = x17f_re + x21f_re;
                   x21e_re = x17f_re - x21f_re;
                   x17f_im = x17g_im - x23g_im;
                   x21f_im = s2*x21g_im;
                   x17e_im = x17f_im + x21f_im;
                   x21e_im = x17f_im - x21f_im;

                   x18f_re = x18z_re - x30z_re;
                   x30f_re = x18z_re + x30z_re;
                   x18f_im = x18z_im - x30z_im;
                   x30f_im = x18z_im + x30z_im;
                   x22f_re = x22z_re - x26z_re;
                   x26f_re = x22z_re + x26z_re;
                   x22f_im = x22z_im - x26z_im;
                   x26f_im = x22z_im + x26z_im;
                   x18e_re = x18f_re - x22f_re;
                   x22e_re = s2*x22f_re;
                   x18d_re = x18e_re + x22e_re;
                   x22d_re = x18e_re - x22e_re;
                   x18e_im = x18f_im - x22f_im;
                   x22e_im = s2*x22f_im;
                   x18d_im = x18e_im + x22e_im;
                   x22d_im = x18e_im - x22e_im;

                   x19g_im = x19z_im - x29z_im;
                   x29g_im = x19z_im + x29z_im;
                   x19g_re = x19z_re - x29z_re;
                   x29g_re = x19z_re + x29z_re;
                   x19f_re = x19g_re - x21g_re;
                   x23f_re = s2*x23g_re;
                   x19e_re = x19f_re + x23f_re;
                   x23e_re = x19f_re - x23f_re;
                   x19f_im = x19g_im - x21g_im;
                   x23f_im = s2*x23g_im;
                   x19e_im = x19f_im + x23f_im;
                   x23e_im = x19f_im - x23f_im;
                   x17d_re = x17e_re - x19e_re;
                   x19d_re = s5*x19e_re;
                   x17c_re = x17d_re + x19d_re;
                   x19c_re = x17d_re - x19d_re;
                   x17d_im = x17e_im - x19e_im;
                   x19d_im = s5*x19e_im;
                   x17c_im = x17d_im + x19d_im;
                   x19c_im = x17d_im - x19d_im;
                   x21d_re = x21e_re - x23e_re;
                   x23d_re = s6*x23e_re;
                   x21c_re = x21d_re + x23d_re;
                   x23c_re = x21d_re - x23d_re;
                   x21d_im = x21e_im - x23e_im;
                   x23d_im = s6*x23e_im;
                   x21c_im = x21d_im + x23d_im;
                   x23c_im = x21d_im - x23d_im;
                   x25f_re = x25g_re - x31g_re;
                   x29f_re = s2*x29g_re;
                   x25e_re = x25f_re + x29f_re;
                   x29e_re = x25f_re - x29f_re;
                   x25f_im = x25g_im - x31g_im;
                   x29f_im = s2*x29g_im;
                   x25e_im = x25f_im + x29f_im;
                   x29e_im = x25f_im - x29f_im;
                   x26e_re = x26f_re - x30f_re;
                   x30e_re = s2*x30f_re;
                   x26d_re = x26e_re + x30e_re;
                   x30d_re = x26e_re - x30e_re;
                   x26e_im = x26f_im - x30f_im;
                   x30e_im = s2*x30f_im;
                   x26d_im = x26e_im + x30e_im;
                   x30d_im = x26e_im - x30e_im;
                   x27f_re = x27g_re - x29g_re;
                   x31f_re = s2*x31g_re;
                   x27e_re = x27f_re + x31f_re;
                   x31e_re = x27f_re - x31f_re;
                   x27f_im = x27g_im - x29g_im;
                   x31f_im = s2*x31g_im;
                   x27e_im = x27f_im + x31f_im;
                   x31e_im = x27f_im - x31f_im;
                   x25d_re = x25e_re - x27e_re;
                   x27d_re = s5*x27e_re;
                   x27c_re = x25d_re - x27d_re;
                   x25c_re = x25d_re + x27d_re;
                   x25d_im = x25e_im - x27e_im;
                   x27d_im = s5*x27e_im;
                   x27c_im = x25d_im - x27d_im;
                   x25c_im = x25d_im + x27d_im;
                   x29d_re = x29e_re - x31e_re;
                   x31d_re = s6*x31e_re;
                   x29c_re = x29d_re + x31d_re;
                   x31c_re = x29d_re - x31d_re;
                   x29d_im = x29e_im - x31e_im;
                   x31d_im = s6*x31e_im;
                   x29c_im = x29d_im + x31d_im;
                   x31c_im = x29d_im - x31d_im;

                   x20e_re = x20z_re - x28z_re;
                   x28e_re = x20z_re + x28z_re;
                   x20e_im = x20z_im - x28z_im;
                   x28e_im = x20z_im + x28z_im;
                   x28d_im = s1*x28e_im;
                   x24c_re = x24z_im + x28d_im;
                   x28c_re = x24z_im - x28d_im;
                   x26c_im = s3*x26d_im;
                   x24b_re = x24c_re + x26c_im;
                   x26b_re = x24c_re - x26c_im;
                   x25b_im = s7*x25c_im;
                   x24a_re = x24b_re + x25b_im;
                   x25a_re = x24b_re - x25b_im;
                   x28d_re = s1*x28e_re;
                   x24c_im = x28d_re + x24z_re;
                   x28c_im = x28d_re - x24z_re;
                   x26c_re = s3*x26d_re;
                   x24b_im = x26c_re + x24c_im;
                   x26b_im = x26c_re - x24c_im;
                   x25b_re = s7*x25c_re;
                   x24a_im = x25b_re + x24b_im;
                   x25a_im = x25b_re - x24b_im;
                   x20d_re = s1*x20e_re;
                   x20c_re = x16z_re - x20d_re;
                   x16c_re = x16z_re + x20d_re;
                   x18c_re = s3*x18d_re;
                   x16b_re = x16c_re + x18c_re;
                   x18b_re = x16c_re - x18c_re;
                   x17b_re = s7*x17c_re;
                   x16a_re = x16b_re + x17b_re;
                   x17a_re = x16b_re - x17b_re;
                   x20d_im = s1*x20e_im;
                   x20c_im = x16z_im - x20d_im;
                   x16c_im = x16z_im + x20d_im;
                   x18c_im = s3*x18d_im;
                   x16b_im = x16c_im + x18c_im;
                   x18b_im = x16c_im - x18c_im;
                   x17b_im = s7*x17c_im;
                   x16a_im = x16b_im + x17b_im;
                   x17a_im = x16b_im - x17b_im;

                   out[kk*ispan+1*ospan+ll]    = x16a_re + x24a_re;
                   out[kk*ispan+1*ospan+ll+1]  = x16a_im - x24a_im;
                   out[kk*ispan+31*ospan+ll]   = x16a_re - x24a_re;
                   out[kk*ispan+31*ospan+ll+1] = x16a_im + x24a_im;
                   out[kk*ispan+15*ospan+ll]   = x17a_re - x25a_re;
                   out[kk*ispan+15*ospan+ll+1] = x17a_im - x25a_im;
                   out[kk*ispan+17*ospan+ll]   = x17a_re + x25a_re;
                   out[kk*ispan+17*ospan+ll+1] = x17a_im + x25a_im;

                   x27b_im = s8*x27c_im;
                   x26a_re = x26b_re + x27b_im;
                   x27a_re = x26b_re - x27b_im;
                   x27b_re = s8*x27c_re;
                   x26a_im = x26b_im - x27b_re;
                   x27a_im = x26b_im + x27b_re;
                   x19b_re = s8*x19c_re;
                   x18a_re = x18b_re + x19b_re;
                   x19a_re = x18b_re - x19b_re;
                   x19b_im = s8*x19c_im;
                   x18a_im = x18b_im + x19b_im;
                   x19a_im = x18b_im - x19b_im;

                   out[kk*ispan+7*ospan+ll]    = x18a_re - x26a_re;
                   out[kk*ispan+7*ospan+ll+1]  = x18a_im - x26a_im;
                   out[kk*ispan+25*ospan+ll]   = x18a_re + x26a_re;
                   out[kk*ispan+25*ospan+ll+1] = x18a_im + x26a_im;
                   out[kk*ispan+9*ospan+ll]    = x19a_re + x27a_re;
                   out[kk*ispan+9*ospan+ll+1]  = x19a_im + x27a_im;
                   out[kk*ispan+23*ospan+ll]   = x19a_re - x27a_re;
                   out[kk*ispan+23*ospan+ll+1] = x19a_im - x27a_im;

                   x30c_im = s4*x30d_im;
                   x28b_re = x28c_re + x30c_im;
                   x30b_re = x28c_re - x30c_im;
                   x29b_im = s9*x29c_im;
                   x28a_re = x28b_re + x29b_im;
                   x29a_re = x28b_re - x29b_im;
                   x30c_re = s4*x30d_re;
                   x28b_im = x28c_im - x30c_re;
                   x30b_im = x28c_im + x30c_re;
                   x29b_re = s9*x29c_re;
                   x28a_im = x28b_im - x29b_re;
                   x29a_im = x28b_im + x29b_re;
                   x22c_re = s4*x22d_re;
                   x20b_re = x20c_re + x22c_re;
                   x22b_re = x20c_re - x22c_re;
                   x21b_re = s9*x21c_re;
                   x20a_re = x20b_re + x21b_re;
                   x21a_re = x20b_re - x21b_re;
                   x22c_im = s4*x22d_im;
                   x20b_im = x20c_im + x22c_im;
                   x22b_im = x20c_im - x22c_im;
                   x21b_im = s9*x21c_im;
                   x20a_im = x20b_im + x21b_im;
                   x21a_im = x20b_im - x21b_im;

                   out[kk*ispan+3*ospan+ll]    = x20a_re - x28a_re;
                   out[kk*ispan+3*ospan+ll+1]  = x20a_im - x28a_im;
                   out[kk*ispan+29*ospan+ll]   = x20a_re + x28a_re;
                   out[kk*ispan+29*ospan+ll+1] = x20a_im + x28a_im;
                   out[kk*ispan+13*ospan+ll]   = x21a_re + x29a_re;
                   out[kk*ispan+13*ospan+ll+1] = x21a_im + x29a_im;
                   out[kk*ispan+19*ospan+ll]   = x21a_re - x29a_re;
                   out[kk*ispan+19*ospan+ll+1] = x21a_im - x29a_im;

                   x23b_re = s10*x23c_re;
                   x22a_re = x22b_re + x23b_re;
                   x23a_re = x22b_re - x23b_re;
                   x23b_im = s10*x23c_im;
                   x22a_im = x22b_im + x23b_im;
                   x23a_im = x22b_im - x23b_im;
                   x31b_im = s10*x31c_im;
                   x30a_re = x30b_re + x31b_im;
                   x31a_re = x30b_re - x31b_im;
                   x31b_re = s10*x31c_re;
                   x31a_im = x30b_im + x31b_re;
                   x30a_im = x30b_im - x31b_re;

                   out[kk*ispan+5*ospan+ll]    = x22a_re + x30a_re;
                   out[kk*ispan+5*ospan+ll+1]  = x22a_im + x30a_im;
                   out[kk*ispan+27*ospan+ll]   = x22a_re - x30a_re;
                   out[kk*ispan+27*ospan+ll+1] = x22a_im - x30a_im;
                   out[kk*ispan+11*ospan+ll]   = x23a_re - x31a_re;
                   out[kk*ispan+11*ospan+ll+1] = x23a_im - x31a_im;
                   out[kk*ispan+21*ospan+ll]   = x23a_re + x31a_re;
                   out[kk*ispan+21*ospan+ll+1] = x23a_im + x31a_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[0*ispan+ll];
                   t00_im = in[0*ispan+ll+1];
                   t01_re = in[2*ispan+ll];
                   t01_im = in[2*ispan+ll+1];
                   t02_re = in[4*ispan+ll];
                   t02_im = in[4*ispan+ll+1];
                   t03_re = in[6*ispan+ll];
                   t03_im = in[6*ispan+ll+1];
                   t04_re = in[8*ispan+ll];
                   t04_im = in[8*ispan+ll+1];
                   t05_re = in[10*ispan+ll];
                   t05_im = in[10*ispan+ll+1];
                   t06_re = in[12*ispan+ll];
                   t06_im = in[12*ispan+ll+1];
                   t07_re = in[14*ispan+ll];
                   t07_im = in[14*ispan+ll+1];
                   t08_re = in[16*ispan+ll];
                   t08_im = in[16*ispan+ll+1];
                   t09_re = in[18*ispan+ll];
                   t09_im = in[18*ispan+ll+1];
                   t10_re = in[20*ispan+ll];
                   t10_im = in[20*ispan+ll+1];
                   t11_re = in[22*ispan+ll];
                   t11_im = in[22*ispan+ll+1];
                   t12_re = in[24*ispan+ll];
                   t12_im = in[24*ispan+ll+1];
                   t13_re = in[26*ispan+ll];
                   t13_im = in[26*ispan+ll+1];
                   t14_re = in[28*ispan+ll];
                   t14_im = in[28*ispan+ll+1];
                   t15_re = in[30*ispan+ll];
                   t15_im = in[30*ispan+ll+1];
                   t16_re = in[32*ispan+ll];
                   t16_im = in[32*ispan+ll+1];
                   t17_re = in[34*ispan+ll];
                   t17_im = in[34*ispan+ll+1];
                   t18_re = in[36*ispan+ll];
                   t18_im = in[36*ispan+ll+1];
                   t19_re = in[38*ispan+ll];
                   t19_im = in[38*ispan+ll+1];
                   t20_re = in[40*ispan+ll];
                   t20_im = in[40*ispan+ll+1];
                   t21_re = in[42*ispan+ll];
                   t21_im = in[42*ispan+ll+1];
                   t22_re = in[44*ispan+ll];
                   t22_im = in[44*ispan+ll+1];
                   t23_re = in[46*ispan+ll];
                   t23_im = in[46*ispan+ll+1];
                   t24_re = in[48*ispan+ll];
                   t24_im = in[48*ispan+ll+1];
                   t25_re = in[50*ispan+ll];
                   t25_im = in[50*ispan+ll+1];
                   t26_re = in[52*ispan+ll];
                   t26_im = in[52*ispan+ll+1];
                   t27_re = in[54*ispan+ll];
                   t27_im = in[54*ispan+ll+1];
                   t28_re = in[56*ispan+ll];
                   t28_im = in[56*ispan+ll+1];
                   t29_re = in[58*ispan+ll];
                   t29_im = in[58*ispan+ll+1];
                   t30_re = in[60*ispan+ll];
                   t30_im = in[60*ispan+ll+1];
                   t31_re = in[62*ispan+ll];
                   t31_im = in[62*ispan+ll+1];

                   x00z_re = t00_re + t16_re;
                   x16z_re = t00_re - t16_re;
                   x00z_im = t00_im + t16_im;
                   x16z_im = t00_im - t16_im;
                   x01z_re = t01_re + t17_re;
                   x17z_re = t01_re - t17_re;
                   x01z_im = t01_im + t17_im;
                   x17z_im = t01_im - t17_im;
                   x02z_re = t02_re + t18_re;
                   x18z_re = t02_re - t18_re;
                   x02z_im = t02_im + t18_im;
                   x18z_im = t02_im - t18_im;
                   x03z_re = t03_re + t19_re;
                   x19z_re = t03_re - t19_re;
                   x03z_im = t03_im + t19_im;
                   x19z_im = t03_im - t19_im;
                   x04z_re = t04_re + t20_re;
                   x20z_re = t04_re - t20_re;
                   x04z_im = t04_im + t20_im;
                   x20z_im = t04_im - t20_im;
                   x05z_re = t05_re + t21_re;
                   x21z_re = t05_re - t21_re;
                   x05z_im = t05_im + t21_im;
                   x21z_im = t05_im - t21_im;
                   x06z_re = t06_re + t22_re;
                   x22z_re = t06_re - t22_re;
                   x06z_im = t06_im + t22_im;
                   x22z_im = t06_im - t22_im;
                   x07z_re = t07_re + t23_re;
                   x23z_re = t07_re - t23_re;
                   x07z_im = t07_im + t23_im;
                   x23z_im = t07_im - t23_im;
                   x08z_re = t08_re + t24_re;
                   x24z_re = t08_re - t24_re;
                   x08z_im = t08_im + t24_im;
                   x24z_im = t08_im - t24_im;
                   x09z_re = t09_re + t25_re;
                   x25z_re = t09_re - t25_re;
                   x09z_im = t09_im + t25_im;
                   x25z_im = t09_im - t25_im;
                   x10z_re = t10_re + t26_re;
                   x26z_re = t10_re - t26_re;
                   x10z_im = t10_im + t26_im;
                   x26z_im = t10_im - t26_im;
                   x11z_re = t11_re + t27_re;
                   x27z_re = t11_re - t27_re;
                   x11z_im = t11_im + t27_im;
                   x27z_im = t11_im - t27_im;
                   x12z_re = t12_re + t28_re;
                   x28z_re = t12_re - t28_re;
                   x12z_im = t12_im + t28_im;
                   x28z_im = t12_im - t28_im;
                   x13z_re = t13_re + t29_re;
                   x29z_re = t13_re - t29_re;
                   x13z_im = t13_im + t29_im;
                   x29z_im = t13_im - t29_im;
                   x14z_re = t14_re + t30_re;
                   x30z_re = t14_re - t30_re;
                   x14z_im = t14_im + t30_im;
                   x30z_im = t14_im - t30_im;
                   x15z_re = t15_re + t31_re;
                   x31z_re = t15_re - t31_re;
                   x15z_im = t15_im + t31_im;
                   x31z_im = t15_im - t31_im;

                   x00c_re = x00z_re + x08z_re;
                   x08c_re = x00z_re - x08z_re;
                   x00c_im = x00z_im + x08z_im;
                   x08c_im = x00z_im - x08z_im;
                   x02c_re = x02z_re + x10z_re;
                   x10e_re = x02z_re - x10z_re;
                   x02c_im = x02z_im + x10z_im;
                   x10e_im = x02z_im - x10z_im;
                   x04c_re = x04z_re + x12z_re;
                   x12c_re = x04z_re - x12z_re;
                   x04c_im = x04z_im + x12z_im;
                   x12c_im = x04z_im - x12z_im;
                   x06c_re = x06z_re + x14z_re;
                   x14e_re = x06z_re - x14z_re;
                   x06c_im = x06z_im + x14z_im;
                   x14e_im = x06z_im - x14z_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = x01z_re + x09z_re;
                   x09f_re = x01z_re - x09z_re;
                   x01c_im = x01z_im + x09z_im;
                   x09f_im = x01z_im - x09z_im;
                   x03c_re = x03z_re + x11z_re;
                   x11f_re = x03z_re - x11z_re;
                   x03c_im = x03z_im + x11z_im;
                   x11f_im = x03z_im - x11z_im;
                   x05e_re = x05z_re + x13z_re;
                   x13e_re = x05z_re - x13z_re;
                   x05e_im = x05z_im + x13z_im;
                   x13e_im = x05z_im - x13z_im;
                   x07e_re = x07z_re + x15z_re;
                   x15f_re = x07z_re - x15z_re;
                   x07e_im = x07z_im + x15z_im;
                   x15f_im = x07z_im - x15z_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[0*ospan+ll]    = x00a_re + x01a_re;
                   out[0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[16*ospan+ll]   = x00a_re - x01a_re;
                   out[16*ospan+ll+1] = x00a_im - x01a_im;
                   out[8*ospan+ll]    = x02a_re + x03a_im;
                   out[8*ospan+ll+1]  = x02a_im - x03a_re;
                   out[24*ospan+ll]   = x02a_re - x03a_im;
                   out[24*ospan+ll+1] = x02a_im + x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[4*ospan+ll]    = x04a_re + x06a_re;
                   out[4*ospan+ll+1]  = x04a_im - x06a_im;
                   out[28*ospan+ll]   = x04a_re - x06a_re;
                   out[28*ospan+ll+1] = x04a_im + x06a_im;
                   out[12*ospan+ll]   = x05a_re - x07a_re;
                   out[12*ospan+ll+1] = x05a_im + x07a_im;
                   out[20*ospan+ll]   = x05a_re + x07a_re;
                   out[20*ospan+ll+1] = x05a_im - x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[2*ospan+ll]    = x08a_re + x12a_re;
                   out[2*ospan+ll+1]  = x08a_im + x12a_im;
                   out[30*ospan+ll]   = x08a_re - x12a_re;
                   out[30*ospan+ll+1] = x08a_im - x12a_im;
                   out[14*ospan+ll]   = x09a_re - x13a_re;
                   out[14*ospan+ll+1] = x09a_im - x13a_im;
                   out[18*ospan+ll]   = x09a_re + x13a_re;
                   out[18*ospan+ll+1] = x09a_im + x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[6*ospan+ll]    = x10a_re - x14a_re;
                   out[6*ospan+ll+1]  = x10a_im - x14a_im;
                   out[26*ospan+ll]   = x10a_re + x14a_re;
                   out[26*ospan+ll+1] = x10a_im + x14a_im;
                   out[10*ospan+ll]   = x11a_re + x15a_re;
                   out[10*ospan+ll+1] = x11a_im + x15a_im;
                   out[22*ospan+ll]   = x11a_re - x15a_re;
                   out[22*ospan+ll+1] = x11a_im - x15a_im;

                   x17g_re = x17z_re - x31z_re;
                   x31g_re = x17z_re + x31z_re;
                   x17g_im = x17z_im - x31z_im;
                   x31g_im = x17z_im + x31z_im;
                   x21g_re = x21z_re - x27z_re;
                   x27g_re = x21z_re + x27z_re;
                   x21g_im = x21z_im - x27z_im;
                   x27g_im = x21z_im + x27z_im;
                   x23g_re = x23z_re - x25z_re;
                   x25g_re = x23z_re + x25z_re;
                   x23g_im = x23z_im - x25z_im;
                   x25g_im = x23z_im + x25z_im;
                   x17f_re = x17g_re - x23g_re;
                   x21f_re = s2*x21g_re;
                   x17e_re = x17f_re + x21f_re;
                   x21e_re = x17f_re - x21f_re;
                   x17f_im = x17g_im - x23g_im;
                   x21f_im = s2*x21g_im;
                   x17e_im = x17f_im + x21f_im;
                   x21e_im = x17f_im - x21f_im;

                   x18f_re = x18z_re - x30z_re;
                   x30f_re = x18z_re + x30z_re;
                   x18f_im = x18z_im - x30z_im;
                   x30f_im = x18z_im + x30z_im;
                   x22f_re = x22z_re - x26z_re;
                   x26f_re = x22z_re + x26z_re;
                   x22f_im = x22z_im - x26z_im;
                   x26f_im = x22z_im + x26z_im;
                   x18e_re = x18f_re - x22f_re;
                   x22e_re = s2*x22f_re;
                   x18d_re = x18e_re + x22e_re;
                   x22d_re = x18e_re - x22e_re;
                   x18e_im = x18f_im - x22f_im;
                   x22e_im = s2*x22f_im;
                   x18d_im = x18e_im + x22e_im;
                   x22d_im = x18e_im - x22e_im;

                   x19g_im = x19z_im - x29z_im;
                   x29g_im = x19z_im + x29z_im;
                   x19g_re = x19z_re - x29z_re;
                   x29g_re = x19z_re + x29z_re;
                   x19f_re = x19g_re - x21g_re;
                   x23f_re = s2*x23g_re;
                   x19e_re = x19f_re + x23f_re;
                   x23e_re = x19f_re - x23f_re;
                   x19f_im = x19g_im - x21g_im;
                   x23f_im = s2*x23g_im;
                   x19e_im = x19f_im + x23f_im;
                   x23e_im = x19f_im - x23f_im;
                   x17d_re = x17e_re - x19e_re;
                   x19d_re = s5*x19e_re;
                   x17c_re = x17d_re + x19d_re;
                   x19c_re = x17d_re - x19d_re;
                   x17d_im = x17e_im - x19e_im;
                   x19d_im = s5*x19e_im;
                   x17c_im = x17d_im + x19d_im;
                   x19c_im = x17d_im - x19d_im;
                   x21d_re = x21e_re - x23e_re;
                   x23d_re = s6*x23e_re;
                   x21c_re = x21d_re + x23d_re;
                   x23c_re = x21d_re - x23d_re;
                   x21d_im = x21e_im - x23e_im;
                   x23d_im = s6*x23e_im;
                   x21c_im = x21d_im + x23d_im;
                   x23c_im = x21d_im - x23d_im;
                   x25f_re = x25g_re - x31g_re;
                   x29f_re = s2*x29g_re;
                   x25e_re = x25f_re + x29f_re;
                   x29e_re = x25f_re - x29f_re;
                   x25f_im = x25g_im - x31g_im;
                   x29f_im = s2*x29g_im;
                   x25e_im = x25f_im + x29f_im;
                   x29e_im = x25f_im - x29f_im;
                   x26e_re = x26f_re - x30f_re;
                   x30e_re = s2*x30f_re;
                   x26d_re = x26e_re + x30e_re;
                   x30d_re = x26e_re - x30e_re;
                   x26e_im = x26f_im - x30f_im;
                   x30e_im = s2*x30f_im;
                   x26d_im = x26e_im + x30e_im;
                   x30d_im = x26e_im - x30e_im;
                   x27f_re = x27g_re - x29g_re;
                   x31f_re = s2*x31g_re;
                   x27e_re = x27f_re + x31f_re;
                   x31e_re = x27f_re - x31f_re;
                   x27f_im = x27g_im - x29g_im;
                   x31f_im = s2*x31g_im;
                   x27e_im = x27f_im + x31f_im;
                   x31e_im = x27f_im - x31f_im;
                   x25d_re = x25e_re - x27e_re;
                   x27d_re = s5*x27e_re;
                   x27c_re = x25d_re - x27d_re;
                   x25c_re = x25d_re + x27d_re;
                   x25d_im = x25e_im - x27e_im;
                   x27d_im = s5*x27e_im;
                   x27c_im = x25d_im - x27d_im;
                   x25c_im = x25d_im + x27d_im;
                   x29d_re = x29e_re - x31e_re;
                   x31d_re = s6*x31e_re;
                   x29c_re = x29d_re + x31d_re;
                   x31c_re = x29d_re - x31d_re;
                   x29d_im = x29e_im - x31e_im;
                   x31d_im = s6*x31e_im;
                   x29c_im = x29d_im + x31d_im;
                   x31c_im = x29d_im - x31d_im;

                   x20e_re = x20z_re - x28z_re;
                   x28e_re = x20z_re + x28z_re;
                   x20e_im = x20z_im - x28z_im;
                   x28e_im = x20z_im + x28z_im;
                   x28d_im = s1*x28e_im;
                   x24c_re = x24z_im + x28d_im;
                   x28c_re = x24z_im - x28d_im;
                   x26c_im = s3*x26d_im;
                   x24b_re = x24c_re + x26c_im;
                   x26b_re = x24c_re - x26c_im;
                   x25b_im = s7*x25c_im;
                   x24a_re = x24b_re + x25b_im;
                   x25a_re = x24b_re - x25b_im;
                   x28d_re = s1*x28e_re;
                   x24c_im = x28d_re + x24z_re;
                   x28c_im = x28d_re - x24z_re;
                   x26c_re = s3*x26d_re;
                   x24b_im = x26c_re + x24c_im;
                   x26b_im = x26c_re - x24c_im;
                   x25b_re = s7*x25c_re;
                   x24a_im = x25b_re + x24b_im;
                   x25a_im = x25b_re - x24b_im;
                   x20d_re = s1*x20e_re;
                   x20c_re = x16z_re - x20d_re;
                   x16c_re = x16z_re + x20d_re;
                   x18c_re = s3*x18d_re;
                   x16b_re = x16c_re + x18c_re;
                   x18b_re = x16c_re - x18c_re;
                   x17b_re = s7*x17c_re;
                   x16a_re = x16b_re + x17b_re;
                   x17a_re = x16b_re - x17b_re;
                   x20d_im = s1*x20e_im;
                   x20c_im = x16z_im - x20d_im;
                   x16c_im = x16z_im + x20d_im;
                   x18c_im = s3*x18d_im;
                   x16b_im = x16c_im + x18c_im;
                   x18b_im = x16c_im - x18c_im;
                   x17b_im = s7*x17c_im;
                   x16a_im = x16b_im + x17b_im;
                   x17a_im = x16b_im - x17b_im;

                   out[1*ospan+ll]    = x16a_re + x24a_re;
                   out[1*ospan+ll+1]  = x16a_im - x24a_im;
                   out[31*ospan+ll]   = x16a_re - x24a_re;
                   out[31*ospan+ll+1] = x16a_im + x24a_im;
                   out[15*ospan+ll]   = x17a_re - x25a_re;
                   out[15*ospan+ll+1] = x17a_im - x25a_im;
                   out[17*ospan+ll]   = x17a_re + x25a_re;
                   out[17*ospan+ll+1] = x17a_im + x25a_im;

                   x27b_im = s8*x27c_im;
                   x26a_re = x26b_re + x27b_im;
                   x27a_re = x26b_re - x27b_im;
                   x27b_re = s8*x27c_re;
                   x26a_im = x26b_im - x27b_re;
                   x27a_im = x26b_im + x27b_re;
                   x19b_re = s8*x19c_re;
                   x18a_re = x18b_re + x19b_re;
                   x19a_re = x18b_re - x19b_re;
                   x19b_im = s8*x19c_im;
                   x18a_im = x18b_im + x19b_im;
                   x19a_im = x18b_im - x19b_im;

                   out[7*ospan+ll]    = x18a_re - x26a_re;
                   out[7*ospan+ll+1]  = x18a_im - x26a_im;
                   out[25*ospan+ll]   = x18a_re + x26a_re;
                   out[25*ospan+ll+1] = x18a_im + x26a_im;
                   out[9*ospan+ll]    = x19a_re + x27a_re;
                   out[9*ospan+ll+1]  = x19a_im + x27a_im;
                   out[23*ospan+ll]   = x19a_re - x27a_re;
                   out[23*ospan+ll+1] = x19a_im - x27a_im;

                   x30c_im = s4*x30d_im;
                   x28b_re = x28c_re + x30c_im;
                   x30b_re = x28c_re - x30c_im;
                   x29b_im = s9*x29c_im;
                   x28a_re = x28b_re + x29b_im;
                   x29a_re = x28b_re - x29b_im;
                   x30c_re = s4*x30d_re;
                   x28b_im = x28c_im - x30c_re;
                   x30b_im = x28c_im + x30c_re;
                   x29b_re = s9*x29c_re;
                   x28a_im = x28b_im - x29b_re;
                   x29a_im = x28b_im + x29b_re;
                   x22c_re = s4*x22d_re;
                   x20b_re = x20c_re + x22c_re;
                   x22b_re = x20c_re - x22c_re;
                   x21b_re = s9*x21c_re;
                   x20a_re = x20b_re + x21b_re;
                   x21a_re = x20b_re - x21b_re;
                   x22c_im = s4*x22d_im;
                   x20b_im = x20c_im + x22c_im;
                   x22b_im = x20c_im - x22c_im;
                   x21b_im = s9*x21c_im;
                   x20a_im = x20b_im + x21b_im;
                   x21a_im = x20b_im - x21b_im;

                   out[3*ospan+ll]    = x20a_re - x28a_re;
                   out[3*ospan+ll+1]  = x20a_im - x28a_im;
                   out[29*ospan+ll]   = x20a_re + x28a_re;
                   out[29*ospan+ll+1] = x20a_im + x28a_im;
                   out[13*ospan+ll]   = x21a_re + x29a_re;
                   out[13*ospan+ll+1] = x21a_im + x29a_im;
                   out[19*ospan+ll]   = x21a_re - x29a_re;
                   out[19*ospan+ll+1] = x21a_im - x29a_im;

                   x23b_re = s10*x23c_re;
                   x22a_re = x22b_re + x23b_re;
                   x23a_re = x22b_re - x23b_re;
                   x23b_im = s10*x23c_im;
                   x22a_im = x22b_im + x23b_im;
                   x23a_im = x22b_im - x23b_im;
                   x31b_im = s10*x31c_im;
                   x30a_re = x30b_re + x31b_im;
                   x31a_re = x30b_re - x31b_im;
                   x31b_re = s10*x31c_re;
                   x31a_im = x30b_im + x31b_re;
                   x30a_im = x30b_im - x31b_re;

                   out[5*ospan+ll]    = x22a_re + x30a_re;
                   out[5*ospan+ll+1]  = x22a_im + x30a_im;
                   out[27*ospan+ll]   = x22a_re - x30a_re;
                   out[27*ospan+ll+1] = x22a_im - x30a_im;
                   out[11*ospan+ll]   = x23a_re - x31a_re;
                   out[11*ospan+ll+1] = x23a_im - x31a_im;
                   out[21*ospan+ll]   = x23a_re + x31a_re;
                   out[21*ospan+ll+1] = x23a_im + x31a_im;
            }
	}

	break;

      default:                                         /* Inverse Pass */
        if (ispan != ospan/2) {
            for (kk=0; kk<mm; kk+=2) {
                o00_re = twids[1*kk*ispan];   o00_im = twids[1*kk*ispan+1];
                o01_re = twids[2*kk*ispan];   o01_im = twids[2*kk*ispan+1];
                o02_re = twids[3*kk*ispan];   o02_im = twids[3*kk*ispan+1];
                o03_re = twids[4*kk*ispan];   o03_im = twids[4*kk*ispan+1];
                o04_re = twids[5*kk*ispan];   o04_im = twids[5*kk*ispan+1];
                o05_re = twids[6*kk*ispan];   o05_im = twids[6*kk*ispan+1];
                o06_re = twids[7*kk*ispan];   o06_im = twids[7*kk*ispan+1];
                o07_re = twids[8*kk*ispan];   o07_im = twids[8*kk*ispan+1];
                o08_re = twids[9*kk*ispan];   o08_im = twids[9*kk*ispan+1];
                o09_re = twids[10*kk*ispan];  o09_im = twids[10*kk*ispan+1];
                o10_re = twids[11*kk*ispan];  o10_im = twids[11*kk*ispan+1];
                o11_re = twids[12*kk*ispan];  o11_im = twids[12*kk*ispan+1];
                o12_re = twids[13*kk*ispan];  o12_im = twids[13*kk*ispan+1];
                o13_re = twids[14*kk*ispan];  o13_im = twids[14*kk*ispan+1];
                o14_re = twids[15*kk*ispan];  o14_im = twids[15*kk*ispan+1];
                o15_re = twids[16*kk*ispan];  o15_im = twids[16*kk*ispan+1];
                o16_re = twids[17*kk*ispan];  o16_im = twids[17*kk*ispan+1];
                o17_re = twids[18*kk*ispan];  o17_im = twids[18*kk*ispan+1];
                o18_re = twids[19*kk*ispan];  o18_im = twids[19*kk*ispan+1];
                o19_re = twids[20*kk*ispan];  o19_im = twids[20*kk*ispan+1];
                o20_re = twids[21*kk*ispan];  o20_im = twids[21*kk*ispan+1];
                o21_re = twids[22*kk*ispan];  o21_im = twids[22*kk*ispan+1];
                o22_re = twids[23*kk*ispan];  o22_im = twids[23*kk*ispan+1];
                o23_re = twids[24*kk*ispan];  o23_im = twids[24*kk*ispan+1];
                o24_re = twids[25*kk*ispan];  o24_im = twids[25*kk*ispan+1];
                o25_re = twids[26*kk*ispan];  o25_im = twids[26*kk*ispan+1];
                o26_re = twids[27*kk*ispan];  o26_im = twids[27*kk*ispan+1];
                o27_re = twids[28*kk*ispan];  o27_im = twids[28*kk*ispan+1];
                o28_re = twids[29*kk*ispan];  o28_im = twids[29*kk*ispan+1];
                o29_re = twids[30*kk*ispan];  o29_im = twids[30*kk*ispan+1];
                o30_re = twids[31*kk*ispan];  o30_im = twids[31*kk*ispan+1];
                istep  = kk*RADIXSIZE;

                for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[ispan*(istep+0)+ll];
                   t00_im = in[ispan*(istep+0)+ll+1];
                   t01_re = o00_re*in[ispan*(istep+ 2)+ll]   - o00_im*in[ispan*(istep+ 2)+ll+1];
                   t01_im = o00_re*in[ispan*(istep+ 2)+ll+1] + o00_im*in[ispan*(istep+ 2)+ll];
                   t02_re = o01_re*in[ispan*(istep+ 4)+ll]   - o01_im*in[ispan*(istep+ 4)+ll+1];
                   t02_im = o01_re*in[ispan*(istep+ 4)+ll+1] + o01_im*in[ispan*(istep+ 4)+ll];
                   t03_re = o02_re*in[ispan*(istep+ 6)+ll]   - o02_im*in[ispan*(istep+ 6)+ll+1];
                   t03_im = o02_re*in[ispan*(istep+ 6)+ll+1] + o02_im*in[ispan*(istep+ 6)+ll];
                   t04_re = o03_re*in[ispan*(istep+ 8)+ll]   - o03_im*in[ispan*(istep+ 8)+ll+1];
                   t04_im = o03_re*in[ispan*(istep+ 8)+ll+1] + o03_im*in[ispan*(istep+ 8)+ll];
                   t05_re = o04_re*in[ispan*(istep+10)+ll]   - o04_im*in[ispan*(istep+10)+ll+1];
                   t05_im = o04_re*in[ispan*(istep+10)+ll+1] + o04_im*in[ispan*(istep+10)+ll];
                   t06_re = o05_re*in[ispan*(istep+12)+ll]   - o05_im*in[ispan*(istep+12)+ll+1];
                   t06_im = o05_re*in[ispan*(istep+12)+ll+1] + o05_im*in[ispan*(istep+12)+ll];
                   t07_re = o06_re*in[ispan*(istep+14)+ll]   - o06_im*in[ispan*(istep+14)+ll+1];
                   t07_im = o06_re*in[ispan*(istep+14)+ll+1] + o06_im*in[ispan*(istep+14)+ll];
                   t08_re = o07_re*in[ispan*(istep+16)+ll]   - o07_im*in[ispan*(istep+16)+ll+1];
                   t08_im = o07_re*in[ispan*(istep+16)+ll+1] + o07_im*in[ispan*(istep+16)+ll];
                   t09_re = o08_re*in[ispan*(istep+18)+ll]   - o08_im*in[ispan*(istep+18)+ll+1];
                   t09_im = o08_re*in[ispan*(istep+18)+ll+1] + o08_im*in[ispan*(istep+18)+ll];
                   t10_re = o09_re*in[ispan*(istep+20)+ll]   - o09_im*in[ispan*(istep+20)+ll+1];
                   t10_im = o09_re*in[ispan*(istep+20)+ll+1] + o09_im*in[ispan*(istep+20)+ll];
                   t11_re = o10_re*in[ispan*(istep+22)+ll]   - o10_im*in[ispan*(istep+22)+ll+1];
                   t11_im = o10_re*in[ispan*(istep+22)+ll+1] + o10_im*in[ispan*(istep+22)+ll];
                   t12_re = o11_re*in[ispan*(istep+24)+ll]   - o11_im*in[ispan*(istep+24)+ll+1];
                   t12_im = o11_re*in[ispan*(istep+24)+ll+1] + o11_im*in[ispan*(istep+24)+ll];
                   t13_re = o12_re*in[ispan*(istep+26)+ll]   - o12_im*in[ispan*(istep+26)+ll+1];
                   t13_im = o12_re*in[ispan*(istep+26)+ll+1] + o12_im*in[ispan*(istep+26)+ll];
                   t14_re = o13_re*in[ispan*(istep+28)+ll]   - o13_im*in[ispan*(istep+28)+ll+1];
                   t14_im = o13_re*in[ispan*(istep+28)+ll+1] + o13_im*in[ispan*(istep+28)+ll];
                   t15_re = o14_re*in[ispan*(istep+30)+ll]   - o14_im*in[ispan*(istep+30)+ll+1];
                   t15_im = o14_re*in[ispan*(istep+30)+ll+1] + o14_im*in[ispan*(istep+30)+ll];
                   t16_re = o15_re*in[ispan*(istep+32)+ll]   - o15_im*in[ispan*(istep+32)+ll+1];
                   t16_im = o15_re*in[ispan*(istep+32)+ll+1] + o15_im*in[ispan*(istep+32)+ll];
                   t17_re = o16_re*in[ispan*(istep+34)+ll]   - o16_im*in[ispan*(istep+34)+ll+1];
                   t17_im = o16_re*in[ispan*(istep+34)+ll+1] + o16_im*in[ispan*(istep+34)+ll];
                   t18_re = o17_re*in[ispan*(istep+36)+ll]   - o17_im*in[ispan*(istep+36)+ll+1];
                   t18_im = o17_re*in[ispan*(istep+36)+ll+1] + o17_im*in[ispan*(istep+36)+ll];
                   t19_re = o18_re*in[ispan*(istep+38)+ll]   - o18_im*in[ispan*(istep+38)+ll+1];
                   t19_im = o18_re*in[ispan*(istep+38)+ll+1] + o18_im*in[ispan*(istep+38)+ll];
                   t20_re = o19_re*in[ispan*(istep+40)+ll]   - o19_im*in[ispan*(istep+40)+ll+1];
                   t20_im = o19_re*in[ispan*(istep+40)+ll+1] + o19_im*in[ispan*(istep+40)+ll];
                   t21_re = o20_re*in[ispan*(istep+42)+ll]   - o20_im*in[ispan*(istep+42)+ll+1];
                   t21_im = o20_re*in[ispan*(istep+42)+ll+1] + o20_im*in[ispan*(istep+42)+ll];
                   t22_re = o21_re*in[ispan*(istep+44)+ll]   - o21_im*in[ispan*(istep+44)+ll+1];
                   t22_im = o21_re*in[ispan*(istep+44)+ll+1] + o21_im*in[ispan*(istep+44)+ll];
                   t23_re = o22_re*in[ispan*(istep+46)+ll]   - o22_im*in[ispan*(istep+46)+ll+1];
                   t23_im = o22_re*in[ispan*(istep+46)+ll+1] + o22_im*in[ispan*(istep+46)+ll];
                   t24_re = o23_re*in[ispan*(istep+48)+ll]   - o23_im*in[ispan*(istep+48)+ll+1];
                   t24_im = o23_re*in[ispan*(istep+48)+ll+1] + o23_im*in[ispan*(istep+48)+ll];
                   t25_re = o24_re*in[ispan*(istep+50)+ll]   - o24_im*in[ispan*(istep+50)+ll+1];
                   t25_im = o24_re*in[ispan*(istep+50)+ll+1] + o24_im*in[ispan*(istep+50)+ll];
                   t26_re = o25_re*in[ispan*(istep+52)+ll]   - o25_im*in[ispan*(istep+52)+ll+1];
                   t26_im = o25_re*in[ispan*(istep+52)+ll+1] + o25_im*in[ispan*(istep+52)+ll];
                   t27_re = o26_re*in[ispan*(istep+54)+ll]   - o26_im*in[ispan*(istep+54)+ll+1];
                   t27_im = o26_re*in[ispan*(istep+54)+ll+1] + o26_im*in[ispan*(istep+54)+ll];
                   t28_re = o27_re*in[ispan*(istep+56)+ll]   - o27_im*in[ispan*(istep+56)+ll+1];
                   t28_im = o27_re*in[ispan*(istep+56)+ll+1] + o27_im*in[ispan*(istep+56)+ll];
                   t29_re = o28_re*in[ispan*(istep+58)+ll]   - o28_im*in[ispan*(istep+58)+ll+1];
                   t29_im = o28_re*in[ispan*(istep+58)+ll+1] + o28_im*in[ispan*(istep+58)+ll];
                   t30_re = o29_re*in[ispan*(istep+60)+ll]   - o29_im*in[ispan*(istep+60)+ll+1];
                   t30_im = o29_re*in[ispan*(istep+60)+ll+1] + o29_im*in[ispan*(istep+60)+ll];
                   t31_re = o30_re*in[ispan*(istep+62)+ll]   - o30_im*in[ispan*(istep+62)+ll+1];
                   t31_im = o30_re*in[ispan*(istep+62)+ll+1] + o30_im*in[ispan*(istep+62)+ll];

                   x00z_re = t00_re + t16_re;
                   x16z_re = t00_re - t16_re;
                   x00z_im = t00_im + t16_im;
                   x16z_im = t00_im - t16_im;
                   x01z_re = t01_re + t17_re;
                   x17z_re = t01_re - t17_re;
                   x01z_im = t01_im + t17_im;
                   x17z_im = t01_im - t17_im;
                   x02z_re = t02_re + t18_re;
                   x18z_re = t02_re - t18_re;
                   x02z_im = t02_im + t18_im;
                   x18z_im = t02_im - t18_im;
                   x03z_re = t03_re + t19_re;
                   x19z_re = t03_re - t19_re;
                   x03z_im = t03_im + t19_im;
                   x19z_im = t03_im - t19_im;
                   x04z_re = t04_re + t20_re;
                   x20z_re = t04_re - t20_re;
                   x04z_im = t04_im + t20_im;
                   x20z_im = t04_im - t20_im;
                   x05z_re = t05_re + t21_re;
                   x21z_re = t05_re - t21_re;
                   x05z_im = t05_im + t21_im;
                   x21z_im = t05_im - t21_im;
                   x06z_re = t06_re + t22_re;
                   x22z_re = t06_re - t22_re;
                   x06z_im = t06_im + t22_im;
                   x22z_im = t06_im - t22_im;
                   x07z_re = t07_re + t23_re;
                   x23z_re = t07_re - t23_re;
                   x07z_im = t07_im + t23_im;
                   x23z_im = t07_im - t23_im;
                   x08z_re = t08_re + t24_re;
                   x24z_re = t08_re - t24_re;
                   x08z_im = t08_im + t24_im;
                   x24z_im = t08_im - t24_im;
                   x09z_re = t09_re + t25_re;
                   x25z_re = t09_re - t25_re;
                   x09z_im = t09_im + t25_im;
                   x25z_im = t09_im - t25_im;
                   x10z_re = t10_re + t26_re;
                   x26z_re = t10_re - t26_re;
                   x10z_im = t10_im + t26_im;
                   x26z_im = t10_im - t26_im;
                   x11z_re = t11_re + t27_re;
                   x27z_re = t11_re - t27_re;
                   x11z_im = t11_im + t27_im;
                   x27z_im = t11_im - t27_im;
                   x12z_re = t12_re + t28_re;
                   x28z_re = t12_re - t28_re;
                   x12z_im = t12_im + t28_im;
                   x28z_im = t12_im - t28_im;
                   x13z_re = t13_re + t29_re;
                   x29z_re = t13_re - t29_re;
                   x13z_im = t13_im + t29_im;
                   x29z_im = t13_im - t29_im;
                   x14z_re = t14_re + t30_re;
                   x30z_re = t14_re - t30_re;
                   x14z_im = t14_im + t30_im;
                   x30z_im = t14_im - t30_im;
                   x15z_re = t15_re + t31_re;
                   x31z_re = t15_re - t31_re;
                   x15z_im = t15_im + t31_im;
                   x31z_im = t15_im - t31_im;

                   x00c_re = x00z_re + x08z_re;
                   x08c_re = x00z_re - x08z_re;
                   x00c_im = x00z_im + x08z_im;
                   x08c_im = x00z_im - x08z_im;
                   x02c_re = x02z_re + x10z_re;
                   x10e_re = x02z_re - x10z_re;
                   x02c_im = x02z_im + x10z_im;
                   x10e_im = x02z_im - x10z_im;
                   x04c_re = x04z_re + x12z_re;
                   x12c_re = x04z_re - x12z_re;
                   x04c_im = x04z_im + x12z_im;
                   x12c_im = x04z_im - x12z_im;
                   x06c_re = x06z_re + x14z_re;
                   x14e_re = x06z_re - x14z_re;
                   x06c_im = x06z_im + x14z_im;
                   x14e_im = x06z_im - x14z_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = x01z_re + x09z_re;
                   x09f_re = x01z_re - x09z_re;
                   x01c_im = x01z_im + x09z_im;
                   x09f_im = x01z_im - x09z_im;
                   x03c_re = x03z_re + x11z_re;
                   x11f_re = x03z_re - x11z_re;
                   x03c_im = x03z_im + x11z_im;
                   x11f_im = x03z_im - x11z_im;
                   x05e_re = x05z_re + x13z_re;
                   x13e_re = x05z_re - x13z_re;
                   x05e_im = x05z_im + x13z_im;
                   x13e_im = x05z_im - x13z_im;
                   x07e_re = x07z_re + x15z_re;
                   x15f_re = x07z_re - x15z_re;
                   x07e_im = x07z_im + x15z_im;
                   x15f_im = x07z_im - x15z_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[kk*ispan+0*ospan+ll]    = x00a_re + x01a_re;
                   out[kk*ispan+0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[kk*ispan+16*ospan+ll]   = x00a_re - x01a_re;
                   out[kk*ispan+16*ospan+ll+1] = x00a_im - x01a_im;
                   out[kk*ispan+8*ospan+ll]    = x02a_re - x03a_im;
                   out[kk*ispan+8*ospan+ll+1]  = x02a_im + x03a_re;
                   out[kk*ispan+24*ospan+ll]   = x02a_re + x03a_im;
                   out[kk*ispan+24*ospan+ll+1] = x02a_im - x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[kk*ispan+4*ospan+ll]    = x04a_re - x06a_re;
                   out[kk*ispan+4*ospan+ll+1]  = x04a_im + x06a_im;
                   out[kk*ispan+28*ospan+ll]   = x04a_re + x06a_re;
                   out[kk*ispan+28*ospan+ll+1] = x04a_im - x06a_im;
                   out[kk*ispan+12*ospan+ll]   = x05a_re + x07a_re;
                   out[kk*ispan+12*ospan+ll+1] = x05a_im - x07a_im;
                   out[kk*ispan+20*ospan+ll]   = x05a_re - x07a_re;
                   out[kk*ispan+20*ospan+ll+1] = x05a_im + x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[kk*ispan+2*ospan+ll]    = x08a_re - x12a_re;
                   out[kk*ispan+2*ospan+ll+1]  = x08a_im - x12a_im;
                   out[kk*ispan+30*ospan+ll]   = x08a_re + x12a_re;
                   out[kk*ispan+30*ospan+ll+1] = x08a_im + x12a_im;
                   out[kk*ispan+14*ospan+ll]   = x09a_re + x13a_re;
                   out[kk*ispan+14*ospan+ll+1] = x09a_im + x13a_im;
                   out[kk*ispan+18*ospan+ll]   = x09a_re - x13a_re;
                   out[kk*ispan+18*ospan+ll+1] = x09a_im - x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[kk*ispan+6*ospan+ll]    = x10a_re + x14a_re;
                   out[kk*ispan+6*ospan+ll+1]  = x10a_im + x14a_im;
                   out[kk*ispan+26*ospan+ll]   = x10a_re - x14a_re;
                   out[kk*ispan+26*ospan+ll+1] = x10a_im - x14a_im;
                   out[kk*ispan+10*ospan+ll]   = x11a_re - x15a_re;
                   out[kk*ispan+10*ospan+ll+1] = x11a_im - x15a_im;
                   out[kk*ispan+22*ospan+ll]   = x11a_re + x15a_re;
                   out[kk*ispan+22*ospan+ll+1] = x11a_im + x15a_im;

                   x17g_re = x17z_re - x31z_re;
                   x31g_re = x17z_re + x31z_re;
                   x17g_im = x17z_im - x31z_im;
                   x31g_im = x17z_im + x31z_im;
                   x21g_re = x21z_re - x27z_re;
                   x27g_re = x21z_re + x27z_re;
                   x21g_im = x21z_im - x27z_im;
                   x27g_im = x21z_im + x27z_im;
                   x23g_re = x23z_re - x25z_re;
                   x25g_re = x23z_re + x25z_re;
                   x23g_im = x23z_im - x25z_im;
                   x25g_im = x23z_im + x25z_im;
                   x17f_re = x17g_re - x23g_re;
                   x21f_re = s2*x21g_re;
                   x17e_re = x17f_re + x21f_re;
                   x21e_re = x17f_re - x21f_re;
                   x17f_im = x17g_im - x23g_im;
                   x21f_im = s2*x21g_im;
                   x17e_im = x17f_im + x21f_im;
                   x21e_im = x17f_im - x21f_im;

                   x18f_re = x18z_re - x30z_re;
                   x30f_re = x18z_re + x30z_re;
                   x18f_im = x18z_im - x30z_im;
                   x30f_im = x18z_im + x30z_im;
                   x22f_re = x22z_re - x26z_re;
                   x26f_re = x22z_re + x26z_re;
                   x22f_im = x22z_im - x26z_im;
                   x26f_im = x22z_im + x26z_im;
                   x18e_re = x18f_re - x22f_re;
                   x22e_re = s2*x22f_re;
                   x18d_re = x18e_re + x22e_re;
                   x22d_re = x18e_re - x22e_re;
                   x18e_im = x18f_im - x22f_im;
                   x22e_im = s2*x22f_im;
                   x18d_im = x18e_im + x22e_im;
                   x22d_im = x18e_im - x22e_im;

                   x19g_im = x19z_im - x29z_im;
                   x29g_im = x19z_im + x29z_im;
                   x19g_re = x19z_re - x29z_re;
                   x29g_re = x19z_re + x29z_re;
                   x19f_re = x19g_re - x21g_re;
                   x23f_re = s2*x23g_re;
                   x19e_re = x19f_re + x23f_re;
                   x23e_re = x19f_re - x23f_re;
                   x19f_im = x19g_im - x21g_im;
                   x23f_im = s2*x23g_im;
                   x19e_im = x19f_im + x23f_im;
                   x23e_im = x19f_im - x23f_im;
                   x17d_re = x17e_re - x19e_re;
                   x19d_re = s5*x19e_re;
                   x17c_re = x17d_re + x19d_re;
                   x19c_re = x17d_re - x19d_re;
                   x17d_im = x17e_im - x19e_im;
                   x19d_im = s5*x19e_im;
                   x17c_im = x17d_im + x19d_im;
                   x19c_im = x17d_im - x19d_im;
                   x21d_re = x21e_re - x23e_re;
                   x23d_re = s6*x23e_re;
                   x21c_re = x21d_re + x23d_re;
                   x23c_re = x21d_re - x23d_re;
                   x21d_im = x21e_im - x23e_im;
                   x23d_im = s6*x23e_im;
                   x21c_im = x21d_im + x23d_im;
                   x23c_im = x21d_im - x23d_im;
                   x25f_re = x25g_re - x31g_re;
                   x29f_re = s2*x29g_re;
                   x25e_re = x25f_re + x29f_re;
                   x29e_re = x25f_re - x29f_re;
                   x25f_im = x25g_im - x31g_im;
                   x29f_im = s2*x29g_im;
                   x25e_im = x25f_im + x29f_im;
                   x29e_im = x25f_im - x29f_im;
                   x26e_re = x26f_re - x30f_re;
                   x30e_re = s2*x30f_re;
                   x26d_re = x26e_re + x30e_re;
                   x30d_re = x26e_re - x30e_re;
                   x26e_im = x26f_im - x30f_im;
                   x30e_im = s2*x30f_im;
                   x26d_im = x26e_im + x30e_im;
                   x30d_im = x26e_im - x30e_im;
                   x27f_re = x27g_re - x29g_re;
                   x31f_re = s2*x31g_re;
                   x27e_re = x27f_re + x31f_re;
                   x31e_re = x27f_re - x31f_re;
                   x27f_im = x27g_im - x29g_im;
                   x31f_im = s2*x31g_im;
                   x27e_im = x27f_im + x31f_im;
                   x31e_im = x27f_im - x31f_im;
                   x25d_re = x25e_re - x27e_re;
                   x27d_re = s5*x27e_re;
                   x27c_re = x25d_re - x27d_re;
                   x25c_re = x25d_re + x27d_re;
                   x25d_im = x25e_im - x27e_im;
                   x27d_im = s5*x27e_im;
                   x27c_im = x25d_im - x27d_im;
                   x25c_im = x25d_im + x27d_im;
                   x29d_re = x29e_re - x31e_re;
                   x31d_re = s6*x31e_re;
                   x29c_re = x29d_re + x31d_re;
                   x31c_re = x29d_re - x31d_re;
                   x29d_im = x29e_im - x31e_im;
                   x31d_im = s6*x31e_im;
                   x29c_im = x29d_im + x31d_im;
                   x31c_im = x29d_im - x31d_im;

                   x20e_re = x20z_re - x28z_re;
                   x28e_re = x20z_re + x28z_re;
                   x20e_im = x20z_im - x28z_im;
                   x28e_im = x20z_im + x28z_im;
                   x28d_im = s1*x28e_im;
                   x24c_re = x24z_im + x28d_im;
                   x28c_re = x24z_im - x28d_im;
                   x26c_im = s3*x26d_im;
                   x24b_re = x24c_re + x26c_im;
                   x26b_re = x24c_re - x26c_im;
                   x25b_im = s7*x25c_im;
                   x24a_re = x24b_re + x25b_im;
                   x25a_re = x24b_re - x25b_im;
                   x28d_re = s1*x28e_re;
                   x24c_im = x28d_re + x24z_re;
                   x28c_im = x28d_re - x24z_re;
                   x26c_re = s3*x26d_re;
                   x24b_im = x26c_re + x24c_im;
                   x26b_im = x26c_re - x24c_im;
                   x25b_re = s7*x25c_re;
                   x24a_im = x25b_re + x24b_im;
                   x25a_im = x25b_re - x24b_im;
                   x20d_re = s1*x20e_re;
                   x20c_re = x16z_re - x20d_re;
                   x16c_re = x16z_re + x20d_re;
                   x18c_re = s3*x18d_re;
                   x16b_re = x16c_re + x18c_re;
                   x18b_re = x16c_re - x18c_re;
                   x17b_re = s7*x17c_re;
                   x16a_re = x16b_re + x17b_re;
                   x17a_re = x16b_re - x17b_re;
                   x20d_im = s1*x20e_im;
                   x20c_im = x16z_im - x20d_im;
                   x16c_im = x16z_im + x20d_im;
                   x18c_im = s3*x18d_im;
                   x16b_im = x16c_im + x18c_im;
                   x18b_im = x16c_im - x18c_im;
                   x17b_im = s7*x17c_im;
                   x16a_im = x16b_im + x17b_im;
                   x17a_im = x16b_im - x17b_im;

                   out[kk*ispan+1*ospan+ll]    = x16a_re - x24a_re;
                   out[kk*ispan+1*ospan+ll+1]  = x16a_im + x24a_im;
                   out[kk*ispan+31*ospan+ll]   = x16a_re + x24a_re;
                   out[kk*ispan+31*ospan+ll+1] = x16a_im - x24a_im;
                   out[kk*ispan+17*ospan+ll]   = x17a_re - x25a_re;
                   out[kk*ispan+17*ospan+ll+1] = x17a_im - x25a_im;
                   out[kk*ispan+15*ospan+ll]   = x17a_re + x25a_re;
                   out[kk*ispan+15*ospan+ll+1] = x17a_im + x25a_im;

                   x27b_im = s8*x27c_im;
                   x26a_re = x26b_re + x27b_im;
                   x27a_re = x26b_re - x27b_im;
                   x27b_re = s8*x27c_re;
                   x26a_im = x26b_im - x27b_re;
                   x27a_im = x26b_im + x27b_re;
                   x19b_re = s8*x19c_re;
                   x18a_re = x18b_re + x19b_re;
                   x19a_re = x18b_re - x19b_re;
                   x19b_im = s8*x19c_im;
                   x18a_im = x18b_im + x19b_im;
                   x19a_im = x18b_im - x19b_im;

                   out[kk*ispan+7*ospan+ll]    = x18a_re + x26a_re;
                   out[kk*ispan+7*ospan+ll+1]  = x18a_im + x26a_im;
                   out[kk*ispan+25*ospan+ll]   = x18a_re - x26a_re;
                   out[kk*ispan+25*ospan+ll+1] = x18a_im - x26a_im;
                   out[kk*ispan+9*ospan+ll]    = x19a_re - x27a_re;
                   out[kk*ispan+9*ospan+ll+1]  = x19a_im - x27a_im;
                   out[kk*ispan+23*ospan+ll]   = x19a_re + x27a_re;
                   out[kk*ispan+23*ospan+ll+1] = x19a_im + x27a_im;

                   x30c_im = s4*x30d_im;
                   x28b_re = x28c_re + x30c_im;
                   x30b_re = x28c_re - x30c_im;
                   x29b_im = s9*x29c_im;
                   x28a_re = x28b_re + x29b_im;
                   x29a_re = x28b_re - x29b_im;
                   x30c_re = s4*x30d_re;
                   x28b_im = x28c_im - x30c_re;
                   x30b_im = x28c_im + x30c_re;
                   x29b_re = s9*x29c_re;
                   x28a_im = x28b_im - x29b_re;
                   x29a_im = x28b_im + x29b_re;
                   x22c_re = s4*x22d_re;
                   x20b_re = x20c_re + x22c_re;
                   x22b_re = x20c_re - x22c_re;
                   x21b_re = s9*x21c_re;
                   x20a_re = x20b_re + x21b_re;
                   x21a_re = x20b_re - x21b_re;
                   x22c_im = s4*x22d_im;
                   x20b_im = x20c_im + x22c_im;
                   x22b_im = x20c_im - x22c_im;
                   x21b_im = s9*x21c_im;
                   x20a_im = x20b_im + x21b_im;
                   x21a_im = x20b_im - x21b_im;

                   out[kk*ispan+3*ospan+ll]    = x20a_re + x28a_re;
                   out[kk*ispan+3*ospan+ll+1]  = x20a_im + x28a_im;
                   out[kk*ispan+29*ospan+ll]   = x20a_re - x28a_re;
                   out[kk*ispan+29*ospan+ll+1] = x20a_im - x28a_im;
                   out[kk*ispan+13*ospan+ll]   = x21a_re - x29a_re;
                   out[kk*ispan+13*ospan+ll+1] = x21a_im - x29a_im;
                   out[kk*ispan+19*ospan+ll]   = x21a_re + x29a_re;
                   out[kk*ispan+19*ospan+ll+1] = x21a_im + x29a_im;

                   x23b_re = s10*x23c_re;
                   x22a_re = x22b_re + x23b_re;
                   x23a_re = x22b_re - x23b_re;
                   x23b_im = s10*x23c_im;
                   x22a_im = x22b_im + x23b_im;
                   x23a_im = x22b_im - x23b_im;
                   x31b_im = s10*x31c_im;
                   x30a_re = x30b_re + x31b_im;
                   x31a_re = x30b_re - x31b_im;
                   x31b_re = s10*x31c_re;
                   x31a_im = x30b_im + x31b_re;
                   x30a_im = x30b_im - x31b_re;

                   out[kk*ispan+5*ospan+ll]    = x22a_re - x30a_re;
                   out[kk*ispan+5*ospan+ll+1]  = x22a_im - x30a_im;
                   out[kk*ispan+27*ospan+ll]   = x22a_re + x30a_re;
                   out[kk*ispan+27*ospan+ll+1] = x22a_im + x30a_im;
                   out[kk*ispan+11*ospan+ll]   = x23a_re + x31a_re;
                   out[kk*ispan+11*ospan+ll+1] = x23a_im + x31a_im;
                   out[kk*ispan+21*ospan+ll]   = x23a_re - x31a_re;
                   out[kk*ispan+21*ospan+ll+1] = x23a_im - x31a_im;
                }
            }
	}
	else {
            for (ll=0; ll<ispan*2; ll+=2) {
                   t00_re = in[0*ispan+ll];
                   t00_im = in[0*ispan+ll+1];
                   t01_re = in[2*ispan+ll];
                   t01_im = in[2*ispan+ll+1];
                   t02_re = in[4*ispan+ll];
                   t02_im = in[4*ispan+ll+1];
                   t03_re = in[6*ispan+ll];
                   t03_im = in[6*ispan+ll+1];
                   t04_re = in[8*ispan+ll];
                   t04_im = in[8*ispan+ll+1];
                   t05_re = in[10*ispan+ll];
                   t05_im = in[10*ispan+ll+1];
                   t06_re = in[12*ispan+ll];
                   t06_im = in[12*ispan+ll+1];
                   t07_re = in[14*ispan+ll];
                   t07_im = in[14*ispan+ll+1];
                   t08_re = in[16*ispan+ll];
                   t08_im = in[16*ispan+ll+1];
                   t09_re = in[18*ispan+ll];
                   t09_im = in[18*ispan+ll+1];
                   t10_re = in[20*ispan+ll];
                   t10_im = in[20*ispan+ll+1];
                   t11_re = in[22*ispan+ll];
                   t11_im = in[22*ispan+ll+1];
                   t12_re = in[24*ispan+ll];
                   t12_im = in[24*ispan+ll+1];
                   t13_re = in[26*ispan+ll];
                   t13_im = in[26*ispan+ll+1];
                   t14_re = in[28*ispan+ll];
                   t14_im = in[28*ispan+ll+1];
                   t15_re = in[30*ispan+ll];
                   t15_im = in[30*ispan+ll+1];
                   t16_re = in[32*ispan+ll];
                   t16_im = in[32*ispan+ll+1];
                   t17_re = in[34*ispan+ll];
                   t17_im = in[34*ispan+ll+1];
                   t18_re = in[36*ispan+ll];
                   t18_im = in[36*ispan+ll+1];
                   t19_re = in[38*ispan+ll];
                   t19_im = in[38*ispan+ll+1];
                   t20_re = in[40*ispan+ll];
                   t20_im = in[40*ispan+ll+1];
                   t21_re = in[42*ispan+ll];
                   t21_im = in[42*ispan+ll+1];
                   t22_re = in[44*ispan+ll];
                   t22_im = in[44*ispan+ll+1];
                   t23_re = in[46*ispan+ll];
                   t23_im = in[46*ispan+ll+1];
                   t24_re = in[48*ispan+ll];
                   t24_im = in[48*ispan+ll+1];
                   t25_re = in[50*ispan+ll];
                   t25_im = in[50*ispan+ll+1];
                   t26_re = in[52*ispan+ll];
                   t26_im = in[52*ispan+ll+1];
                   t27_re = in[54*ispan+ll];
                   t27_im = in[54*ispan+ll+1];
                   t28_re = in[56*ispan+ll];
                   t28_im = in[56*ispan+ll+1];
                   t29_re = in[58*ispan+ll];
                   t29_im = in[58*ispan+ll+1];
                   t30_re = in[60*ispan+ll];
                   t30_im = in[60*ispan+ll+1];
                   t31_re = in[62*ispan+ll];
                   t31_im = in[62*ispan+ll+1];

                   x00z_re = t00_re + t16_re;
                   x16z_re = t00_re - t16_re;
                   x00z_im = t00_im + t16_im;
                   x16z_im = t00_im - t16_im;
                   x01z_re = t01_re + t17_re;
                   x17z_re = t01_re - t17_re;
                   x01z_im = t01_im + t17_im;
                   x17z_im = t01_im - t17_im;
                   x02z_re = t02_re + t18_re;
                   x18z_re = t02_re - t18_re;
                   x02z_im = t02_im + t18_im;
                   x18z_im = t02_im - t18_im;
                   x03z_re = t03_re + t19_re;
                   x19z_re = t03_re - t19_re;
                   x03z_im = t03_im + t19_im;
                   x19z_im = t03_im - t19_im;
                   x04z_re = t04_re + t20_re;
                   x20z_re = t04_re - t20_re;
                   x04z_im = t04_im + t20_im;
                   x20z_im = t04_im - t20_im;
                   x05z_re = t05_re + t21_re;
                   x21z_re = t05_re - t21_re;
                   x05z_im = t05_im + t21_im;
                   x21z_im = t05_im - t21_im;
                   x06z_re = t06_re + t22_re;
                   x22z_re = t06_re - t22_re;
                   x06z_im = t06_im + t22_im;
                   x22z_im = t06_im - t22_im;
                   x07z_re = t07_re + t23_re;
                   x23z_re = t07_re - t23_re;
                   x07z_im = t07_im + t23_im;
                   x23z_im = t07_im - t23_im;
                   x08z_re = t08_re + t24_re;
                   x24z_re = t08_re - t24_re;
                   x08z_im = t08_im + t24_im;
                   x24z_im = t08_im - t24_im;
                   x09z_re = t09_re + t25_re;
                   x25z_re = t09_re - t25_re;
                   x09z_im = t09_im + t25_im;
                   x25z_im = t09_im - t25_im;
                   x10z_re = t10_re + t26_re;
                   x26z_re = t10_re - t26_re;
                   x10z_im = t10_im + t26_im;
                   x26z_im = t10_im - t26_im;
                   x11z_re = t11_re + t27_re;
                   x27z_re = t11_re - t27_re;
                   x11z_im = t11_im + t27_im;
                   x27z_im = t11_im - t27_im;
                   x12z_re = t12_re + t28_re;
                   x28z_re = t12_re - t28_re;
                   x12z_im = t12_im + t28_im;
                   x28z_im = t12_im - t28_im;
                   x13z_re = t13_re + t29_re;
                   x29z_re = t13_re - t29_re;
                   x13z_im = t13_im + t29_im;
                   x29z_im = t13_im - t29_im;
                   x14z_re = t14_re + t30_re;
                   x30z_re = t14_re - t30_re;
                   x14z_im = t14_im + t30_im;
                   x30z_im = t14_im - t30_im;
                   x15z_re = t15_re + t31_re;
                   x31z_re = t15_re - t31_re;
                   x15z_im = t15_im + t31_im;
                   x31z_im = t15_im - t31_im;

                   x00c_re = x00z_re + x08z_re;
                   x08c_re = x00z_re - x08z_re;
                   x00c_im = x00z_im + x08z_im;
                   x08c_im = x00z_im - x08z_im;
                   x02c_re = x02z_re + x10z_re;
                   x10e_re = x02z_re - x10z_re;
                   x02c_im = x02z_im + x10z_im;
                   x10e_im = x02z_im - x10z_im;
                   x04c_re = x04z_re + x12z_re;
                   x12c_re = x04z_re - x12z_re;
                   x04c_im = x04z_im + x12z_im;
                   x12c_im = x04z_im - x12z_im;
                   x06c_re = x06z_re + x14z_re;
                   x14e_re = x06z_re - x14z_re;
                   x06c_im = x06z_im + x14z_im;
                   x14e_im = x06z_im - x14z_im;
                   x00b_re = x00c_re + x04c_re;
                   x04b_re = x00c_re - x04c_re;
                   x02b_re = x02c_re + x06c_re;
                   x06b_re = x02c_re - x06c_re;
                   x00a_re = x00b_re + x02b_re;
                   x02a_re = x00b_re - x02b_re;
                   x00b_im = x00c_im + x04c_im;
                   x04b_im = x00c_im - x04c_im;
                   x02b_im = x02c_im + x06c_im;
                   x06b_im = x02c_im - x06c_im;
                   x00a_im = x00b_im + x02b_im;
                   x02a_im = x00b_im - x02b_im;
                   x01c_re = x01z_re + x09z_re;
                   x09f_re = x01z_re - x09z_re;
                   x01c_im = x01z_im + x09z_im;
                   x09f_im = x01z_im - x09z_im;
                   x03c_re = x03z_re + x11z_re;
                   x11f_re = x03z_re - x11z_re;
                   x03c_im = x03z_im + x11z_im;
                   x11f_im = x03z_im - x11z_im;
                   x05e_re = x05z_re + x13z_re;
                   x13e_re = x05z_re - x13z_re;
                   x05e_im = x05z_im + x13z_im;
                   x13e_im = x05z_im - x13z_im;
                   x07e_re = x07z_re + x15z_re;
                   x15f_re = x07z_re - x15z_re;
                   x07e_im = x07z_im + x15z_im;
                   x15f_im = x07z_im - x15z_im;
                   x01b_re = x01c_re + x05e_re;
                   x05d_re = x01c_re - x05e_re;
                   x03b_re = x03c_re + x07e_re;
                   x07d_re = x03c_re - x07e_re;
                   x01a_re = x01b_re + x03b_re;
                   x03a_re = x01b_re - x03b_re;
                   x01b_im = x01c_im + x05e_im;
                   x05d_im = x01c_im - x05e_im;
                   x03b_im = x03c_im + x07e_im;
                   x07d_im = x03c_im - x07e_im;
                   x01a_im = x01b_im + x03b_im;
                   x03a_im = x01b_im - x03b_im;

                   out[0*ospan+ll]    = x00a_re + x01a_re;
                   out[0*ospan+ll+1]  = x00a_im + x01a_im;
                   out[16*ospan+ll]   = x00a_re - x01a_re;
                   out[16*ospan+ll+1] = x00a_im - x01a_im;
                   out[8*ospan+ll]    = x02a_re - x03a_im;
                   out[8*ospan+ll+1]  = x02a_im + x03a_re;
                   out[24*ospan+ll]   = x02a_re + x03a_im;
                   out[24*ospan+ll+1] = x02a_im - x03a_re;

                   x07c_re = x05d_re + x07d_re;
                   x05c_re = x05d_re - x07d_re;
                   x05b_re = s1*x05c_re;
                   x04a_re = x04b_re + x05b_re;
                   x05a_re = x04b_re - x05b_re;
                   x07b_re = s1*x07c_re;
                   x06a_im = x06b_re + x07b_re;
                   x07a_im = x06b_re - x07b_re;
                   x07c_im = x05d_im + x07d_im;
                   x05c_im = x05d_im - x07d_im;
                   x05b_im = s1*x05c_im;
                   x04a_im = x04b_im + x05b_im;
                   x05a_im = x04b_im - x05b_im;
                   x07b_im = s1*x07c_im;
                   x06a_re = x06b_im + x07b_im;
                   x07a_re = x06b_im - x07b_im;

                   out[4*ospan+ll]    = x04a_re - x06a_re;
                   out[4*ospan+ll+1]  = x04a_im + x06a_im;
                   out[28*ospan+ll]   = x04a_re + x06a_re;
                   out[28*ospan+ll+1] = x04a_im - x06a_im;
                   out[12*ospan+ll]   = x05a_re + x07a_re;
                   out[12*ospan+ll+1] = x05a_im - x07a_im;
                   out[20*ospan+ll]   = x05a_re - x07a_re;
                   out[20*ospan+ll+1] = x05a_im + x07a_im;

                   x09e_re = x09f_re - x15f_re;
                   x15e_re = x09f_re + x15f_re;
                   x09e_im = x09f_im - x15f_im;
                   x15e_im = x09f_im + x15f_im;
                   x11e_re = x11f_re - x13e_re;
                   x13d_re = x11f_re + x13e_re;
                   x13d_re = x13d_re - x15e_re;
                   x15d_re = s2*x15e_re;
                   x13c_re = x13d_re + x15d_re;
                   x15c_re = x13d_re - x15d_re;
                   x11e_im = x11f_im - x13e_im;
                   x13d_im = x11f_im + x13e_im;
                   x13d_im = x13d_im - x15e_im;
                   x15d_im = s2*x15e_im;
                   x13c_im = x13d_im + x15d_im;
                   x15c_im = x13d_im - x15d_im;
                   x14d_re = x10e_re + x14e_re;
                   x10d_re = x10e_re - x14e_re;
                   x10c_re = s1*x10d_re;
                   x08b_re = x08c_re + x10c_re;
                   x10b_re = x08c_re - x10c_re;
                   x14c_re = s1*x14d_re;
                   x14d_im = x10e_im + x14e_im;
                   x10d_im = x10e_im - x14e_im;
                   x10c_im = s1*x10d_im;
                   x08b_im = x08c_im + x10c_im;
                   x10b_im = x08c_im - x10c_im;
                   x14c_im = s1*x14d_im;
                   x12b_im = -x12c_re - x14c_re;
                   x14b_im = -x12c_re + x14c_re;
                   x12b_re = x12c_im + x14c_im;
                   x14b_re = x12c_im - x14c_im;
                   x09d_re = x09e_re - x11e_re;
                   x11d_re = s2*x11e_re;
                   x09c_re = x09d_re + x11d_re;
                   x11c_re = x09d_re - x11d_re;
                   x09b_re = s3*x09c_re;
                   x08a_re = x08b_re + x09b_re;
                   x09a_re = x08b_re - x09b_re;
                   x09d_im = x09e_im - x11e_im;
                   x11d_im = s2*x11e_im;
                   x09c_im = x09d_im + x11d_im;
                   x11c_im = x09d_im - x11d_im;
                   x09b_im = s3*x09c_im;
                   x08a_im = x08b_im + x09b_im;
                   x09a_im = x08b_im - x09b_im;
                   x13b_im = s3*x13c_im;
                   x12a_re = x12b_re + x13b_im;
                   x13a_re = x12b_re - x13b_im;
                   x13b_re = s3*x13c_re;
                   x12a_im = x12b_im - x13b_re;
                   x13a_im = x12b_im + x13b_re;

                   out[2*ospan+ll]    = x08a_re - x12a_re;
                   out[2*ospan+ll+1]  = x08a_im - x12a_im;
                   out[30*ospan+ll]   = x08a_re + x12a_re;
                   out[30*ospan+ll+1] = x08a_im + x12a_im;
                   out[14*ospan+ll]   = x09a_re + x13a_re;
                   out[14*ospan+ll+1] = x09a_im + x13a_im;
                   out[18*ospan+ll]   = x09a_re - x13a_re;
                   out[18*ospan+ll+1] = x09a_im - x13a_im;

                   x11b_re = s4*x11c_re;
                   x10a_re = x10b_re + x11b_re;
                   x11a_re = x10b_re - x11b_re;
                   x11b_im = s4*x11c_im;
                   x10a_im = x10b_im + x11b_im;
                   x11a_im = x10b_im - x11b_im;
                   x15b_im = s4*x15c_im;
                   x14a_re = x14b_re + x15b_im;
                   x15a_re = x14b_re - x15b_im;
                   x15b_re = s4*x15c_re;
                   x14a_im = x14b_im - x15b_re;
                   x15a_im = x14b_im + x15b_re;

                   out[6*ospan+ll]    = x10a_re + x14a_re;
                   out[6*ospan+ll+1]  = x10a_im + x14a_im;
                   out[26*ospan+ll]   = x10a_re - x14a_re;
                   out[26*ospan+ll+1] = x10a_im - x14a_im;
                   out[10*ospan+ll]   = x11a_re - x15a_re;
                   out[10*ospan+ll+1] = x11a_im - x15a_im;
                   out[22*ospan+ll]   = x11a_re + x15a_re;
                   out[22*ospan+ll+1] = x11a_im + x15a_im;

                   x17g_re = x17z_re - x31z_re;
                   x31g_re = x17z_re + x31z_re;
                   x17g_im = x17z_im - x31z_im;
                   x31g_im = x17z_im + x31z_im;
                   x21g_re = x21z_re - x27z_re;
                   x27g_re = x21z_re + x27z_re;
                   x21g_im = x21z_im - x27z_im;
                   x27g_im = x21z_im + x27z_im;
                   x23g_re = x23z_re - x25z_re;
                   x25g_re = x23z_re + x25z_re;
                   x23g_im = x23z_im - x25z_im;
                   x25g_im = x23z_im + x25z_im;
                   x17f_re = x17g_re - x23g_re;
                   x21f_re = s2*x21g_re;
                   x17e_re = x17f_re + x21f_re;
                   x21e_re = x17f_re - x21f_re;
                   x17f_im = x17g_im - x23g_im;
                   x21f_im = s2*x21g_im;
                   x17e_im = x17f_im + x21f_im;
                   x21e_im = x17f_im - x21f_im;

                   x18f_re = x18z_re - x30z_re;
                   x30f_re = x18z_re + x30z_re;
                   x18f_im = x18z_im - x30z_im;
                   x30f_im = x18z_im + x30z_im;
                   x22f_re = x22z_re - x26z_re;
                   x26f_re = x22z_re + x26z_re;
                   x22f_im = x22z_im - x26z_im;
                   x26f_im = x22z_im + x26z_im;
                   x18e_re = x18f_re - x22f_re;
                   x22e_re = s2*x22f_re;
                   x18d_re = x18e_re + x22e_re;
                   x22d_re = x18e_re - x22e_re;
                   x18e_im = x18f_im - x22f_im;
                   x22e_im = s2*x22f_im;
                   x18d_im = x18e_im + x22e_im;
                   x22d_im = x18e_im - x22e_im;

                   x19g_im = x19z_im - x29z_im;
                   x29g_im = x19z_im + x29z_im;
                   x19g_re = x19z_re - x29z_re;
                   x29g_re = x19z_re + x29z_re;
                   x19f_re = x19g_re - x21g_re;
                   x23f_re = s2*x23g_re;
                   x19e_re = x19f_re + x23f_re;
                   x23e_re = x19f_re - x23f_re;
                   x19f_im = x19g_im - x21g_im;
                   x23f_im = s2*x23g_im;
                   x19e_im = x19f_im + x23f_im;
                   x23e_im = x19f_im - x23f_im;
                   x17d_re = x17e_re - x19e_re;
                   x19d_re = s5*x19e_re;
                   x17c_re = x17d_re + x19d_re;
                   x19c_re = x17d_re - x19d_re;
                   x17d_im = x17e_im - x19e_im;
                   x19d_im = s5*x19e_im;
                   x17c_im = x17d_im + x19d_im;
                   x19c_im = x17d_im - x19d_im;
                   x21d_re = x21e_re - x23e_re;
                   x23d_re = s6*x23e_re;
                   x21c_re = x21d_re + x23d_re;
                   x23c_re = x21d_re - x23d_re;
                   x21d_im = x21e_im - x23e_im;
                   x23d_im = s6*x23e_im;
                   x21c_im = x21d_im + x23d_im;
                   x23c_im = x21d_im - x23d_im;
                   x25f_re = x25g_re - x31g_re;
                   x29f_re = s2*x29g_re;
                   x25e_re = x25f_re + x29f_re;
                   x29e_re = x25f_re - x29f_re;
                   x25f_im = x25g_im - x31g_im;
                   x29f_im = s2*x29g_im;
                   x25e_im = x25f_im + x29f_im;
                   x29e_im = x25f_im - x29f_im;
                   x26e_re = x26f_re - x30f_re;
                   x30e_re = s2*x30f_re;
                   x26d_re = x26e_re + x30e_re;
                   x30d_re = x26e_re - x30e_re;
                   x26e_im = x26f_im - x30f_im;
                   x30e_im = s2*x30f_im;
                   x26d_im = x26e_im + x30e_im;
                   x30d_im = x26e_im - x30e_im;
                   x27f_re = x27g_re - x29g_re;
                   x31f_re = s2*x31g_re;
                   x27e_re = x27f_re + x31f_re;
                   x31e_re = x27f_re - x31f_re;
                   x27f_im = x27g_im - x29g_im;
                   x31f_im = s2*x31g_im;
                   x27e_im = x27f_im + x31f_im;
                   x31e_im = x27f_im - x31f_im;
                   x25d_re = x25e_re - x27e_re;
                   x27d_re = s5*x27e_re;
                   x27c_re = x25d_re - x27d_re;
                   x25c_re = x25d_re + x27d_re;
                   x25d_im = x25e_im - x27e_im;
                   x27d_im = s5*x27e_im;
                   x27c_im = x25d_im - x27d_im;
                   x25c_im = x25d_im + x27d_im;
                   x29d_re = x29e_re - x31e_re;
                   x31d_re = s6*x31e_re;
                   x29c_re = x29d_re + x31d_re;
                   x31c_re = x29d_re - x31d_re;
                   x29d_im = x29e_im - x31e_im;
                   x31d_im = s6*x31e_im;
                   x29c_im = x29d_im + x31d_im;
                   x31c_im = x29d_im - x31d_im;

                   x20e_re = x20z_re - x28z_re;
                   x28e_re = x20z_re + x28z_re;
                   x20e_im = x20z_im - x28z_im;
                   x28e_im = x20z_im + x28z_im;
                   x28d_im = s1*x28e_im;
                   x24c_re = x24z_im + x28d_im;
                   x28c_re = x24z_im - x28d_im;
                   x26c_im = s3*x26d_im;
                   x24b_re = x24c_re + x26c_im;
                   x26b_re = x24c_re - x26c_im;
                   x25b_im = s7*x25c_im;
                   x24a_re = x24b_re + x25b_im;
                   x25a_re = x24b_re - x25b_im;
                   x28d_re = s1*x28e_re;
                   x24c_im = x28d_re + x24z_re;
                   x28c_im = x28d_re - x24z_re;
                   x26c_re = s3*x26d_re;
                   x24b_im = x26c_re + x24c_im;
                   x26b_im = x26c_re - x24c_im;
                   x25b_re = s7*x25c_re;
                   x24a_im = x25b_re + x24b_im;
                   x25a_im = x25b_re - x24b_im;
                   x20d_re = s1*x20e_re;
                   x20c_re = x16z_re - x20d_re;
                   x16c_re = x16z_re + x20d_re;
                   x18c_re = s3*x18d_re;
                   x16b_re = x16c_re + x18c_re;
                   x18b_re = x16c_re - x18c_re;
                   x17b_re = s7*x17c_re;
                   x16a_re = x16b_re + x17b_re;
                   x17a_re = x16b_re - x17b_re;
                   x20d_im = s1*x20e_im;
                   x20c_im = x16z_im - x20d_im;
                   x16c_im = x16z_im + x20d_im;
                   x18c_im = s3*x18d_im;
                   x16b_im = x16c_im + x18c_im;
                   x18b_im = x16c_im - x18c_im;
                   x17b_im = s7*x17c_im;
                   x16a_im = x16b_im + x17b_im;
                   x17a_im = x16b_im - x17b_im;

                   out[1*ospan+ll]    = x16a_re - x24a_re;
                   out[1*ospan+ll+1]  = x16a_im + x24a_im;
                   out[31*ospan+ll]   = x16a_re + x24a_re;
                   out[31*ospan+ll+1] = x16a_im - x24a_im;
                   out[17*ospan+ll]   = x17a_re - x25a_re;
                   out[17*ospan+ll+1] = x17a_im - x25a_im;
                   out[15*ospan+ll]   = x17a_re + x25a_re;
                   out[15*ospan+ll+1] = x17a_im + x25a_im;

                   x27b_im = s8*x27c_im;
                   x26a_re = x26b_re + x27b_im;
                   x27a_re = x26b_re - x27b_im;
                   x27b_re = s8*x27c_re;
                   x26a_im = x26b_im - x27b_re;
                   x27a_im = x26b_im + x27b_re;
                   x19b_re = s8*x19c_re;
                   x18a_re = x18b_re + x19b_re;
                   x19a_re = x18b_re - x19b_re;
                   x19b_im = s8*x19c_im;
                   x18a_im = x18b_im + x19b_im;
                   x19a_im = x18b_im - x19b_im;

                   out[7*ospan+ll]    = x18a_re + x26a_re;
                   out[7*ospan+ll+1]  = x18a_im + x26a_im;
                   out[25*ospan+ll]   = x18a_re - x26a_re;
                   out[25*ospan+ll+1] = x18a_im - x26a_im;
                   out[9*ospan+ll]    = x19a_re - x27a_re;
                   out[9*ospan+ll+1]  = x19a_im - x27a_im;
                   out[23*ospan+ll]   = x19a_re + x27a_re;
                   out[23*ospan+ll+1] = x19a_im + x27a_im;

                   x30c_im = s4*x30d_im;
                   x28b_re = x28c_re + x30c_im;
                   x30b_re = x28c_re - x30c_im;
                   x29b_im = s9*x29c_im;
                   x28a_re = x28b_re + x29b_im;
                   x29a_re = x28b_re - x29b_im;
                   x30c_re = s4*x30d_re;
                   x28b_im = x28c_im - x30c_re;
                   x30b_im = x28c_im + x30c_re;
                   x29b_re = s9*x29c_re;
                   x28a_im = x28b_im - x29b_re;
                   x29a_im = x28b_im + x29b_re;
                   x22c_re = s4*x22d_re;
                   x20b_re = x20c_re + x22c_re;
                   x22b_re = x20c_re - x22c_re;
                   x21b_re = s9*x21c_re;
                   x20a_re = x20b_re + x21b_re;
                   x21a_re = x20b_re - x21b_re;
                   x22c_im = s4*x22d_im;
                   x20b_im = x20c_im + x22c_im;
                   x22b_im = x20c_im - x22c_im;
                   x21b_im = s9*x21c_im;
                   x20a_im = x20b_im + x21b_im;
                   x21a_im = x20b_im - x21b_im;

                   out[3*ospan+ll]    = x20a_re + x28a_re;
                   out[3*ospan+ll+1]  = x20a_im + x28a_im;
                   out[29*ospan+ll]   = x20a_re - x28a_re;
                   out[29*ospan+ll+1] = x20a_im - x28a_im;
                   out[13*ospan+ll]   = x21a_re - x29a_re;
                   out[13*ospan+ll+1] = x21a_im - x29a_im;
                   out[19*ospan+ll]   = x21a_re + x29a_re;
                   out[19*ospan+ll+1] = x21a_im + x29a_im;

                   x23b_re = s10*x23c_re;
                   x22a_re = x22b_re + x23b_re;
                   x23a_re = x22b_re - x23b_re;
                   x23b_im = s10*x23c_im;
                   x22a_im = x22b_im + x23b_im;
                   x23a_im = x22b_im - x23b_im;
                   x31b_im = s10*x31c_im;
                   x30a_re = x30b_re + x31b_im;
                   x31a_re = x30b_re - x31b_im;
                   x31b_re = s10*x31c_re;
                   x31a_im = x30b_im + x31b_re;
                   x30a_im = x30b_im - x31b_re;

                   out[5*ospan+ll]    = x22a_re - x30a_re;
                   out[5*ospan+ll+1]  = x22a_im - x30a_im;
                   out[27*ospan+ll]   = x22a_re + x30a_re;
                   out[27*ospan+ll+1] = x22a_im + x30a_im;
                   out[11*ospan+ll]   = x23a_re + x31a_re;
                   out[11*ospan+ll+1] = x23a_im + x31a_im;
                   out[21*ospan+ll]   = x23a_re - x31a_re;
                   out[21*ospan+ll+1] = x23a_im - x31a_im;
            }
	}

	break;
    }

    return;
}



void radixpass_generic(float[] in,        float[] out, float[] twids,
                       int     size,      int     la,  int     dirflag,
                       int     radixsize, float[] tt,  float[] wn)
{
/* Local variables */
    int   kk, ll, mm;
    int   istep, ispan, ospan;
    int   irow, icol;
    float wxx_re, wxx_im;
    float xxx_re, xxx_im;
    float txx_re, txx_im;
    float yxx_re, yxx_im;

 /* Verify parameters */
    if (size < radixsize || la < 1) return;

 /* Initialize pointers */
    ospan = 2*size/radixsize;
    ispan = la;
    mm    = ospan/ispan;

    switch (dirflag) {
      case FFT_FLAGS_FORWARD:                            /* Forward Pass */
        for (kk=0; kk<mm; kk+=2) {
            istep = kk*radixsize;
            for (ll=0; ll<ispan*2; ll+=2) {
                tt[0] = in[ispan*(istep+0)+ll];
                tt[1] = in[ispan*(istep+0)+ll+1];
	        for (irow=1; irow<radixsize; irow++) {
                    wxx_re = twids[irow*kk*ispan];
                    wxx_im = twids[irow*kk*ispan+1];
                    xxx_re = in[ispan*(istep+irow*2)+ll];
                    xxx_im = in[ispan*(istep+irow*2)+ll+1];

                    tt[irow*2]   = wxx_re*xxx_re + wxx_im*xxx_im;
	            tt[irow*2+1] = wxx_re*xxx_im - wxx_im*xxx_re;
                }
	        for (irow=0; irow<radixsize; irow++) {
	            yxx_re = 0.0F;
	            yxx_im = 0.0F;

	            for (icol=0; icol<radixsize; icol++) {
                        wxx_re  = wn[(irow*radixsize+icol)*2];
                        wxx_im  = wn[(irow*radixsize+icol)*2+1];
                        txx_re  = tt[icol*2];
                        txx_im  = tt[icol*2+1];
                        yxx_re += wxx_re*txx_re - wxx_im*txx_im;
                        yxx_im += wxx_re*txx_im + wxx_im*txx_re;
		    }

	            out[kk*ispan+irow*ospan+ll]   = yxx_re;
	            out[kk*ispan+irow*ospan+ll+1] = yxx_im;
		}
            }
        }
        break;

      default:                                           /* Inverse Pass */
        for (kk=0; kk<mm; kk+=2) {
            istep = kk*radixsize;
            for (ll=0; ll<ispan*2; ll+=2) {
                tt[0] = in[ispan*(istep+0)+ll];
                tt[1] = in[ispan*(istep+0)+ll+1];
	        for (irow=1; irow<radixsize; irow++) {
                    wxx_re = twids[irow*kk*ispan];
                    wxx_im = twids[irow*kk*ispan+1];
                    xxx_re = in[ispan*(istep+irow*2)+ll];
                    xxx_im = in[ispan*(istep+irow*2)+ll+1];

                    tt[irow*2]   = wxx_re*xxx_re - wxx_im*xxx_im;
	            tt[irow*2+1] = wxx_re*xxx_im + wxx_im*xxx_re;
		}
	        for (irow=0; irow<radixsize; irow++) {
	            yxx_re = 0.0F;
	            yxx_im = 0.0F;

                    for (icol=0; icol<radixsize; icol++) {
                        wxx_re  = wn[(irow*radixsize+icol)*2];
                        wxx_im  = wn[(irow*radixsize+icol)*2+1];
                        txx_re  = tt[icol*2];
                        txx_im  = tt[icol*2+1];
                        yxx_re += wxx_re*txx_re + wxx_im*txx_im;
                        yxx_im += wxx_re*txx_im - wxx_im*txx_re;
		    }

                    out[kk*ispan+irow*ospan+ll]   = yxx_re;
	            out[kk*ispan+irow*ospan+ll+1] = yxx_im;
		}
            }
        }
        break;
    }

    return;
}



/*
-----------------------------------------------------------------------
  FUNCTION:
    fft_func_scale()

  SYNOPSIS:
    void fft_func_scale (float[] cin, int n, int dirflag,
                         int typeflag, int packflag)

  ARGUMENTS:
    float[] cin   --- complex input/output vector treated as real array
    int n         --- FFT size (in real samples)
    int dirflag   --- forward/inverse FFT flag
    int typeflag  --- COMPLEX/REAL FFT type
    int packflag  --- type of real FFT bin packing/unpacking

  PURPOSE:
    Scales FFT/IFFT data to produce a numerically correct result.
    Without a call to this function, some FFT/IFFT options will
    produce a result which is incorrect by a constant scale factor.

  REVISIONS:
    02/12/00 	rdh	baseline
-----------------------------------------------------------------------
*/

void fft_func_scale (float[] cin, int n, int dirflag, int typeflag, int packflag)
{
    return;
}


/*
-----------------------------------------------------------------------
  FUNCTION:
    fft_pack()

  SYNOPSIS:
    void fft_pack (float[] ain, const float *t, int n,
                   int dirflag, int packflag)

  ARGUMENTS:
    float[] ain   --- complex input/output vector treated as real array
    float[] t     --- complex twiddle factor vector treated as real array
    int n         --- FFT size (in real samples)
    int dirflag   --- forward/inverse FFT flag
    int packflag  --- type of real FFT bin packing/unpacking

  PURPOSE:
    Packs and unpacks input data to allow fft_work() to perform a
    complex FFT/IFFT on real input/output data

  REVISIONS:
    05/01/00 	rdh	baseline
-----------------------------------------------------------------------
*/

void fft_pack (float[] ain, float[] twids, int size, int dirflag, int packflag)
{
 /* Local Variables */
    int   ii, jj, kk, nd2;
    float wr, wi, xr, xi, yr, yi, tr, ti;
    float xrpyr, xrmyr, xipyi, ximyi;

 /* Verify parameters */
    if (size < 1) return;

 /* Perform a Forward Pack Pass */
    switch (dirflag) {
      case FFT_FLAGS_FORWARD:
        tr     = ain[0];
        ti     = ain[1];
        xr     = tr + ti;
        xi     = tr - ti;
        ain[0] = 2.0F * xr;
        ain[1] = 2.0F * xi;

        for(ii=2,jj=size*2-2,kk=size*4-2; ii<=size; ii+=2,jj-=2,kk-=2) {
            xr    = ain[ii];
            yr    = ain[jj];
            xrpyr = xr + yr;
            xrmyr = xr - yr;
            xi    = ain[ii+1];
            yi    = ain[jj+1];
            xipyi = xi + yi;
            ximyi = xi - yi;

            wr = twids[kk];
            wi = twids[kk+1];
            tr = wr*xipyi + wi*xrmyr;
            ti = wi*xipyi - wr*xrmyr;
            xr = xrpyr + tr;
            yr = xrpyr - tr;
            xi = ti + ximyi;
            yi = ti - ximyi;

            ain[ii  ] = xr;
            ain[ii+1] = xi;
            ain[jj  ] = yr;
            ain[jj+1] = yi;
	}
	/* Unpack the spectral data */
	switch (packflag) {
          case FFT_FLAGS_UNPACKED:
	    ain[size*2]   = ain[1];
	    ain[size*2+1] = 0.0F;
	    ain[1]        = 0.0F;
	    break;

	  case FFT_FLAGS_NONYQUIST:
	    ain[1] = 0.0F;
	    break;
	}
        break;

 /* Perform an Inverse Unpack Pass */
      case FFT_FLAGS_INVERSE:
	/* Data to be inverse FFT'd must be re-packed */
	switch (packflag) {
          case FFT_FLAGS_UNPACKED:
	    ain[1    ] = ain[size*2];
	    ain[size*2  ] = 0.0F;
	    ain[size*2+1] = 0.0F;
	    break;
	}

        tr = ain[0];
        ti = ain[1];
        ain[0] = tr + ti;
        ain[1] = tr - ti;

        for(ii=2,jj=size*2-2,kk=size*2+2; ii<=size; ii+=2,jj-=2,kk+=2) {
            xr    = ain[ii];
            yr    = ain[jj];
            xrpyr = xr + yr;
            xrmyr = xr - yr;
            xi    = ain[ii+1];
            yi    = ain[jj+1];
            xipyi = xi + yi;
            ximyi = xi - yi;

            wr = twids[kk];
            wi = twids[kk+1];
            tr = wr*xipyi + wi*xrmyr;
            ti = wi*xipyi - wr*xrmyr;
            xr = xrpyr + tr;
            yr = xrpyr - tr;
            xi = ti + ximyi;
            yi = ti - ximyi;

            ain[ii  ] = xr;
            ain[ii+1] = xi;
            ain[jj  ] = yr;
            ain[jj+1] = yi;
	}
        break;
    }

    return;
}



/*
 * DOUBLE precision variations
 * ===========================
 *
 * The following functions are ALL made by copying the single-precision
 * versions and changing "float" to "double".  DO NOT modify without
 * checking the corresponding single-precision versions.
 */


  protected final void fft_work (double data[]) {
      System.out.println("fft_work is not implemented for double data in Java.  Use native.");
  }

}
