Real ex_update_models(fitinfo fit[], int num_models, int weighted, int approximate_roughness, int forced) { int n = 0; Real sumsq = 0.; int i; // printf("calling update\n"); MODELS = num_models; fit[0].penalty = 0.; if (*constraints) (*constraints)(fit); sumsq = fit[0].penalty; if (!forced && sumsq >= FIT_REJECT_PENALTY) return sumsq; for (i=0; i < num_models; i++) { int n_i = 0; Real sumsq_i = 0.; fit_update(&fit[i], approximate_roughness); if (weighted) fit_wsumsq(&fit[i],&n_i,&sumsq_i); else fit_sumsq(&fit[i],&n_i,&sumsq_i); fit[i].chisq_est = sumsq_i/n_i; n += n_i; sumsq += sumsq_i; } // printf("sumsq=%10g, n=%4d, pars=%d\n",sumsq,n,fit[0].pars.n); return n < fit[0].pars.n ? sumsq : sumsq / (n - fit[0].pars.n) ; }
void fit_partial(fitinfo *fit, int approx, Real portion, Real best, int weighted, int *totaldf, Real *totalsumsq) { int i, samples; Real *work, *Q, *A, *B, *C, *D; int nQ, worksize; Real sumsq = 0.; int df = 0; /* FIXME kill partial for now --- we need to refactor the * the other bits so they allow single point computations a little * more cleanly. */ portion = 1.; /* If all, update the model and calculate sumsq using all points. */ if (portion >= 1.) { fit_update(fit, approx); if (weighted) fit_wsumsq(fit,&df,&sumsq); else fit_sumsq(fit,&df,&sumsq); fit->chisq_est = sumsq/df; return; } /* Generate the profile from the model */ model_profile(&fit->m, &fit->p); /* Find the Q points at which we need to calculate the model */ find_target_Q(fit); /* Clear work vector so resolution isn't calculated */ worksize = fit->worksize; fit->worksize = 0; work = fit->work; fit->work = NULL; /* Stash Q,R info */ nQ = fit->nQ; Q = fit->fitQ; A = fit->fitA; B = fit->fitB; C = fit->fitC; D = fit->fitD; /* For the rest of this function, assume a single point Q vector */ fit->nQ = 1; /* Clear results vector */ for (i=0; i < nQ; i++) A[i] = NOVALUE; /* First pass --- calculate a few randomly selected Q values */ /* We wat to take the minimum number of samples which will allow us to */ /* reject the hypothesis that the current individual comes from a */ /* chisq distribution as good or better than the one which gave rise */ /* to the best chisq. Any individual so bad is unlikely to propagate */ /* its genes to the next generation. For individuals as good as or */ /* better than the best, we want to keep sampling up to some portion. */ /* FIXME use a proper statistical test? */ for (i=0; i < 5; i++) { int k= (int)floor(frandom()*nQ); partial_point(fit,k,Q,A,B,C,D,weighted,&df,&sumsq); } samples = (int)ceil(portion*nQ); while (i++ < samples) { int k= (int)floor(frandom()*nQ); partial_point(fit,k,Q,A,B,C,D,weighted,&df,&sumsq); if (sumsq/df > 10.*best) break; } /* Accumulate the sumsq for this fit. */ /* printf("sample %d of %d with %g vs. %g\n",df,samples,sumsq/df,best); */ *totalsumsq += sumsq; *totaldf += df; fit->chisq_est = sumsq/df; /* Restore work vector */ fit->worksize = worksize; fit->work = work; /* Restore Q,R info */ fit->nQ = nQ; fit->fitQ = Q; fit->fitA = A; fit->fitB = B; fit->fitC = C; fit->fitD = D; }