Array.cxx
Go to the documentation of this file.
1 #include "WireCellUtil/Array.h"
2 
3 #include <unsupported/Eigen/FFT>
4 
5 #include <algorithm>
6 #include <complex>
7 
8 using namespace WireCell;
9 using namespace WireCell::Array;
10 
11 
12 
13 //http://stackoverflow.com/a/33636445
14 
16 {
17  const int nrows = arr.rows();
18  const int ncols = arr.cols();
19 
20  Eigen::FFT< float > fft;
21  Eigen::MatrixXcf matc(nrows, ncols);
22 
23  for (int irow = 0; irow < nrows; ++irow) {
24  Eigen::VectorXcf fspec(ncols); // frequency spectrum
25  // fft wants vectors, also input arr is const
26  Eigen::VectorXf tmp = arr.row(irow);
27  fft.fwd(fspec, tmp);
28  matc.row(irow) = fspec;
29  }
30 
31  for (int icol = 0; icol < ncols; ++icol) {
32  Eigen::VectorXcf pspec(nrows); // periodicity spectrum
33  fft.fwd(pspec, matc.col(icol));
34  matc.col(icol) = pspec;
35  }
36 
37  return matc;
38 }
39 
41 {
42  const int nrows = arr.rows();
43  const int ncols = arr.cols();
44 
45  Eigen::FFT< float > fft;
46  Eigen::MatrixXcf matc(nrows, ncols);
47 
48  if (dim == 0) {
49  for (int irow = 0; irow < nrows; ++irow) {
50  Eigen::VectorXcf fspec(ncols);
51  Eigen::VectorXf tmp = arr.row(irow);
52  fft.fwd(fspec, tmp);
53  matc.row(irow) = fspec;
54  }
55  }
56  else if (dim == 1) {
57  for (int icol = 0; icol < ncols; ++icol) {
58  Eigen::VectorXcf fspec(nrows);
59  Eigen::VectorXf tmp = arr.col(icol);
60  fft.fwd(fspec, tmp);
61  matc.col(icol) = fspec;
62  }
63  }
64  return matc;
65 }
66 
68 {
69  const int nrows = arr.rows();
70  const int ncols = arr.cols();
71 
72  Eigen::FFT< float > fft;
73  Eigen::MatrixXcf matc(nrows, ncols);
74 
75  matc = arr.matrix();
76 
77  if (dim == 0) {
78  for (int irow = 0; irow < nrows; ++irow) {
79  Eigen::VectorXcf pspec(ncols);
80  fft.fwd(pspec,matc.row(irow));
81  matc.row(irow) = pspec;
82  }
83  }
84  else {
85  for (int icol = 0; icol < ncols; ++icol) {
86  Eigen::VectorXcf pspec(nrows);
87  fft.fwd(pspec, matc.col(icol));
88  matc.col(icol) = pspec;
89  }
90  }
91  return matc;
92 }
93 
94 
95 
97 {
98  const int nrows = arr.rows();
99  const int ncols = arr.cols();
100 
101  // fft works on matrices, not arrays, also don't step on const input
102  Eigen::MatrixXcf partial(nrows, ncols);
103  partial = arr.matrix();
104 
105  Eigen::FFT< float > fft;
106 
107  for (int icol = 0; icol < ncols; ++icol) {
108  Eigen::VectorXcf pspec(nrows); // wire spectrum
109  fft.inv(pspec, partial.col(icol));
110  partial.col(icol) = pspec;
111  }
112 
113  //shared_array_xxf ret = std::make_shared<array_xxf> (nrows, ncols);
114  array_xxf ret(nrows, ncols);
115 
116  for (int irow = 0; irow < nrows; ++irow) {
117  Eigen::VectorXf wave(ncols); // back to real-valued time series
118  fft.inv(wave, partial.row(irow));
119  ret.row(irow) = wave;
120  }
121 
122  return ret;
123 }
124 
126 {
127  const int nrows = arr.rows();
128  const int ncols = arr.cols();
129 
130  // fft works on matrices, not arrays, also don't step on const input
131  Eigen::MatrixXcf ret(nrows, ncols);
132  ret = arr.matrix();
133 
134  Eigen::FFT< float > fft;
135 
136  if (dim == 1) {
137  for (int icol = 0; icol < ncols; ++icol) {
138  Eigen::VectorXcf pspec(nrows);
139  fft.inv(pspec, ret.col(icol));
140  ret.col(icol) = pspec;
141  }
142  }
143  else if (dim == 0) {
144  for (int irow = 0; irow < nrows; ++irow) {
145  Eigen::VectorXcf pspec(ncols);
146  fft.inv(pspec, ret.row(irow));
147  ret.row(irow) = pspec;
148  }
149  }
150  return ret;
151 }
152 
154 {
155  const int nrows = arr.rows();
156  const int ncols = arr.cols();
157 
158  // fft works on matrices, not arrays, also don't step on const input
159  Eigen::MatrixXcf partial(nrows, ncols);
160  partial = arr.matrix();
161 
162  Eigen::FFT< float > fft;
163 
164  array_xxf ret(nrows, ncols);
165 
166  if (dim == 0) {
167  for (int irow = 0; irow < nrows; ++irow) {
168  Eigen::VectorXf wave(ncols); // back to real-valued time series
169  fft.inv(wave, partial.row(irow));
170  ret.row(irow) = wave;
171  }
172  }
173  else if (dim == 1) {
174  for (int icol = 0; icol < ncols; ++icol) {
175  Eigen::VectorXf wave(nrows);
176  fft.inv(wave, partial.col(icol));
177  ret.col(icol) = wave;
178  }
179  }
180  return ret;
181 }
182 
183 
184 
185 // this is a cut-and-paste mashup of dft() and idft() in order to avoid temporaries.
189 {
190  const int nrows = arr.rows();
191  const int ncols = arr.cols();
192 
193  Eigen::FFT< float > fft;
194 
195  Eigen::MatrixXcf matc(nrows, ncols);
196  for (int irow = 0; irow < nrows; ++irow) {
197  Eigen::VectorXcf fspec(ncols); // frequency spectrum
198  // fft wants vectors, also input arr is const
199  Eigen::VectorXf tmp = arr.row(irow);
200  fft.fwd(fspec, tmp);
201  matc.row(irow) = fspec;
202  }
203 
204  for (int icol = 0; icol < ncols; ++icol) {
205  Eigen::VectorXcf pspec(nrows); // periodicity spectrum
206  fft.fwd(pspec, matc.col(icol));
207  matc.col(icol) = pspec;
208  }
209 
210  // deconvolution via multiplication in frequency space
211  Eigen::MatrixXcf filt = matc.array() * filter;
212 
213  for (int icol = 0; icol < ncols; ++icol) {
214  Eigen::VectorXcf pspec(nrows); // wire spectrum
215  fft.inv(pspec, filt.col(icol));
216  filt.col(icol) = pspec;
217  }
218 
219  array_xxf ret(nrows, ncols);
220 
221  for (int irow = 0; irow < nrows; ++irow) {
222  Eigen::VectorXf wave(ncols); // back to real-valued time series
223  fft.inv(wave, filt.row(irow));
224  ret.row(irow) = wave;
225  }
226 
227  return ret;
228 }
229 
array_xxc dft_cc(const array_xxc &arr, int dim=1)
Definition: Array.cxx:67
array_xxf idft_cr(const array_xxc &arr, int dim=0)
Definition: Array.cxx:153
Eigen::ArrayXXcf array_xxc
A complex, 2D array.
Definition: Array.h:57
array_xxc dft_rc(const array_xxf &arr, int dim=0)
Definition: Array.cxx:40
array_xxc idft_cc(const array_xxc &arr, int dim=1)
Definition: Array.cxx:125
array_xxf deconv(const array_xxf &arr, const array_xxc &filter)
Definition: Array.cxx:187
string tmp
Definition: languages.py:63
Definition: Main.h:22
array_xxf idft(const array_xxc &arr)
Definition: Array.cxx:96
unsigned nrows(sqlite3 *db, std::string const &tablename)
Definition: helpers.cc:84
array_xxc dft(const array_xxf &arr)
Definition: Array.cxx:15
Eigen::ArrayXXf array_xxf
A real, 2D array.
Definition: Array.h:54