BALL 1.5.0
FFT2D.h
Go to the documentation of this file.
1// -*- Mode: C++; tab-width: 2; -*-
2// vi: set ts=2:
3//
4
5#ifndef BALL_MATHS_TFFT2D_H
6#define BALL_MATHS_TFFT2D_H
7
8#ifndef BALL_COMMON_EXCEPTION_H
10#endif
11
12#ifndef BALL_DATATYPE_REGULARDATA2D_H
14#endif
15
16#ifndef BALL_MATHS_VECTOR2_H
17# include <BALL/MATHS/vector2.h>
18#endif
19
20#include <cmath>
21#include <complex>
22#include <fftw3.h>
23
25
26
27namespace BALL
28{
40 template <typename ComplexTraits>
41 class TFFT2D
42 : public TRegularData2D<std::complex<typename ComplexTraits::ComplexPrecision> >
43 {
44 public:
45
46 typedef std::complex<typename ComplexTraits::ComplexPrecision> Complex;
49
51
52
55
56
57 TFFT2D();
58
60 TFFT2D(const TFFT2D &data);
61
71 // ldn is not any longer the binary logarithm but the absolute number of grid points
72 TFFT2D(Size nX, Size nY, double stepPhysX=1., double stepPhysY=1., Vector2 origin=Vector2(0.,0.), bool inFourierSpace=false);
73
75 virtual ~TFFT2D();
76
78
82
84 const TFFT2D& operator = (const TFFT2D& fft_2d);
85
88 virtual void clear();
89
92 virtual void destroy();
93
95
99
102 bool operator == (const TFFT2D& fft_2d) const;
104
105 // @name Accessors
106
109 void doFFT();
110
113 void doiFFT();
114
120 bool translate(const Vector2& trans_origin);
121
127 bool setPhysStepWidth(double new_width_x, double new_width_y);
128
131 double getPhysStepWidthX() const;
132
135 double getPhysStepWidthY() const;
136
139 double getFourierStepWidthX() const;
140
143 double getFourierStepWidthY() const;
144
147 double getPhysSpaceMinX() const;
148
151 double getPhysSpaceMinY() const;
152
155 double getPhysSpaceMaxX() const;
156
159 double getPhysSpaceMaxY() const;
160
163 double getFourierSpaceMinX() const;
164
167 double getFourierSpaceMinY() const;
168
171 double getFourierSpaceMaxX() const;
172
175 double getFourierSpaceMaxY() const;
176
182 Size getMaxXIndex() const;
183
189 Size getMaxYIndex() const;
190
195
198 Vector2 getGridCoordinates(Position position) const;
199
206 Complex getData(const Vector2& pos) const;
207
215 Complex getInterpolatedValue(const Vector2& pos) const;
216
224 void setData(const Vector2& pos, Complex val);
225
231 Complex& operator[](const Vector2& pos);
232
238 const Complex& operator[](const Vector2& pos) const;
239
244 const Complex& operator [] (const IndexType& index) const { return TRegularData2D<Complex>::operator [](index); }
245
251
257 {
259 }
260
265 const Complex& operator[](const Position& pos) const
266 {
268 }
269
270 //
272 {
273 numPhysToFourier_ = num;
274 }
275
276 //
278 {
279 numFourierToPhys_ = num;
280 }
281
286 Complex phase(const Vector2& pos) const;
287
291 bool isInFourierSpace() const;
292
293 protected:
303
304 // new version for FFTW3
305 typename ComplexTraits::FftwPlan planForward_;
306 typename ComplexTraits::FftwPlan planBackward_;
307
308
309 // to control plan calculation with new fftw3
313
314 };
315
319
322 template <typename ComplexTraits>
325
330 template <typename ComplexTraits>
332
333 template <typename ComplexTraits>
336 dataLength_(0),
337 dataAdress_(0),
338 planCalculated_(false)
339 {
340 }
341
342 template <typename ComplexTraits>
344 {
345 // test whether data_.size() == fft2D.data_.size()
346 // instead of testing 2 lengths. Better for vector handling.
347
348 if (lengthX_ == fft2D.lengthX_ &&
349 lengthY_ == fft2D.lengthY_ &&
350 origin_ == fft2D.origin_ &&
351 stepPhysX_ == fft2D.stepPhysX_ &&
352 stepPhysY_ == fft2D.stepPhysY_ &&
353 stepFourierX_ == fft2D.stepFourierX_ &&
354 stepFourierY_ == fft2D.stepFourierY_ &&
355 minPhys_ == fft2D.minPhys_ &&
356 maxPhys_ == fft2D.maxPhys_ &&
357 minFourier_ == fft2D.minFourier_ &&
358 maxFourier_ == fft2D.maxFourier_ &&
359 numPhysToFourier_ == fft2D.numPhysToFourier_ &&
360 numFourierToPhys_ == fft2D.numFourierToPhys_)
361 {
362 Vector2 min = inFourierSpace_ ? minFourier_ : minPhys_;
363 Vector2 max = inFourierSpace_ ? maxFourier_ : maxPhys_;
364 double stepX = inFourierSpace_ ? stepFourierX_ : stepPhysX_;
365 double stepY = inFourierSpace_ ? stepFourierY_ : stepPhysY_;
366
367 for (double posX=min.x; posX<=max.x; posX+=stepX)
368 {
369 for (double posY=min.y; posY<=max.y; posY+=stepY)
370 {
371 if (getData(Vector2(posX,posY)) != fft2D.getData(Vector2(posX,posY)))
372 {
373 return false;
374 }
375 }
376 }
377
378 return true;
379 }
380
381 return false;
382 }
383
384 template <typename ComplexTraits>
386 {
387 Position internalOriginX = (Position) Maths::rint(trans_origin.x*stepPhysX_);
388 Position internalOriginY = (Position) Maths::rint(trans_origin.y*stepPhysY_);
389
390 if ((internalOriginX <= lengthX_) && (internalOriginY <= lengthY_))
391 {
392 origin_.x = trans_origin.x;
393 origin_.y = trans_origin.y;
394
395 minPhys_ = Vector2(-origin_.x,-origin_.y);
396 maxPhys_ = Vector2(((lengthX_-1)*stepPhysX_)-origin_.x,((lengthY_-1)*stepPhysY_)-origin_.y);
397 minFourier_ = Vector2(-(lengthX_/2.-1)*stepFourierX_,-(lengthY_/2.-1)*stepFourierY_);
398 maxFourier_ = Vector2((lengthX_/2.)*stepFourierX_,(lengthY_/2.)*stepFourierY_);
399
400 return true;
401 }
402 else
403 {
404 return false;
405 }
406 }
407
408 template <typename ComplexTraits>
409 bool TFFT2D<ComplexTraits>::setPhysStepWidth(double new_width_x, double new_width_y)
410 {
411 if ((new_width_x <= 0) || (new_width_y <= 0))
412 {
413 return false;
414 }
415 else
416 {
417 stepPhysX_ = new_width_x;
418 stepPhysY_ = new_width_y;
419 stepFourierX_ = 2.*Constants::PI/(stepPhysX_*lengthX_);
420 stepFourierY_ = 2.*Constants::PI/(stepPhysY_*lengthY_);
421
422 minPhys_ = Vector2(-origin_.x,-origin_.y);
423 maxPhys_ = Vector2(((lengthX_-1)*stepPhysX_)-origin_.x,((lengthY_-1)*stepPhysY_)-origin_.y);
424 minFourier_ = Vector2(-(lengthX_/2.-1)*stepFourierX_,-(lengthY_/2.-1)*stepFourierY_);
425 maxFourier_ = Vector2((lengthX_/2.)*stepFourierX_,(lengthY_/2.)*stepFourierY_);
426
427 return true;
428 }
429 }
430
431 template <typename ComplexTraits>
433 {
434 return stepPhysX_;
435 }
436
437 template <typename ComplexTraits>
439 {
440 return stepPhysY_;
441 }
442
443 template <typename ComplexTraits>
445 {
446 return stepFourierX_;
447 }
448
449 template <typename ComplexTraits>
451 {
452 return stepFourierY_;
453 }
454
455 template <typename ComplexTraits>
457 {
458 return minPhys_.x;
459 }
460
461 template <typename ComplexTraits>
463 {
464 return minPhys_.y;
465 }
466
467 template <typename ComplexTraits>
469 {
470 return maxPhys_.x;
471 }
472
473 template <typename ComplexTraits>
475 {
476 return maxPhys_.y;
477 }
478
479 template <typename ComplexTraits>
481 {
482 return minFourier_.x;
483 }
484
485 template <typename ComplexTraits>
487 {
488 return minFourier_.y;
489 }
490
491 template <typename ComplexTraits>
493 {
494 return maxFourier_.x;
495 }
496
497 template <typename ComplexTraits>
499 {
500 return maxFourier_.y;
501 }
502
503 template <typename ComplexTraits>
505 {
506 return (lengthX_ - 1);
507 }
508
509 template <typename ComplexTraits>
511 {
512 return (lengthY_ - 1);
513 }
514
515 template <typename ComplexTraits>
517 {
518 return numFourierToPhys_;
519 }
520
521 // new for compatibility with FFT3D
522 template <typename ComplexTraits>
524 {
525 if (!inFourierSpace_)
526 {
527 if (position >= ComplexVector::size())
528 {
529 throw Exception::OutOfGrid(__FILE__, __LINE__);
530 }
531
532 Vector2 r;
533 Position x, y;
534
535
536 // AR: ??????
537 y = position % lengthY_;
538 x = position / lengthY_;
539
540 r.set(-origin_.x + (float)x * stepPhysX_,
541 -origin_.y + (float)y * stepPhysY_);
542
543 return r;
544 }
545 else
546 {
547 if (position >= ComplexVector::size())
548 {
549 throw Exception::OutOfGrid(__FILE__, __LINE__);
550 }
551
552 Vector2 r;
553 Index x, y;
554
555 // AR: ??????
556 y = position % lengthY_;
557 x = position / lengthY_;
558
559 if (x>=lengthX_/2.)
560 {
561 x-=lengthX_;
562 }
563
564 if (y>=lengthY_/2.)
565 {
566 y-=lengthY_;
567 }
568
569 r.set((float)x * stepFourierX_,
570 (float)y * stepFourierY_);
571
572 return r;
573 }
574 }
575
576
577
578 template <typename ComplexTraits>
580 {
581 Complex result;
582 double normalization=1.;
583
584 if (!inFourierSpace_)
585 {
586 result = (*this)[pos];
587 normalization=1./((float)pow((float)(lengthX_*lengthY_),(int)numFourierToPhys_));
588 }
589 else
590 {
591 result = (*this)[pos] * phase(pos);
592 normalization=1./(2.*Constants::PI)*(stepPhysX_*stepPhysY_)/((float)pow((float)(lengthX_*lengthY_),(int)numFourierToPhys_));
593 }
594
595 result *= normalization;
596
597 return result;
598 }
599
600 template <typename ComplexTraits>
602 {
603 Complex result;
604
605 Vector2 min = inFourierSpace_ ? minFourier_ : minPhys_;
606 Vector2 max = inFourierSpace_ ? maxFourier_ : maxPhys_;
607 double stepX = inFourierSpace_ ? stepFourierX_ : stepPhysX_;
608 double stepY = inFourierSpace_ ? stepFourierY_ : stepPhysY_;
609
610 if ( (pos.x < min.x) || (pos.y < min.y)
611 || (pos.x > max.x) || (pos.y > max.y) )
612 {
613 throw Exception::OutOfGrid(__FILE__, __LINE__);
614 }
615
616 Vector2 h(pos.x - min.x, pos.y - min.y);
617 double modX = fmod((double)h.x,stepX);
618 double modY = fmod((double)h.y,stepY);
619
620 if (modX==0 && modY ==0) // we are on the grid
621 {
622 return getData(pos);
623 }
624
625 double beforeX = floor(h.x/stepX)*stepX+ min.x;
626 double beforeY = floor(h.y/stepY)*stepY+ min.y;
627 double afterX = ceil(h.x/stepX)*stepX+ min.x;
628 double afterY = ceil(h.y/stepY)*stepY+ min.y;
629
630 double tx = (pos.x - beforeX)/stepX;
631 double ty = (pos.y - beforeY)/stepY;
632
633 result = getData(Vector2(beforeX,beforeY))*(typename ComplexTraits::ComplexPrecision)((1.-tx)*(1.-ty));
634 result += getData(Vector2(afterX, beforeY))*(typename ComplexTraits::ComplexPrecision)( tx *(1.-ty));
635 result += getData(Vector2(beforeX,afterY ))*(typename ComplexTraits::ComplexPrecision)((1.-tx)* ty );
636 result += getData(Vector2(afterX, afterY ))*(typename ComplexTraits::ComplexPrecision)( tx * ty );
637
638 return result;
639 }
640
641 template <typename ComplexTraits>
643 {
644 Complex dummy;
645
646 if (!inFourierSpace_)
647 {
648 dummy = Complex(val.real()*((float)pow((float)(lengthX_*lengthY_),(int)numFourierToPhys_)),
649 val.imag()*((float)pow((float)(lengthX_*lengthY_),(int)numFourierToPhys_)));
650
651 (*this)[pos]=dummy;
652 }
653 else
654 {
655 val*=phase(pos)*(typename ComplexTraits::ComplexPrecision)((2*Constants::PI/(stepPhysX_*stepPhysY_)))
656 *(typename ComplexTraits::ComplexPrecision)pow((typename ComplexTraits::ComplexPrecision)(lengthX_*lengthY_),(int)numFourierToPhys_);
657
658 dummy = val;
659
660 (*this)[pos]=dummy;
661 }
662 }
663
664 template <typename ComplexTraits>
666 {
667 Index internalPos;
668
669 if (!inFourierSpace_)
670 {
671 Index i, j;
672
673 i = (Index) Maths::rint((pos.x+origin_.x)/stepPhysX_);
674 j = (Index) Maths::rint((pos.y+origin_.y)/stepPhysY_);
675
676 internalPos = j + i*lengthY_;
677 }
678 else
679 {
680 Index i, j;
681
682 i = (Index) Maths::rint(pos.x/stepFourierX_);
683 j = (Index) Maths::rint(pos.y/stepFourierY_);
684
685 if (i<0)
686 {
687 i+=lengthX_;
688 }
689
690 if (j<0)
691 {
692 j+=lengthY_;
693 }
694
695 internalPos = (j + i*lengthY_);
696 }
697
698 if ((internalPos < 0) || (internalPos>=(Index) (lengthX_*lengthY_)))
699 {
700 throw Exception::OutOfGrid(__FILE__, __LINE__);
701 }
702
703 return operator [] (internalPos);
704 }
705
706 template <typename ComplexTraits>
708 {
709 Index internalPos;
710
711 if (!inFourierSpace_)
712 {
713 Index i, j;
714
715 i = (Index) Maths::rint((pos.x+origin_.x)/stepPhysX_);
716 j = (Index) Maths::rint((pos.y+origin_.y)/stepPhysY_);
717
718 internalPos = j + i*lengthY_;
719 }
720 else
721 {
722 Index i, j;
723
724 i = (Index) Maths::rint(pos.x/stepFourierX_);
725 j = (Index) Maths::rint(pos.y/stepFourierY_);
726
727 if (i<0)
728 {
729 i+=lengthX_;
730 }
731
732 if (j<0)
733 {
734 j+=lengthY_;
735 }
736
737 internalPos = (j + i*lengthY_);
738 }
739
740 if ((internalPos < 0) || (internalPos>=(Index) (lengthX_*lengthY_)))
741 {
742 throw Exception::OutOfGrid(__FILE__, __LINE__);
743 }
744
745 return operator [] (internalPos);
746 }
747
748 template <typename ComplexTraits>
750 {
751 double phase = 2.*Constants::PI*( Maths::rint(pos.x/stepFourierX_)*Maths::rint(origin_.x/stepPhysX_)
752 /lengthX_
753 + Maths::rint(pos.y/stepFourierY_)*Maths::rint(origin_.y/stepPhysY_)
754 /lengthY_ );
755
756 Complex result = Complex(cos(phase), sin(phase));
757
758 return result;
759 }
760
761 template <typename ComplexTraits>
763 {
764 return inFourierSpace_;
765 }
766
767 template <typename ComplexTraits>
770 {
771 // first decide if the FFT3D data is in Fourier space.
772 if (!from.isInFourierSpace())
773 {
774 // create a new grid
775 Size lengthX = from.getMaxXIndex()+1;
776 Size lengthY = from.getMaxYIndex()+1;
777
779 Vector2(from.getPhysSpaceMinX(), from.getPhysSpaceMinY()),
780 Vector2(from.getPhysSpaceMaxX(), from.getPhysSpaceMaxY()));
781
782 // and fill it
783 double normalization=1./(pow((float)(lengthX*lengthY),from.getNumberOfInverseTransforms()));
784 typename TFFT2D<ComplexTraits>::Complex dataIn;
785 typename TFFT2D<ComplexTraits>::Complex dataOut;
786
787 for (Position i = 0; i < from.size(); i++)
788 {
789 Position x, y;
790
791 y = i % lengthY;
792 x = i / lengthY;
793
794 dataIn = from[i];
795 dataOut = dataIn;
796
797 newGrid[x + y*lengthY] = dataOut*(typename ComplexTraits::ComplexPrecision)normalization;
798 }
799
800 to = newGrid;
801
802 return to;
803 }
804 else
805 {
806 // we are in Fourier space
807
808 // create a new grid
809 Size lengthX = from.getMaxXIndex()+1;
810 Size lengthY = from.getMaxYIndex()+1;
811 //float stepPhysX = from.getPhysStepWidthX();
812 //float stepPhysY = from.getPhysStepWidthY();
813 float stepFourierX = from.getFourierStepWidthX();
814 float stepFourierY = from.getFourierStepWidthY();
815
816
817
819 Vector2(from.getFourierSpaceMinX(),
820 from.getFourierSpaceMinY()),
821 Vector2(from.getFourierSpaceMaxX(),
822 from.getFourierSpaceMaxY()));
823
824 // and fill it
825 // AR: old double normalization=1./(sqrt(2.*Constants::PI))*(stepPhysX*stepPhysY*stepPhysZ)/(pow((float)(lengthX*lengthY*lengthZ),from.getNumberOfInverseTransforms()));
826 double normalization=1./(2.*Constants::PI)/(pow((float)(lengthX*lengthY),from.getNumberOfInverseTransforms()));
827
828
829 Index x, y;
830 Vector2 r;
831 typename TFFT2D<ComplexTraits>::Complex dataIn;
832 typename TFFT2D<ComplexTraits>::Complex dataOut;
833
834 for (Position i = 0; i < from.size(); i++)
835 {
836 y = i % lengthY;
837 x = i / lengthY;
838
839 if (x>lengthX/2.)
840 {
841 x-=lengthX;
842 }
843
844 if (y>lengthY/2.)
845 {
846 y-=lengthY;
847 }
848
849 r.set((float)x * stepFourierX,
850 (float)y * stepFourierY);
851
852 dataIn = from[i];
853 dataOut = dataIn;
854
855 newGrid[x + y*lengthY] = dataOut*(typename ComplexTraits::ComplexPrecision)normalization*from.phase(r);
856 }
857
858 to = newGrid;
859
860 return to;
861 }
862 }
863
864 template <typename ComplexTraits>
866 {
867 // first decide if the FFT2D data is in Fourier space.
868 if (!from.isInFourierSpace())
869 {
870 // create a new grid
871 Size lengthX = from.getMaxXIndex()+1;
872 Size lengthY = from.getMaxYIndex()+1;
873
874 RegularData2D newGrid(RegularData2D::IndexType(lengthX, lengthY),
876 from.getPhysSpaceMinY()),
878 from.getPhysSpaceMaxY()));
879
880 // and fill it
881 double normalization = 1./(pow((float)(lengthX*lengthY),from.getNumberOfInverseTransforms()));
882 typename TFFT2D<ComplexTraits>::Complex dataIn;
883 typename TFFT2D<ComplexTraits>::Complex dataOut;
884
885 typename TFFT2D<ComplexTraits>::IndexType current_index;
886 typename RegularData2D::IndexType regdat_index;
887 for (current_index.x = 0; current_index.x < lengthX; current_index.x++)
888 {
889 for (current_index.y = 0; current_index.y < lengthY; current_index.y++)
890 {
891 regdat_index.x = current_index.x;
892 regdat_index.y = current_index.y;
893
894 dataIn = from[current_index];
895 dataOut = dataIn;
896
897 newGrid[regdat_index] = dataOut.real()*normalization;
898 }
899 }
900
901 to = newGrid;
902
903 return to;
904 }
905 else
906 {
907 // we are in Fourier space
908
909 // create a new grid
910 Size lengthX = from.getMaxXIndex()+1;
911 Size lengthY = from.getMaxYIndex()+1;
912 //float stepPhysX = from.getPhysStepWidthX();
913 //float stepPhysY = from.getPhysStepWidthY();
914 float stepFourierX = from.getFourierStepWidthX();
915 float stepFourierY = from.getFourierStepWidthY();
916
917 RegularData2D newGrid(RegularData2D::IndexType(lengthX, lengthY), Vector2(from.getFourierSpaceMinX(), from.getFourierSpaceMinY()), Vector2(from.getFourierSpaceMaxX(), from.getFourierSpaceMaxY()));
918
919 // and fill it
920 // AR: old version double normalization=1./(sqrt(2.*Constants::PI))*(stepPhysX*stepPhysY*stepPhysZ)/(pow((float)(lengthX*lengthY*lengthZ),from.getNumberOfInverseTransforms()));
921 double normalization=1./(2.*Constants::PI)/(pow((float)(lengthX*lengthY),from.getNumberOfInverseTransforms()));
922
923 Index x, y;
924 signed int xp, yp;
925 Vector2 r;
926 typename TFFT2D<ComplexTraits>::Complex dataIn;
927 typename TFFT2D<ComplexTraits>::Complex dataOut;
928
929 RegularData2D::IndexType current_index;
930 for (Position i = 0; i < from.size(); i++)
931 {
932 y = i % lengthY;
933 x = i / lengthY;
934
935 xp = x;
936 yp = y;
937
938 if (xp>=lengthX/2.)
939 {
940 xp-=(int)lengthX;
941 }
942 if (yp>=lengthY/2.)
943 {
944 yp-=(int)lengthY;
945 }
946
947 if (x>=lengthX/2.)
948 {
949 x-=(int)(lengthX/2.);
950 }
951 else
952 {
953 x+=(int)(lengthX/2.);
954 }
955
956 if (y>=lengthY/2.)
957 {
958 y-=(int)(lengthY/2.);
959 }
960 else
961 {
962 y+=(int)(lengthY/2.);
963 }
964
965
966 r.set((float)xp * stepFourierX,
967 (float)yp * stepFourierY);
968
969 dataIn = from[i];
970 dataOut = dataIn;
971
972 current_index.x = x;
973 current_index.y = y;
974
975 newGrid[current_index] = (dataOut*(typename ComplexTraits::ComplexPrecision)normalization*from.phase(r)).real();
976 }
977
978 to = newGrid;
979
980 return to;
981 }
982 }
983
984
985
986}
987
988#endif // BALL_MATHS_TFFT2D_H
#define BALL_CREATE(name)
Definition: create.h:62
BALL_EXPORT std::ostream & operator<<(std::ostream &os, const Exception::GeneralException &e)
TVector2< float > Vector2
Definition: vector2.h:771
Definition: constants.h:13
BALL_SIZE_TYPE Position
TFFT2D< BALL_FFTW_DEFAULT_TRAITS > FFT2D
Definition: FFT2D.h:318
std::complex< BALL_COMPLEX_PRECISION > Complex
Definition: complex.h:21
BALL_INDEX_TYPE Index
BALL_EXTERN_VARIABLE const double PI
PI.
Definition: constants.h:35
BALL_EXTERN_VARIABLE const double h
Definition: constants.h:102
T max(const T &a, const T &b)
Definition: MATHS/common.h:75
double rint(double x)
round to integral value in floating-point format
Definition: MATHS/common.h:327
T min(const T &a, const T &b)
Definition: MATHS/common.h:102
long floor(const T &t)
Definition: MATHS/common.h:284
BALL_INLINE size_type size() const
const ValueType & operator[](const IndexType &index) const
The index type used to refer to a specific element in the grid (x-, and y-index)
Definition: regularData2D.h:49
const TFFT2D & operator=(const TFFT2D &fft_2d)
Assignment operator.
Size getMaxXIndex() const
Definition: FFT2D.h:504
void setNumberOfFFTTransforms(Size num)
Definition: FFT2D.h:271
double getFourierSpaceMinX() const
Definition: FFT2D.h:480
double getPhysSpaceMinY() const
Definition: FFT2D.h:462
Vector2 minPhys_
Definition: FFT2D.h:301
Complex getData(const Vector2 &pos) const
Definition: FFT2D.h:579
double stepFourierX_
Definition: FFT2D.h:300
TFFT2D(Size nX, Size nY, double stepPhysX=1., double stepPhysY=1., Vector2 origin=Vector2(0., 0.), bool inFourierSpace=false)
Size numFourierToPhys_
Definition: FFT2D.h:297
double getPhysStepWidthY() const
Definition: FFT2D.h:438
Vector2 maxPhys_
Definition: FFT2D.h:301
double stepPhysX_
Definition: FFT2D.h:299
double stepFourierY_
Definition: FFT2D.h:300
virtual ~TFFT2D()
Destructor.
Vector2 maxFourier_
Definition: FFT2D.h:302
double getPhysStepWidthX() const
Definition: FFT2D.h:432
void setData(const Vector2 &pos, Complex val)
Definition: FFT2D.h:642
double getPhysSpaceMaxY() const
Definition: FFT2D.h:474
const Complex & operator[](const Position &pos) const
Definition: FFT2D.h:265
double getFourierSpaceMaxY() const
Definition: FFT2D.h:498
TFFT2D(const TFFT2D &data)
Copy constructor.
double getPhysSpaceMinX() const
Definition: FFT2D.h:456
bool setPhysStepWidth(double new_width_x, double new_width_y)
Definition: FFT2D.h:409
bool isInFourierSpace() const
Definition: FFT2D.h:762
Complex & operator[](const Vector2 &pos)
Definition: FFT2D.h:665
Size lengthY_
Definition: FFT2D.h:294
Complex & operator[](const Position &pos)
Definition: FFT2D.h:256
Size numPhysToFourier_
Definition: FFT2D.h:296
bool inFourierSpace_
Definition: FFT2D.h:295
void setNumberOfiFFTTransforms(Size num)
Definition: FFT2D.h:277
TRegularData2D< std::complex< typenameComplexTraits::ComplexPrecision > >::IndexType IndexType
Definition: FFT2D.h:48
Complex phase(const Vector2 &pos) const
Definition: FFT2D.h:749
Size lengthX_
Definition: FFT2D.h:294
Size getNumberOfInverseTransforms() const
Definition: FFT2D.h:516
Vector2 minFourier_
Definition: FFT2D.h:302
Complex getInterpolatedValue(const Vector2 &pos) const
Definition: FFT2D.h:601
std::complex< typename ComplexTraits::ComplexPrecision > Complex
Definition: FFT2D.h:46
double stepPhysY_
Definition: FFT2D.h:299
Size dataLength_
Definition: FFT2D.h:310
bool translate(const Vector2 &trans_origin)
Definition: FFT2D.h:385
Size getMaxYIndex() const
Definition: FFT2D.h:510
ComplexTraits::FftwPlan planForward_
Definition: FFT2D.h:305
double getFourierSpaceMaxX() const
Definition: FFT2D.h:492
double getFourierSpaceMinY() const
Definition: FFT2D.h:486
ComplexTraits::FftwPlan planBackward_
Definition: FFT2D.h:306
TFFT2D()
Default constructor.
Definition: FFT2D.h:334
virtual void clear()
double getFourierStepWidthX() const
Definition: FFT2D.h:444
bool planCalculated_
Definition: FFT2D.h:312
double getFourierStepWidthY() const
Definition: FFT2D.h:450
Vector2 origin_
Definition: FFT2D.h:298
TRegularData2D< std::complex< typename ComplexTraits::ComplexPrecision > > ComplexVector
Definition: FFT2D.h:47
Complex * dataAdress_
Definition: FFT2D.h:311
bool operator==(const TFFT2D &fft_2d) const
Definition: FFT2D.h:343
Vector2 getGridCoordinates(Position position) const
Definition: FFT2D.h:523
double getPhysSpaceMaxX() const
Definition: FFT2D.h:468
virtual void destroy()
void set(const T &value)
Definition: vector2.h:459