/** Returns a ztilt gradient operator that converts the OPDs defined on xloc to subapertures defines on saloc. */ dsp *mkz(loc_t* xloc, double *amp,loc_t *saloc, int saorc, double scale, double dispx, double dispy) { dsp *zt=mkzt(xloc,amp,saloc,saorc,scale,dispx, dispy); dsp *z=dsptrans(zt); dspfree(zt); return z; }
/** Release memory. */ void free_powfs(POWFS_S *powfs, const PARMS_S *parms){ const int npowfs=parms->maos.npowfs; for(int ipowfs=0; ipowfs<npowfs; ipowfs++){ for(int iwvl=0; iwvl<parms->maos.nwvl; iwvl++){ cfree(powfs[ipowfs].dtf[iwvl].U); cfree(powfs[ipowfs].dtf[iwvl].nominal); dspfree(powfs[ipowfs].dtf[iwvl].si); } free(powfs[ipowfs].dtf); locfree(powfs[ipowfs].loc); locfree(powfs[ipowfs].saloc); dfree(powfs[ipowfs].amp); free(powfs[ipowfs].locxamp); free(powfs[ipowfs].locyamp); } }
int main(int argc, char* argv[]){ /*dsp *RLMc1=dspread("RLMc_old.bin"); */ if(argc!=2){ error("Need 1 argument\n"); } dspcell *RLM=dspcellread("%s",argv[1]); dsp *RLMc=dspcell2sp(RLM); tic;info2("chol ..."); spchol *R1=chol_factorize(RLMc); toc("done"); rand_t rstat; seed_rand(&rstat,1); dmat *y=dnew(RLMc->m, 1); drandn(y, 1, &rstat); dmat *x=NULL, *x2=NULL, *x3=NULL; chol_convert(R1, 1); tic; chol_solve(&x, R1, y); toc("cholmod");tic; chol_solve(&x, R1, y); toc("cholmod");tic; chol_solve_upper(&x3, R1, y); toc("upper");tic; chol_solve_upper(&x3, R1, y); toc("upper");tic; chol_solve_lower(&x2, R1,y); toc("lower");tic; chol_solve_lower(&x2, R1,y); toc("lower");tic; chol_solve(&x, R1, y); toc("cholmod");tic; chol_solve(&x, R1, y); toc("cholmod");tic; writebin(y,"y"); writebin(x,"x"); writebin(x2,"x2"); writebin(x3,"x3"); chol_free(R1); dspfree(RLMc); dspcellfree(RLM); }
static void setup_aster_kalman(SIM_S *simu, ASTER_S *aster, STAR_S *star, const PARMS_S *parms){ int ndtrat=parms->skyc.ndtrat; if(parms->skyc.multirate){ aster->res_ngs=dnew(1,1); //assemble neam if(aster->neam) error("neam is already set?\n"); aster->neam=calloc(1, sizeof(dcell*)); aster->neam[0]=cellnew(aster->nwfs, aster->nwfs); for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ int ng=aster->g->p[iwfs]->nx; aster->neam[0]->p[iwfs+aster->nwfs*iwfs]=dnew(ng, ng); } aster->dtrats=dnew(aster->nwfs, 1); aster->idtrats=dnew(aster->nwfs, 1); int wfs0_min=0, wfs0_max=0; PISTAT_S *pistat0=&star[aster->wfs[0].istar].pistat[aster->wfs[0].ipowfs]; for(int idtrat=0; idtrat<parms->skyc.ndtrat; idtrat++){ if(wfs0_min==0 && pistat0->snr->p[idtrat]>3){ wfs0_min=idtrat; } if(pistat0->snr->p[idtrat]>=parms->skyc.snrmin->p[idtrat]){ wfs0_max=idtrat; } } aster->kalman=calloc(1, sizeof(kalman_t*)); double resmin=INFINITY; kalman_t *kalman_min=0; int idtrat_min=0; //Try progressively lower sampling frequencies until performance starts to degrades for(int idtrat_limit=wfs0_max; idtrat_limit>wfs0_min; idtrat_limit--){ setup_aster_kalman_dtrat(aster, star, parms, idtrat_limit); aster->kalman[0]=sde_kalman(simu->sdecoeff, parms->maos.dt, aster->dtrats, aster->g, aster->neam[0], 0); dmat *rests=0; #if 1 //more accurate dmat *res=skysim_sim(parms->skyc.dbg?&rests:0, simu->mideal, simu->mideal_oa, simu->rmsol, aster, 0, parms, -1, 1, -1); double res0=res?res->p[0]:simu->rmsol; dfree(res); #else rests=kalman_test(aster->kalman[0], simu->mideal); double res0=calc_rms(rests, parms->maos.mcc, parms->skyc.evlstart); #endif if(parms->skyc.dbg){ writebin(rests, "isky%d_iaster%d_dtrat%d_rest", simu->isky, aster->iaster, idtrat_limit); } if(parms->skyc.verbose) info2("res0=%g, resmin=%g\n", sqrt(res0)*1e9, sqrt(resmin)*1e9); dfree(rests); if(res0<resmin-100e-18){//better by 10 nm resmin=res0; kalman_free(kalman_min); kalman_min=aster->kalman[0]; aster->kalman[0]=0; idtrat_min=idtrat_limit; }else{ kalman_free(aster->kalman[0]);aster->kalman[0]=0; if(isfinite(resmin) && res0>resmin*2){//stop trying. break; } } } setup_aster_kalman_dtrat(aster, star, parms, idtrat_min); if(parms->skyc.verbose) info2("selected\n"); aster->res_ngs->p[0]=resmin; aster->kalman[0]=kalman_min; }else{ if(aster->neam) dcellfreearr(aster->neam, ndtrat); aster->neam=calloc(ndtrat, sizeof(dcell*)); aster->res_ngs=dnew(ndtrat,3); PDMAT(aster->res_ngs, pres_ngs); aster->kalman=calloc(ndtrat, sizeof(kalman_t*)); dmat *dtrats=dnew(aster->nwfs,1); for(int idtrat=0; idtrat<ndtrat; idtrat++){ //assemble neam //TIC;tic; aster->neam[idtrat]=cellnew(aster->nwfs, aster->nwfs); for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ dmat *tmp=ddup(aster->wfs[iwfs].pistat->sanea->p[idtrat]);/*in rad */ dcwpow(tmp, 2); dsp *tmp2=dspnewdiag(tmp->nx, tmp->p, 1); dspfull(&aster->neam[idtrat]->p[iwfs+aster->nwfs*iwfs], tmp2,'n',1); dfree(tmp); dspfree(tmp2); } int dtrat=parms->skyc.dtrats->p[idtrat]; for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ dtrats->p[iwfs]=dtrat; } aster->kalman[idtrat]=sde_kalman(simu->sdecoeff, parms->maos.dt, dtrats, aster->g, aster->neam[idtrat], 0); //toc("kalman"); #if 1 dmat *res=skysim_sim(0, simu->mideal, simu->mideal_oa, simu->rmsol, aster, 0, parms, idtrat, 1, -1); double rms=res?res->p[0]:simu->rmsol; dfree(res); #else dmat *res=kalman_test(aster->kalman[idtrat], simu->mideal); double rms=calc_rms(res, parms->maos.mcc, parms->skyc.evlstart); dfree(res); #endif //toc("estimate"); pres_ngs[0][idtrat]=rms; } dfree(dtrats); } }
static void test_accuracy(int argc, char **argv){ double displacex=0.01; double displacey=0.05; double scale=1.01;/*.414065; */ int wrap=0; double D=30; double D2=32; int save=1; if(argc>1){ scale=strtod(argv[1], 0); } if(argc>2){ displacex=strtod(argv[2], 0); } if(argc>3){ displacey=strtod(argv[3], 0); } if(argc>4){ wrap=strtol(argv[4], 0, 10); } if(argc>5){ D=strtod(argv[5], 0); } if(argc>6){ D2=strtod(argv[6], 0); } if(argc>7){ save=strtol(argv[7], 0, 10); } double dx=1/64.; double dsa=0.5; map_t *screen=mapnew(D2/dx, D2/dx, dx, dx, 0); dset((dmat*)screen, 1); for(long iy=0; iy<screen->ny; iy++){ for(long ix=0; ix<screen->nx; ix++){ screen->p[ix+iy*screen->nx]=sin((double)ix/screen->nx*2*M_PI)*sin((double)iy/screen->ny*2*M_PI); } } /*loc for the map */ loc_t *locin=mksqloc(screen->nx,screen->ny,dx,dx,screen->ox,screen->oy); //pts_t *pts=realloc(mkannloc(D, 0, 1./2.,0), sizeof(pts_t)); pts_t *pts=realloc(mksqloc_auto(D/dsa, D/dsa, dsa, dsa), sizeof(pts_t)); pts->dx=dx; pts->dy=dx; pts->nx=dsa/dx; pts->ny=pts->nx; loc_t *loc=pts2loc(pts); loc_create_map(locin); loc_create_stat(loc); loc_create_map(loc); locstat_t *locstat=loc->stat; map_t *screen2=mapnew2(locin->map); dset((dmat*)screen2, NAN); loc_embed(screen2, locin, screen->p); double *phi_pts, *phi_loc, *phi_stat; double *phi_loc2loc, *phi_h, *phi_cub, *phi_cub2, *phi_cubh; double cubic=0.3; int ii; info("displacex=%g, displacey=%g, scale=%g, wrap=%d\n", displacex, displacey,scale,wrap); double diff1, diff2,diff3,diff14,diff15; diff1=0; diff2=0; diff3=0; diff14=0; diff15=0; phi_pts=calloc(loc->nloc, sizeof(double)); phi_loc=calloc(loc->nloc, sizeof(double)); phi_stat=calloc(loc->nloc, sizeof(double)); phi_loc2loc=calloc(loc->nloc, sizeof(double)); map_t *map1=mapnew2(loc->map); prop_grid_map(screen, map1, -2, displacex, displacey, scale, wrap, 0,0); tic; prop_grid_map(screen, map1, 1, displacex, displacey, scale, wrap, 0,0); toc("map\t\t"); prop_grid_pts(screen, pts, phi_pts, -2, displacex, displacey, scale, wrap, 0,0); tic; prop_grid_pts(screen, pts, phi_pts, 1, displacex, displacey, scale, wrap, 0,0); toc("pts\t\t"); prop_grid_stat(screen, locstat, phi_stat, -2,displacex, displacey, scale, wrap, 0,0); tic; prop_grid_stat(screen, locstat, phi_stat , 1, displacex, displacey, scale, wrap, 0,0); toc("stat\t");tic; prop_grid(screen, loc, phi_loc, -2,displacex, displacey, scale, wrap, 0,0); tic; prop_grid(screen, loc, phi_loc, 1,displacex, displacey, scale, wrap, 0,0); toc("loc\t\t"); prop_nongrid(locin, screen->p,loc, phi_loc2loc, -2,displacex, displacey, scale,0,0); toc("nongrid\t"); tic; prop_nongrid(locin, screen->p,loc, phi_loc2loc, 1,displacex, displacey, scale,0,0); toc("nongrid\t"); phi_h=calloc(loc->nloc,sizeof(double)); tic; dsp *hfor=mkh(locin, loc, displacex, displacey, scale); toc("mkh\t\t\t"); dspmulvec(phi_h,hfor, screen->p, 'n', -2); tic; dspmulvec(phi_h,hfor, screen->p, 'n', 1); toc("mul h\t\t"); phi_cub=calloc(loc->nloc,sizeof(double)); phi_cub2=calloc(loc->nloc,sizeof(double)); double *phi_cub3=calloc(loc->nloc,sizeof(double)); double *phi_cub4=calloc(loc->nloc,sizeof(double)); phi_cubh=calloc(loc->nloc, sizeof(double)); prop_nongrid_cubic(locin,screen->p,loc,phi_cub,-2, displacex, displacey, scale, cubic,0,0); tic; prop_nongrid_cubic(locin,screen->p,loc,phi_cub,1, displacex, displacey, scale, cubic,0,0); toc("nongrid, cubic\t"); prop_grid_cubic(screen, loc, phi_cub2, -2,displacex, displacey, scale, cubic, 0,0); tic; prop_grid_cubic(screen, loc, phi_cub2, 1,displacex, displacey, scale, cubic, 0,0); toc("grid, cubic\t"); prop_grid_cubic(screen2, loc,phi_cub3, -2,displacex, displacey, scale, cubic, 0,0); tic; prop_grid_cubic(screen2, loc,phi_cub3, 1,displacex, displacey, scale, cubic, 0,0); toc("grid2, cubic\t"); prop_grid_stat_cubic(screen, locstat,phi_cub4, -2,displacex, displacey, scale, cubic, 0,0); tic; prop_grid_stat_cubic(screen, locstat,phi_cub4, 1,displacex, displacey, scale, cubic, 0,0); toc("grid 2stat, cubic\t"); dsp *hforcubic; tic; hforcubic=mkh_cubic(locin, loc, displacex, displacey, scale, cubic); toc("mkh cubic \t\t"); dspmulvec(phi_cubh, hforcubic,screen->p,'n',-2); tic; dspmulvec(phi_cubh, hforcubic,screen->p,'n',1); toc("cubic mul h\t\t"); double diffc12=0,diff45=0,diff46=0,diff47=0; for(ii=0; ii<loc->nloc; ii++){ diff1+=fabs(phi_loc[ii]-phi_pts[ii]); diff2+=fabs(phi_stat[ii]-phi_loc[ii]); diff3+=fabs(phi_stat[ii]-phi_pts[ii]); diff14+=fabs(phi_loc2loc[ii]-phi_pts[ii]); diff15+=fabs(phi_h[ii]-phi_pts[ii]); diff45+=fabs(phi_loc2loc[ii]-phi_h[ii]); diffc12+=fabs(phi_cub[ii]-phi_cubh[ii]); diff46+=fabs(phi_cub[ii]-phi_cub2[ii]); diff47+=fabs(phi_cub[ii]-phi_cub3[ii]); } info2("(pts-loc)=\t%g\n(loc-stat)=\t%g\n(stat-pts)=\t%g\n" "(loc2loc-pts)=\t%g\n(h-pts)=\t%g\n" "(loc2loc-h)=\t%g\n" "(cub:h-loc2loc)=\t%g\n" "(cub:map2loc-loc2loc)=\t%g\n" "(cub:locmap2loc-loc2loc=\t%g\n" ,diff1, diff2,diff3,diff14,diff15,diff45,diffc12, diff46, diff47); // exit(0); if(!save) return; mapwrite(screen2,"accphi_screen2"); mapwrite(screen,"accphi_screen"); locwrite((loc_t*)pts,"accphi_pts"); locwrite(loc,"accphi_loc"); locwrite(locin, "accphi_locin"); loc_create_map_npad(locin, 0, 0, 0); mapwrite(locin->map, "accphi_locin_map"); mapwrite(loc->map, "accphi_loc_map"); mapwrite(map1, "accphi_map2map.bin"); writedbl(phi_pts,loc->nloc,1,"accphi_pts1.bin"); writedbl(phi_loc,loc->nloc,1,"accphi_loc0.bin"); writedbl(phi_stat,loc->nloc,1,"accphi_stat.bin"); writedbl(phi_loc2loc,loc->nloc,1,"accphi_loc2loc.bin"); writedbl(phi_h,loc->nloc,1,"accphi_loc2h.bin"); writedbl(phi_cub,loc->nloc,1,"accphi_cub_loc2loc.bin"); writedbl(phi_cub2,loc->nloc,1,"accphi_cub_map2loc.bin"); writedbl(phi_cub3,loc->nloc,1,"accphi_cub_locmap2loc.bin"); writedbl(phi_cub4,loc->nloc,1,"accphi_cub_locmap2stat.bin"); writedbl(phi_cubh,loc->nloc,1,"accphi_cub_loc2h.bin"); info("saved\n"); writedbl(phi_pts,loc->nloc,1,"accphi_pts.bin"); writedbl(phi_cub,loc->nloc,1,"accphi_cub.bin"); writebin(hfor, "accphi_hfor"); writebin(hforcubic, "accphi_cub_hfor"); dspfree(hfor); dspfree(hforcubic); free(phi_loc); free(phi_stat); free(phi_loc2loc); free(phi_pts); free(phi_h); free(phi_cub); free(phi_cubh); cellfree(screen); locfree(locin); }
/** Returns the transpose of a ztilt gradient operator that converts the OPDs defined on xloc to subapertures defines on saloc. */ dsp * mkzt(loc_t* xloc, double *amp, loc_t *saloc, int saorc, double scale, double dispx, double dispy) { /*compute ztilt influence function from xloc to saloc saorc: SALOC is subaperture origin or center. 1: origin (lower left corner), 0: center. */ long nsa=saloc->nloc; double dsa=saloc->dx; double dx1=1./xloc->dx; double dx2=scale*dx1; double dy1=1./xloc->dy; double dy2=scale*dy1; loc_create_map(xloc); map_t *map=xloc->map; dispx=(dispx-map->ox+saorc*dsa*0.5*scale)*dx1; dispy=(dispy-map->oy+saorc*dsa*0.5*scale)*dy1; double dsa2=dsa*0.5*dx2; long nmax=(dsa2*2+2)*(dsa2*2+2); long *ind=mycalloc(nmax,long); loc_t *sloc=mycalloc(1,loc_t); sloc->dx=xloc->dx; sloc->dy=xloc->dy; sloc->locx=mycalloc(nmax,double); sloc->locy=mycalloc(nmax,double); double *amploc=NULL; if(amp) amploc=mycalloc(nmax,double); dsp*zax=dspnew(xloc->nloc,nsa,xloc->nloc); dsp*zay=dspnew(xloc->nloc,nsa,xloc->nloc); long xcount=0,ycount=0; spint *xpp=zax->p; spint *xpi=zax->i; double *xpx=zax->x; spint *ypp=zay->p; spint *ypi=zay->i; double *ypx=zay->x; const double *locx=xloc->locx; const double *locy=xloc->locy; double *slocx=sloc->locx; double *slocy=sloc->locy; for(int isa=0; isa<nsa; isa++){ /*center of subaperture when mapped onto XLOC*/ double scx=saloc->locx[isa]*dx2+dispx; double scy=saloc->locy[isa]*dy2+dispy; int count=0; /*find points that belongs to this subaperture. */ for(int iy=iceil(scy-dsa2); iy<ifloor(scy+dsa2);iy++){ for(int ix=iceil(scx-dsa2); ix<ifloor(scx+dsa2);ix++){ int ii=loc_map_get(map, ix, iy); if(ii>0){ ii--; ind[count]=ii; slocx[count]=locx[ii]; slocy[count]=locy[ii]; if(amp) amploc[count]=amp[ii]; count++; } } } /*locwrite(sloc,"sloc_isa%d",isa); */ /*writedbl(amploc,count,1,"amploc_isa%d",isa); */ sloc->nloc=count; dmat *mcc=loc_mcc_ptt(sloc,amploc); /*writebin(mcc,"mcc_isa%d",isa); */ dinvspd_inplace(mcc); /*writebin(mcc,"imcc_isa%d",isa); */ xpp[isa]=xcount; ypp[isa]=ycount; for(int ic=0; ic<count; ic++){ double xx=IND(mcc,0,1)+IND(mcc,1,1)*slocx[ic]+IND(mcc,2,1)*slocy[ic]; double yy=IND(mcc,0,2)+IND(mcc,1,2)*slocx[ic]+IND(mcc,2,2)*slocy[ic]; if(amp){ xx*=amploc[ic]; yy*=amploc[ic]; } xpi[xcount]=ind[ic]; xpx[xcount]=xx; xcount++; ypi[ycount]=ind[ic]; ypx[ycount]=yy; ycount++; } dfree(mcc); } xpp[nsa]=xcount; ypp[nsa]=ycount; locfree(sloc); free(ind); dspsetnzmax(zax,xcount); dspsetnzmax(zay,ycount); dsp*ZAT=dspcat(zax,zay,1); dspfree(zax); dspfree(zay); if(amp) free(amploc); return ZAT; }
/** Assemble the DM fitting matrix The fitting is done by minimizing \f$||H_X x - H_A a||^2_W\f$ where \f$H_X, H_A\f$ are ray tracing operator from tomography grid xloc, and deformable mirror grid aloc to pupil grid ploc. The norm is weighted using bilinear influence functions within the telescope aperture. We have \f$a=\left[H_A^T(W_0-W_1 W_1^T)H_A\right]^{-1} H_A^T (W_0-W_1) H_X x\f$ For details see www.opticsinfobase.org/abstract.cfm?URI=josaa-19-9-1803 */ static void setup_recon_fit_matrix(RECON_T *recon, const PARMS_T *parms){ const int nfit=parms->fit.nfit; const int ndm=parms->ndm; if(ndm==0) return; dspcell *HATc=dspcelltrans(recon->HA); PDSPCELL(HATc, HAT); PDSPCELL(recon->HA,HA); info2("Before assembling fit matrix:\t%.2f MiB\n",get_job_mem()/1024.); /*Assemble Fit matrix. */ int npsr=recon->npsr; if(parms->load.fit){ if(!(zfexist("FRM") && zfexist("FRU") && zfexist("FRV"))){ error("FRM, FRU, FRV (.bin) not all exist\n"); } warning("Loading saved recon->FR\n"); recon->FR.M=readbin("FRM"); recon->FR.U=dcellread("FRU"); recon->FR.V=dcellread("FRV"); }else{ if(recon->HXF){ info2("Building recon->FR\n"); recon->FR.M=cellnew(ndm, npsr); PDSPCELL(recon->FR.M, FRM); PDSPCELL(recon->HXF, HXF); for(int ips=0; ips<npsr; ips++){ for(int ifit=0; ifit<nfit; ifit++){ if(fabs(recon->fitwt->p[ifit])<1.e-12) continue; dsp *tmp=dspmulsp(recon->W0, HXF[ips][ifit],"nn"); for(int idm=0; idm<ndm; idm++){ dspmulsp2(&FRM[ips][idm],HAT[ifit][idm], tmp, "nn", recon->fitwt->p[ifit]); } dspfree(tmp); } } recon->FR.V=cellnew(npsr, 1); dmat **FRV=recon->FR.V->p; for(int ips=0; ips<npsr; ips++){ int nloc=recon->xloc->p[ips]->nloc; FRV[ips]=dnew(nloc,nfit); for(int ifit=0; ifit<nfit; ifit++){ /*notice the sqrt. */ if(fabs(recon->fitwt->p[ifit])<1.e-12) continue; dspmulvec(FRV[ips]->p+ifit*nloc, HXF[ips][ifit], recon->W1->p, 't', sqrt(recon->fitwt->p[ifit])); } } if(parms->save.recon){ writebin(recon->FR.M,"FRM"); writebin(recon->FR.V,"FRV"); } }else{ info("Avoid building recon->FR.M\n"); recon->FR.M=NULL; recon->FR.V=NULL; } /*Always need FR.U as it is used to do FL.U, FL.V */ recon->FR.U=cellnew(ndm, 1); dmat **FRU=recon->FR.U->p; for(int idm=0; idm<ndm; idm++){ int nloc=recon->aloc->p[idm]->nloc; FRU[idm]=dnew(nloc, nfit); for(int ifit=0; ifit<nfit; ifit++){ /*notice the sart. */ if(fabs(recon->fitwt->p[ifit])<1.e-12) continue; dspmulvec(FRU[idm]->p+ifit*nloc, HA[idm][ifit], recon->W1->p,'t', sqrt(recon->fitwt->p[ifit])); } } if(parms->save.recon){ writebin(recon->FR.U,"FRU"); } } if(parms->load.fit){ if(!(zfexist("FLM") && zfexist("FLU") && zfexist("FLV"))){ error("FLM, FLU, FLV (.bin) not all exist\n"); } warning("Loading saved recon->FL\n"); recon->FL.M=readbin("FLM"); recon->FL.U=dcellread("FLU"); recon->FL.V=dcellread("FLV"); }else{ info2("Building recon->FL\n"); recon->FL.M=cellnew(ndm, ndm); dsp *(*FLM)[ndm]=(dsp*(*)[ndm])recon->FL.M->p; for(int idm=0; idm<ndm; idm++){ for(int ifit=0; ifit<nfit; ifit++){ if(fabs(recon->fitwt->p[ifit])<1.e-12) continue; dsp *tmp=dspmulsp(recon->W0, HA[idm][ifit],"nn"); for(int jdm=0; jdm<ndm; jdm++){ dspmulsp2(&FLM[idm][jdm],HAT[ifit][jdm], tmp,"nn", recon->fitwt->p[ifit]); } dspfree(tmp); } } dspcellfree(HATc); if(fabs(parms->fit.tikcr)>1.e-15){ double tikcr=parms->fit.tikcr; /*Estimated from the formula. 1/nloc is due to W0, the other scaling is due to ray tracing between different sampling freq.*/ int nact=0; for(int idm=0; idm<parms->ndm; idm++){ nact+=recon->aloc->p[idm]->nloc; } double maxeig=4./nact; info2("Adding tikhonov constraint of %g to FLM\n", tikcr); info2("The maximum eigen value is estimated to be around %e\n", maxeig); dcelladdI(recon->FL.M,tikcr*maxeig); } {/*Low rank terms. */ recon->FL.U=dcellcat_each(recon->FR.U, recon->fitNW, 2); dcell *tmp=NULL;/*negative NW. */ dcelladd(&tmp, 1, recon->fitNW, -1); recon->FL.V=dcellcat_each(recon->FR.U, tmp, 2); dcellfree(tmp); } if(recon->actslave){ dcelladd(&recon->FL.M, 1, recon->actslave, 1); } /*dspcellsym(recon->FL.M); */ info2("DM Fit number of Low rank terms: %ld in RHS, %ld in LHS\n", recon->FR.U->p[0]->ny, recon->FL.U->p[0]->ny); if(parms->save.recon){ writebin(recon->FL.M,"FLM.bin"); writebin(recon->FL.U,"FLU"); writebin(recon->FL.V,"FLV"); } } if((parms->fit.alg==0 || parms->fit.alg==2) && parms->fit.bgs){ muv_direct_diag_prep(&(recon->FL),(parms->fit.alg==2)*parms->fit.svdthres); } if((parms->fit.alg==0 || parms->fit.alg==2) && !parms->fit.bgs){ if(fabs(parms->fit.tikcr)<1.e-14){ warning("tickcr=%g is too small, chol may fail.\n", parms->fit.tikcr); } muv_direct_prep(&(recon->FL),(parms->fit.alg==2)*parms->fit.svdthres); info2("After cholesky/svd on matrix:\t%.2f MiB\n",get_job_mem()/1024.); } if(parms->save.recon){ if(recon->FL.C){ chol_convert(recon->FL.C, 1); chol_save(recon->FL.C,"FLC.bin"); } if(recon->FL.MI) writebin(recon->FL.MI,"FLMI"); if(recon->FL.Up) writebin(recon->FL.Up, "FLUp"); if(recon->FL.Vp) writebin(recon->FL.Vp, "FLVp"); if(recon->FL.CB){ for(int ib=0; ib<recon->FL.nb; ib++){ chol_save(recon->FL.CB[ib],"FLCB_%d.bin", ib); } } if(recon->FL.MIB){ writebin(recon->FL.MIB,"FLMIB"); } } info2("After assemble fit matrix:\t%.2f MiB\n",get_job_mem()/1024.); }