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; }