struct c_complex Lentz_Dn(struct c_complex z,long n) /*:10*/ #line 126 "./mie.w" { struct c_complex alpha_j1,alpha_j2,zinv,aj; struct c_complex alpha,result,ratio,runratio; /*12:*/ #line 156 "./mie.w" zinv= c_sdiv(2.0,z); alpha= c_smul(n+0.5,zinv); aj= c_smul(-n-1.5,zinv); alpha_j1= c_add(aj,c_inv(alpha)); alpha_j2= aj; ratio= c_div(alpha_j1,alpha_j2); runratio= c_mul(alpha,ratio); /*:12*/ #line 131 "./mie.w" do /*13:*/ #line 179 "./mie.w" { aj.re= zinv.re-aj.re; aj.im= zinv.im-aj.im; alpha_j1= c_add(c_inv(alpha_j1),aj); alpha_j2= c_add(c_inv(alpha_j2),aj); ratio= c_div(alpha_j1,alpha_j2); zinv.re*= -1; zinv.im*= -1; runratio= c_mul(ratio,runratio); } /*:13*/ #line 134 "./mie.w" while(fabs(c_abs(ratio)-1.0)> 1e-12); result= c_add(c_sdiv((double)-n,z),runratio); return result; }
void Dn_down(struct c_complex z,long nstop,struct c_complex*D) /*:19*/ #line 247 "./mie.w" { long k; struct c_complex zinv,k_over_z; D[nstop-1]= Lentz_Dn(z,nstop); zinv= c_inv(z); for(k= nstop-1;k>=1;k--){ k_over_z= c_smul((double)k,zinv); D[k-1]= c_sub(k_over_z,c_inv(c_add(D[k],k_over_z))); } }
void Dn_up(struct c_complex z,long nstop,struct c_complex*D) /*:16*/ #line 216 "./mie.w" { struct c_complex zinv,k_over_z; long k; D[0]= c_inv(c_tan(z)); zinv= c_inv(z); for(k= 1;k<nstop;k++){ k_over_z= c_smul((double)k,zinv); D[k]= c_sub(c_inv(c_sub(k_over_z,D[k-1])),k_over_z); } }
/*{{{ 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; }