void ML_multi_DownhillSimplex::start_amoeba(int& nfunk) { nfunk = 0; amoeba(simplex, funk_vals, get_function_tolerance(), &ML_multi::bounded_eval_neg_log_likelihood_at, // &ML_multi::eval_neg_log_likelihood_at, nfunk); // Now set the ratepvector and Likelihood parameters to reflect // the minimum found at vertex 0 of the simplex v_ratep_type parameters(simplex[0]); assert(parameters.size() == branch_rate_manager.get_ratepvector().size()); branch_rate_manager.get_ratepvector().assign(parameters); compute(); if (DEBUG_START_AMOEBA) { std::cout << "end of start_amoeba(): "; std::cout << " ftol=" << get_gradient_tolerance(); std::cout << " nfunk=" << nfunk; std::cout << " minimum at simplex[0]=" << get_neg_log_likelihood(); std::cout << std::endl << std::endl << "parm\tval" << std::endl; for (size_t i = 0; i < branch_rate_manager.get_ratepvector().size(); ++i) { std::cout << branch_rate_manager.get_ratepvector()[i].get_name() << "\t" << branch_rate_manager.get_ratepvector()[i].get_ratep() << std::endl; } std::cout << std::endl; if (DEBUG_PRINT_DATA_STRUCTURES) print_data_structures(); } }
void zspace_minimization(char *fname) { int n,niter,i,j; double *a,**pp,*yy,FTOL=1.0E-3,chi2min,qromo(),midpnt(),s1; fprintf(stderr,"\n\nCHI2 MINIMIZATION OF W_P(R_P)+xi(s,p) DATA..........\n"); fprintf(stderr, "-----------------------------------------------------\n\n"); OUTPUT=0; wp_input(); Work.imodel=2; /* Find the number of free parameters in the minimization * for the real-space correlation function. */ for(n=0,i=1;i<=100;++i) { n+=HOD.free[i]; if(OUTPUT) printf("zspace_min> free[%i] = %d\n",i,HOD.free[i]); } wp.ncf=n; a=dvector(1,n); if(POWELL) pp=dmatrix(1,n,1,n); else pp=dmatrix(1,n+1,1,n); yy=dvector(1,n+1); initial_zspace_values(a,pp,yy); if(POWELL) { powell(a,pp,n,FTOL,&niter,&chi2min,func_chi2); chi2min = func_chi2(a); } else amoeba(pp,yy,n,FTOL,func_chi2,&niter); s1=qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt); GALAXY_BIAS=s1/GALAXY_DENSITY; if(!ThisTask) { printf("ZSPACEMIN %e %e ",chi2min,HOD.M_min); for(i=1;i<=n;++i)printf("%e ",a[i]); printf(" %f\n",GALAXY_BIAS); } output_parameter_file(fname); }
void fit_color_samples() { int n,niter,i,j; double *a,**pp,*yy,FTOL=1.0E-3,chi2min,s1,dlogm,m; FILE *fp; char aa[1000]; mcmc_color_minimization(); fprintf(stderr,"\n\nCHI2 MINIMIZATION OF W_P(R_P) COLOR DATA..........\n"); fprintf(stderr, "--------------------------------------------\n\n"); HOD.blue_fraction = 0.5857; /* <- Millenium fraction (sloan);; SDSS fraction -> 0.565; */ HOD.blue_fraction = 0.6555; /* <- Millenium fraction (B-V>0.8) */ HOD.blue_fraction = 0.565; /* SDSS -19,-20 */ HOD.blue_fraction = 0.492; /* SDSS -20,-21 */ HOD.blue_fraction = 0.379; /* SDSS -21 */ wp_color.ON = 1; if(POWELL) FTOL=1.0E-3; else FTOL=1.0E-5; for(n=0,i=1;i<=7;++i) { n+=HOD.free[i]; if(!OUTPUT)continue; printf("wp_min> free[%i] = %d\n",i,HOD.free[i]); } /* The parameters that govern the blue fraction aren't * listed in the HOD.free array, so add them in. * NB: There are four parameters for these two functions, * one of which is fit by the number densities. */ n+=3; if(OUTPUT)printf("wp_min> Number of free parameters: %d\n",n); wp_color_input(); wp.ncf=n; a=dvector(1,n); if(POWELL) pp=dmatrix(1,n,1,n); else pp=dmatrix(1,n+1,1,n); yy=dvector(1,n+1); initial_color_values(a,pp,yy); if(POWELL) { if(OUTPUT)printf("wp_min> starting powell.\n"); powell(a,pp,n,FTOL,&niter,&chi2min,chi2_wp_color); chi2min = chi2_wp_color(a); } else { if(OUTPUT)printf("wp_min> starting amoeba.\n"); amoeba(pp,yy,n,FTOL,chi2_wp_color,&niter); for(i=1;i<=n;++i)a[i]=pp[1][i]; chi2min = chi2_wp_color(a); } s1=qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt); GALAXY_BIAS=s1/GALAXY_DENSITY; printf("POWELL %e %e %e ",chi2min,HOD.M_min,HOD.fblue0_cen); if(HOD.pdfc==7) printf("%e ",HOD.M_cen_max); for(i=1;i<=n;++i)printf("%e ",a[i]); printf(" %f\n",GALAXY_BIAS); /* Output the fit and the HOD curve. */ sprintf(aa,"%s.fit",Task.root_filename); fp=fopen(aa,"w"); fprintf(fp,"%e %e %e ",chi2min,HOD.M_min,HOD.fblue0_cen); if(HOD.pdfc==7) fprintf(fp,"%e ",HOD.M_cen_max); for(i=1;i<=n;++i)fprintf(fp,"%e ",a[i]); fprintf(fp," %f\n",GALAXY_BIAS); fclose(fp); sprintf(aa,"%s.HOD",Task.root_filename); fp=fopen(aa,"w"); dlogm=(log(HOD.M_max)-log(HOD.M_low))/99; for(i=1;i<=100;++i) { m=exp((i-1)*dlogm)*HOD.M_low; fprintf(fp,"%e %e %e %e\n",m,N_cen(m),N_sat(m),N_avg(m)); } fclose(fp); }
/* * Fit to a gaussian */ int SimplexFitting::fitGaussian(double* fitting, double &err, int howToInitParams) // mIndex1 and mIndex2 are the //starting index and endind index of the fitting range. { float pp[VARNUM+1][VARNUM+1], yy[VARNUM+1]; float da[VARNUM]={2.0, 2.0, 2.0, 2.0, 2.0}; float a[VARNUM]={0.7, 0.0, 0.2, 0.0, 0.0}; float min_a[VARNUM]; float ptol[VARNUM]; int nvar=4; int iter, jmin, i, iter_counter; float errmin; float delfac=2.0; float ftol2=5.0e-4; float ptol2=5.0e-4; float ftol1=1.0e-5; float ptol1=1.0e-5; //init params if (howToInitParams == 0) { a[0]=mRaw[mIndex1]; a[2]=1.414*(mIndex2-mIndex1)/(mDim-1); } else { a[0]=mRaw[(mIndex1+mIndex2)/2-1]; a[1]=0.5*(mIndex2-mIndex1)/(mDim-1); //sigma=0.3*(mIndex2-mIndex1)/(mDim-1); a[2]=1.414*0.3*(mIndex2-mIndex1)/(mDim-1); } //find the range of fitting data; double min, max; double range; if( (mIndex2-mIndex1)>0 ){ if( mRaw[mIndex1]> mRaw[mIndex1+1] ){ max=mRaw[mIndex1]; min=mRaw[mIndex1+1]; }else{ min=mRaw[mIndex1]; max=mRaw[mIndex1+1]; } for(i=mIndex1+1;i<mIndex2;i++){ if( mRaw[i]>max ) max=mRaw[i]; else if( mRaw[i]<min) min=mRaw[i]; } range=max-min; } else range=mRaw[mIndex1]; iter_counter=0; err=100000.0; double scaling; while(iter_counter<MAX_ITER){ amoebaInit(&pp[0][0], yy, VARNUM+1, nvar, delfac, ptol2, a, da, &SimplexFitting::funk, ptol); amoeba(&pp[0][0], yy, VARNUM+1, nvar, ftol2, &SimplexFitting::funk, &iter, ptol, &jmin); for (i = 0; i < nvar; i++) a[i] = pp[i][jmin]; amoebaInit(&pp[0][0], yy, VARNUM+1, nvar, delfac, ptol1, a, da, &SimplexFitting::funk, ptol); amoeba(&pp[0][0], yy, VARNUM+1, nvar, ftol1, &SimplexFitting::funk, &iter, ptol, &jmin); for (i = 0; i < nvar; i++) a[i] = pp[i][jmin]; funk(a, &errmin); if( (errmin<err || errmin<MIN_ERROR*range) && a[0]>0.0){ err=errmin; for(i=0;i<nvar;i++) min_a[i]=a[i]; } iter_counter++; if(errmin<MIN_ERROR*range && a[0]>0.0) break; //re-initialize parameters if(iter_counter%2) scaling=0.5*iter_counter/(MAX_ITER-1); else scaling=-0.5*iter_counter/(MAX_ITER-1); a[0]=(1+scaling)*mRaw[mIndex1]; if(howToInitParams==0) a[1]=0.0; else a[1]=0.5*(mIndex2-mIndex1)/(mDim-1); a[2]=(1+scaling)*1.414*(mIndex2-mIndex1)/(mDim-1); a[3]=0.0; }// iteration for (i=0; i < mDim; i++) { fitting[i]=min_a[0]*exp( -((float)(i-mIndex1)/(mDim-1)-min_a[1])* ((float)(i-mIndex1)/(mDim-1)-min_a[1])/(min_a[2]*min_a[2])) +min_a[3]; } if( debugLevel>=3){ printf("Iteration Num=%d threshold=%f Simplex fitting parameters for \ range %d to %d are:\n", iter_counter, MIN_ERROR*range, mIndex1, mIndex2); printf("Fitting error=%f\t a[0]=%f\t a[1]=%f\t a[2]=%f\t a[3]=%f\n",err, min_a[0], min_a[1], min_a[2], min_a[3]); }
// Main programm int main (int argc, char *argv[]) { Search_settings sett; Command_line_opts opts; Search_range s_range; Aux_arrays aux_arr; double *F; // F-statistic array int i, j, r, c, a, b, g; int d, o, m, k; int bins = 2, ROW, dim = 4; // neighbourhood of point will be divide into defined number of bins double pc[4]; // % define neighbourhood around each parameter for initial grid double pc2[4]; // % define neighbourhood around each parameter for direct maximum search (MADS & Simplex) double tol = 1e-10; // double delta = 1e-5; // initial step in MADS function // double *results; // Vector with results from Fstatnet function // double *maximum; // True maximum of Fstat // double results_max[11]; double s1, s2, s3, s4; double sgnlo[4]; double **arr; // arr[ROW][COL], arrg[ROW][COL]; double nSource[3]; double sinalt, cosalt, sindelt, cosdelt; double F_min; char path[512]; double x, y; ROW = pow((bins+1),4); #ifdef YEPPP yepLibrary_Init(); Yep64f *results_max = (Yep64f*)malloc(sizeof(Yep64f)*11); Yep64f *results_first = (Yep64f*)malloc(sizeof(Yep64f)*11); Yep64f *results = (Yep64f*)malloc(sizeof(Yep64f)*11); Yep64f *maximum = (Yep64f*)malloc(sizeof(Yep64f)*11); // Yep64f *sgnlo = (Yep64f*)malloc(sizeof(Yep64f)*4); // Yep64f *nSource = (Yep64f*)malloc(sizeof(Yep64f)*3); Yep64f *mean = (Yep64f*)malloc(sizeof(Yep64f)*4); enum YepStatus status; #endif pc[0] = 0.015; pc[1] = 0.015; pc[2] = 0.015; pc[3] = 0.015; for (i = 0; i < 4; i++){ pc2[i] = 2*pc[i]/bins; } // Time tests double tdiff; clock_t tstart, tend; // Command line options handle_opts(&sett, &opts, argc, argv); // Output data handling /* struct stat buffer; if (stat(opts.prefix, &buffer) == -1) { if (errno == ENOENT) { // Output directory apparently does not exist, try to create one if(mkdir(opts.prefix, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) { perror (opts.prefix); return 1; } } else { // can't access output directory perror (opts.prefix); return 1; } } */ sprintf(path, "%s/candidates.coi", opts.dtaprefix); //Glue function if(strlen(opts.glue)) { glue(&opts); sprintf(opts.dtaprefix, "./data_total"); sprintf(opts.dtaprefix, "%s/followup_total_data", opts.prefix); opts.ident = 000; } FILE *coi; int z; if ((coi = fopen(path, "r")) != NULL) { // while(!feof(coi)) { /* if(!fread(&w, sizeof(unsigned short int), 1, coi)) { break; } fread(&mean, sizeof(float), 5, coi); fread(&fra, sizeof(unsigned short int), w, coi); fread(&ops, sizeof(int), w, coi); if((fread(&mean, sizeof(float), 4, coi)) == 4){ */ while(fscanf(coi, "%le %le %le %le", &mean[0], &mean[1], &mean[2], &mean[3]) == 4){ //Time test // tstart = clock(); arr = matrix(ROW, 4); //Function neighbourhood - generating grid around point arr = neigh(mean, pc, bins); // Output data handling /* struct stat buffer; if (stat(opts.prefix, &buffer) == -1) { if (errno == ENOENT) { // Output directory apparently does not exist, try to create one if(mkdir(opts.prefix, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) { perror (opts.prefix); return 1; } } else { // can't access output directory perror (opts.prefix); return 1; } } */ // Grid data if(strlen(opts.addsig)) { read_grid(&sett, &opts); } // Search settings search_settings(&sett); // Detector network settings detectors_settings(&sett, &opts); // Array initialization init_arrays(&sett, &opts, &aux_arr, &F); // Amplitude modulation functions for each detector for(i=0; i<sett.nifo; i++) rogcvir(&ifo[i]); // Adding signal from file if(strlen(opts.addsig)) { add_signal(&sett, &opts, &aux_arr, &s_range); } // Setting number of using threads (not required) omp_set_num_threads(1); results_max[5] = 0.; // ifo zostaje shared // ifo....shft i ifo....xdatm{a,b] prerobić na lokalne tablice w fstatnet // w regionie parallel wprowadzić tablice private aa i bb ; alokować i przekazywać je jako argumenty do fstatnet i amoeba // Main loop - over all parameters + parallelisation #pragma omp parallel default(shared) private(d, i, sgnlo, sinalt, cosalt, sindelt, cosdelt, nSource, results, maximum) { double **sigaa, **sigbb; // aa[nifo][N] sigaa = matrix(sett.nifo, sett.N); sigbb = matrix(sett.nifo, sett.N); #pragma omp for for (d = 0; d < ROW; ++d){ for (i = 0; i < 4; i++){ sgnlo[i] = arr[d][i]; // sgnlo[i] = mean[i]; } sinalt = sin(sgnlo[3]); cosalt = cos(sgnlo[3]); sindelt = sin(sgnlo[2]); cosdelt = cos(sgnlo[2]); nSource[0] = cosalt*cosdelt; nSource[1] = sinalt*cosdelt; nSource[2] = sindelt; for (i = 0; i < sett.nifo; ++i){ modvir(sinalt, cosalt, sindelt, cosdelt, sett.N, &ifo[i], &aux_arr, sigaa[i], sigbb[i]); } // F-statistic in given point results = Fstatnet(&sett, sgnlo, nSource, sigaa, sigbb); //printf("Fstatnet: %le %le %le %le %le %le\n", results[6], results[7], results[8], results[9], results[5], results[4]); #pragma omp critical if(results[5] < results_max[5]){ for (i = 0; i < 11; i++){ results_max[i] = results[i]; } } // Maximum search using simplex algorithm if(opts.simplex_flag){ // puts("Simplex"); maximum = amoeba(&sett, &aux_arr, sgnlo, nSource, results, dim, tol, pc2, sigaa, sigbb); printf("Amoeba: %le %le %le %le %le %le\n", maximum[6], maximum[7], maximum[8], maximum[9], maximum[5], maximum[4]); // Maximum value in points searching #pragma omp critical if(maximum[5] < results_max[5]){ for (i = 0; i < 11; i++){ results_max[i] = maximum[i]; } } } //simplex } // d - main outside loop free_matrix(sigaa, sett.nifo, sett.N); free_matrix(sigbb, sett.nifo, sett.N); } //pragma for(g = 0; g < 11; g++) results_first[g] = results_max[g]; // Maximum search using MADS algorithm if(opts.mads_flag) { // puts("MADS"); maximum = MADS(&sett, &aux_arr, results_max, mean, tol, pc2, bins); } //Time test // tend = clock(); // tdiff = (tend - tstart)/(double)CLOCKS_PER_SEC; printf("%le %le %le %le %le %le\n", results_max[6], results_max[7], results_max[8], results_max[9], results_max[5], results_max[4]); } // while fread coi // } } //if coi else { perror (path); return 1; } // Output information /* puts("**********************************************************************"); printf("*** Maximum value of F-statistic for grid is : (-)%.8le ***\n", -results_first[5]); printf("Sgnlo: %.8le %.8le %.8le %.8le\n", results_first[6], results_first[7], results_first[8], results_first[9]); printf("Amplitudes: %.8le %.8le %.8le %.8le\n", results_first[0], results_first[1], results_first[2], results_first[3]); printf("Signal-to-noise ratio: %.8le\n", results_first[4]); printf("Signal-to-noise ratio from estimated amplitudes (for h0 = 1): %.8le\n", results_first[10]); puts("**********************************************************************"); if((opts.mads_flag)||(opts.simplex_flag)){ printf("*** True maximum is : (-)%.8le ***\n", -maximum[5]); printf("Sgnlo for true maximum: %.8le %.8le %.8le %.8le\n", maximum[6], maximum[7], maximum[8], maximum[9]); printf("Amplitudes for true maximum: %.8le %.8le %.8le %.8le\n", maximum[0], maximum[1], maximum[2], maximum[3]); printf("Signal-to-noise ratio for true maximum: %.8le\n", maximum[4]); printf("Signal-to-noise ratio from estimated amplitudes (for h0 = 1) for true maximum: %.8le\n", maximum[10]); puts("**********************************************************************"); }*/ // Cleanup & memory free free(results_max); free(results_first); free(results); free(maximum); free(mean); free_matrix(arr, ROW, 4); cleanup_followup(&sett, &opts, &s_range, &aux_arr, F); return 0; }
/* least squares solver. * returns number of iterations if solution converged, else -1. */ int lstsqr ( double (*chisqr)(double p[]), /* function to evaluate chisqr with at p */ double params0[], /* in: guess: back: best */ double params1[], /* second guess to set characteristic scale */ int np, /* entries in params0[] and params1[] */ double ftol) /* desired fractional tolerance */ { /* set up the necessary temp arrays and call the amoeba() multivariat * solver. amoeba() was evidently transliterated from fortran because * it indexes the arrays starting at [1]. */ double **p; /* np+1 rows, np columns (+1 due to 1-based) */ double *y; /* np columns ( " ) */ int iter; int i, j; int ret; /* save the caller's 0-based chi sqr function */ chisqr_0based = chisqr; /* fill p[][] with np+1 rows of each set of guesses of the np params. * fill y[] with chisqr() for each of these sets. * chisqr() is actually the function the amoeba is minimizing. */ p = (double **) malloc ((np+2)*sizeof(double *)); y = (double *) malloc ((np+2)*sizeof(double)); for (i = 1; i <= np+1; i++) { double *pi = p[i] = (double *) malloc ((np+1)*sizeof(double)); for (j = 1; j <= np; j++) pi[j] = (j == i-1) ? params1[j-1] : params0[j-1]; y[i] = chisqr_1based(pi); } /* solve */ ret = amoeba (p, y, np, ftol, chisqr_1based, &iter); /* on return, each row i of p has solutions at p[1..np+1][i]. * average them?? pick first one?? */ if (ret == 0) { for (i = 0; i < np; i++) { #ifdef USE_AVERAGE double sum = 0.0; for (j = 1; j <= np+1; j++) sum += p[j][i+1]; params0[i] = sum/(np+1); #else params0[i] = p[1][i+1]; #endif } ret = iter; } /* free the temp space */ for (i = 1; i < np+2; i++) free ((void *)p[i]); free ((void *)p); free ((void *)y); return (ret); }
int main(int argc, char* argv[]) { double *params, **xi, **pxi, mlk; double *y; long n, iter, i, j, nfunk; char* fileName = "armasq.dat"; xobs = loadmat(fileName, &nn, &mm); nn *= mm; if(argc < 3) { printf("Need to specify p an q\n"); exit(0); } else { p = atoi(argv[1]); q= atoi(argv[2]); // printf("%d %d\n", p, q); } n = p + q; if(argc > 5) { fileName = argv[4]; } if (argc < 4) { printf( "need to specify the minimization method:\n\tarma p\tfor Powell\n\tarma n\tfor Nelder and Mead\n"); exit(0); } else if (argv[3][0] == 'p') { printf("Using Powell method\n"); params = vector(n); xi = (double**) malloc(n * sizeof(double*)); //intialize the initial point and directions for (i = 0; i < n; i++) { params[i] = 0.0; xi[i] = vector(n); for (j = 0; j < n; j++) { if (i == j) xi[i][j] = .1; else xi[i][j] = 0; } } powell(params, xi, n, TOLERANCE, &iter, &mlk, armalk_wrapper); printf("Maximum LK %E\t after %ld iterations with parameters:\n", 1/mlk, iter); for (i = 0; i < n; i++) { printf("%E\n", params[i]); } free_vector(params); for (i = 0; i < n; i++) { free_vector(xi[i]); } free(xi); } else if (argv[3][0] == 'n') { printf("Using Nelder & Mead method\n"); y = vector(n+1); xi = (double**) malloc((n + 1) * sizeof(double*)); //intialize the initial points for (i = 0; i < n + 1; i++) { xi[i] = vector(n); for (j = 0; j < n; j++) { if (i == j) xi[i][j] = .1; else xi[i][j] = 0; } y[i] = armalk_wrapper(xi[i]); } amoeba(xi, y, n, TOLERANCE, armalk_wrapper, &nfunk); printf("After %ld function evaluations, the converged new points are:\n", nfunk); for (i = 0; i < n+1; i++) { printf("\tPoint %ld: MLK = %E, parameters:", i, 1/y[i]); for (j = 0; j < n; j++) printf(" %E ", xi[i][j]); printf("\n"); } free_vector(y); for (i = 0; i < n + 1; i++) { free_vector(xi[i]); } free(xi); } free(xobs); return 1; }
double max_rz_arr(fcomplex * data, int numdata, double rin, double zin, double *rout, double *zout, rderivs * derivs) /* Return the Fourier frequency and Fourier f-dot that */ /* maximizes the power. */ { double y[3], x[3][2], step = 0.4; float locpow; int numeval; maxdata = data; nummaxdata = numdata; locpow = get_localpower3d(data, numdata, rin, zin, 0.0); /* Now prep the maximization at LOWACC for speed */ /* Use a slightly larger working value for 'z' just incase */ /* the true value of z is a little larger than z. This */ /* keeps a little more accuracy. */ max_kern_half_width = z_resp_halfwidth(fabs(zin) + 4.0, LOWACC); /* Initialize the starting simplex */ x[0][0] = rin - step; x[0][1] = zin / ZSCALE - step; x[1][0] = rin - step; x[1][1] = zin / ZSCALE + step; x[2][0] = rin + step; x[2][1] = zin / ZSCALE; /* Initialize the starting function values */ y[0] = power_call_rz(x[0]); y[1] = power_call_rz(x[1]); y[2] = power_call_rz(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-7, power_call_rz, &numeval); /* Restart at minimum using HIGHACC to get a better result */ max_kern_half_width = z_resp_halfwidth(fabs(x[0][1]) + 4.0, HIGHACC); /* Re-Initialize some of the starting simplex */ x[1][0] = x[0][0] + 0.01; x[1][1] = x[0][1]; x[2][0] = x[0][0]; x[2][1] = x[0][1] + 0.01; /* Re-Initialize the starting function values */ y[0] = power_call_rz(x[0]); y[1] = power_call_rz(x[1]); y[2] = power_call_rz(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-10, power_call_rz, &numeval); /* The following calculates derivatives at the peak */ *rout = x[0][0]; *zout = x[0][1] * ZSCALE; locpow = get_localpower3d(data, numdata, *rout, *zout, 0.0); get_derivs3d(data, numdata, *rout, *zout, 0.0, locpow, derivs); return -y[0]; }
void max_rz_arr_harmonics(fcomplex* data[], int num_harmonics, int r_offset[], int numdata, double rin, double zin, double *rout, double *zout, rderivs derivs[], double power[]) /* Return the Fourier frequency and Fourier f-dot that */ /* maximizes the power. */ { double y[3], x[3][2], step = 0.4; float *locpow; int numeval; int i; locpow = gen_fvect(num_harmonics); maxlocpow = gen_fvect(num_harmonics); maxr_offset = r_offset; maxdata_harmonics = data; //FIXME: z needs to be multiplied by i everywhere for (i=1;i<=num_harmonics;i++) { locpow[i-1] = get_localpower3d(data[i-1], numdata, (r_offset[i-1]+rin)*i-r_offset[i-1], zin*i, 0.0); maxlocpow[i-1]=locpow[i-1]; } nummaxdata = numdata; max_num_harmonics = num_harmonics; /* Now prep the maximization at LOWACC for speed */ /* Use a slightly larger working value for 'z' just incase */ /* the true value of z is a little larger than z. This */ /* keeps a little more accuracy. */ max_kern_half_width = z_resp_halfwidth(fabs(zin*num_harmonics) + 4.0, LOWACC); /* Initialize the starting simplex */ x[0][0] = rin - step; x[0][1] = zin / ZSCALE - step; x[1][0] = rin - step; x[1][1] = zin / ZSCALE + step; x[2][0] = rin + step; x[2][1] = zin / ZSCALE; /* Initialize the starting function values */ y[0] = power_call_rz_harmonics(x[0]); y[1] = power_call_rz_harmonics(x[1]); y[2] = power_call_rz_harmonics(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-7, power_call_rz_harmonics, &numeval); /* Restart at minimum using HIGHACC to get a better result */ max_kern_half_width = z_resp_halfwidth(fabs(x[0][1]*num_harmonics) + 4.0, HIGHACC); /* Re-Initialize some of the starting simplex */ x[1][0] = x[0][0] + 0.01; x[1][1] = x[0][1]; x[2][0] = x[0][0]; x[2][1] = x[0][1] + 0.01; /* Re-Initialize the starting function values */ y[0] = power_call_rz_harmonics(x[0]); y[1] = power_call_rz_harmonics(x[1]); y[2] = power_call_rz_harmonics(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-10, power_call_rz_harmonics, &numeval); /* The following calculates derivatives at the peak */ *rout = x[0][0]; *zout = x[0][1] * ZSCALE; for (i=1; i<=num_harmonics; i++) { locpow[i-1] = get_localpower3d(data[i-1], numdata, (r_offset[i-1]+*rout)*i-r_offset[i-1], (*zout)*i, 0.0); x[0][0] = (r_offset[i-1]+*rout)*i-r_offset[i-1]; x[0][1] = *zout/ZSCALE * i; maxdata = data[i-1]; power[i-1] = -power_call_rz(x[0]); get_derivs3d(data[i-1], numdata, (r_offset[i-1]+*rout)*i-r_offset[i-1], (*zout)*i, 0.0, locpow[i-1], &(derivs[i-1])); } vect_free(locpow); vect_free(maxlocpow); }