// -*- C++ -*-

// ===== FUNCTIONS declared in permute/reverse.h: =====

reverse(Type *f, ulong n);
// reverse order of array

reverse_nh(Type *f, ulong n);
// reverse array around index n/2:
// used by recursive fht

// ===== FUNCTIONS declared in permute/rotate.h: =====

rotate_left(Type *f, ulong n, ulong s);
// rotate towards element #0

rotate_right(Type *f, ulong n, ulong s);
// rotate away from element #0
// undefined if s>=n

rotate(Type *f, ulong n, long s);
// undefined if abs(s)>=n

// ===== FUNCTIONS declared in permute/evenoddpermute.h: =====

// ----- SRCFILE=permute/evenoddpermute.cc: -----
void evenodd_permute(double *f, long n);
// lower half --> even indices
// higher half --> odd indices
// same as transposing the array as 2 x n/2 - matrix
// useful to combine real/imag part into a Complex array
// called by real_imag_to_complex()

void inverse_evenodd_permute(double *f, long n);
// inverse of evenodd_permute():
// put part of data with even indices
// sorted into the lower half,
// odd part into the higher half
// same as transposing the array as n/2 x 2 - matrix
// useful to separate real/imag part from a Complex array
// called by complex_to_real_imag()

evenodd_permute(Type *f, long n);
//
// lower half --> even indices
// higher half --> odd indices
//
// same as transposing the array as 2 x n/2 - matrix
//
// useful to combine real/imag part into a Complex array

inverse_evenodd_permute(Type *f, long n);
//
// inverse of evenodd_permute():
// put part of data with even indices
// sorted into the lower half,
// odd part into the higher half
//
// same as transposing the array as n/2 x 2 - matrix
//
// useful to separate real/imag part from a Complex array

// ===== FUNCTIONS declared in permute/evenoddrevpermute.h: =====

inverse_evenoddrev_permute(const Type *x, Type *y, ulong n);
// reordering needed for fht based dct

inverse_evenoddrev_permute(Type *x, ulong n);
// reordering needed for fht based dct
// inplace version

evenoddrev_permute(const Type *y, Type *x, ulong n);
// reordering needed for fht based inverse dct

evenoddrev_permute(Type *x, ulong n);
// reordering needed for fht based inverse dct
// inplace version

// ===== FUNCTIONS declared in permute/graypermute.h: =====

gray_permute(const Type *f, Type *g, ulong n);
// after this routine
// g[graycode(k)] == f[k]

inverse_gray_permute(const Type *f, Type *g, ulong n);
// after this routine
// g[k] == f[graycode(k)]

gray_permute_cycle(Type *f, ulong s, ulong len);
// moves one cycle of length len starting at index s
// called by gray_permute()

inverse_gray_permute_cycle(Type *f, ulong s, ulong len);
// moves one cycle of length len starting at index s
// called by inverse_gray_permute()

gray_permute_ge_512(Type *f, ulong n);
// permutes the upper half for lenths >= 512
// called by gray_permute()

inverse_gray_permute_ge_512(Type *f, ulong n);
// permutes the upper half for lenths >= 512
// called by inverse_gray_permute()

gray_permute(Type *f, ulong n);
// heavily optimised version

inverse_gray_permute(Type *f, ulong n);
// heavily optimised version

// ----- SRCFILE=permute/graypermute.cc: -----
ulong * xor_tab(ulong ldx);
// called by halfgray_permute()
// ldx: z[0] [1] [2] [3] ...
//   1:   1  
//   2:   1   2 
//   3:   1   3   4  
//   4:   1   2   7   8  
//   5:   1   3   5  15  16  
//   6:   1   2   6  10  31  32  
//   7:   1   3   4  12  21  63  64  
//   8:   1   2   7   8  25  42 127  128  
//   9:   1   3   5  15  17  51  85  255  256  
//  10:   1   2   6  10  30  34 102  170  511  512  
//  11:   1   3   4  12  20  60  68  204  341 1023  1024  
//  12:   1   2   7   8  24  40 120  136  409  682  2047  2048  
//  13:   1   3   5  15  16  48  80  240  273  819  1365  4095  4096  

half_gray_permute(Type *f, ulong n);
// formerly used by (inplace-) gray_permute() and inverse_gray_permute()
// allows inplace permutation with operation count n:
// let h(.) be halfgray_permute(.)
// then
// gray_permute(f, n) == { h(f, n);  h(f, n/2); h(f+n/2, n/2); }
// and
// inverse_gray_permute(f, n) == { h(f, n/2); h(f+n/2, n/2);  h(f, n); }

// ===== FUNCTIONS declared in permute/revbinpermute.h: =====

revbin(ulong m, ulong ldn);
// return m bitreversed
// ldn := number of bits to reverse

revbin_update(ulong r, ulong n);
// let r = revbin(x, ld(n)) at entry
// then return  revbin(x+1, ld(n))

revbin_permute(Type *f, ulong n);

