inline void reaccum_moments(accum &A, int *t, int n) { clear_accum(A); for(int i=0; i<n; i++) accum_moment(A, RAPID_moment[t[i]]); }
void nemo_main(void) { char line[80]; stream instr = stropen(getparam("in"),"r"); int mom = getiparam("moment"); int maxsize = getiparam("maxsize"); real x; Moment m; bool Qminmax = getbparam("minmax"); bool Qmedian = getbparam("median"); ini_moment(&m,ABS(mom),maxsize); while (fgets(line,80,instr) != NULL) { x = atof(line); accum_moment(&m,x,1.0); if (maxsize > 0) { debug_moment(1,&m); printf("%d ",n_moment(&m)); if (Qminmax) printf("%g %g\n",min_moment(&m), max_moment(&m)); else if (Qmedian) printf("%g\n",median_moment(&m)); else printf("%g\n",show_moment(&m,mom)); } } if (maxsize == 0) { printf("%d ",n_moment(&m)); if (Qminmax) printf("%g %g\n",min_moment(&m), max_moment(&m)); else if (Qmedian) printf("%g\n",median_moment(&m)); else printf("%g\n",show_moment(&m,mom)); } }
nemo_main() { stream instr, tabstr; real tsnap, ekin, etot, dr, r, rv, v, vr, vt, aux; real varmin[MAXOPT], varmax[MAXOPT]; real var0[MAXOPT], var1[MAXOPT], var2[MAXOPT]; Moment var[MAXOPT]; string headline=NULL, options, times, mnmxmode; Body *btab = NULL, *bp, *bq; bool Qmin, Qmax, Qmean, Qsig, Qtime, scanopt(); int i, n, nbody, bits, nsep, isep, nopt, ParticlesBit; char fmt[20],*pfmt; string *burststring(), *opt; rproc btrtrans(), fopt[MAXOPT], faux; ParticlesBit = (MassBit | PhaseSpaceBit | PotentialBit | AccelerationBit | AuxBit | KeyBit); instr = stropen(getparam("in"), "r"); /* open input file */ mnmxmode= getparam("mode"); opt = burststring(getparam("var"),", "); nopt = 0; /* count options */ while (opt[nopt]) { /* scan through options */ fopt[nopt] = btrtrans(opt[nopt]); nopt++; if (nopt==MAXOPT) { dprintf(0,"\n\nMaximum number of var's = %d exhausted\n",MAXOPT); break; } } dprintf(0,"var: \n"); for (i=0; i<nopt; i++) dprintf(0,"%s ",opt[i]); dprintf(0,"\n"); dprintf(0,"mode: %s\n",mnmxmode); Qmin = scanopt(mnmxmode,"min"); Qmax = scanopt(mnmxmode,"max"); Qmean = scanopt(mnmxmode,"mean"); Qsig = scanopt(mnmxmode,"sigma"); Qtime = scanopt(mnmxmode,"time"); if (!Qmin && !Qmax && !Qmean && !Qsig && !Qtime) error("No mode selected"); #if 0 pfmt = getparam("tab"); if (pfmt!=NULL && *pfmt!=NULL) { dprintf(0,"Saving table in %s\n",pfmt); tabstr = stropen(pfmt,"w"); } else #endif tabstr = stdout; times = getparam("times"); pfmt = getparam("format"); strcpy (fmt,pfmt); if (strchr(fmt,' ')==NULL && strchr(fmt,',')==NULL) strcat (fmt," "); /* append blank if user did not specify sep */ get_history(instr); /* read history */ for(;;) { /* repeating until first or all times are read */ get_history(instr); if (!get_tag_ok(instr, SnapShotTag)) break; /* done with work */ get_snap(instr, &btab, &nbody, &tsnap, &bits); if (!streq(times,"all") && !within(tsnap,times,0.0001)) continue; /* skip work on this snapshot */ if ( (bits & ParticlesBit) == 0) continue; /* skip work, only diagnostics here */ for (bp = btab, i=0; bp < btab+nbody; bp++, i++) { for (n=0; n<nopt; n++) { aux = fopt[n](bp,tsnap,i); if (i==0) ini_moment(&var[n],2,0); accum_moment(&var[n], aux, 1.0); } } if (Qtime) fprintf(tabstr,fmt,tsnap); if (Qmin) { for (n=0; n<nopt; n++) fprintf(tabstr,fmt,min_moment(&var[n])); } if (Qmax) { for (n=0; n<nopt; n++) fprintf(tabstr,fmt,max_moment(&var[n])); } if (Qmean) { for (n=0; n<nopt; n++) fprintf(tabstr,fmt,mean_moment(&var[n])); } if (Qsig) { for (n=0; n<nopt; n++) fprintf(tabstr,fmt,sigma_moment(&var[n])); } fprintf(tabstr,"\n"); } strclose(instr); }
nemo_main() { int i, j, k; real x, xmin, xmax, mean, sigma, skew, kurt, median, bad, w, *data; real sum, sov; Moment m; bool Qmin, Qmax, Qbad, Qw, Qmedian, Qmmcount = getbparam("mmcount"); real nu, nppb = getdparam("nppb"); int npar = getiparam("npar"); int ngood = 0; int min_count, max_count; instr = stropen (getparam("in"), "r"); read_image (instr,&iptr); strclose(instr); if (hasvalue("win")) { instr = stropen (getparam("win"), "r"); read_image (instr,&wptr); strclose(instr); if (Nx(iptr) != Nx(wptr)) error("X sizes of in/win don't match"); if (Ny(iptr) != Ny(wptr)) error("X sizes of in/win don't match"); if (Nz(iptr) != Nz(wptr)) error("X sizes of in/win don't match"); Qw = TRUE; } else Qw = FALSE; nx = Nx(iptr); ny = Ny(iptr); nz = Nz(iptr); Qmin = hasvalue("min"); if (Qmin) xmin = getdparam("min"); Qmax = hasvalue("max"); if (Qmax) xmax = getdparam("max"); Qbad = hasvalue("bad"); if (Qbad) bad = getdparam("bad"); Qmedian = getbparam("median"); if (Qmedian) data = (real *) allocate(nx*ny*nz*sizeof(real)); sov = Dx(iptr)*Dy(iptr)*Dz(iptr); /* voxel volume; TODO: should we do 2D vs. 3D ? */ ini_moment(&m,4,0); for (i=0; i<nx; i++) { for (j=0; j<ny; j++) { for (k=0; k<nz; k++) { x = CubeValue(iptr,i,j,k); if (Qmin && x<xmin) continue; if (Qmax && x>xmax) continue; if (Qbad && x==bad) continue; w = Qw ? CubeValue(wptr,i,j,k) : 1.0; accum_moment(&m,x,w); if (Qmedian) data[ngood++] = x; } } } if (npar > 0) { nu = n_moment(&m)/nppb - npar; if (nu < 1) error("%g: No degrees of freedom",nu); printf("chi2= %g\n", show_moment(&m,2)/nu/nppb); printf("df= %g\n", nu); } else { nsize = nx * ny * nz; mean = mean_moment(&m); sigma = sigma_moment(&m); skew = skewness_moment(&m); kurt = kurtosis_moment(&m); sum = show_moment(&m,1); printf ("Min=%f Max=%f\n",min_moment(&m), max_moment(&m)); printf ("Number of points : %d\n",n_moment(&m)); printf ("Mean and dispersion : %f %f\n",mean,sigma); printf ("Skewness and kurtosis : %f %f\n",skew,kurt); printf ("Sum and Sum*Dx*Dy*Dz : %f %f\n",sum, sum*sov); if (Qmedian) printf ("Median : %f\n",get_median(ngood,data)); if (Qmmcount) { min_count = max_count = 0; xmin = min_moment(&m); xmax = max_moment(&m); for (i=0; i<nx; i++) { for (j=0; j<ny; j++) { for (k=0; k<nz; k++) { x = CubeValue(iptr,i,j,k); if (x==xmin) min_count++; if (x==xmax) max_count++; } } } /* i */ printf("Min_Max_count : %d %d\n",min_count,max_count); } printf ("%d/%d out-of-range points discarded\n",nsize-n_moment(&m), nsize); } }
nemo_main() { int i, j, k, ki; real x, y, z, xmin, xmax, mean, sigma, skew, kurt, bad, w, *data; real dmin, dmax; real sum, sov, q1, q2, q3; Moment m; bool Qmin, Qmax, Qbad, Qw, Qmedian, Qrobust, Qtorben, Qmmcount = getbparam("mmcount"); bool Qx, Qy, Qz, Qone, Qall, Qign = getbparam("ignore"); bool Qhalf = getbparam("half"); bool Qmaxpos = getbparam("maxpos"); real nu, nppb = getdparam("nppb"); int npar = getiparam("npar"); int ngood; int ndat = 0; int nplanes; int min_count, max_count; int maxmom = getiparam("maxmom"); int maxpos[2]; char slabel[32]; instr = stropen (getparam("in"), "r"); read_image (instr,&iptr); strclose(instr); nx = Nx(iptr); ny = Ny(iptr); nz = Nz(iptr); dprintf(1,"# data order debug: %f %f\n",Frame(iptr)[0], Frame(iptr)[1]); if (hasvalue("tab")) tabstr = stropen(getparam("tab"),"w"); planes = (int *) allocate((nz+1)*sizeof(int)); nplanes = nemoinpi(getparam("planes"),planes,nz+1); Qall = (planes[0]==-1); if (planes[0]==0) { Qone = FALSE; nplanes = nz; for (k=0; k<nz; k++) planes[k] = k; } else if (!Qall) { Qone = (!Qall && nplanes==1); for (k=0; k<nplanes; k++) { if (planes[k]<1 || planes[k]>nz) error("%d is an illegal plane [1..%d]",planes[k],nz); planes[k]--; } } if (hasvalue("win")) { instr = stropen (getparam("win"), "r"); read_image (instr,&wptr); strclose(instr); if (Nx(iptr) != Nx(wptr)) error("X sizes of in=/win= don't match"); if (Ny(iptr) != Ny(wptr)) error("Y sizes of in=/win= don't match"); if (Nz(iptr) != Nz(wptr)) error("Z sizes of in=/win= don't match"); Qw = TRUE; } else Qw = FALSE; Qmin = hasvalue("min"); if (Qmin) xmin = getdparam("min"); Qmax = hasvalue("max"); if (Qmax) xmax = getdparam("max"); Qbad = hasvalue("bad"); if (Qbad) bad = getdparam("bad"); Qmedian = getbparam("median"); Qrobust = getbparam("robust"); Qtorben = getbparam("torben"); if (Qtorben) Qmedian = TRUE; if (Qmedian || Qrobust || Qtorben) { ndat = nx*ny*nz; data = (real *) allocate(ndat*sizeof(real)); } sov = 1.0; /* volume of a pixel/voxel */ Qx = Qign && Nx(iptr)==1; Qy = Qign && Ny(iptr)==1; Qz = Qign && Nz(iptr)==1; sov *= Qx ? 1.0 : Dx(iptr); sov *= Qy ? 1.0 : Dy(iptr); sov *= Qz ? 1.0 : Dz(iptr); strcpy(slabel,"*"); if (!Qx) strcat(slabel,"Dx*"); if (!Qy) strcat(slabel,"Dy*"); if (!Qz) strcat(slabel,"Dz*"); if (maxmom < 0) { warning("No work done, maxmom<0"); stop(0); } if (Qall) { /* treat cube as one data block */ ini_moment(&m,maxmom,ndat); ngood = 0; for (k=0; k<nz; k++) { for (j=0; j<ny; j++) { for (i=0; i<nx; i++) { x = CubeValue(iptr,i,j,k); if (Qhalf && x>=0.0) continue; if (Qmin && x<xmin) continue; if (Qmax && x>xmax) continue; if (Qbad && x==bad) continue; w = Qw ? CubeValue(wptr,i,j,k) : 1.0; accum_moment(&m,x,w); if (Qhalf && x<0) accum_moment(&m,-x,w); if (Qmedian) data[ngood++] = x; if (tabstr) fprintf(tabstr,"%g\n",x); } } } if (npar > 0) { nu = n_moment(&m)/nppb - npar; if (nu < 1) error("%g: No degrees of freedom",nu); printf("chi2= %g\n", show_moment(&m,2)/nu/nppb); printf("df= %g\n", nu); } else { nsize = nx * ny * nz; sum = mean = sigma = skew = kurt = 0; if (maxmom > 0) { mean = mean_moment(&m); sum = show_moment(&m,1); } if (maxmom > 1) sigma = sigma_moment(&m); if (maxmom > 2) skew = skewness_moment(&m); if (maxmom > 3) kurt = kurtosis_moment(&m); printf ("Number of points : %d\n",n_moment(&m)); printf ("Min and Max : %f %f\n",min_moment(&m), max_moment(&m)); printf ("Mean and dispersion : %f %f\n",mean,sigma); printf ("Skewness and kurtosis : %f %f\n",skew,kurt); printf ("Sum and Sum*%s : %f %f\n",slabel, sum, sum*sov); if (Qmedian) { if (Qtorben) { printf ("Median Torben : %f (%d)\n",median_torben(ngood,data,min_moment(&m),max_moment(&m)),ngood); } else { printf ("Median : %f\n",get_median(ngood,data)); q2 = median(ngood,data); q1 = median_q1(ngood,data); q3 = median_q3(ngood,data); printf ("Q1,Q2,Q3 : %f %f %f\n",q1,q2,q3); } #if 1 if (ndat>0) printf ("MedianL : %f\n",median_moment(&m)); #endif } if (Qrobust) { compute_robust_moment(&m); printf ("Mean Robust : %f\n",mean_robust_moment(&m)); printf ("Sigma Robust : %f\n",sigma_robust_moment(&m)); printf ("Median Robust : %f\n",median_robust_moment(&m)); } if (Qmmcount) { min_count = max_count = 0; xmin = min_moment(&m); xmax = max_moment(&m); for (i=0; i<nx; i++) { for (j=0; j<ny; j++) { for (k=0; k<nz; k++) { x = CubeValue(iptr,i,j,k); if (x==xmin) min_count++; if (x==xmax) max_count++; } } } /* i */ printf("Min_Max_count : %d %d\n",min_count,max_count); } printf ("%d/%d out-of-range points discarded\n",nsize-n_moment(&m), nsize); } } else { /* treat each plane seperately */ /* tabular output, one line per (selected) plane */ printf("# iz z min max N mean sigma skew kurt sum sumsov "); if (Qmedian) printf(" [med med]"); if (Qrobust) printf(" robust[N mean sig med]"); if (Qmaxpos) printf(" maxposx maxposy"); printf("\n"); ini_moment(&m,maxmom,ndat); for (ki=0; ki<nplanes; ki++) { reset_moment(&m); k = planes[ki]; z = Zmin(iptr) + k*Dz(iptr); ngood = 0; for (j=0; j<ny; j++) { for (i=0; i<nx; i++) { x = CubeValue(iptr,i,j,k); if (Qmin && x<xmin) continue; if (Qmax && x>xmax) continue; if (Qbad && x==bad) continue; if (Qmaxpos) { if (i==0 && j==0) { dmax = x; maxpos[0] = 0; maxpos[1] = 0;} else if (x>dmax) { dmax = x; maxpos[0] = i; maxpos[1] = j;} } w = Qw ? CubeValue(wptr,i,j,k) : 1.0; accum_moment(&m,x,w); if (Qmedian) data[ngood++] = x; } } nsize = nx * ny * nz; sum = mean = sigma = skew = kurt = 0; if (maxmom > 0) { mean = mean_moment(&m); sum = show_moment(&m,1); } if (maxmom > 1) sigma = sigma_moment(&m); if (maxmom > 2) skew = skewness_moment(&m); if (maxmom > 3) kurt = kurtosis_moment(&m); if (n_moment(&m) == 0) { printf("# %d no data\n",k+1); continue; } printf("%d %f %f %f %d %f %f %f %f %f %f", k+1, z, min_moment(&m), max_moment(&m), n_moment(&m), mean,sigma,skew,kurt,sum,sum*sov); if (Qmedian) { printf (" %f",get_median(ngood,data)); if (ndat>0) printf (" %f",median_moment(&m)); } if (Qrobust) { compute_robust_moment(&m); printf (" %d %f %f %f",n_robust_moment(&m), mean_robust_moment(&m), sigma_robust_moment(&m), median_robust_moment(&m)); } if (Qmaxpos) { printf(" %d %d",maxpos[0],maxpos[1]); } #if 0 if (Qmmcount) { min_count = max_count = 0; xmin = min_moment(&m); xmax = max_moment(&m); for (i=0; i<nx; i++) { for (j=0; j<ny; j++) { x = CubeValue(iptr,i,j,k); if (x==xmin) min_count++; if (x==xmax) max_count++; } } /* i,j */ printf(" %d %d",min_count,max_count); } printf ("%d/%d out-of-range points discarded\n",nsize-n_moment(&m), nsize); #endif printf("\n"); } /* ki */ } }
local void histogram(void) { int i,j,k, l, kmin, kmax, lcount = 0; real count[MAXHIST], under, over; real xdat,ydat,xplt,yplt,dx,r,sum,sigma2, q, qmax; real mean, sigma, mad, skew, kurt, h3, h4, lmin, lmax, median; real rmean, rsigma, rrange[2]; Moment m; dprintf (0,"read %d values\n",npt); dprintf (0,"min and max value in column(s) %s: %g %g\n",getparam("xcol"),xmin,xmax); if (!Qauto) { xmin = xrange[0]; xmax = xrange[1]; dprintf (0,"min and max value reset to : %g %g\n",xmin,xmax); lmin = xmax; lmax = xmin; for (i=0; i<npt; i++) { if (x[i]>xmin && x[i]<=xmax) { lmin = MIN(lmin, x[i]); lmax = MAX(lmax, x[i]); } } dprintf (0,"min and max value in range : %g %g\n",lmin,lmax); } for (k=0; k<nsteps; k++) count[k] = 0; /* init histogram */ under = over = 0; ini_moment(&m, 4, Qrobust||Qmad ? npt : 0); for (i=0; i<npt; i++) { if (Qbin) { k=ring_index(nsteps,bins,x[i]); } else { if (xmax != xmin) k = (int) floor((x[i]-xmin)/(xmax-xmin)*nsteps); else k = 0; dprintf(2,"%d k=%d %g\n",i,k,x[i]); } if (k==nsteps && x[i]==xmax) k--; /* include upper edge */ if (k<0) { under++; continue; } if (k>=nsteps) { over++; continue; } count[k] = count[k] + 1; dprintf (4,"%d : %f %d\n",i,x[i],k); accum_moment(&m,x[i],1.0); } if (under > 0) error("bug: under = %d",under); if (over > 0) error("bug: over = %d",over); under = Nunder; over = Nover; mean = mean_moment(&m); sigma = sigma_moment(&m); skew = skewness_moment(&m); kurt = kurtosis_moment(&m); h3 = h3_moment(&m); h4 = h4_moment(&m); if (Qmad) mad = mad_moment(&m); if (nsigma > 0) { /* remove outliers iteratively, starting from the largest */ iq = (int *) allocate(npt*sizeof(int)); for (i=0; i<npt; i++) { #if 1 iq[i] = x[i] < xmin || x[i] > xmax; #else iq[i] = 0; #endif } lcount = 0; do { /* loop to remove outliers one by one */ qmax = -1.0; for (i=0, l=-1; i<npt; i++) { /* find largest deviation from current mean */ if (iq[i]) continue; /* but skip previously flagged points */ q = (x[i]-mean)/sigma; q = ABS(q); if (q > qmax) { qmax = q; l = i; } } if (qmax > nsigma) { lcount++; iq[l] = 1; decr_moment(&m,x[l],1.0); mean = mean_moment(&m); sigma = sigma_moment(&m); skew = skewness_moment(&m); kurt = kurtosis_moment(&m); h3 = h3_moment(&m); h4 = h4_moment(&m); if (Qmad) mad = mad_moment(&m); dprintf(1,"%d/%d: removing point %d, m/s=%g %g qmax=%g\n", lcount,npt,l,mean,sigma,qmax); if (sigma <= 0) { /* RELATED TO presetting MINMAX */ warning("BUG"); accum_moment(&m,x[l],1.0); mean = mean_moment(&m); sigma = sigma_moment(&m); skew = skewness_moment(&m); kurt = kurtosis_moment(&m); h3 = h3_moment(&m); h4 = h4_moment(&m); dprintf(1,"%d/%d: LAST removing point %d, m/s=%g %g qmax=%g\n", lcount,npt,l,mean,sigma,qmax); break; } } else dprintf(1,"%d/%d: keeping point %d, m/s=%g %g qmax=%g\n", lcount,npt,l,mean,sigma,qmax); /* if (lcount > npt/2) break; */ } while (qmax > nsigma); dprintf(0,"Removed %d/%d points for nsigma=%g\n",lcount,npt,nsigma); /* @algorithm left shift array values from mask array */ /* now shift all points into the array, decreasing npt */ /* otherwise the median is not correctly computed */ for (i=0, k=0; i<npt; i++) { dprintf(1,"iq->%d\n",iq[i]); if (iq[i]) k++; if (k==0) continue; /* ?? */ if (i-k < 0) continue; dprintf(1,"SHIFT: %d <= %d\n",i-k,i); x[i-k] = x[i]; } npt -= lcount; /* correct for outliers */ free(iq); } /* nsigma > 0 */ if (npt != n_moment(&m)) error("Counting error, probably in removing outliers..."); dprintf (0,"Number of points : %d\n",npt); if (npt>1) dprintf (0,"Mean and dispersion : %g %g %g\n",mean,sigma,sigma/sqrt(npt-1.0)); else dprintf (0,"Mean and dispersion : %g %g 0.0\n",mean,sigma); if (Qmad) dprintf (0,"MAD : %g\n",mad); dprintf (0,"Skewness and kurtosis: %g %g\n",skew,kurt); dprintf (0,"h3 and h4 : %g %g\n", h3, h4); if (Qmedian) { if (npt % 2) median = x[(npt-1)/2]; else median = 0.5 * (x[npt/2] + x[npt/2-1]); dprintf (0,"Median : %g\n",median); } else if (Qtorben) { median = median_torben(npt,x,xmin,xmax); dprintf (0,"Median_torben : %g\n",median); } dprintf (0,"Sum : %g\n",show_moment(&m,1)); if (Qrobust) { compute_robust_moment(&m); rmean = mean_robust_moment(&m); rsigma = sigma_robust_moment(&m); robust_range(&m, rrange); dprintf (0,"Robust N : %d\n",n_robust_moment(&m)); dprintf (0,"Robust Mean Disp : %g %g\n",rmean,rsigma); dprintf (0,"Robust Range : %g %g\n",rrange[0],rrange[1]); if (outstr) { for (i=0; i<npt; i++) { if (x[i]<rrange[0] || x[i]>rrange[1]) continue; fprintf(outstr,"%g %d\n",x[i],i+1); } } } if (lcount > 0) { warning("Recompute histogram because of outlier removals"); /* recompute histogram if we've lost some outliers */ for (k=0; k<nsteps; k++) count[k] = 0; /* init histogram */ under = over = 0; for (i=0; i<npt; i++) { if (xmax != xmin) k = (int) floor((x[i]-xmin)/(xmax-xmin)*nsteps); else k = 0; if (k==nsteps && x[i]==xmax) k--; /* include upper edge */ if (k<0) { under++; continue; } if (k>=nsteps) { over++; continue; } count[k] = count[k] + 1; dprintf (4,"%d : %f %d\n",i,x[i],k); } if (under > 0 || over > 0) error("under=%d over=%d in recomputed histo",under,over); } dprintf (3,"Histogram values : \n"); dx=(xmax-xmin)/nsteps; kmax=0; sum=0.0; for (k=0; k<nsteps; k++) { sum = sum + dx*count[k]; if (ylog) { if (count[k]>0.0) count[k] = log10(count[k]); else count[k] = -1.0; } if (count[k]>kmax) kmax=count[k]; dprintf (3,"%f ",count[k]); if (Qcumul) { if (k==0) count[k] += under; else count[k] += count[k-1]; } } dprintf (3,"\n"); sigma2 = 2.0 * sigma * sigma; /* gaussian */ sum /= sigma * sqrt(2*PI); /* scaling factor for equal area gauss */ if (ylog && over>0) over = log10(over); if (ylog && under>0) under = log10(under); kmax *= 1.1; /* add 10% */ if (Qcumul) kmax = npt; if (maxcount>0) /* force scaling by user ? */ kmax=maxcount; if (Qtab) { maxcount = 0; for (k=0; k<nsteps; k++) maxcount = MAX(maxcount,count[k]); if (maxcount>0) r = 29.0/maxcount; else r = 1.0; printf(" Bin Value Number\n"); printf(" Underflow %d\n",Nunder); for (k=0; k<nsteps; k++) { j = (int) (r*count[k]) + 1; if (ylog) printf("%3d %13.6g %13.6g ", k+1, xmin+(k+0.5)*dx, count[k]); else printf("%3d %13.6g %8d ", k+1, xmin+(k+0.5)*dx, (int)count[k]); while (j-- > 0) printf("*"); printf("\n"); } printf(" Overflow %d\n",Nover); stop(0); } #ifdef YAPP /* PLOTTING */ plinit("***",0.0,20.0,0.0,20.0); xplot[0] = xmin; xplot[1] = xmax; yplot[0] = 0.0; yplot[1] = (real) kmax; xaxis (2.0, 2.0, 16.0, xplot, -7, xtrans, xlab); xaxis (2.0, 18.0,16.0, xplot, -7, xtrans, NULL); yaxis (2.0, 2.0, 16.0, yplot, -7, ytrans, ylab); yaxis (18.0, 2.0, 16.0, yplot, -7, ytrans, NULL); pljust(-1); /* set to left just */ pltext(input,2.0,18.2,0.32,0.0); /* filename */ pljust(1); pltext(headline,18.0,18.2,0.24,0.0); /* headline */ pljust(-1); /* return to left just */ xdat=xmin; dx=(xmax-xmin)/nsteps; plmove(xtrans(xmin),ytrans(0.0)); for (k=0; k<nsteps; k++) { /* nsteps= */ xplt = xtrans(xdat); yplt = ytrans((real)count[k]); plline (xplt,yplt); xdat += dx; xplt = xtrans(xdat); plline (xplt,yplt); } plline(xplt,ytrans(0.0)); for (i=0; i<nxcoord; i++) { plmove(xtrans(xcoord[i]),ytrans(yplot[0])); plline(xtrans(xcoord[i]),ytrans(yplot[1])); } if (Qgauss) { /* plot model and residuals */ if (ylog) plmove(xtrans(xmin),ytrans(-1.0)); else plmove(xtrans(xmin),ytrans(0.0)); for (k=0; k<100; k++) { xdat = xmin + (k+0.5)*(xmax-xmin)/100.0; ydat = sum * exp( -sqr(xdat-mean)/sigma2); if (ylog) ydat = log10(ydat); plline(xtrans(xdat), ytrans(ydat)); } } if (Qresid) { plltype(0,2); /* dotted residuals */ xdat = xmin+0.5*dx; dprintf(1,"# residuals from gauss\n"); for (k=0; k<nsteps; k++, xdat +=dx) { ydat = sum * exp( -sqr(xdat-mean)/sigma2); dprintf(1,"%g %g %g\n",xdat,count[k],ydat); if (ylog) ydat = log10(ydat); ydat = count[k] - ydat; if (k==0) plmove(xtrans(xdat),ytrans(ydat)); else plline(xtrans(xdat),ytrans(ydat)); } plltype(0,1); /* back to normal line type */ } plstop(); #endif }
int box::split_recurse(int *t, int n) { // The orientation for the parent box is already assigned to this->pR. // The axis along which to split will be column 0 of this->pR. // The mean point is passed in on this->pT. // When this routine completes, the position and orientation in model // space will be established, as well as its dimensions. Child boxes // will be constructed and placed in the parent's CS. if (n == 1) { return split_recurse(t); } // walk along the tris for the box, and do the following: // 1. collect the max and min of the vertices along the axes of <or>. // 2. decide which group the triangle goes in, performing appropriate swap. // 3. accumulate the mean point and covariance data for that triangle. accum M1, M2; double C[3][3]; double c[3]; double minval[3], maxval[3]; int rc; // for return code on procedure calls. int in; tri *ptr; int i; double axdmp; int n1 = 0; // The number of tris in group 1. // Group 2 will have n - n1 tris. // project approximate mean point onto splitting axis, and get coord. axdmp = (pR[0][0] * pT[0] + pR[1][0] * pT[1] + pR[2][0] * pT[2]); clear_accum(M1); clear_accum(M2); MTxV(c, pR, RAPID_tri[t[0]].p1); minval[0] = maxval[0] = c[0]; minval[1] = maxval[1] = c[1]; minval[2] = maxval[2] = c[2]; for(i=0; i<n; i++) { in = t[i]; ptr = RAPID_tri + in; MTxV(c, pR, ptr->p1); minmax(minval[0], maxval[0], c[0]); minmax(minval[1], maxval[1], c[1]); minmax(minval[2], maxval[2], c[2]); MTxV(c, pR, ptr->p2); minmax(minval[0], maxval[0], c[0]); minmax(minval[1], maxval[1], c[1]); minmax(minval[2], maxval[2], c[2]); MTxV(c, pR, ptr->p3); minmax(minval[0], maxval[0], c[0]); minmax(minval[1], maxval[1], c[1]); minmax(minval[2], maxval[2], c[2]); // grab the mean point of the in'th triangle, project // it onto the splitting axis (1st column of pR) and // see where it lies with respect to axdmp. mean_from_moment(c, RAPID_moment[in]); if (((pR[0][0]*c[0] + pR[1][0]*c[1] + pR[2][0]*c[2]) < axdmp) && ((n!=2)) || ((n==2) && (i==0))) { // accumulate first and second order moments for group 1 accum_moment(M1, RAPID_moment[in]); // put it in group 1 by swapping t[i] with t[n1] int temp = t[i]; t[i] = t[n1]; t[n1] = temp; n1++; } else { // accumulate first and second order moments for group 2 accum_moment(M2, RAPID_moment[in]); // leave it in group 2 // do nothing...it happens by default } } // done using this->pT as a mean point. // error check! if ((n1 == 0) || (n1 == n)) { // our partitioning has failed: all the triangles fell into just // one of the groups. So, we arbitrarily partition them into // equal parts, and proceed. n1 = n/2; // now recompute accumulated stuff reaccum_moments(M1, t, n1); reaccum_moments(M2, t + n1, n - n1); } // With the max and min data, determine the center point and dimensions // of the parent box. c[0] = (minval[0] + maxval[0])*0.5; c[1] = (minval[1] + maxval[1])*0.5; c[2] = (minval[2] + maxval[2])*0.5; pT[0] = c[0] * pR[0][0] + c[1] * pR[0][1] + c[2] * pR[0][2]; pT[1] = c[0] * pR[1][0] + c[1] * pR[1][1] + c[2] * pR[1][2]; pT[2] = c[0] * pR[2][0] + c[1] * pR[2][1] + c[2] * pR[2][2]; d[0] = (maxval[0] - minval[0])*0.5; d[1] = (maxval[1] - minval[1])*0.5; d[2] = (maxval[2] - minval[2])*0.5; // allocate new boxes P = RAPID_boxes + RAPID_boxes_inited++; N = RAPID_boxes + RAPID_boxes_inited++; // Compute the orienations for the child boxes (eigenvectors of // covariance matrix). Select the direction of maximum spread to be // the split axis for each child. double tR[3][3]; if (n1 > 1) { mean_from_accum(P->pT, M1); covariance_from_accum(C, M1); if (eigen_and_sort1(tR, C) > 30) { // unable to find an orientation. We'll just pick identity. Midentity(tR); } McM(P->pR, tR); if ((rc = P->split_recurse(t, n1)) != RAPID_OK) return rc; } else { if ((rc = P->split_recurse(t)) != RAPID_OK) return rc; } McM(C, P->pR); MTxM(P->pR, pR, C); // and F1 VmV(c, P->pT, pT); MTxV(P->pT, pR, c); if ((n-n1) > 1) { mean_from_accum(N->pT, M2); covariance_from_accum (C, M2); if (eigen_and_sort1(tR, C) > 30) { // unable to find an orientation. We'll just pick identity. Midentity(tR); } McM(N->pR, tR); if ((rc = N->split_recurse(t + n1, n - n1)) != RAPID_OK) return rc; } else { if ((rc = N->split_recurse(t+n1)) != RAPID_OK) return rc; } McM(C, N->pR); MTxM(N->pR, pR, C); VmV(c, N->pT, pT); MTxV(N->pT, pR, c); return RAPID_OK; }
int RAPID_model::build_hierarchy() { // allocate the boxes and set the box list globals num_boxes_alloced = num_tris * 2; b = new box[num_boxes_alloced]; if (b == 0) return RAPID_ERR_MODEL_OUT_OF_MEMORY; RAPID_boxes = b; RAPID_boxes_inited = 1; // we are in process of initializing b[0]. // Determine initial orientation, mean point, and splitting axis. int i; accum M; // double F1[3]; // double S1[6]; double C[3][3]; RAPID_moment = new moment[num_tris]; if (RAPID_moment == 0) { delete [] b; return RAPID_ERR_MODEL_OUT_OF_MEMORY; } compute_moments(RAPID_moment, tris, num_tris); clear_accum(M); for(i=0; i<num_tris; i++) accum_moment(M, RAPID_moment[i]); mean_from_accum(b[0].pT, M); covariance_from_accum(C, M); eigen_and_sort1(b[0].pR, C); // create the index list int *t = new int[num_tris]; if (t == 0) { delete [] b; delete [] RAPID_moment; return RAPID_ERR_MODEL_OUT_OF_MEMORY; } for(i=0; i<num_tris; i++) t[i] = i; // set the tri pointer RAPID_tri = tris; // do the build int rc = b[0].split_recurse(t, num_tris); if (rc != RAPID_OK) { delete [] b; delete [] RAPID_moment; delete [] t; return RAPID_ERR_MODEL_OUT_OF_MEMORY; } // free the moment list delete [] RAPID_moment; RAPID_moment = 0; // null the tri pointer RAPID_tri = 0; // free the index list delete [] t; return RAPID_OK; }
int build_recurse(PQP_Model *m, int bn, int first_tri, int num_tris) { BV *b = m->child(bn); // compute a rotation matrix PQP_REAL C[3][3], E[3][3], R[3][3], s[3], axis[3], mean[3], coord; #if RAPID2_FIT moment *tri_moment = new moment[num_tris]; compute_moments(tri_moment, &(m->tris[first_tri]), num_tris); accum acc; clear_accum(acc); for(int i = 0; i < num_tris; i++) accum_moment(acc, tri_moment[i]); delete [] tri_moment; covariance_from_accum(C,acc); #else get_covariance_triverts(C,&m->tris[first_tri],num_tris); #endif Meigen(E, s, C); // place axes of E in order of increasing s int min, mid, max; if (s[0] > s[1]) { max = 0; min = 1; } else { min = 0; max = 1; } if (s[2] < s[min]) { mid = min; min = 2; } else if (s[2] > s[max]) { mid = max; max = 2; } else { mid = 2; } McolcMcol(R,0,E,max); McolcMcol(R,1,E,mid); R[0][2] = E[1][max]*E[2][mid] - E[1][mid]*E[2][max]; R[1][2] = E[0][mid]*E[2][max] - E[0][max]*E[2][mid]; R[2][2] = E[0][max]*E[1][mid] - E[0][mid]*E[1][max]; // fit the BV b->FitToTris(R, &m->tris[first_tri], num_tris); if (num_tris == 1) { // BV is a leaf BV - first_child will index a triangle b->first_child = -(first_tri + 1); } else if (num_tris > 1) { // BV not a leaf - first_child will index a BV b->first_child = m->num_bvs; m->num_bvs+=2; // choose splitting axis and splitting coord McolcV(axis,R,0); #if RAPID2_FIT mean_from_accum(mean,acc); #else get_centroid_triverts(mean,&m->tris[first_tri],num_tris); #endif coord = VdotV(axis, mean); // now split int num_first_half = split_tris(&m->tris[first_tri], num_tris, axis, coord); // recursively build the children build_recurse(m, m->child(bn)->first_child, first_tri, num_first_half); build_recurse(m, m->child(bn)->first_child + 1, first_tri + num_first_half, num_tris - num_first_half); } return PQP_OK; }