Esempio n. 1
0
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) ;
}
Esempio n. 2
0
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;
}