boundary_conditions.hh
Go to the documentation of this file.
1 /* -*- mia-c++ -*-
2  *
3  * This file is part of MIA - a toolbox for medical image analysis
4  * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
5  *
6  * MIA is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef mia_core_boundary_conditions_hh
22 #define mia_core_boundary_conditions_hh
23 
24 #include <mia/core/msgstream.hh>
25 #include <mia/core/type_traits.hh>
26 #include <mia/core/factory.hh>
27 #include <mia/core/product_base.hh>
28 #include <mia/core/splinekernel.hh>
29 
30 #include <vector>
31 #include <memory>
32 
34 
40 };
41 
53 public:
54 
57 
60 
62  static const char * const type_descr;
63 
65  static const char * const data_descr;
66 
67 
69  typedef std::unique_ptr<CSplineBoundaryCondition> Pointer;
70 
72 
73 
77  CSplineBoundaryCondition(const CSplineBoundaryCondition& /*other*/) = default;
78 
84  CSplineBoundaryCondition(int width);
85 
92  bool apply(CSplineKernel::VIndex& index, CSplineKernel::VWeight& weights) const;
93 
99  void set_width(int width);
100 
102  int get_width() const {
103  return m_width;
104  }
105 
116  template <typename T>
117  void filter_line(std::vector<T>& coeff, const std::vector<double>& poles) const;
118 
126  void filter_line(std::vector<double>& coeff, const std::vector<double>& poles) const;
127 
135  template <typename T>
136  void template_filter_line(std::vector<T>& coeff, const std::vector<double>& poles) const;
137 
141  virtual
142  CSplineBoundaryCondition *clone() const __attribute__((warn_unused_result)) = 0 ;
143 private:
144 
145  virtual void do_apply(CSplineKernel::VIndex& index, CSplineKernel::VWeight& weights) const = 0;
146  virtual void test_supported(int npoles) const = 0;
147 
148  virtual void do_set_width(int width);
149 
150 
151  virtual double initial_coeff(const std::vector<double>& coeff, double pole) const = 0;
152  virtual double initial_anti_coeff(const std::vector<double>& coeff, double pole)const = 0;
153 
154 
155  int m_width;
156 };
161 
166 public:
171  CSplineBoundaryConditionPlugin(const char * name);
172 private:
173  virtual CSplineBoundaryCondition *do_create() const;
174 
175  virtual CSplineBoundaryCondition *do_create(int width) const = 0;
176 
177  int m_width;
178 };
179 
185 
186 
189 
197 };
198 
199 
205 inline
207 {
208  return CSplineBoundaryConditionPluginHandler::instance().produce_unique(descr);
209 }
210 
211 
219  __attribute__((deprecated));
220 
221 
223 
239 template <typename T, int size>
240 struct __dispatch_filter_line {
241  static void apply(const CSplineBoundaryCondition& bc, std::vector<T>& coeff, const std::vector<double>& poles);
242 };
243 
244 template <typename T, int size>
245 void __dispatch_filter_line<T, size>::apply(const CSplineBoundaryCondition& bc, std::vector<T>& coeff,
246  const std::vector<double>& poles)
247 {
248  std::vector<double> temp(coeff.size());
249  for (int i = 0; i < size; ++i) {
250  std::transform(coeff.begin(), coeff.end(), temp.begin(),
251  [i](const T& x) { return x[i]; });
252  bc.filter_line(temp, poles);
253  for (size_t j = 0; j < coeff.size(); ++j)
254  coeff[j][i] = temp[j];
255  }
256 }
257 
263 template <typename T>
264 struct __dispatch_filter_line<T,1> {
265  static void apply(const CSplineBoundaryCondition& bc, std::vector<T>& coeff, const std::vector<double>& poles) {
266  bc.template_filter_line(coeff, poles);
267  }
268 };
269 
271 
272 template <typename T>
273 void CSplineBoundaryCondition::filter_line(std::vector<T>& coeff, const std::vector<double>& poles) const
274 {
275  typedef atomic_data<T> atom;
276  __dispatch_filter_line<T, atom::size>::apply(*this, coeff, poles);
277 }
278 
279 
280 template <typename T>
281 void CSplineBoundaryCondition::template_filter_line(std::vector<T>& coeff, const std::vector<double>& poles) const
282 {
283  std::vector<double> temp(coeff.begin(), coeff.end());
284  filter_line(temp, poles);
285  std::transform(temp.begin(), temp.end(), coeff.begin(), [](double x) {return static_cast<T>(x);});
286 }
287 
289 #endif