Example #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) ;
}
Example #2
0
static void
partial_point(fitinfo *fit, int k, Real Q[],
	      Real A[], Real B[], Real C[], Real D[],
	      int weighted, int *df, Real *sumsq)
{
  /* FIXME don't remove this without fixing fit_w?sumsq.  In particular,
     it is now assuming fitQ matches data.Q, which is not true for this
     code.  The underlying problem is that the theory calculation points
     not correspond to the data points, either because there are multiple
     points with the same resolution or because all four cross sections
     are not measured at every Q value or because thick layers requires
     oversampling in Q to avoid aliasing effects.
   */
  assert(1==0);
  if (A[k] == NOVALUE) {
    /* Set next point */
    fit->fitQ = Q+k;
    fit->fitA = A+k;
    fit->fitB = B+k;
    fit->fitC = C+k;
    fit->fitD = D+k;

    /* Compute reflectivity */
    if (fit->datatype == FIT_REAL) calc_real(fit);
    else if (fit->datatype == FIT_IMAGINARY) calc_imaginary(fit);
    else calc_magnitude(fit);

    /* Accumulate sumsq */
    if (weighted) fit_wsumsq(fit,df,sumsq);
    else fit_sumsq(fit,df,sumsq);
  }
}
Example #3
0
Real fit_chisq(const fitinfo *fit)
{
  Real sumsq = 0.;
  int n = 0;
  fit_sumsq(fit,&n,&sumsq);
  return sumsq / (n - fit->pars.n);
}
Example #4
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;
}