void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i, j; int N, Nperm; int *d; int subs[2]; double *ptr; gsl_permutation *c; if(nrhs != 1) mexErrMsgTxt("1 input required"); if(nlhs != 1) mexErrMsgTxt("Requires one output."); if(mxGetM(prhs[0]) * mxGetN(prhs[0]) != 1) mexErrMsgTxt("N must be scalar"); N = mxGetScalar(prhs[0]); Nperm = (int) (gsl_sf_fact(N)); c = gsl_permutation_calloc (N); gsl_permutation_init(c); plhs[0] = mxCreateDoubleMatrix(Nperm, N, mxREAL); ptr = mxGetPr(plhs[0]); for(i = 0; i < Nperm; i++) { d = gsl_permutation_data(c); for(j = 0; j < N; j++) { subs[0] = i; subs[1] = j; ptr[mxCalcSingleSubscript(plhs[0], 2, subs)] = (double)d[j] + 1.; } gsl_permutation_next(c); } gsl_permutation_free(c); }
int main (void) { gsl_permutation * p = gsl_permutation_alloc (3) ; gsl_permutation_init (p) ; do { gsl_permutation_fprintf (stdout, p, " %u") ; printf("\n") ; } while (gsl_permutation_next(p) == GSL_SUCCESS); }
static VALUE rb_gsl_permutation_next(VALUE obj) { gsl_permutation *p = NULL; Data_Get_Struct(obj, gsl_permutation, p); return INT2FIX(gsl_permutation_next(p)); }
int rgb_permutations(Test **test,int irun) { uint i,j,k,permindex=0,t; Vtest vtest; double *testv; size_t ps[4096]; gsl_permutation** lookup; MYDEBUG(D_RGB_PERMUTATIONS){ printf("#==================================================================\n"); printf("# rgb_permutations: Debug with %u\n",D_RGB_PERMUTATIONS); } /* * Number of permutations. Note that the minimum ntuple value for a * valid test is 2. If ntuple is less than 2, we choose the default * test size as 5 (like operm5). */ if(ntuple<2){ test[0]->ntuple = 5; } else { test[0]->ntuple = ntuple; } k = test[0]->ntuple; nperms = gsl_sf_fact(k); /* * A vector to accumulate rands in some sort order */ testv = (double *)malloc(k*sizeof(double)); MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: There are %u permutations of length k = %u\n",nperms,k); } /* * Create a test, initialize it. */ Vtest_create(&vtest,nperms); vtest.cutoff = 5.0; for(i=0;i<nperms;i++){ vtest.x[i] = 0.0; vtest.y[i] = (double) test[0]->tsamples/nperms; } MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: Allocating permutation lookup table.\n"); } lookup = (gsl_permutation**) malloc(nperms*sizeof(gsl_permutation*)); for(i=0;i<nperms;i++){ lookup[i] = gsl_permutation_alloc(k); } for(i=0;i<nperms;i++){ if(i == 0){ gsl_permutation_init(lookup[i]); } else { gsl_permutation_memcpy(lookup[i],lookup[i-1]); gsl_permutation_next(lookup[i]); } } MYDEBUG(D_RGB_PERMUTATIONS){ for(i=0;i<nperms;i++){ printf("# rgb_permutations: %u => ",i); gsl_permutation_fprintf(stdout,lookup[i]," %u"); printf("\n"); } } /* * We count the order permutations in a long string of samples of * rgb_permutation_k non-overlapping rands. This is done by: * a) Filling testv[] with rgb_permutation_k rands. * b) Using gsl_sort_index to generate the permutation index. * c) Incrementing a counter for that index (a-c done tsamples times) * d) Doing a straight chisq on the counter vector with nperms-1 DOF * * This test should be done with tsamples > 30*nperms, easily met for * reasonable rgb_permutation_k */ for(t=0;t<test[0]->tsamples;t++){ /* * To sort into a perm, test vector needs to be double. */ for(i=0;i<k;i++) { testv[i] = (double) gsl_rng_get(rng); MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: testv[%u] = %u\n",i,(uint) testv[i]); } } gsl_sort_index(ps,testv,1,k); MYDEBUG(D_RGB_PERMUTATIONS){ for(i=0;i<k;i++) { printf("# rgb_permutations: ps[%u] = %lu\n",i,ps[i]); } } for(i=0;i<nperms;i++){ if(memcmp(ps,lookup[i]->data,k*sizeof(size_t))==0){ permindex = i; MYDEBUG(D_RGB_PERMUTATIONS){ printf("# Found permutation: "); gsl_permutation_fprintf(stdout,lookup[i]," %u"); printf(" = %u\n",i); } break; } } vtest.x[permindex]++; MYDEBUG(D_RGB_PERMUTATIONS){ printf("# rgb_permutations: Augmenting vtest.x[%u] = %f\n",permindex,vtest.x[permindex]); } }