25 #ifndef STA_STENSOR_KERNELS_H
26 #define STA_STENSOR_KERNELS_H
38 enum STA_CONVOLUTION_KERNELS {
39 STA_CONV_KERNEL_UNKNOWN=-1,
40 STA_CONV_KERNEL_GAUSS_BESSEL=0,
41 STA_CONV_KERNEL_GAUSS_LAGUERRE=1,
42 STA_CONV_KERNEL_GAUSS=2,
44 STA_CONV_KERNEL_FOURIER=4
58 virtual std::complex<T>
get(T rsqr, T theta, T phi,
int l,
int m)=0;
59 virtual std::complex<T>
get(T rsqr)=0;
60 virtual std::string getName()=0;
61 virtual STA_CONVOLUTION_KERNELS getID()=0;
62 virtual bool radialComplex()=0;
63 virtual std::complex<T> weight()=0;
68 template<
typename T>
class Gauss;
70 template<
typename T>
class SH;
74 template<
typename T,
typename S>
77 std::complex<T> * kernel,
78 const std::size_t shape[],
84 const S v_size[]=NULL,
93 bool zero_order=(L==0);
104 voxel_size[0]=voxel_size[1]=voxel_size[2]=T ( 1 );
107 voxel_size[0]*=v_size[0];
108 voxel_size[1]*=v_size[1];
109 voxel_size[2]*=v_size[2];
113 printf(
"%f %f %f\n",voxel_size[0],voxel_size[1],voxel_size[2]);
118 std::complex<double> norm=kf.weight();
126 std::size_t jumpZ=shape[2]*shape[1];
142 #pragma omp parallel for num_threads(get_numCPUs())
143 for (
int z=0;z<shape_[0];z++)
147 std::complex<T> * K=kernel+z*jumpZ*stride;
148 T Z=(T(z-z2))* voxel_size[0];
150 vecq[0] = vec[0]*vec[0];
152 for (
int y=0;y<shape_[1];y++)
154 T Y=(T(y-y2))* voxel_size[1];
156 vecq[1] = vec[1]*vec[1];
157 for (
int x=0;x<shape_[2];x++)
159 T X=(T(x-x2)) * voxel_size[2];
161 vecq[2] = vec[2]*vec[2];
162 T sum = vecq[0]+vecq[1]+vecq[2];
165 std::complex<T> & current=(*K);
171 std::complex<T> & current=K[L+m];
172 T length=std::sqrt(sum);
175 theta=std::acos( Z/length);
176 T phi=std::atan2( Y, X);
177 current=kf.get(sum,-theta,-phi,L,m);
186 #pragma omp parallel for num_threads(get_numCPUs())
187 for (
int z=0;z<shape_[0];z++)
191 std::complex<T> * K=kernel+z*jumpZ*stride;
194 if (z>z2) Z=-(shape[0]-Z);
198 vecq[0] = vec[0]*vec[0];
200 for (
int y=0;y<shape_[1];y++)
203 if (y>y2) Y=-(shape[1]-Y);
207 vecq[1] = vec[1]*vec[1];
208 for (
int x=0;x<shape_[2];x++)
211 if (x>x2) X=-(shape[2]-X);
216 vecq[2] = vec[2]*vec[2];
217 T sum = vecq[0]+vecq[1]+vecq[2];
220 std::complex<T> & current=(*K);
226 std::complex<T> & current=K[L+m];
227 T length=std::sqrt(sum);
230 theta=std::acos( Z/length);
231 T phi=std::atan2( Y, X);
232 current=kf.get(sum,-theta,-phi,L,m);
249 class Gauss:
public Kernel<T>
252 std::complex<T> imag;
255 std::string getName() {
256 return std::string(
"Gauss");
258 STA_CONVOLUTION_KERNELS getID() {
259 return STA_CONV_KERNEL_GAUSS;
261 bool radialComplex() {
267 Gauss() : Kernel<T>()
270 imag = std::complex<T>(0,1);
277 printf(
"sigma has been set to 0!!!\n");
280 std::complex<T> weight()
282 return std::complex<T>(T(1.0)/std::pow(T(t*2*M_PI),T(3.0/2.0)));
286 std::complex<T>
get(T rsqr, T theta, T phi,
int l=0,
int m=0)
289 std::complex<T> tmp=1;
291 tmp*=std::exp(-rsqr/(T(2.0)*t));
294 tmp*=hanalysis::basis_SphericalHarmonicsSemiSchmidt(l,m,(
double)theta,(
double)phi);
300 std::complex<T>
get(T rsqr)
302 std::complex<T> tmp=1;
303 tmp*=std::exp(-rsqr/(T(2.0)*t));
314 class GaussLaguerre:
public Kernel<T>
319 std::complex<double> imag;
325 std::string getName() {
326 return std::string(
"GaussLaguerre");
328 STA_CONVOLUTION_KERNELS getID() {
329 return STA_CONV_KERNEL_GAUSS_LAGUERRE;
331 bool radialComplex() {
335 GaussLaguerre() : Kernel<T>()
337 imag = std::complex<T>(0,1);
341 void setDegree(
int d) {
348 printf(
"sigma has been set to 0!!!\n");
352 std::complex<T> weight()
354 return std::complex<T>(1);
359 std::complex<T>
get(T rsqr, T theta, T phi,
int l=0,
int m=0)
362 std::complex<T> tmp=1;
364 tmp*=std::exp(-rsqr/(T(2.0)*t));
365 tmp*=gsl_sf_laguerre_n ((
double)degree,l+0.5,rsqr/(2.0*t));
368 tmp*=hanalysis::basis_SphericalHarmonicsSemiSchmidt(l,m,(
double)theta,(
double)phi);
374 std::complex<T>
get(T rsqr)
377 std::complex<T> tmp=1;
378 tmp*=std::exp(-rsqr/(T(2.0)*t));
379 tmp*=gsl_sf_laguerre_n ((
double)degree,0.5,rsqr/(2.0*t));
390 class GaussBessel:
public Kernel<T>
400 std::string getName() {
401 return std::string(
"GaussBessel");
403 STA_CONVOLUTION_KERNELS getID() {
404 return STA_CONV_KERNEL_GAUSS_BESSEL;
406 bool radialComplex() {
409 GaussBessel() : Kernel<T>()
424 printf(
"sigma has been set to 0!!!\n");
429 printf(
"sigma has been set to 0!!!\n");
432 std::complex<T> weight()
438 std::complex<T>
get(T rsqr, T theta, T phi,
int l=0,
int m=0)
441 std::complex<T> tmp=1;
442 tmp*=std::exp(-rsqr/(T(2.0)*s*t));
446 tmp*=hanalysis::basis_SphericalHarmonicsSemiSchmidt(l,m,(
double)theta,(
double)phi);
449 for (
int i=0;i<=l;i++)
451 double fact=gsl_sf_fact(l)/(gsl_sf_fact(i)*gsl_sf_fact(l-i));
452 tmp2+=fact*std::pow(1.0/(s*t),l-i)*std::pow(freq/(sqrtt),i)*std::pow(r,l-i)*gsl_sf_bessel_jl (i,freq*r/sqrtt);
457 tmp*=gsl_sf_bessel_j0 (freq*r/sqrtt);
462 std::complex<T>
get(T rsqr)
465 std::complex<T> tmp=1;
467 tmp*=gsl_sf_bessel_j0 (freq*r/sqrtt);
468 tmp*=std::exp(-rsqr/(2.0*s*t));
482 class SH:
public Kernel<T>
490 std::string getName() {
491 return std::string(
"SH");
493 STA_CONVOLUTION_KERNELS getID() {
494 return STA_CONV_KERNEL_SH;
496 bool radialComplex() {
504 void setRadius(T f) {
507 void setSmooth(T s) {
510 printf(
"sigma has been set to 0!!!\n");
513 std::complex<T> weight()
516 return std::complex<T>(1.0/(freq+0.1));
519 std::complex<T>
get(T rsqr, T theta, T phi,
int l=0,
int m=0)
522 std::complex<T> tmp=1;
524 r=((r-freq)*(r-freq)/(s*s*2));
535 tmp*=hanalysis::basis_SphericalHarmonicsSemiSchmidt(l,m,(
double)theta,(
double)phi);
536 tmp*=sqrt((2*l+1)/(4*M_PI));
541 std::complex<T>
get(T rsqr)
544 std::complex<T> tmp=1;
545 tmp*=std::exp(-((r-freq)*(r-freq)/(s*s*2)));
555 class Fourier:
public Kernel<T>
566 std::string getName() {
567 return std::string(
"Fourier");
569 STA_CONVOLUTION_KERNELS getID() {
570 return STA_CONV_KERNEL_FOURIER;
572 bool radialComplex() {
575 Fourier() : Kernel<T>()
580 getFourierFreqAndNorm(a,currentl,currentn,kln, Nln);
582 void setRadius(T a) {
585 getFourierFreqAndNorm(a,currentl,currentn,kln, Nln);
588 void setRadFunc(
int n){
590 getFourierFreqAndNorm(a,currentl,currentn,kln, Nln);
593 std::complex<T> weight()
597 return std::complex<T>(1.0);
600 std::complex<T>
get(T rsqr, T theta, T phi,
int l=0,
int m=0)
605 getFourierFreqAndNorm(a,currentl,currentn,kln, Nln);
612 std::complex<T> tmp=Nln;
615 tmp*=std::exp(-rsqr/2);
619 tmp*=hanalysis::basis_SphericalHarmonicsSemiSchmidt(l,m,(
double)theta,(
double)phi);
620 tmp*=sqrt((2*l+1)/(4*M_PI));
622 tmp*=gsl_sf_bessel_jl (l,kln *r);
626 std::complex<T>
get(T rsqr)
631 getFourierFreqAndNorm(a,currentl,currentn,kln, Nln);
638 std::complex<T> tmp=Nln;
641 tmp*=std::exp(-rsqr/2);
643 tmp*=gsl_sf_bessel_jl (0,kln *r);
STA_FIELD_STORAGE
tensor field data storage
Definition: stensor.h:5163
Definition: stensor_kernels.h:70
Definition: stensor_kernels.h:69
Definition: stensor_kernels.h:67
Definition: stensor_kernels.h:68
Definition: stensor.h:5167
Definition: stensor_kernels.h:71
The STA-ImageAnalysisToolkit namespace.
Definition: stafield.h:55
Definition: stensor_kernels.h:49
Definition: stensor.h:5170