5 #ifndef BALL_MATHS_TFFT1D_H
6 #define BALL_MATHS_TFFT1D_H
8 #ifndef BALL_COMMON_EXCEPTION_H
12 #ifndef BALL_DATATYPE_REGULARDATA1D_H
35 template <
typename ComplexTraits>
37 :
public TRegularData1D<std::complex<typename ComplexTraits::ComplexPrecision> >
41 typedef std::complex<typename ComplexTraits::ComplexPrecision>
Complex;
54 TFFT1D(const TFFT1D &data);
66 TFFT1D(
Size ldn,
double stepPhys = 1.,
double origin = 0.,
bool inFourierSpace = false);
78 const TFFT1D& operator = (const TFFT1D& fft1d);
96 bool operator == (const TFFT1D& fft1d) const;
192 Complex& operator [] (const
double pos);
199 const
Complex& operator [] (const
double pos) const;
283 template <
typename ComplexTraits>
287 inFourierSpace_(false),
289 planCalculated_(false)
294 template <
typename ComplexTraits>
297 if (ComplexVector::size() == fft1d.
size() &&
310 double min = inFourierSpace_ ? minFourier_ : minPhys_;
311 double max = inFourierSpace_ ? maxFourier_ : maxPhys_;
312 double step = inFourierSpace_ ? stepFourier_ : stepPhys_;
314 for (
double pos=min; pos<=
max; pos+=step)
316 if (getData(pos) != fft1d.
getData(pos))
328 template <
typename ComplexTraits>
331 Position internalOrigin = (int)
rint(trans_origin/stepPhys_);
332 if (internalOrigin <= length_)
334 origin_ = trans_origin;
336 minPhys_ = ((-1.)*origin_);
337 maxPhys_ = (((length_-1)*stepPhys_)-origin_);
338 minFourier_ = ((-1.)*(length_/2.-1)*stepFourier_);
339 maxFourier_ = ((length_/2.)*stepFourier_);
349 template <
typename ComplexTraits>
358 stepPhys_ = new_width;
359 stepFourier_ = 2.*M_PI/(stepPhys_*length_);
361 minPhys_ = ((-1.)*origin_);
362 maxPhys_ = (((length_-1)*stepPhys_)-origin_);
363 minFourier_ = ((-1.)*(length_/2.-1)*stepFourier_);
364 maxFourier_ = ((length_/2.)*stepFourier_);
370 template <
typename ComplexTraits>
376 template <
typename ComplexTraits>
382 template <
typename ComplexTraits>
388 template <
typename ComplexTraits>
394 template <
typename ComplexTraits>
400 template <
typename ComplexTraits>
406 template <
typename ComplexTraits>
409 return (length_ - 1);
412 template <
typename ComplexTraits>
415 return numFourierToPhys_;
419 template <
typename ComplexTraits>
422 if (!inFourierSpace_)
424 if (position >= ComplexVector::size())
431 r = -origin_ + (
float)position * stepPhys_;
437 if (position >= ComplexVector::size())
452 r = (
float)x * stepFourier_;
458 template <
typename ComplexTraits>
462 double normalization=1.;
464 if (!inFourierSpace_)
466 result = (*this)[pos];
467 normalization=1./pow((
double)length_,(
int)numFourierToPhys_);
471 result = (*this)[pos]*phase(pos);
473 normalization=1./(sqrt(2.*M_PI))/pow((
double)length_,(int)numFourierToPhys_);
476 result *= normalization;
481 template <
typename ComplexTraits>
486 double min = inFourierSpace_ ? minFourier_ : minPhys_;
487 double max = inFourierSpace_ ? maxFourier_ : maxPhys_;
488 double step = inFourierSpace_ ? stepFourier_ : stepPhys_;
490 if ((pos < min) || (pos > max))
495 double h = pos -
min;
496 double mod = fmod(h,step);
503 double before =
floor(h/step)*step+
min;
504 double after = ceil(h/step)*step+
min;
506 double t = (pos - before)/step;
508 result = getData(before)*(
typename ComplexTraits::ComplexPrecision)(1.-t);
509 result += getData(after)*(
typename ComplexTraits::ComplexPrecision)t;
514 template <
typename ComplexTraits>
518 if (!inFourierSpace_)
520 dummy =
Complex(val.real()*((
typename ComplexTraits::ComplexPrecision)pow((
typename ComplexTraits::ComplexPrecision)(length_),(
int)numFourierToPhys_)),
521 val.imag()*((
typename ComplexTraits::ComplexPrecision)pow((
typename ComplexTraits::ComplexPrecision)(length_),(
int)numFourierToPhys_)));
527 val*=phase(pos)*(
typename ComplexTraits::ComplexPrecision)((sqrt(2*M_PI)/stepPhys_))
528 *(
typename ComplexTraits::ComplexPrecision)pow((
typename ComplexTraits::ComplexPrecision)length_,(
int)numFourierToPhys_);
536 template <
typename ComplexTraits>
541 if (!inFourierSpace_)
543 internalPos = (
Index)
rint((pos+origin_)/stepPhys_);
547 internalPos = (
Index)
rint(pos/stepFourier_);
551 internalPos+=length_;
555 if ((internalPos < 0) || (internalPos>=(
Index) length_))
560 return operator [] ((
Position)internalPos);
563 template <
typename ComplexTraits>
568 if (!inFourierSpace_)
570 internalPos = (
Index)
rint((pos+origin_)/stepPhys_);
574 internalPos = (
Index)
rint(pos/stepFourier_);
578 internalPos+=length_;
582 if ((internalPos < 0) || (internalPos>=(
Index) length_))
587 return operator [] ((
Position)internalPos);
590 template <
typename ComplexTraits>
593 double phase = 2.*M_PI*(
rint(pos/stepFourier_))
594 *(
rint(origin_/stepPhys_))
601 template <
typename ComplexTraits>
604 return inFourierSpace_;
672 template <
typename ComplexTraits>
673 const RegularData1D& operator << (RegularData1D& to, const TFFT1D<ComplexTraits>& from)
676 if (!from.isInFourierSpace())
679 Size lengthX = from.getMaxIndex()+1;
682 newGrid.
setOrigin(from.getPhysSpaceMin());
683 newGrid.
setDimension(from.getPhysSpaceMax()-from.getPhysSpaceMin());
686 double normalization = 1./(pow((
float)(lengthX),from.getNumberOfInverseTransforms()));
688 for (
Position i = 0; i < from.size(); i++)
690 newGrid[i] = from[i].real()*normalization;
702 Size lengthX = from.getMaxIndex()+1;
704 float stepFourierX = from.getFourierStepWidth();
707 newGrid.
setOrigin(from.getFourierSpaceMin());
708 newGrid.
setDimension(from.getFourierSpaceMax()-from.getFourierSpaceMin());
712 double normalization=1./sqrt(2.*M_PI)/(pow((
float)(lengthX),from.getNumberOfInverseTransforms()));
718 for (
Position i = 0; i < from.size(); i++)
731 x-=(int)(lengthX/2.);
735 x+=(int)(lengthX/2.);
739 r = ((
float)xp * stepFourierX);
741 newGrid[i] = (from[i]*(
typename ComplexTraits::ComplexPrecision)normalization*from.phase(r)).real();
750 #endif // BALL_MATHS_TFFT1D_H