Beispiel #1
0
int rnorm(taucs_ccs_matrix* A, double* x, double* y, double* aux)
{
  int i;
  int one = 1;
  double relerr;
  
  for(i=0; i<A->n; i++) aux[i] = y[i]-x[i];
  relerr = my_dnrm2(&(A->n),aux,&one)/my_dnrm2(&(A->n),x,&one); 
  taucs_printf("2-norm relative forward error %.2e \n",relerr);
  
  if (relerr > 1e-8) {
    taucs_printf("test failed, error seems too high (but\n");
    taucs_printf("maybe the matrix is too ill-conditioned)\n");
    return 1;
  }
  return 0;
}
/* N>1 */
double
fit_N_point_em_f(hpixelf *parr, int npix, int Nf, double *freqs, double *bmaj, double *bmin, double *bpa, double ref_freq, int maxiter, int max_em_iter, double *ll, double *mm, double *sI, double *sP, int N, int Nh, hpoint *hull){

 int ci,cj,ck;
 double *p,*p1,*p2, // params m x 1
     *x; // observed data n x 1, the image pixel fluxes
 double *xdummy, *xsub; //extra arrays
 int m,n;
 double *b; /* affine combination */

 double opts[CLM_OPTS_SZ], info[CLM_INFO_SZ];

 double l_min,l_max,m_min,m_max,sumI;
 double fraction;

 double penalty; /* penalty for solutions with components out of pixel range */

 fit_double_point_dataf lmdata;

 /* for initial average pixel fit */
 hpixel *parrav;
 double mean_bmaj,mean_bmin,mean_bpa,mean_err;


 /***** first do a fit for average pixesl, using average PSF ******/
 if ((parrav=(hpixel*)calloc((size_t)(npix),sizeof(hpixel)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }
 for (ci=0; ci<npix; ++ci) {
   parrav[ci].x=parr[ci].x;
   parrav[ci].y=parr[ci].y;
   parrav[ci].l=parr[ci].l;
   parrav[ci].m=parr[ci].m;
   parrav[ci].ra=parr[ci].ra;
   parrav[ci].dec=parr[ci].dec;
   parrav[ci].sI=0.0;
   for (cj=0; cj<Nf; ++cj) {
    parrav[ci].sI+=parr[ci].sI[cj];
   }
   parrav[ci].sI/=(double)Nf;
 }
 mean_bmaj=mean_bmin=mean_bpa=0.0;
 for (cj=0; cj<Nf; ++cj) {
  mean_bmaj+=bmaj[cj];
  mean_bmin+=bmin[cj];
  mean_bpa+=bpa[cj];
 }
 mean_bmaj/=(double)Nf;
 mean_bmin/=(double)Nf;
 mean_bpa/=(double)Nf;
 

 /* we get mean_err=2*3*N+npix*log(error) */
 mean_err=fit_N_point_em(parrav, npix, mean_bmaj, mean_bmin, mean_bpa, maxiter, max_em_iter, ll, mm, sI, N, Nh, hull);

 free(parrav);


 opts[0]=CLM_INIT_MU; opts[1]=1E-15; opts[2]=1E-15; opts[3]=1E-15;
  opts[4]=-CLM_DIFF_DELTA; 

 m=4; /* 1x1 flux, 3x1 spec index for each component */
 n=Nf*npix; /* no of pixels */

 if ((p=(double*)calloc((size_t)(m),sizeof(double)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }
 if ((p1=(double*)calloc((size_t)(m),sizeof(double)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }
 if ((p2=(double*)calloc((size_t)(m),sizeof(double)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }
 if ((x=(double*)calloc((size_t)(n),sizeof(double)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }
 if ((xsub=(double*)calloc((size_t)(n),sizeof(double)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }
 if ((xdummy=(double*)calloc((size_t)(n),sizeof(double)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }
 if ((b=(double*)calloc((size_t)(N),sizeof(double)))==0) {
     fprintf(stderr,"%s: %d: no free memory\n",__FILE__,__LINE__);
     exit(1);
 }



 l_min=m_min=INFINITY_L;
 l_max=m_max=-INFINITY_L;
 sumI=0.0;
 /* only use valid pixels for initial conditions */
 for (ci=0; ci<npix; ci++) {
   if (parr[ci].ra!=-1 && parr[ci].m!=-1) {
       if (l_min>parr[ci].l) {
          l_min=parr[ci].l;
       }
       if (l_max<parr[ci].l) {
         l_max=parr[ci].l;
       }
       if (m_min>parr[ci].m) {
          m_min=parr[ci].m;
       }
       if (m_max<parr[ci].m) {
         m_max=parr[ci].m;
       }
   }
 }
 ck=0;
 for (cj=0; cj<Nf; ++cj) {
  for (ci=0; ci<npix; ci++) {
       x[ck++]=parr[ci].sI[cj];
       sumI+=parr[ci].sI[cj];
  }
 }
 sumI/=(double)n;

 fraction=1.0;///(double)N;
/**********************************/
 for (ci=0; ci<N; ci++) {
  sP[ci]=0.0;
  sP[ci+N]=0.0;
  sP[ci+2*N]=0.0;

  b[ci]=fraction;    
 }
 
  lmdata.Nf=Nf;
  lmdata.parr=parr;
  lmdata.freqs=freqs;
  lmdata.bmaj=bmaj;
  lmdata.bmin=bmin;
  lmdata.bpa=bpa;
  lmdata.ref_freq=ref_freq;

 double aic1,aic2,aic3;
 for (ci=0; ci<max_em_iter; ci++) {
   for (cj=0; cj<N; cj++) {
     /* calculate contribution from hidden data, subtract from x */
    memcpy(xdummy,x,(size_t)(n)*sizeof(double));
    for (ck=0; ck<N; ck++) {
     if (ck!=cj) {
       lmdata.ll=&ll[ck]; /* pointer to positions */
       lmdata.mm=&mm[ck];
       p[0]=sI[ck];
       p[1]=sP[ck];
       p[2]=sP[ck+N];
       p[3]=sP[ck+2*N];

       mylm_fit_single_pf(p, xsub, m, n, (void*)&lmdata);
       /* xdummy=xdummy-b*xsub */
       my_daxpy(n, xsub, -b[ck], xdummy);
     }
    }

    lmdata.ll=&ll[cj]; /* pointer to positions */
    lmdata.mm=&mm[cj];
    p[0]=p1[0]=p2[0]=sI[cj];
    p[1]=p1[1]=p2[1]=sP[cj];
    p[2]=p2[2]=sP[cj+N]; p1[2]=0.0;
    p[3]=sP[cj+2*N]; p1[3]=p2[3]=0.0;

    //ret=dlevmar_dif(mylm_fit_single_pf, p, xdummy, m, n, maxiter, opts, info, NULL, NULL, (void*)&lmdata);  // no Jacobian
    clevmar_der_single_nocuda(mylm_fit_single_pf, NULL, p, xdummy, m, n, maxiter, opts, info, 2, (void*)&lmdata);  // no Jacobian
/* penalize only 1/10 of parameters */
    aic3=0.3+log(info[1]);
    clevmar_der_single_nocuda(mylm_fit_single_pf_2d, NULL, p2, xdummy, m-1, n, maxiter, opts, info, 2, (void*)&lmdata);  // no Jacobian
    aic2=0.2+log(info[1]);
    clevmar_der_single_nocuda(mylm_fit_single_pf_1d, NULL, p1, xdummy, m-2, n, maxiter, opts, info, 2, (void*)&lmdata);  // no Jacobian
    aic1=0.1+log(info[1]);
    /* choose one with minimum error */
    if (aic3<aic2) {
     if (aic3<aic1) {
       /* 3d */
       sI[cj]=p[0];
       sP[cj]=p[1];
       sP[cj+N]=p[2];
       sP[cj+2*N]=p[3];
     } else {
       /* 1d */
       sI[cj]=p1[0];
       sP[cj]=p1[1];
       sP[cj+N]=p1[2];
       sP[cj+2*N]=p1[3];
     }
   } else {
     if (aic2<aic1) {
       /* 2d */
       sI[cj]=p2[0];
       sP[cj]=p2[1];
       sP[cj+N]=p2[2];
       sP[cj+2*N]=p2[3];
     } else {
       /* 1d */
       sI[cj]=p1[0];
       sP[cj]=p1[1];
       sP[cj+N]=p1[2];
       sP[cj+2*N]=p1[3];
     }
   }
  }
 }
/**********************************/



#ifdef DEBUG
  print_levmar_info(info[0],info[1],(int)info[5], (int)info[6], (int)info[7], (int)info[8], (int)info[9]);
  printf("Levenberg-Marquardt returned %d in %g iter, reason %g\nSolution: ", ret, info[5], info[6]);
#endif
 /* check for solutions such that l_min <= ll <= l_max and m_min <= mm <= m_max */
 penalty=0.0;
 for (ci=0; ci<N; ci++) {
   /* position out of range */
   if (ll[ci]<l_min || ll[ci]>l_max || mm[ci]<m_min || mm[ci]>m_max) {
    penalty+=INFINITY_L;
   }
   /* spec index too high to be true */
   if (fabs(sP[ci])>20.0) {
    penalty+=INFINITY_L;
   }
 }

 /* calculate error */
 memcpy(xdummy,x,(size_t)(n)*sizeof(double));
 for (cj=0; cj<N; cj++) {
    for (ck=0; ck<N; ck++) {
       lmdata.ll=&ll[ck]; /* pointer to positions */
       lmdata.mm=&mm[ck];
       p[0]=sI[ck];
       p[1]=sP[ck];
       p[2]=sP[ck+N];
       p[3]=sP[ck+2*N];

       mylm_fit_single_pf(p, xsub, m, n, (void*)&lmdata);
       /* xdummy=xdummy-b*xsub */
       my_daxpy(n, xsub, -1.0, xdummy);
    }
 }
 /*sumI=0.0;
 for (ci=0; ci<n; ++ci ){
  sumI+=xdummy[ci]*xdummy[ci];
 } */
 sumI=my_dnrm2(n,xdummy);
 sumI=sumI*sumI;
 free(p);
 free(p1);
 free(p2);
 free(x);
 free(xdummy);
 free(xsub);
 free(b);

 /* AIC, 4*N parms */
 //return 2*4*N+npix*Nf*log(sumI)+penalty;
 return 2*4*N+Nf*(mean_err-2*3*N)+log(sumI)*npix*Nf+penalty;
}