Color ray_shade(int level, Real w, Ray v, RContext *rc, Object *ol) { Inode *i = ray_intersect(ol, v); if (i != NULL) { Light *l; Real wf; Material *m = i->m; Vector3 p = ray_point(v, i->t); Cone recv = cone_make(p, i->n, PIOVER2); Color c = c_mult(m->c, c_scale(m->ka, ambient(rc))); rc->p = p; for (l = rc->l; l != NULL; l = l->next) if ((*l->transport)(l, recv, rc) && (wf = shadow(l, p, ol)) > RAY_WF_MIN) c = c_add(c, c_mult(m->c, c_scale(wf * m->kd * v3_dot(l->outdir,i->n), l->outcol))); if (level++ < MAX_RAY_LEVEL) { if ((wf = w * m->ks) > RAY_WF_MIN) { Ray r = ray_make(p, reflect_dir(v.d, i->n)); c = c_add(c, c_mult(m->s, c_scale(m->ks, ray_shade(level, wf, r, rc, ol)))); } if ((wf = w * m->kt) > RAY_WF_MIN) { Ray t = ray_make(p, refract_dir(v.d, i->n, (i->enter)? 1/m->ir: m->ir)); if (v3_sqrnorm(t.d) > 0) { c = c_add(c, c_mult(m->s, c_scale(m->kt, ray_shade(level, wf, t, rc, ol)))); } } } inode_free(i); return c; } else { return BG_COLOR; } }
Color textured_plastic(RContext *rc) { Color c, ct = texture_map(rc->m->tinfo, rc->t); c = c_add(c_mult(ct, c_add(c_scale(rc->m->ka, ambient(rc)), c_scale(rc->m->kd, diffuse(rc)))), c_mult(rc->m->s, c_scale(rc->m->ks, specular(rc)))); return c; }
void polymult (header *hd) { header *st=hd,*hd1,*result; int c,c1,c2,i,r,j,k; double *m1,*m2,*mr,x; complex *mc1,*mc2,*mcr,xc,hc; interval *mi1,*mi2,*mir,xi,hi; hd1=next_param(st); equal_params_2(&hd,&hd1); if (error) return; getmatrix(hd,&r,&c1,&m1); if (r!=1) wrong_arg(); getmatrix(hd1,&r,&c2,&m2); if (r!=1) wrong_arg(); if ((LONG)c1+c2-1>INT_MAX) wrong_arg(); c=c1+c2-1; if (iscomplex(hd)) { mc1=(complex *)m1; mc2=(complex *)m2; result=new_cmatrix(1,c,""); if (error) return; mcr=(complex *)matrixof(result); c_copy(xc,*mc1); mc1++; for (i=0; i<c2; i++) c_mult(xc,mc2[i],mcr[i]); for (j=1; j<c1; j++) { c_copy(xc,*mc1); mc1++; for (k=j,i=0; i<c2-1; i++,k++) { c_mult(xc,mc2[i],hc); c_add(hc,mcr[k],mcr[k]); } c_mult(xc,mc2[i],mcr[k]); } } else if (isinterval(hd)) { mi1=(interval *)m1; mi2=(interval *)m2; result=new_imatrix(1,c,""); if (error) return; mir=(interval *)matrixof(result); i_copy(xi,*mi1); mi1++; for (i=0; i<c2; i++) i_mult(xi,mi2[i],mir[i]); for (j=1; j<c1; j++) { i_copy(xi,*mi1); mi1++; for (k=j,i=0; i<c2-1; i++,k++) { i_mult(xi,mi2[i],hi); c_add(hi,mir[k],mir[k]); } c_mult(xi,mi2[i],mir[k]); } } else if (isreal(hd)) { result=new_matrix(1,c,""); if (error) return; mr=matrixof(result); x=*m1++; for (i=0; i<c2; i++) mr[i]=x*m2[i]; for (j=1; j<c1; j++) { x=*m1++; for (k=j,i=0; i<c2-1; i++,k++) mr[k]+=x*m2[i]; mr[k]=x*m2[i]; } } else wrong_arg(); moveresult(st,result); }
static struct polynom *pol_div(struct polynom *p,struct polynom *q,struct polynom *p1,struct polynom *p2) { int i,j; struct complex z,z1; z.x=0; z.y=0; // RS 7.2.2013 p->n=p1->n-p2->n; if (p->n<0) { sur_print("\nDegree of dividend < Degree of divisor"); WAIT; return(p); } for (i=0; i<=p->n; ++i) p->a[i].x=p->a[i].y=0.0; for (i=0; i<=p1->n; ++i) { q->a[i].x=p1->a[i].x; q->a[i].y=p1->a[i].y; } for (i=p1->n; i>=p2->n; --i) { if (c_zero(&(q->a[i]))) continue; c_div(&z,&(q->a[i]),&(p2->a[p2->n])); p->a[i-p2->n].x=z.x; p->a[i-p2->n].y=z.y; q->a[i].x=q->a[i].y=0.0; for (j=i-1; j>=i-p2->n; --j) c_sub(&(q->a[j]),&(q->a[j]), c_mult(&z1,&z,&(p2->a[p2->n-i+j]))); } i=p2->n-1; while (c_zero(&(q->a[i])) && i>0) --i; q->n=i; return(p); }
void fft (double *a, int n, int signum) { complex z; double h; int i; if (n==0) return; nn=n; ram=newram; if (!freeram(2*(1+n)*sizeof(complex))) outofram(); ff=(complex *)a; zz=(complex *)ram; ram+=n*sizeof(complex); fh=(complex *)ram; ram+=n*sizeof(complex); /* compute zz[k]=e^{-2*pi*i*k/n}, k=0,...,n-1 */ h=2*M_PI/n; z[0]=cos(h); z[1]=signum*sin(h); zz[0][0]=1; zz[0][1]=0; for (i=1; i<n; i++) { if (i%16) { zz[i][0]=cos(i*h); zz[i][1]=signum*sin(i*h); } else c_mult(zz[i-1],z,zz[i]); } rfft(0,n,1,1); if (signum==1) for (i=0; i<n; i++) { ff[i][0]*=n; ff[i][1]*=n; } }
Color *radiosity_prog(int n, Poly **p, Color *e, Color *rho) { int src, rcv, iter = 0; Real ff, mts, *a = NEWTARRAY(n, Real); Color d, *dm = NEWTARRAY(n, Color); Color ma, *m = NEWTARRAY(n, Color); initialize(n, m, dm, a, p, e); while (iter-- < max_iter) { src = select_shooter(n, dm, a); if (converged(src, dm)) break; for (rcv = 0; rcv < n; rcv++) { if (rcv == src || (ff = formfactor(src, rcv, n, p, a)) < REL_EPS) continue; d = c_scale(ff, c_mult(rho[rcv], dm[src])); m[rcv] = c_add(m[rcv], d); dm[rcv] = c_add(dm[rcv], d); } dm[src] = c_make(0,0,0); } ma = ambient_rad(n, dm, a); for (rcv = 0; rcv < n; rcv++) m[rcv] = c_add(m[rcv], ma); efree(a), efree(dm); return m; }
// 1D Fourier Transform: fft_1d_helper(x, N, stride, y) // if N > 1 then // 1. take the FFT of the even elements in x, and store it in the first half of y // x' = x // stride' = 2 * stride // y' = y // 2. take the FFT of the odd elements in x, and store it in the second half of y // x' = x + stride // stride' = 2 * stride // y' = y + N/2 // 3. for each frequency step k in 0 ... N/2 // i. compute the component at Wkn = exp(-j*2*pi/N * k) // y[k] = y[k] + Wkn * y[k + N/2] // ii. compute the component at Wkn = exp(-j*2*pi/N * (k + N/2)) // y[k + N/2] = y[k] + Wkn * y[k + N/2] // otherwise just return the element at x[0] void fft_1d_helper(complex* x, int N, int stride, complex* y, complex* Wkn, int Wkn_stride){ if(N > 1) { fft_1d_helper(x, N/2, 2*stride, y, Wkn, 2*Wkn_stride); fft_1d_helper(x + stride, N/2, 2*stride, y + N/2, Wkn, 2*Wkn_stride); for(int k=0; k<N/2; k++) { complex Wkn1 = Wkn[k*Wkn_stride]; complex Wkn2 = Wkn[(k + N/2)*Wkn_stride]; complex yk1 = c_add(y[k], c_mult(Wkn1, y[k + N/2])); complex yk2 = c_add(y[k], c_mult(Wkn2, y[k + N/2])); y[k] = yk1; y[k+N/2] = yk2; } } else { y[0] = x[0]; } }
void polyzeros (header *hd) { header *st=hd,*result; int i,j,r,c; double *m,*mr,x; complex *mc,*mcr,xc,hc; hd=getvalue(hd); if (error) return; if (hd->type==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); if (r!=1) wrong_arg(); result=new_matrix(1,c+1,""); if (error) return; mr=matrixof(result); mr[0]=-m[0]; mr[1]=1.0; for (i=1; i<c; i++) { x=-m[i]; mr[i+1]=1.0; for (j=i; j>=1; j--) mr[j]=mr[j-1]+x*mr[j]; mr[0]*=x; } } else if (hd->type==s_complex || hd->type==s_cmatrix) { getmatrix(hd,&r,&c,&m); mc=(complex *)m; if (r!=1) wrong_arg(); result=new_cmatrix(1,c+1,""); if (error) return; mcr=(complex *)matrixof(result); mcr[0][0]=-mc[0][0]; mcr[0][1]=-mc[0][1]; mcr[1][0]=1.0; mcr[1][1]=0.0; for (i=1; i<c; i++) { xc[0]=-mc[i][0]; xc[1]=-mc[i][1]; mcr[i+1][0]=1.0; mcr[i+1][1]=0.0; for (j=i; j>=1; j--) { c_mult(xc,mcr[j],hc); c_add(hc,mcr[j-1],mcr[j]); } c_mult(xc,mcr[0],mcr[0]); } } else wrong_arg(); moveresult(st,result); }
static struct complex *pol_value( struct polynom *p, struct complex *z, /* pointer to argument */ struct complex *v /* pointer to function value */ ) { int i; v->x=p->a[p->n].x; v->y=p->a[p->n].y; for (i=p->n-1; i>=0; --i) c_add(v,&(p->a[i]),c_mult(v,z,v)); return(v); }
void polydd (header *hd) { header *st=hd,*hd1,*result; int c1,c2,i,j,r; double *m1,*m2,*mr,x; complex *mc1,*mc2,*mcr,hc,xc; hd1=next_param(st); equal_params_2(&hd,&hd1); if (error) return; getmatrix(hd,&r,&c1,&m1); if (r!=1) wrong_arg(); getmatrix(hd1,&r,&c2,&m2); if (r!=1) wrong_arg(); if (c1!=c2) wrong_arg(); if (iscomplex(hd)) /* complex values */ { mc1=(complex *)m1; mc2=(complex *)m2; result=new_cmatrix(1,c1,""); if (error) return; mcr=(complex *)matrixof(result); c_copy(mcr[c1-1],mc2[c1-1]); for (i=c1-2; i>=0; i--) { c_copy(xc,mc1[i]); c_mult(xc,mcr[i+1],hc); c_sub(mc2[i],hc,mcr[i]); for (j=i+1; j<c1-1; j++) { c_mult(xc,mcr[j+1],hc); c_sub(mcr[j],hc,mcr[j]); } } } else { result=new_matrix(1,c1,""); if (error) return; mr=matrixof(result); mr[c1-1]=m2[c1-1]; for (i=c1-2; i>=0; i--) { x=m1[i]; mr[i]=m2[i]-x*mr[i+1]; for (j=i+1; j<c1-1; j++) mr[j]=mr[j]-x*mr[j+1]; } } moveresult(st,result); }
static struct polynom *pol_mult(struct polynom *p,struct polynom *p1,struct polynom *p2) { int i,j; struct complex tulo; p->n=p1->n+p2->n; if (p->n>MAXN-1) { pol_dim_overflow(); return(p); } for (i=0; i<=p->n; ++i) p->a[i].x=p->a[i].y=0.0; for (i=0; i<=p1->n; ++i) for (j=0; j<=p2->n; ++j) c_add(&(p->a[i+j]),&(p->a[i+j]), c_mult(&tulo,&(p1->a[i]),&(p2->a[j]))); return(p); }
void rfft (long m0, long p0, long q0, long n) /***** rfft make a fft on x[m],x[m+q0],...,x[m+(p0-1)*q0] (p points). one has xi_p0 = xi_n^n = zz[n] ; i.e., p0*n=nn. *****/ { long p,q,m,l; long mh,ml; int found=0; complex sum,h; if (p0==1) return; if (test_key()==escape) { error=301; return; } if (p0%2==0) { p=p0/2; q=2; } else { q=3; while (q*q<=p0) { if (p0%q==0) { found=1; break; } q+=2; } if (found) p=p0/q; else { q=p0; p=1; } } if (p>1) for (m=0; m<q; m++) rfft((m0+m*q0)%nn,p,q*q0,nn/p); mh=m0; for (l=0; l<p0; l++) { ml=l%p; c_copy(sum,ff[(m0+ml*q*q0)%nn]); for (m=1; m<q; m++) { c_mult(ff[(m0+(m+ml*q)*q0)%nn],zz[(n*l*m)%nn],h); c_add(sum,h,sum); } sum[0]/=q; sum[1]/=q; c_copy(fh[mh],sum); mh+=q0; if (mh>=nn) mh-=nn; } for (l=0; l<p0; l++) { c_copy(ff[m0],fh[m0]); m0+=q0; } }
/*{{{ subtract(transform_info_ptr tinfo)*/ METHODDEF DATATYPE * subtract(transform_info_ptr tinfo) { struct subtract_storage *local_arg=(struct subtract_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; transform_info_ptr side_tinfo= &local_arg->side_tinfo; int channels1, channels2, points1, points2, channel1, channel2, point1, point2; int itempart, offset1, offset2; int itemskip=1+tinfo->leaveright; int side_itemskip=1+side_tinfo->leaveright; if (side_tinfo->tsdata==NULL || args[ARGS_EVERY].is_set) { /*{{{ (Try to) Read the next subtract epoch */ if (side_tinfo->tsdata!=NULL) free_tinfo(side_tinfo); if ((side_tinfo->tsdata=(*side_tinfo->methods->transform)(side_tinfo))!=NULL) { multiplexed(side_tinfo); } /*}}} */ } if (side_tinfo->tsdata==NULL) { ERREXIT(tinfo->emethods, "subtract: Last subtract epoch couldn't be read.\n"); } if (local_arg->ttest) { if (itemskip!=3 && itemskip!=4) { ERREXIT(tinfo->emethods, "subtract: Not 3 or 4 values per item in tinfo to calculate t comparison.\n"); } if (side_itemskip!=3 && side_itemskip!=4) { ERREXIT(tinfo->emethods, "subtract: Not 3 or 4 values per item in side_tinfo to calculate t comparison.\n"); } } else { if (tinfo->itemsize!=side_tinfo->itemsize) { /* Note we accept different itemskip values - itemskip takes precedence over side_itemskip. */ ERREXIT(tinfo->emethods, "subtract: Item counts of input epochs don't match.\n"); } if (local_arg->type==SUBTRACT_TYPE_COMPLEXMULTIPLY || local_arg->type==SUBTRACT_TYPE_COMPLEXDIVIDE) { if (tinfo->itemsize%2!=0) { ERREXIT(tinfo->emethods, "subtract: Item size must be divisible by 2 for complex operations.\n"); } itemskip=side_itemskip=2; } else { /* If leaveright is set, we still want to do something with all single items: */ itemskip=side_itemskip=1; } } if (args[ARGS_RECYCLE_CHANNELS].is_set && tinfo->nr_of_channels>side_tinfo->nr_of_channels) { channels1=tinfo->nr_of_channels; channels2=side_tinfo->nr_of_channels; } else { channels1=channels2=min(tinfo->nr_of_channels, side_tinfo->nr_of_channels); } if (args[ARGS_RECYCLE_POINTS].is_set && tinfo->nr_of_points>side_tinfo->nr_of_points) { points1=tinfo->nr_of_points; points2=side_tinfo->nr_of_points; } else { points1=points2=min(tinfo->nr_of_points, side_tinfo->nr_of_points); } multiplexed(tinfo); for (point1=point2=0; point1<points1; point1++, point2++) { /* Flip point2 back to the start if it hits the end */ if (point2==points2) point2=0; for (channel1=channel2=0; channel1<channels1; channel1++, channel2++) { /* Flip channel2 back to the start if it hits the end */ if (channel2==channels2) channel2=0; for (itempart=0; itempart<tinfo->itemsize; itempart+=itemskip) { offset1=(point1*tinfo->nr_of_channels+channel1)*tinfo->itemsize+itempart; offset2=(point2*side_tinfo->nr_of_channels+channel2)*side_tinfo->itemsize+itempart; switch (local_arg->type) { case SUBTRACT_TYPE_ADD: tinfo->tsdata[offset1]+=side_tinfo->tsdata[offset2]; break; case SUBTRACT_TYPE_MEAN: /* Work identically here regarding 'sum-only' items as average.c */ if (itempart<tinfo->itemsize-tinfo->leaveright) { tinfo->tsdata[offset1]=(tinfo->tsdata[offset1]+side_tinfo->tsdata[offset2])/2; } else { /* Simple sum for the leaveright (`sum-only') items */ tinfo->tsdata[offset1]+=side_tinfo->tsdata[offset2]; } break; case SUBTRACT_TYPE_WMEAN: /* Work identically here regarding 'sum-only' items as average.c */ if (itempart<tinfo->itemsize-tinfo->leaveright) { tinfo->tsdata[offset1]=(tinfo->tsdata[offset1]*tinfo->nrofaverages+side_tinfo->tsdata[offset2]*side_tinfo->nrofaverages)/(tinfo->nrofaverages+side_tinfo->nrofaverages); } else { /* Non-weighted sum for the leaveright (`sum-only') items */ tinfo->tsdata[offset1]+=side_tinfo->tsdata[offset2]; } break; case SUBTRACT_TYPE_SUBTRACT: tinfo->tsdata[offset1]-=side_tinfo->tsdata[offset2]; break; case SUBTRACT_TYPE_MULTIPLY: tinfo->tsdata[offset1]*=side_tinfo->tsdata[offset2]; break; case SUBTRACT_TYPE_DIVIDE: tinfo->tsdata[offset1]/=side_tinfo->tsdata[offset2]; break; case SUBTRACT_TYPE_COMPLEXMULTIPLY: { complex c1, c2, c3; /* Note that we directly conjugate c2 before multiplication->c3=c1*c2' */ c1.Re= tinfo->tsdata[offset1]; c1.Im= tinfo->tsdata[offset1+1]; c2.Re=side_tinfo->tsdata[offset1]; c2.Im= -side_tinfo->tsdata[offset1+1]; c3=c_mult(c1, c2); tinfo->tsdata[offset1]=c3.Re; tinfo->tsdata[offset1+1]=c3.Im; } break; case SUBTRACT_TYPE_COMPLEXDIVIDE: { complex c1, c2, c3; /* Note that we directly conjugate c2 before multiplication->c3=c1/c2' */ c1.Re= tinfo->tsdata[offset1]; c1.Im= tinfo->tsdata[offset1+1]; c2.Re=side_tinfo->tsdata[offset1]; c2.Im= -side_tinfo->tsdata[offset1+1]; c3=c_mult(c1, c_inv(c2)); tinfo->tsdata[offset1]=c3.Re; tinfo->tsdata[offset1+1]=c3.Im; } break; } if (local_arg->ttest) { /*{{{ Calculate t and p values for tinfo-side_tinfo. It is ensured that type==SUBTRACT_TYPE_SUBTRACT. */ int const n1=(int const)(itemskip==4 ? tinfo->tsdata[offset1+3] : tinfo->nrofaverages); int const n2=(int const)(side_itemskip==4 ? side_tinfo->tsdata[offset2+3] : side_tinfo->nrofaverages); /* tsdata[offset+2] is sum(x^2), tsdata[offset+1] is sum(x) */ /* stddevq is really n*square(sigma) */ double const stddevq1=(tinfo->tsdata[offset1+2]-square((double)tinfo->tsdata[offset1+1])/n1); double const stddevq2=(side_tinfo->tsdata[offset2+2]-square((double)side_tinfo->tsdata[offset2+1])/n2); if (args[ARGS_LEAVE_TPARAMETERS].is_set) { long const N=n1+n2-1; /* The degrees of freedom for a t test against zero will be N-1 */ /* The output will nominally have N averages, so we create * tweaked values that will recreate the t value for the paired * t-test when interpreted as sum and sumsquared and tested against zero. */ tinfo->tsdata[offset1+1]=(tinfo->tsdata[offset1+1]/n1-side_tinfo->tsdata[offset2+1]/n2)*N; tinfo->tsdata[offset1+2]=((stddevq1+stddevq2)*(n1+n2)/(n1*n2))*N+square((double)tinfo->tsdata[offset1+1])/N; if (itemskip==4) { tinfo->tsdata[offset1+3]=N; } } else { double const stddev=sqrt((stddevq1+stddevq2)/(n1+n2-2)); double const tval=(tinfo->tsdata[offset1+1]/n1-side_tinfo->tsdata[offset2+1]/n2)/stddev*sqrt(((double)n1*n2)/(n1+n2)); tinfo->tsdata[offset1+1]=tval; tinfo->tsdata[offset1+2]=student_p(n1+n2-2, (float)fabs(tval)); } /*}}} */ } } } } if (args[ARGS_TTEST].is_set && itemskip!=4) { /* Set the output nrofaverages to the necessary value needed for * 'calc ttest' to compute the correct values, but also to allow z score * computation from the t value by 'scale_by -i 1 invsqrtnrofaverages' */ tinfo->nrofaverages=tinfo->nrofaverages+side_tinfo->nrofaverages-1; } else if (local_arg->type==SUBTRACT_TYPE_MEAN) { tinfo->nrofaverages=2; } else if (local_arg->type==SUBTRACT_TYPE_WMEAN) { tinfo->nrofaverages+=side_tinfo->nrofaverages; } return tinfo->tsdata; }
void polydiv (header *hd) { header *st=hd,*hd1,*result,*rest; int c1,c2,i,r,j; double *m1,*m2,*mr,*mh,x,l; complex *mc1,*mc2,*mcr,*mch,xc,lc,hc; interval *mi1,*mi2,*mir,*mih,xi,li,hi; hd1=next_param(st); equal_params_2(&hd,&hd1); if (error) return; getmatrix(hd,&r,&c1,&m1); if (r!=1) wrong_arg(); getmatrix(hd1,&r,&c2,&m2); if (r!=1) wrong_arg(); if (c1<c2) { result=new_real(0.0,""); rest=(header *)newram; moveresult(rest,hd1); } else if (iscomplex(hd)) { mc1=(complex *)m1; mc2=(complex *)m2; result=new_cmatrix(1,c1-c2+1,""); if (error) return; mcr=(complex *)matrixof(result); rest=new_cmatrix(1,c2,""); if (error) return; mch=(complex *)newram; if (!freeram(c1*sizeof(complex))) { output("Out of memory!\n"); error=190; return; } memmove((char *)mch,(char *)mc1,c1*sizeof(complex)); c_copy(lc,mc2[c2-1]); if (lc[0]==0.0 && lc[1]==0.0) wrong_arg(); for (i=c1-c2; i>=0; i--) { c_div(mch[c2+i-1],lc,xc); c_copy(mcr[i],xc); for(j=0; j<c2; j++) { c_mult(mc2[j],xc,hc); c_sub(mch[i+j],hc,mch[i+j]); } } memmove((char *)matrixof(rest),(char *)mch,c2*sizeof(complex)); } else if (isinterval(hd)) { mi1=(interval *)m1; mi2=(interval *)m2; result=new_imatrix(1,c1-c2+1,""); if (error) return; mir=(interval *)matrixof(result); rest=new_imatrix(1,c2,""); if (error) return; mih=(complex *)newram; if (!freeram(c1*sizeof(complex))) { output("Out of memory!\n"); error=190; return; } memmove((char *)mih,(char *)mi1,c1*sizeof(interval)); i_copy(li,mi2[c2-1]); if (li[0]<=0.0 && li[1]>=0.0) wrong_arg(); for (i=c1-c2; i>=0; i--) { i_div(mih[c2+i-1],li,xi); c_copy(mir[i],xi); for(j=0; j<c2; j++) { i_mult(mi2[j],xi,hi); i_sub(mih[i+j],hi,mih[i+j]); } } memmove((char *)matrixof(rest),(char *)mih,c2*sizeof(interval)); } else if (isreal(hd)) { result=new_matrix(1,c1-c2+1,""); if (error) return; mr=matrixof(result); rest=new_matrix(1,c2,""); if (error) return; mh=(double *)newram; if (!freeram(c1*sizeof(double))) { output("Out of memory!\n"); error=190; return; } memmove((char *)mh,(char *)m1,c1*sizeof(double)); l=m2[c2-1]; if (l==0.0) wrong_arg(); for (i=c1-c2; i>=0; i--) { x=mh[c2+i-1]/l; mr[i]=x; for(j=0; j<c2; j++) mh[i+j]-=m2[j]*x; } memmove((char *)matrixof(rest),(char *)mh,c2*sizeof(double)); } else wrong_arg(); moveresult(st,result); moveresult(nextof(st),rest); }
int main(int argc, char** argv) { //Precompute FFT coefficients Wkn_fft = precompute_fft_coefficients(); Wkn_ifft = precompute_ifft_coefficients(); // Declare local variables int i, j, n; // Read in data // 1. allocate buffer space for the data. Holds Nx * Ny * Nf complex numbers. // 2. pass the filename and buffer to read_data which will read the file // into the buffer. printf("Reading Data ...\n"); tick(); complex* s = (complex*)safe_malloc(Nx * Ny * Nf * sizeof(complex), "Failed to allocate memory for radar data."); read_data(s, "scene_4.dat"); tock(); // Perform a single 2D FFT for each frequency // Each element s[i,j,n] is located at s[i * Ny * Nf + j * Nf + n] // Thus x-stride = Ny*Nf, y-stride = Nf, and z-stride = 1 // and each xy plane starts at s + 0 * Ny * Nf + 0 * Nf + n printf("Performing FFT\n"); tick(); for(n=0; n<Nf; n++) fft_2d(s + n, Nx, Ny, Ny*Nf, Nf); tock(); // Multiply each element in the frequency-domain signal by the // downward continuation phase operator. // 1. for each element (i,j,n) in the signal matrix // i in 0 ... Nx, j in 0 ... Ny, n in 0 ... Nf // 2. compute kx, ky, and k // kx = 2*pi/Dx * i/Nx if i < Nx/2, // 2*pi/Dx * (i-Nx)/Nx otherwise // ky = 2*pi/Dy * j/Ny if j < Ny/2, // 2*pi/Dy * (j-Ny)/Ny otherwise // w = 2*pi*(f0 + n*Df) // k = w/c // // 3. compute kz // kz = sqrt(4 * k^2 - kx^2 - ky^2 ) // 4. compute the phase delay // phi = exp(j * kz * z0) // 5. multiply the signal with the phase delay // where s(i,j,k) = s[i * Ny * Nf + j * Nf + n] printf("Performing Downward Continuation.\n"); tick(); for(i=0; i<Nx; i++) for(j=0; j<Ny; j++) for(n=0; n<Nf; n++){ float kx = i < Nx/2 ? 2*pi/Dx * i/Nx : 2*pi/Dx * (i - Nx)/Nx; float ky = j < Ny/2 ? 2*pi/Dy * j/Ny : 2*pi/Dy * (j - Ny)/Ny; float w = 2*pi*(f0 + n*Df); float k = w/c_speed; float kz = sqrt(4*k*k - kx*kx - ky*ky); complex phi = c_jexp(kz * z0); s[i * Ny * Nf + j * Nf + n] = c_mult(s[i * Ny * Nf + j * Nf + n], phi); } tock(); // Calculate the range of the Stolt interpolation indices. // The minimum angular frequency, w_min = 2*pi * f0 // The maximum angular frequency, w_max = 2*pi * (f0 + (N - 1)*Df) // From which the // minimum wavenumber, k_min = w_min / c // maximum wavenumber, k_max = w_max / c // The maximum wavenumber in the x direction, kx_max = 2*pi/Dx * 0.5 * (Nx-1)/Nx // The maximum wavenumber in the y direction, ky_max = 2*pi/Dy * 0.5 * (Ny-1)/Ny // The minimum wavenumbers in the x and y direction are assumed to be 0 // From which the // minimum wavenumber in the z direction, kz_min = sqrt(4*k_min^2 - kx_max^2 - ky_max^2) // maximum wavenumber in the z direction, kz_max = sqrt(4*k_max^2 - 0 - 0) float w_min = 2*pi * f0; float w_max = 2*pi * (f0 + (Nf - 1)*Df); float k_min = w_min / c_speed; float k_max = w_max / c_speed; float kx_max = 2*pi/Dx * 0.5 * (Nx-1)/Nx; float ky_max = 2*pi/Dy * 0.5 * (Ny-1)/Ny; float kz_min = sqrt(4*k_min*k_min - kx_max*kx_max - ky_max*ky_max); float kz_max = sqrt(4*k_max*k_max); // Perform Stolt Interpolation // 1. for each step in the x direction, i in 0 ... Nx // and each step in the y direction, j in 0 ... Ny // 2. compute kx, and ky as per step 2. above // 3. create float buffer of size Nf for storing the interpolation indices, n_interp // 4. for each step in frequency, n in 0 ... Nf // compute kz = kz_min + (kz_max - kz_min) * n/(Nf - 1) // 4. compute desired k = 0.5 * sqrt(kx^2 + ky^2 + kz^2) // 5. which corresponds to the interpolated array element // n_interp[n] = (c*k/(2*pi) - f0)/Df // 6. resample this line in s on interpolated indices n_interp // s[i,j,n] is at s[i * Ny * Nf + j * Nf + n] thus this line // starts at s + i * Ny * Nf + j * Nf + 0, has length Nf, and has stride 1 printf("Performing Stolt Interpolation.\n"); tick(); for(i=0; i<Nx; i++) for(j=0; j<Ny; j++){ float kx = i < Nx/2 ? 2*pi/Dx * i/Nx : 2*pi/Dx * (i - Nx)/Nx; float ky = j < Ny/2 ? 2*pi/Dy * j/Ny : 2*pi/Dy * (j - Ny)/Ny; float n_interp[Nf]; for(n=0; n<Nf; n++){ float kz = kz_min + (kz_max - kz_min) * n/(Nf - 1); float k = 0.5 * sqrt(kx*kx + ky*ky + kz*kz); n_interp[n] = (c_speed*k/(2*pi) - f0)/Df; } resample_1d(s + i*Ny*Nf + j*Nf, Nf, 1, n_interp); } tock(); // Perform a 3D IFFT on the signal // Each element s[i,j,n] is located at s[i * Ny * Nf + j * Nf + n] // Thus x-stride = Ny*Nf, y-stride = Nf, and z-stride = 1 printf("Performing IFFT.\n"); tick(); ifft_3d(s, Nx, Ny, Nf, Ny*Nf, Nf, 1); tock(); // End the simulation by writing out the computed signal and write it out to a file. // Pass the computed matrix and a output filename to write_data() printf("Writing data ...\n"); tick(); write_data(s, "scene_4.out"); tock(); printf("Done.\n"); // Free all the temporary memory free(s); }
void complex_test() { cComplex *one, *two, *target; time_t start, finish; int num_loops, i, total_time; num_loops = 50000000; // allocate memory for two cComplex structures one = (cComplex *)malloc(sizeof(cComplex)); if(one == NULL) printf("\nError allocating memory(%d)", __LINE__); two = (cComplex *)malloc(sizeof(cComplex)); if(two == NULL) printf("\nError allocating memory(%d)", __LINE__); target = (cComplex *)malloc(sizeof(cComplex)); if(target == NULL) printf("\nError allocating memory(%d)", __LINE__); printf("\nChecking c_add() function: (ans: 1 + 1i)"); one->re = 1; one->im = 0; two->re = 0; two->im = 1; c_print_t(one); c_print_t(two); c_add(one, two, target); c_print_t(target); printf("\nChecking c_mult() function: (ans: -8 + 12i"); one->re = 2; one->im = 2; two->re = 1; two->im = 5; c_print_t(one); c_print_t(two); c_mult(one, two, target); c_print_t(target); printf("\nChecking c_exp_complex() function: (ans: 148.4 + 2.59i"); one->re = 5; one->im = 1; c_print_t(one); c_exp_complex(one, target); c_print_t(target); printf("\nChecking speed of %d loops each of c_add(), c_mult() and c_exp_complex()", num_loops); start = clock(); for(i = 0; i < num_loops; i++) { c_add(one, two, target); } finish = clock(); total_time = (int)(finish - start); printf("\nTotal time for %d c_add() calls: %d ms", num_loops, finish-start); start = clock(); for(i = 0; i < num_loops; i++) { c_mult(one, two, target); } finish = clock(); total_time += (int)(finish - start); printf("\nTotal time for %d c_mult() calls: %d ms", num_loops, finish-start); start = clock(); for(i = 0; i < num_loops; i++) { c_exp_complex(one, target); } finish = clock(); total_time += (int)(finish - start); printf("\nTotal time for %d c_exp_complex() calls: %d ms", num_loops, finish-start); printf("\nTotal time for %d loops each of c_add(), c_mult(), and c_exp_complex(): %d ms", num_loops, total_time); }