5 #ifndef LODESTAR_MUXBLOCK_HPP
6 #define LODESTAR_MUXBLOCK_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 MuxBlockOperator {
21 template<
typename TType, MuxBlockOperator TOps = MuxBlockOperator::RowMajor>
29 "MuxBlock not defined for this type.");
33 template<
typename TScalar,
int TRows,
int TCols, MuxBlockOperator TOps>
34 class MuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps> :
36 typename ls::aux::TemplateTools::repeat<TScalar,
37 TRows * TCols, ::std::tuple>::type,
38 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
39 ::std::tuple<MuxBlockOperator>
45 TRows * TCols, ::std::tuple>::type,
46 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
47 ::std::tuple<MuxBlockOperator>
56 explicit MuxBlock(
const MuxBlockOperator ops)
62 void setOperator(
const MuxBlockOperator ops)
64 this->
template p<0>() = ops;
67 MuxBlockOperator 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 "Mux contains less than 1 input 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 "Mux contains less than 1 input 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 "Mux contains less than 2 inputs 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 "Mux contains less than 2 inputs 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 i<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 * TCols > 2) &&
187 (TTRows == 1 || TTCols == 1),
188 "Mux contains less than 3 inputs and/or does not map to a 1D object.");
189 return this->
template i<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 i<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 "Mux contains less than 3 inputs and/or does not map to a 1D object.");
213 return this->
template i<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 i<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 "Mux contains less than 4 inputs and/or does not map to a 1D object.");
237 return this->
template i<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 i<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 "Mux contains less than 4 inputs and/or does not map to a 1D object.");
261 return this->
template i<3>();
267 this->equation = ::std::bind(
268 &
MuxBlock<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 MuxBlockOperator::RowMajor:
285 this->
template o<0>().object(
286 floor<int, double>(TIdx / TCols),
288 floor<int, double>(TIdx / TCols) * TCols)
289 = this->
template i<TIdx>();
291 case MuxBlockOperator::ColMajor:
292 this->
template o<0>().object(
294 floor<int, double>(TIdx / TRows) * TRows,
295 floor<int, double>(TIdx / TRows))
296 = this->
template i<TIdx>();
299 return set<TIdx - 1>();
302 template<
unsigned int TIdx = TRows * TCols - 1>
303 typename ::std::enable_if<(TIdx == 0),
void>::type
306 this->
template o<0>().object(0,
307 0) = this->
template i<TIdx>();
310 template<
unsigned int TIdx = TRows * TCols - 1>
311 typename ::std::enable_if<(TIdx < 0), void>::type
318 template<
typename... TTypes, MuxBlockOperator TOps>
321 ::std::tuple<TTypes...>,
322 ::std::tuple<::std::tuple<TTypes...>>,
323 ::std::tuple<MuxBlockOperator>
328 ::std::tuple<TTypes...>,
329 ::std::tuple<::std::tuple<TTypes...>>,
330 ::std::tuple<MuxBlockOperator>
339 explicit MuxBlock(
const MuxBlockOperator ops)
345 void setOperator(
const MuxBlockOperator ops)
347 this->
template p<0>() = ops;
350 MuxBlockOperator getOperator()
const
352 return this->
template p<0>();
358 this->equation = ::std::bind(
359 &
MuxBlock<::std::tuple<TTypes...>, TOps>::triggerFunction,
361 ::std::placeholders::_1
365 void triggerFunction(
Base &b)
370 template<
unsigned int TIdx = Base::kIns - 1>
371 typename ::std::enable_if<(TIdx > 0),
void>::type
375 this->
template o<0>().
object) = this->
template i<TIdx>().object;
376 return set<TIdx - 1>();
379 template<
unsigned int TIdx = Base::kIns - 1>
380 typename ::std::enable_if<(TIdx == 0),
void>::type
384 this->
template o<0>().
object) = this->
template i<TIdx>().object;
385 this->
template o<0>().propagate();
388 template<
unsigned int TIdx = Base::kIns - 1>
389 typename ::std::enable_if<(TIdx < 0), void>::type
397 template<
typename TScalar,
int TRows,
int TCols, std::MuxBlockOperator TOps>
414 static const ::std::array<::std::string, kIns>
inTypes;
415 static const ::std::array<::std::string, kOuts>
outTypes;
416 static const ::std::array<::std::string, kPars>
parTypes;
421 template<
typename TScalar,
int TRows,
int TCols, std::MuxBlockOperator TOps>
423 ls::aux::TemplateTools::create_array<TRows * TCols>(
424 demangle(
typeid(TScalar).name())
427 template<
typename TScalar,
int TRows,
int TCols, std::MuxBlockOperator TOps>
429 { demangle(
typeid(Eigen::Matrix<TScalar, TRows, TCols>).name()) };
431 template<
typename TScalar,
int TRows,
int TCols, std::MuxBlockOperator TOps>
432 const ::std::array<::std::string, BlockTraits<std::MuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::kPars> BlockTraits<std::MuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::parTypes =
433 { demangle(
typeid(TOps).name()) };
435 template<
typename TScalar,
int TRows,
int TCols, std::MuxBlockOperator TOps>
436 const ::std::array<::std::string, 2> BlockTraits<std::MuxBlock<Eigen::Matrix<TScalar, TRows, TCols>, TOps>>::templateTypes =
437 { demangle(
typeid(Eigen::Matrix<TScalar, TRows, TCols>).name()), demangle(
typeid(TOps).name()) };
442 #endif //LODESTAR_MUXBLOCK_HPP