5 #ifndef LODESTAR_SUMBLOCK_HPP
6 #define LODESTAR_SUMBLOCK_HPP
9 #include "Lodestar/blocks/Block.hpp"
10 #include "Lodestar/aux/TemplateTools.hpp"
15 enum class SumBlockOperator {
21 template<
unsigned int N>
22 static typename ls::aux::TemplateTools::repeat<SumBlockOperator, N, ::std::tuple>::type
23 repeatTuple(SumBlockOperator value = SumBlockOperator::Plus)
25 typename ls::aux::TemplateTools::repeat<SumBlockOperator, N, ::std::tuple>::type tuple{};
26 repeatTupleImpl<N, N - 1>(tuple, value);
31 template<
unsigned int N,
int TIdx = N - 1,
32 typename ::std::enable_if<(TIdx >
33 0),
bool>::type * =
nullptr>
34 static void repeatTupleImpl(
35 typename ls::aux::TemplateTools::repeat<SumBlockOperator, N, ::std::tuple>::type &tuple,
36 SumBlockOperator value)
38 ::std::get<TIdx>(tuple) = value;
39 return repeatTupleImpl<N, TIdx - 1>(tuple, value);
42 template<
unsigned int N,
int TIdx = N - 1,
43 typename ::std::enable_if<(TIdx ==
44 0),
bool>::type * =
nullptr>
45 static void repeatTupleImpl(
46 typename ls::aux::TemplateTools::repeat<SumBlockOperator, N, ::std::tuple>::type &tuple,
47 SumBlockOperator value)
49 ::std::get<0>(tuple) = value;
52 template<
unsigned int N,
int TIdx = N -
53 1, typename ::std::enable_if<(
55 0),
bool>::type * =
nullptr>
56 static void repeatTupleImpl(
57 typename ls::aux::TemplateTools::repeat<SumBlockOperator, N, ::std::tuple>::type &tuple,
58 SumBlockOperator value)
63 static inline int interpret(SumBlockOperator value)
67 case SumBlockOperator::Plus:
69 case SumBlockOperator::Minus:
75 template<
typename TType,
unsigned int N>
78 typename ls::aux::TemplateTools::repeat<TType, N, ::std::tuple>::type,
80 ::std::tuple<::std::array<SumBlockOperator, N>, TType>
85 typename ls::aux::TemplateTools::repeat<TType, N, ::std::tuple>::type,
87 ::std::tuple<::std::array<SumBlockOperator, N>, TType>
90 using Ops = SumBlockOperator;
92 static constexpr
const SumBlockOperator Plus = SumBlockOperator::Plus;
93 static constexpr
const SumBlockOperator Minus = SumBlockOperator::Minus;
109 (this->
template p<0>()).fill(SumBlockOperator::Plus);
119 template<
typename... TOperators>
122 (this->
template p<0>()).fill(SumBlockOperator::Plus);
123 setOperators(op, ops...);
127 template<
int TIdx = 0,
typename... TOperators, typename ::std::enable_if<
128 TIdx < N, bool>::type * =
nullptr>
129 void setOperators(Ops op, TOperators... ops)
132 ls::aux::TemplateTraits::allSame<SumBlockOperator, TOperators...>::value,
133 "Operators must all be SumBlockOperator values."
136 (this->
template p<0>())[TIdx] = op;
138 return setOperators<TIdx + 1>(ops...);
141 template<
int TIdx = 0,
typename... TOperators,
142 typename ::std::enable_if<
143 TIdx >= N,
bool>::type * =
nullptr>
144 void setOperators(Ops op, TOperators... ops)
149 template<
int TIdx = 0,
150 typename ::std::enable_if<
151 TIdx < N, bool>::type * =
nullptr>
152 void setOperators(Ops op)
154 (this->
template p<0>())[TIdx] = op;
157 template<
int TIdx = 0, typename ::std::enable_if<
158 TIdx >= N,
bool>::type * =
nullptr>
159 void setOperators(Ops op)
164 template<
int TIdx = 0,
typename ::std::enable_if<((TIdx == 0) && (TIdx != N))>::type * =
nullptr>
165 void getOperators(::std::vector<SumBlockOperator> &v)
168 v.push_back(this->
template p<0>()[0]);
170 return getOperators<TIdx+1>(v);
173 template<
int TIdx = 0,
typename ::std::enable_if<((TIdx > 0) && (TIdx < N))>::type * =
nullptr>
174 void getOperators(::std::vector<SumBlockOperator> &v)
176 v.push_back(this->
template p<0>()[TIdx]);
178 return getOperators<TIdx+1>(v);
181 template<
int TIdx = 0,
typename ::std::enable_if<((TIdx < 0) || (TIdx >= N))>::type * =
nullptr>
182 void getOperators(::std::vector<SumBlockOperator> &v)
190 return this->
template p<1>();
195 const ::std::array<GiNaC::ex, Base::kIns> &inputSymbols()
197 if (!this->isInitInput_) {
198 for (
int i = 0; i < Base::kIns; i++) {
201 for (
int ii = 0; ii <
204 for (
int jj = 0; jj <
207 "blk" + ::std::to_string(this->
id) +
"_i_" + ::std::to_string(i) +
208 "_r_" + ::std::to_string(ii) +
"_c_" + ::std::to_string(jj),
209 "\\text{BLK}^{i, " + ::std::to_string(i) +
", " + ::std::to_string(ii) +
210 ", " + ::std::to_string(jj) +
"}_{" + ::std::to_string(this->
id) +
"}"};
217 this->inputSymbols_[i] = GiNaC::lst_to_matrix(input);
219 this->inputSymbols_[i] = GiNaC::symbol{
"blk" + ::std::to_string(this->
id) +
"_i_" + ::std::to_string(i),
220 "\\text{BLK}^{i, " + ::std::to_string(i) +
"}_{" +
221 ::std::to_string(this->
id) +
226 this->isInitInput_ =
true;
229 return this->inputSymbols_;
232 const ::std::array<GiNaC::ex, Base::kOuts> &outputSymbols()
234 if (!this->isInitOutput_) {
235 for (
int i = 0; i < Base::kOuts; i++) {
238 for (
int ii = 0; ii <
241 for (
int jj = 0; jj <
244 "blk" + ::std::to_string(this->
id) +
"_o_" + ::std::to_string(i) +
245 "_r_" + ::std::to_string(ii) +
"_c_" + ::std::to_string(jj),
246 "\\text{BLK}^{i, " + ::std::to_string(i) +
", " + ::std::to_string(ii) +
247 ", " + ::std::to_string(jj) +
"}_{" + ::std::to_string(this->
id) +
"}"};
254 this->outputSymbols_[i] = GiNaC::lst_to_matrix(output);
256 this->outputSymbols_[i] = GiNaC::symbol{
"blk" + ::std::to_string(this->
id) +
"_o_" + ::std::to_string(i),
257 "\\text{BLK}^{i, " + ::std::to_string(i) +
"}_{" +
258 ::std::to_string(this->
id) +
263 this->isInitOutput_ =
true;
266 return this->outputSymbols_;
269 const ::std::array<GiNaC::ex, 1> ¶meterSymbols()
271 if (!this->isInitParameter_) {
278 ii < ls::aux::TemplateTraits::BinaryOperators::parseMatrixLike<TType>::rows; ii++) {
280 for (
int jj = 0; jj <
283 "blk" + ::std::to_string(this->
id) +
"_p_" + ::std::to_string(i) +
"_r_" +
284 ::std::to_string(ii) +
"_c_" + ::std::to_string(jj),
285 "\\text{BLK}^{i, " + ::std::to_string(i) +
", " + ::std::to_string(ii) +
286 ", " + ::std::to_string(jj) +
"}_{" + ::std::to_string(this->
id) +
"}"};
293 this->parameterSymbols_[i] = GiNaC::lst_to_matrix(output);
295 this->parameterSymbols_[i] = GiNaC::symbol{
"blk" + ::std::to_string(this->
id) +
"_p_" + ::std::to_string(i),
296 "\\text{BLK}^{i, " + ::std::to_string(i) +
"}_{" +
297 ::std::to_string(this->
id) +
301 Base::isInitParameter_ =
true;
304 return this->parameterSymbols_;
311 ::std::array<GiNaC::ex, 1> parameterSymbols_;
316 this->equation = ::std::bind(
319 ::std::placeholders::_1);
322 GiNaC::function_options fops(
"blkf" + ::std::to_string(this->
id) +
"__", this->blkFunc_NPARAMS);
323 ls::blocks::symbolicEvalFunctionMap[this->id] = [&](const ::std::vector<GiNaC::ex> &exvec) -> GiNaC::ex {
328 for (
auto & ex : exvec) {
329 res += SumBlockOperatorHelper::interpret(this->
template p<0>()[i]) * ex;
337 fops.eval_func(ls::blocks::symbolicEval);
340 this->serial = GiNaC::function::register_new(
346 void triggerFunction(
Base &b)
348 b.template o<0>().object = zero();
349 sum(b.template o<0>().object);
350 b.template o<0>().propagate();
353 template<
unsigned int TIdx = Base::kIns - 1>
354 typename ::std::enable_if<(TIdx > 0),
void>::type
358 SumBlockOperatorHelper::interpret(
359 (this->
template p<0>())[TIdx]) *
360 this->
template i<TIdx>();
361 return sum<TIdx - 1>(res);
364 template<
unsigned int TIdx = Base::kIns - 1>
365 typename ::std::enable_if<(TIdx == 0),
void>::type
369 SumBlockOperatorHelper::interpret((this->
template p<0>())[TIdx]) * this->
template i<TIdx>();
372 template<
unsigned int TIdx = Base::kIns - 1>
373 typename ::std::enable_if<(TIdx < 0), void>::type
381 template<
typename TType,
unsigned int N>
398 static const ::std::array<::std::string, kIns>
inTypes;
399 static const ::std::array<::std::string, kOuts>
outTypes;
400 static const ::std::array<::std::string, kPars>
parTypes;
405 template<
typename TType,
unsigned int N>
407 ls::aux::TemplateTools::create_array<BlockTraits<std::SumBlock<TType, N>>::kIns>(
408 demangle(
typeid(TType).name())
411 template<
typename TType,
unsigned int N>
413 {demangle(
typeid(TType).name())};
415 template<
typename TType,
unsigned int N>
416 const ::std::array<::std::string, BlockTraits<std::SumBlock<TType, N>>::kPars> BlockTraits<std::SumBlock<TType, N>>::parTypes =
418 typeid(::std::array<std::SumBlockOperator, N>).name()
420 demangle(
typeid(TType).name())};
422 template<
typename TType,
unsigned int N>
423 const ::std::array<::std::string, 2> BlockTraits<std::SumBlock<TType, N>>::templateTypes =
424 {demangle(
typeid(TType).name()),
"unsigned int"};
429 #endif //LODESTAR_SUMBLOCK_HPP