5 #ifndef LODESTAR_DEMUXBLOCK_HPP
6 #define LODESTAR_DEMUXBLOCK_HPP
8 #include "Lodestar/blocks/Block.hpp"
9 #include "Lodestar/aux/TemplateTools.hpp"
10 #include "Lodestar/aux/CompileTimeQualifiers.hpp"
11 #include "Eigen/Dense"
16 enum class DemuxBlockOperator {
21 template<
typename TType, DemuxBlockOperator TOps = DemuxBlockOperator::RowMajor>
26 ::std::tuple<DemuxBlockOperator>
29 "DemuxBlock not defined for this type.");
33 template<
typename TScalar,
int TRows,
int TCols, DemuxBlockOperator TOps>
34 class DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps> :
36 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
37 typename aux::TemplateTools::repeat<TScalar,
38 TRows * TCols, ::std::tuple>::type,
39 ::std::tuple<DemuxBlockOperator>
44 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
46 TRows * TCols, ::std::tuple>::type,
47 ::std::tuple<DemuxBlockOperator>
56 explicit DemuxBlock(
const DemuxBlockOperator ops)
62 void setOperator(
const DemuxBlockOperator ops)
64 this->
template p<0>() = ops;
67 DemuxBlockOperator getOperator()
const
69 return this->
template p<0>();
72 template<
int TTRows = TRows,
int TTCols = TCols,
73 typename ::std::enable_if<
74 ((TTRows * TTCols > 0) &&
76 TTCols == 1)),
void *>::type * =
nullptr>
79 return this->
template i<0>();
82 template<
int TTRows = TRows,
int TTCols = TCols,
83 typename ::std::enable_if<
84 !((TTRows * TTCols > 0) &&
86 TTCols == 1)),
void *>::type * =
nullptr>
90 (TTRows * TTCols > 0) &&
91 (TTRows == 1 || TTCols == 1),
92 "Demux contains less than 1 output and/or does not map to a 1D object.");
93 return this->
template i<0>();
96 template<
int TTRows = TRows,
int TTCols = TCols,
97 typename ::std::enable_if<
98 (TTRows * TTCols > 0) &&
100 TTCols == 1),
void *>::type * =
nullptr>
103 return this->
template i<0>();
106 template<
int TTRows = TRows,
int TTCols = TCols,
107 typename ::std::enable_if<
108 !((TTRows * TTCols > 0) &&
110 TTCols == 1)),
void *>::type * =
nullptr>
114 (TTRows * TTCols > 0) &&
115 (TTRows == 1 || TTCols == 1),
116 "Demux contains less than 1 output and/or does not map to a 1D object.");
117 return this->
template i<0>();
120 template<
int TTRows = TRows,
int TTCols = TCols,
121 typename ::std::enable_if<
122 (TTRows * TTCols > 1) &&
124 TTCols == 1),
void *>::type * =
nullptr>
127 return this->
template i<1>();
130 template<
int TTRows = TRows,
int TTCols = TCols,
131 typename ::std::enable_if<
132 !((TTRows * TTCols > 1) &&
134 TTCols == 1)),
void *>::type * =
nullptr>
138 (TTRows * TTCols > 1) &&
139 (TTRows == 1 || TTCols == 1),
140 "Demux contains less than 2 outputs and/or does not map to a 1D object.");
141 return this->
template i<1>();
144 template<
int TTRows = TRows,
int TTCols = TCols,
145 typename ::std::enable_if<
146 (TTRows * TTCols > 1) &&
148 TTCols == 1),
void *>::type * =
nullptr>
151 return this->
template i<1>();
154 template<
int TTRows = TRows,
int TTCols = TCols,
155 typename ::std::enable_if<
156 !((TTRows * TTCols > 1) &&
158 TTCols == 1)),
void *>::type * =
nullptr>
162 (TTRows * TTCols > 1) &&
163 (TTRows == 1 || TTCols == 1),
164 "Demux contains less than 2 outputs and/or does not map to a 1D object.");
165 return this->
template i<1>();
168 template<
int TTRows = TRows,
int TTCols = TCols,
169 typename ::std::enable_if<
170 (TTRows * TTCols > 2) &&
172 TTCols == 1),
void *>::type * =
nullptr>
175 return this->
template o<2>();
178 template<
int TTRows = TRows,
int TTCols = TCols,
179 typename ::std::enable_if<
180 !((TTRows * TTCols > 2) &&
182 TTCols == 1)),
void *>::type * =
nullptr>
186 (TTRows * TTCols > 2) &&
187 (TTRows == 1 || TTCols == 1),
188 "Demux contains less than 3 outputs and/or does not map to a 1D object.");
189 return this->
template o<2>();
192 template<
int TTRows = TRows,
int TTCols = TCols,
193 typename ::std::enable_if<
194 (TTRows * TTCols > 2) &&
196 TTCols == 1),
void *>::type * =
nullptr>
199 return this->
template o<2>();
202 template<
int TTRows = TRows,
int TTCols = TCols,
203 typename ::std::enable_if<
204 !((TTRows * TTCols > 2) &&
206 TTCols == 1)),
void *>::type * =
nullptr>
210 (TTRows * TTCols > 2) &&
211 (TTRows == 1 || TTCols == 1),
212 "Demux contains less than 3 outputs and/or does not map to a 1D object.");
213 return this->
template o<2>();
216 template<
int TTRows = TRows,
int TTCols = TCols,
217 typename ::std::enable_if<
218 (TTRows * TTCols > 3) &&
220 TTCols == 1),
void *>::type * =
nullptr>
223 return this->
template o<3>();
226 template<
int TTRows = TRows,
int TTCols = TCols,
227 typename ::std::enable_if<
228 !((TTRows * TTCols > 3) &&
230 TTCols == 1)),
void *>::type * =
nullptr>
234 (TTRows * TTCols > 3) &&
235 (TTRows == 1 || TTCols == 1),
236 "Demux contains less than 4 outputs and/or does not map to a 1D object.");
237 return this->
template o<3>();
240 template<
int TTRows = TRows,
int TTCols = TCols,
241 typename ::std::enable_if<
242 (TTRows * TTCols > 3) &&
244 TTCols == 1),
void *>::type * =
nullptr>
247 return this->
template o<3>();
250 template<
int TTRows = TRows,
int TTCols = TCols,
251 typename ::std::enable_if<
252 !((TTRows * TTCols > 3) &&
254 TTCols == 1)),
void *>::type * =
nullptr>
258 (TTRows * TTCols > 3) &&
259 (TTRows == 1 || TTCols == 1),
260 "Demux contains less than 4 outputs and/or does not map to a 1D object.");
261 return this->
template o<3>();
267 this->equation = ::std::bind(
268 &
DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>::triggerFunction,
270 ::std::placeholders::_1
274 void triggerFunction(
Base &b)
279 template<
unsigned int TIdx = TRows * TCols - 1>
280 typename ::std::enable_if<(TIdx > 0),
void>::type
283 switch (getOperator()) {
284 case DemuxBlockOperator::RowMajor:
285 this->
template o<TIdx>() = this->
template i<0>().object(
286 floor<int, double>(TIdx / TCols),
288 floor<int, double>(TIdx / TCols) * TCols
291 case DemuxBlockOperator::ColMajor:
292 this->
template o<TIdx>() = this->
template i<0>().object(
294 floor<int, double>(TIdx / TRows) * TRows,
295 floor<int, double>(TIdx / TRows));
298 return get<TIdx - 1>();
301 template<
unsigned int TIdx = TRows * TCols - 1>
302 typename ::std::enable_if<(TIdx == 0),
void>::type
305 this->
template o<TIdx>() = this->
template i<0>().object(0,
309 template<
unsigned int TIdx = TRows * TCols - 1>
310 typename ::std::enable_if<(TIdx < 0), void>::type
317 template<
typename... TTypes, DemuxBlockOperator TOps>
320 ::std::tuple<::std::tuple<TTypes...>>,
321 ::std::tuple<TTypes...>,
322 ::std::tuple<DemuxBlockOperator>
327 ::std::tuple<::std::tuple<TTypes...>>,
328 ::std::tuple<TTypes...>,
329 ::std::tuple<DemuxBlockOperator>
338 explicit DemuxBlock(
const DemuxBlockOperator ops)
344 void setOperator(
const DemuxBlockOperator ops)
346 this->
template p<0>() = ops;
349 DemuxBlockOperator getOperator()
const
351 return this->
template p<0>();
357 this->equation = ::std::bind(
358 &
DemuxBlock<::std::tuple<TTypes...>, TOps>::triggerFunction,
360 ::std::placeholders::_1
364 void triggerFunction(
Base &b)
369 template<
unsigned int TIdx = Base::kOuts - 1>
370 typename ::std::enable_if<(TIdx > 0),
void>::type
373 this->
template o<TIdx>() = ::std::get<TIdx>(
374 this->
template i<0>().
object);
375 return get<TIdx - 1>();
378 template<
unsigned int TIdx = Base::kOuts - 1>
379 typename ::std::enable_if<(TIdx == 0),
void>::type
382 this->
template o<TIdx>() = ::std::get<TIdx>(
383 this->
template i<0>().
object);
386 template<
unsigned int TIdx = Base::kOuts - 1>
387 typename ::std::enable_if<(TIdx < 0), void>::type
396 template<
typename TScalar,
int TRows,
int TCols, std::DemuxBlockOperator TOps>
413 static const ::std::array<::std::string, kIns>
inTypes;
414 static const ::std::array<::std::string, kOuts>
outTypes;
415 static const ::std::array<::std::string, kPars>
parTypes;
420 template<
typename TScalar,
int TRows,
int TCols, std::DemuxBlockOperator TOps>
422 {demangle(
typeid(Eigen::Matrix<TScalar, TRows, TCols>).name())};
424 template<
typename TScalar,
int TRows,
int TCols, std::DemuxBlockOperator TOps>
425 const ::std::array<::std::string, BlockTraits<std::DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::kOuts> BlockTraits<std::DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::outTypes =
426 ls::aux::TemplateTools::create_array<BlockTraits<std::DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::kOuts>(
427 demangle(
typeid(TScalar).name())
430 template<
typename TScalar,
int TRows,
int TCols, std::DemuxBlockOperator TOps>
431 const ::std::array<::std::string, BlockTraits<std::DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::kPars> BlockTraits<std::DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::parTypes =
432 {demangle(
typeid(TOps).name())};
434 template<
typename TScalar,
int TRows,
int TCols, std::DemuxBlockOperator TOps>
435 const ::std::array<::std::string, 2> BlockTraits<std::DemuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::templateTypes =
436 {demangle(
typeid(Eigen::Matrix<TScalar, TRows, TCols>).name()), demangle(
typeid(TOps).name())};
441 #endif //LODESTAR_DEMUXBLOCK_HPP