fork download
  1. #include <cstddef>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5.  
  6. typedef std::size_t index_t;
  7. typedef double element_t;
  8. typedef std::vector<element_t> row_t;
  9. typedef std::vector<row_t> slice_t;
  10. typedef std::vector<slice_t> array_3d_t;
  11.  
  12. // for one dimension
  13. template<class T>
  14. void fftshift_dimension(std::vector<T>& row)
  15. {
  16. using std::swap;
  17. const index_t size = row.size();
  18. if(size <= 1)
  19. return;
  20. const index_t halved_size = size / 2;
  21. //swap the two halves
  22. for(index_t i = 0, j = size - halved_size ; i < halved_size ; ++i, ++j)
  23. swap(row[i], row[j]);
  24. // if the size is odd, rotate the right part
  25. if(size % 2)
  26. {
  27. swap(row[halved_size], row[size - 1]);
  28. const index_t n = size - 2;
  29. for(index_t i = halved_size ; i < n ; ++i)
  30. swap(row[i], row[i + 1]);
  31. }
  32. }
  33.  
  34. // base case
  35. template<class T>
  36. void fftshift(std::vector<T>& array) {
  37. fftshift_dimension(array);
  38. }
  39.  
  40. // reduce the problem for a dimension N+1 to a dimension N
  41. template<class T>
  42. void fftshift(std::vector<std::vector<T>>& array) {
  43. fftshift_dimension(array);
  44. for(auto& slice : array)
  45. fftshift(slice);
  46. }
  47.  
  48. // overloads operator<< to print a 3-dimensional array
  49. std::ostream& operator<<(std::ostream& output, const array_3d_t& input) {
  50. const index_t width = input.size();
  51. for(index_t i = 0; i < width ; i++)
  52. {
  53. const index_t height = input[i].size();
  54. for(index_t j = 0; j < height ; j++)
  55. {
  56. const index_t depth = input[i][j].size();
  57. for(index_t k = 0; k < depth; k++)
  58. output << input[i][j][k] << ' ';
  59. output << '\n';
  60. }
  61. output << '\n';
  62. }
  63. return output;
  64. }
  65.  
  66. int main()
  67. {
  68. constexpr index_t width = 3;
  69. constexpr index_t height = 4;
  70. constexpr index_t depth = 5;
  71.  
  72. array_3d_t input(width, slice_t(height, row_t(depth)));
  73.  
  74. // initialization
  75. for(index_t i = 0 ; i < width ; ++i)
  76. for(index_t j = 0 ; j < height ; ++j)
  77. for(index_t k = 0 ; k < depth ; ++k)
  78. input[i][j][k] = i + j + k;
  79. std::cout << input;
  80.  
  81. // in place fftshift
  82. fftshift(input);
  83.  
  84. std::cout << "and then" << '\n' << input;
  85. }
  86.  
Success #stdin #stdout 0s 3460KB
stdin
Standard input is empty
stdout
0 1 2 3 4 
1 2 3 4 5 
2 3 4 5 6 
3 4 5 6 7 

1 2 3 4 5 
2 3 4 5 6 
3 4 5 6 7 
4 5 6 7 8 

2 3 4 5 6 
3 4 5 6 7 
4 5 6 7 8 
5 6 7 8 9 

and then
7 8 4 5 6 
8 9 5 6 7 
5 6 2 3 4 
6 7 3 4 5 

5 6 2 3 4 
6 7 3 4 5 
3 4 0 1 2 
4 5 1 2 3 

6 7 3 4 5 
7 8 4 5 6 
4 5 1 2 3 
5 6 2 3 4