
#include "perm/cycles.h"

#include "perm/graypermute.h"
#include "perm/revbinpermute.h"
#include "perm/zip.h"
#include "aux1/copy.h"

//#include "perm-all.h"  // all permutation stuff
#include "perm/haarpermute.h"

#include "perm/permapplyfunc.h"
#include "bits/bitlex.h"
#include "bits/bittransforms.h"

#include "fxttypes.h"
#include "fxtio.h"
#include "demo/nextarg.h"


//% Decomposition of a permutation into cycles.
//% Print cycles and code for the permutation.

//#define TIMING // uncomment to disable printing

// Print And Doit:
#define  PAD( x )  { cout << "Using: " << #x << endl;  x; }

int
main(int argc, char **argv)
{
    ulong ldn = 4;
    NXARG(ldn, "Number of elements is 2**ldn");
    ulong n = 1UL << ldn;
    cout << "  n=" << n << endl;

    ulong pcq = 1;
    NXARG(pcq, "How to print code: 0==>no code, 1==>to stdout, 2==>stderr.");


    ulong *y = new ulong[n];
    set_seq(y, n);

//    ulong y[] = {0,  1,  2,  4,  8,  5, 11, 10,  9,  7,  3,  6};  n=sizeof(y)/sizeof(ulong);

    cout << " Apply some permutation:" << endl;
    // choose one or more ...:
//    PAD( revbin_permute(y, n) );
//    PAD( reverse(y, n) );
    PAD( gray_permute(y, n) );  // default
//    PAD( inverse_gray_permute(y, n) );
//    PAD( apply_permutation(negidx2lexrev, y, n) );
//    PAD( apply_permutation(lexrev2negidx, y, n) );
//    PAD( apply_permutation(blue_code, y, n) );
//    PAD( haar_permute(y, n) );
//    PAD( zip(y, n) );


//    for (ulong k=0; k<n; ++k)  cout << y[k] << ", ";
//    cout << endl;

    cout << "Computing cycles:" << endl;
    cycles cc(n);

#ifdef TIMING
    for (ulong k=0; k<32; ++k)  cc.make_cycles(y, n);

#else
    cc.make_cycles(y, n);
    cc.print();
//    cc.print_leaders();


    if ( pcq )
    {
        // ... and print source code:
        cc.print_code("foo_perm", n, 1, (pcq>1));

//        cc.invert();  cc.print_code("inverse_foo_perm", n, 1);
    }
#endif

    delete [] y;

    return 0;
}
// -------------------------

/*
Timing:

time ./bin 16777216
arg 1: 16777216 == n  [Number of elements (must be a power of 2)]  default=16
ldn=24  n=16777216
arg 2: 1 == pcq  [How to print code: 0==>no code, 1==>to stdout, 2==>stderr.]  default=1
 Apply some permutation:
Using: gray_permute(y, n)
Computing cycles:
./bin 16777216  9.95s user 0.26s system 99% cpu 10.224 total
 ==> 16777216*32/9.95 == 53,956,875 processed elements per second

BENCHARGS=16777216

*/

/// Emacs:
/// Local Variables:
/// MyRelDir: "demo/perm"
/// makefile-dir: "../../"
/// make-target: "1demo DSRC=demo/perm/cycles-demo.cc"
/// make-target2: "1demo DSRC=demo/perm/cycles-demo.cc DEMOFLAGS=-DTIMING"
/// End:

