59 : _spatialSize(spatialSize), _temporalSize(temporalSize), _scalarSize(computeScalarSize(spatialSize, temporalSize)),
60 _data(std::allocator_traits<std::allocator<T>>::allocate(allo, _scalarSize)) {}
63 std::allocator_traits<std::allocator<T>>::construct(allo, _data + idx(pos, t), std::forward<Args>(args)...);
67 std::allocator_traits<std::allocator<T>>::destroy(allo, _data + idx(pos, t));
74 T& operator[](
unsigned int pos) {
76 if (pos < 0 || pos > _scalarSize - 1) {
77 std::cout <<
"ERROR Field T& operator[](int pos): pos out of range!" << std::endl;
78 std::cout <<
"pos=" << pos <<
", _scalarSize=" << _scalarSize << std::endl;
85 const T& operator[](
unsigned int pos)
const {
87 if (pos < 0 || pos > _scalarSize - 1) {
88 std::cout <<
"ERROR Field T& operator[](int pos): pos out of range!" << std::endl;
89 std::cout <<
"pos=" << pos <<
", _scalarSize=" << _scalarSize << std::endl;
96 ~Field() { std::allocator_traits<std::allocator<T>>::deallocate(allo, _data, _scalarSize); }
98 unsigned int getScalarSize()
const {
return _scalarSize; }
102 unsigned int getTemporalSize()
const {
return _temporalSize; }
105 for (
unsigned int i = 0; i < _scalarSize; i++) {
106 std::cout <<
"Field elem " << i <<
" = " << _data[i] << std::endl;
112 unsigned int res = spatialSize[0];
113 for (
unsigned int d = 1; d < dim; d++) {
114 res *= (spatialSize[d]);
122 for (
unsigned int d = 0; d < dim; d++) {
123 if (pos[d] < 0 || pos[d] > _spatialSize[d] - 1) {
124 std::cout <<
"ERROR Field idx(): pos out of range!" << std::endl;
125 std::cout <<
"pos=" << pos <<
", _spatialSize=" << _spatialSize << std::endl;
129 if (t < 0 || t > _temporalSize - 1) {
130 std::cout <<
"ERROR Field idx(): t out of range!" << std::endl;
131 std::cout <<
"t=" << t <<
", _temporalSize=" << _temporalSize << std::endl;
135 unsigned int idx = 0, step = 1;
136 for (
unsigned int d = 0; d < dim; d++) {
137 idx += pos[d] * step;
138 step *= _spatialSize[d];
144 static std::allocator<T> allo;
146 const unsigned int _temporalSize;
147 const unsigned int _scalarSize;
164 : _flowfield(spatialSize, temporalSize), _localMean(0.0), _localStandardDeviation(0.0) {
165 fillFromBasefield(basefield, pos, t);
167 computeLocalStandardDeviation();
171 unsigned int size = _flowfield.getScalarSize() * (dim + 1);
173 double*
const my_data =
reinterpret_cast<double* const
>(_flowfield._data);
174 double*
const other_data =
reinterpret_cast<double* const
>(other._flowfield._data);
177 for (
unsigned int i = 0; i < size; i += 1) {
178 double diff(my_data[i] - other_data[i]);
186 void print() { _flowfield.print(); }
189 inline unsigned int posmod(
int i,
int n) {
return (i % n + n) % n; }
192 static_assert(dim == 2 || dim == 3,
"ERROR filtering::Patch::fillFromBasefield only implemented "
196 for (
unsigned int d = 0; d < dim; d++) {
197 center[d] = _flowfield.getSpatialSize()[d] / 2;
201 unsigned int local_t(0);
203 unsigned int base_t(0);
205 for (
int offset_t = 0; offset_t > -(int)_flowfield.getTemporalSize(); offset_t--) {
206 local_t = posmod(offset_t, _flowfield.getTemporalSize());
207 base_t = posmod(t + offset_t, basefield.getTemporalSize());
208 for (
int offset_x = -(
int)(_flowfield.getSpatialSize()[0]) / 2; offset_x <= (
int)(_flowfield.getSpatialSize()[0]) / 2; offset_x++) {
209 local_pos[0] = center[0] + offset_x;
210 base_pos[0] = pos[0] + offset_x;
211 for (
int offset_y = -(
int)(_flowfield.getSpatialSize()[1]) / 2; offset_y <= (
int)(_flowfield.getSpatialSize()[1]) / 2; offset_y++) {
212 local_pos[1] = center[1] + offset_y;
213 base_pos[1] = pos[1] + offset_y;
214 if constexpr (dim == 3) {
215 for (
int offset_z = -(
int)(_flowfield.getSpatialSize()[2]) / 2; offset_z <= (
int)(_flowfield.getSpatialSize()[2]) / 2; offset_z++) {
216 local_pos[2] = center[2] + offset_z;
217 base_pos[2] = pos[2] + offset_z;
218 _flowfield(local_pos, local_t) = basefield(base_pos, base_t);
221 _flowfield(local_pos, local_t) = basefield(base_pos, base_t);
228 void computeLocalMean() {
229 for (
unsigned int i = 0; i < _flowfield.getScalarSize(); i++)
230 _localMean += _flowfield[i];
231 _localMean = _localMean * (1.0 / _flowfield.getScalarSize());
234 void computeLocalStandardDeviation() {
235 for (
unsigned int i = 0; i < _flowfield.getScalarSize(); i++) {
236 Quantities<dim> diff = _localMean - _flowfield[i];
237 _localStandardDeviation += tarch::la::dot(diff, diff);
239 _localStandardDeviation = sqrt(_localStandardDeviation / _flowfield.getScalarSize());
242 Flowfield<dim> _flowfield;
243 Quantities<dim> _localMean;
244 double _localStandardDeviation;
255 : _spatialSize(spatialSize), _temporalSize(temporalSize), _basefield(basefield), _pos(pos), _t(t) {}
261 unsigned int base_t(0);
263 for (
int offset_t = 0; offset_t > -(int)_temporalSize; offset_t--) {
264 base_t = posmod(_t + offset_t, _basefield.getTemporalSize());
265 for (
int offset_x = -(
int)(_spatialSize[0]) / 2; offset_x <= (int)(_spatialSize[0]) / 2; offset_x++) {
266 base_pos[0] = _pos[0] + offset_x;
267 for (
int offset_y = -(
int)(_spatialSize[1]) / 2; offset_y <= (int)(_spatialSize[1]) / 2; offset_y++) {
268 base_pos[1] = _pos[1] + offset_y;
269 if constexpr (dim == 3) {
270 for (
int offset_z = -(
int)(_spatialSize[2]) / 2; offset_z <= (int)(_spatialSize[2]) / 2; offset_z++) {
271 base_pos[2] = _pos[2] + offset_z;
273 auto diff(_basefield(base_pos, base_t) - _basefield(base_pos + other._pos - _pos, posmod(base_t + other._t - _t, _basefield.getTemporalSize())));
274 res += diff[0] * diff[0];
277 auto diff(_basefield(base_pos, base_t) - other._basefield(base_pos, base_t));
278 res += tarch::la::dot(diff, diff);
287 inline unsigned int posmod(
int i,
int n)
const {
return (i % n + n) % n; }
290 const unsigned int _temporalSize;
291 const Flowfield<dim>& _basefield;
293 const unsigned int _t;