static int set (void *vstate, gsl_multifit_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx, int scale) { lmder_state_t *state = (lmder_state_t *) vstate; gsl_matrix *r = state->r; gsl_vector *tau = state->tau; gsl_vector *diag = state->diag; gsl_vector *work1 = state->work1; gsl_permutation *perm = state->perm; int signum; /* Evaluate function at x */ /* return immediately if evaluation raised error */ { int status = GSL_MULTIFIT_FN_EVAL_F_DF (fdf, x, f, J); if (status) return status; } state->par = 0; state->iter = 1; state->fnorm = enorm (f); gsl_vector_set_all (dx, 0.0); /* store column norms in diag */ if (scale) { compute_diag (J, diag); } else { gsl_vector_set_all (diag, 1.0); } /* set delta to 100 |D x| or to 100 if |D x| is zero */ state->xnorm = scaled_enorm (diag, x); state->delta = compute_delta (diag, x); /* Factorize J into QR decomposition */ gsl_matrix_memcpy (r, J); gsl_linalg_QRPT_decomp (r, tau, perm, &signum, work1); gsl_vector_set_zero (state->rptdx); gsl_vector_set_zero (state->w); /* Zero the trial vector, as in the alloc function */ gsl_vector_set_zero (state->f_trial); #ifdef DEBUG printf("r = "); gsl_matrix_fprintf(stdout, r, "%g"); printf("perm = "); gsl_permutation_fprintf(stdout, perm, "%d"); printf("tau = "); gsl_vector_fprintf(stdout, tau, "%g"); #endif return GSL_SUCCESS; }
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]); } }