ra4_draw  4bd0201e3d922d42bd545d4b045ed44db33454a4
named_func.cpp
Go to the documentation of this file.
1 
44 #include "core/named_func.hpp"
45 
46 #include <iostream>
47 #include <utility>
48 
49 #include "core/utilities.hpp"
50 #include "core/function_parser.hpp"
51 
52 using namespace std;
53 
58 
59 namespace{
69  template<typename Operator>
70  function<ScalarFunc> ApplyOp(const function<ScalarFunc> &f,
71  const Operator &op){
72  if(!static_cast<bool>(f)) return f;
73  function<ScalarType(ScalarType)> op_c(op);
74  return [f,op_c](const Baby &b){
75  return op_c(f(b));
76  };
77  }
78 
88  template<typename Operator>
89  function<VectorFunc> ApplyOp(const function<VectorFunc> &f,
90  const Operator &op){
91  if(!static_cast<bool>(f)) return f;
92  function<ScalarType(ScalarType)> op_c(op);
93  return [f,op_c](const Baby &b){
94  VectorType v = f(b);
95  for(auto &x: v){
96  x = op_c(x);
97  }
98  return v;
99  };
100  }
101 
124  template<typename Operator>
125  pair<function<ScalarFunc>, function<VectorFunc> > ApplyOp(const function<ScalarFunc> &sfa,
126  const function<VectorFunc> &vfa,
127  const function<ScalarFunc> &sfb,
128  const function<VectorFunc> &vfb,
129  const Operator &op){
130  function<ScalarType(ScalarType,ScalarType)> op_c(op);
131  function<ScalarFunc> sfo;
132  function<VectorFunc> vfo;
133  if(static_cast<bool>(sfa) && static_cast<bool>(sfb)){
134  sfo = [sfa,sfb,op_c](const Baby &b){
135  return op_c(sfa(b), sfb(b));
136  };
137  }else if(static_cast<bool>(sfa) && static_cast<bool>(vfb)){
138  vfo = [sfa,vfb,op_c](const Baby &b){
139  ScalarType sa = sfa(b);
140  VectorType vb = vfb(b);
141  VectorType vo(vb.size());
142  for(size_t i = 0; i < vo.size(); ++i){
143  vo.at(i) = op_c(sa, vb.at(i));
144  }
145  return vo;
146  };
147  }else if(static_cast<bool>(vfa) && static_cast<bool>(sfb)){
148  vfo = [vfa,sfb,op_c](const Baby &b){
149  VectorType va = vfa(b);
150  ScalarType sb = sfb(b);
151  VectorType vo(va.size());
152  for(size_t i = 0; i < vo.size(); ++i){
153  vo.at(i) = op_c(va.at(i), sb);
154  }
155  return vo;
156  };
157  }else if(static_cast<bool>(vfa) && static_cast<bool>(vfb)){
158  vfo = [vfa,vfb,op_c](const Baby &b){
159  VectorType va = vfa(b);
160  VectorType vb = vfb(b);
161  VectorType vo(va.size() > vb.size() ? vb.size() : va.size());
162  for(size_t i = 0; i < vo.size(); ++i){
163  vo.at(i) = op_c(va.at(i), vb.at(i));
164  }
165  return vo;
166  };
167  }
168  return make_pair(sfo, vfo);
169  }
170 
187  template<>
188  pair<function<ScalarFunc>, function<VectorFunc> > ApplyOp(const function<ScalarFunc> &sfa,
189  const function<VectorFunc> &vfa,
190  const function<ScalarFunc> &sfb,
191  const function<VectorFunc> &vfb,
192  const logical_and<ScalarType> &/*op*/){
193  function<ScalarFunc> sfo;
194  function<VectorFunc> vfo;
195  if(static_cast<bool>(sfa) && static_cast<bool>(sfb)){
196  sfo = [sfa,sfb](const Baby &b){
197  return sfa(b)&&sfb(b);
198  };
199  }else if(static_cast<bool>(sfa) && static_cast<bool>(vfb)){
200  vfo = [sfa,vfb](const Baby &b){
201  ScalarType sa = sfa(b);
202  if(!sa){
203  return VectorType(vfb(b).size(), false);
204  }else{
205  return vfb(b);
206  }
207  };
208  }else if(static_cast<bool>(vfa) && static_cast<bool>(sfb)){
209  vfo = [vfa,sfb](const Baby &b){
210  VectorType va = vfa(b);
211  VectorType vo(va.size());
212  bool evaluated = false;
213  ScalarType sb = 0.;
214  for(size_t i = 0; i < vo.size(); ++i){
215  if(!evaluated && va.at(i)){
216  evaluated = true;
217  sb = sfb(b);
218  }
219  vo.at(i) = va.at(i)&&sb;
220  }
221  return vo;
222  };
223  }else if(static_cast<bool>(vfa) && static_cast<bool>(vfb)){
224  vfo = [vfa,vfb](const Baby &b){
225  VectorType va = vfa(b);
226  VectorType vb = vfb(b);
227  VectorType vo(va.size() > vb.size() ? vb.size() : va.size());
228  for(size_t i = 0; i < vo.size(); ++i){
229  vo.at(i) = va.at(i)&&vb.at(i);
230  }
231  return vo;
232  };
233  }
234  return make_pair(sfo, vfo);
235  }
236 
253  template<>
254  pair<function<ScalarFunc>, function<VectorFunc> > ApplyOp(const function<ScalarFunc> &sfa,
255  const function<VectorFunc> &vfa,
256  const function<ScalarFunc> &sfb,
257  const function<VectorFunc> &vfb,
258  const logical_or<ScalarType> &/*op*/){
259  function<ScalarFunc> sfo;
260  function<VectorFunc> vfo;
261  if(static_cast<bool>(sfa) && static_cast<bool>(sfb)){
262  sfo = [sfa,sfb](const Baby &b){
263  return sfa(b)||sfb(b);
264  };
265  }else if(static_cast<bool>(sfa) && static_cast<bool>(vfb)){
266  vfo = [sfa,vfb](const Baby &b){
267  ScalarType sa = sfa(b);
268  if(sa){
269  return VectorType(vfb(b).size(), true);
270  }else{
271  return vfb(b);
272  }
273  };
274  }else if(static_cast<bool>(vfa) && static_cast<bool>(sfb)){
275  vfo = [vfa,sfb](const Baby &b){
276  VectorType va = vfa(b);
277  VectorType vo(va.size());
278  bool evaluated = false;
279  ScalarType sb = 0.;
280  for(size_t i = 0; i < vo.size(); ++i){
281  if(!(evaluated || va.at(i))){
282  evaluated = true;
283  sb = sfb(b);
284  }
285  vo.at(i) = va.at(i)||sb;
286  }
287  return vo;
288  };
289  }else if(static_cast<bool>(vfa) && static_cast<bool>(vfb)){
290  vfo = [vfa,vfb](const Baby &b){
291  VectorType va = vfa(b);
292  VectorType vb = vfb(b);
293  VectorType vo(va.size() > vb.size() ? vb.size() : va.size());
294  for(size_t i = 0; i < vo.size(); ++i){
295  vo.at(i) = va.at(i)||vb.at(i);
296  }
297  return vo;
298  };
299  }
300  return make_pair(sfo, vfo);
301  }
302 }
303 
310 NamedFunc::NamedFunc(const std::string &name,
311  const std::function<ScalarFunc> &function):
312  name_(name),
313  scalar_func_(function),
314  vector_func_(){
315  CleanName();
316 }
317 
324 NamedFunc::NamedFunc(const std::string &name,
325  const std::function<VectorFunc> &function):
326  name_(name),
327  scalar_func_(),
328  vector_func_(function){
329  CleanName();
330  }
331 
338 NamedFunc::NamedFunc(const string &function):
339  NamedFunc(FunctionParser(function).ResolveAsNamedFunc()){
340 }
341 
348 NamedFunc::NamedFunc(const char *function):
349  NamedFunc(string(function)){
350 }
351 
358 NamedFunc::NamedFunc(const TString &function):
359  NamedFunc(static_cast<const char *>(function)){
360 }
361 
367  name_(ToString(x)),
368  scalar_func_([x](const Baby&){return x;}),
369  vector_func_(){
370 }
371 
376 const string & NamedFunc::Name() const{
377  return name_;
378 }
379 
384 NamedFunc & NamedFunc::Name(const string &name){
385  name_ = name;
386  CleanName();
387  return *this;
388 }
389 
399 NamedFunc & NamedFunc::Function(const std::function<ScalarFunc> &f){
400  if(!static_cast<bool>(f)) return *this;
401  scalar_func_ = f;
402  vector_func_ = function<VectorFunc>();
403  return *this;
404 }
405 
415 NamedFunc & NamedFunc::Function(const std::function<VectorFunc> &f){
416  if(!static_cast<bool>(f)) return *this;
417  scalar_func_ = function<ScalarFunc>();
418  vector_func_ = f;
419  return *this;
420 }
421 
426 const function<ScalarFunc> & NamedFunc::ScalarFunction() const{
427  return scalar_func_;
428 }
429 
434 const function<VectorFunc> & NamedFunc::VectorFunction() const{
435  return vector_func_;
436 }
437 
442 bool NamedFunc::IsScalar() const{
443  return static_cast<bool>(scalar_func_);
444 }
445 
450 bool NamedFunc::IsVector() const{
451  return static_cast<bool>(vector_func_);
452 }
453 
461  return scalar_func_(b);
462 }
463 
471  return vector_func_(b);
472 }
473 
481  name_ = "("+name_ + ")+(" + func.name_ + ")";
482  auto fp = ApplyOp(scalar_func_, vector_func_,
483  func.scalar_func_, func.vector_func_,
484  plus<ScalarType>());
485  scalar_func_ = fp.first;
486  vector_func_ = fp.second;
487  return *this;
488 }
489 
497  name_ = "("+name_ + ")-(" + func.name_ + ")";
498  auto fp = ApplyOp(scalar_func_, vector_func_,
499  func.scalar_func_, func.vector_func_,
500  minus<ScalarType>());
501  scalar_func_ = fp.first;
502  vector_func_ = fp.second;
503  return *this;
504 }
505 
513  name_ = "("+name_ + ")*(" + func.name_ + ")";
514  auto fp = ApplyOp(scalar_func_, vector_func_,
515  func.scalar_func_, func.vector_func_,
516  multiplies<ScalarType>());
517  scalar_func_ = fp.first;
518  vector_func_ = fp.second;
519  return *this;
520 }
521 
529  name_ = "("+name_ + ")/(" + func.name_ + ")";
530  auto fp = ApplyOp(scalar_func_, vector_func_,
531  func.scalar_func_, func.vector_func_,
532  divides<ScalarType>());
533  scalar_func_ = fp.first;
534  vector_func_ = fp.second;
535  return *this;
536 }
537 
545  name_ = "("+name_ + ")%(" + func.name_ + ")";
546  auto fp = ApplyOp(scalar_func_, vector_func_,
547  func.scalar_func_, func.vector_func_,
548  static_cast<ScalarType (*)(ScalarType ,ScalarType)>(fmod));
549  scalar_func_ = fp.first;
550  vector_func_ = fp.second;
551  return *this;
552 }
553 
557  if(IsScalar()) ERROR("Cannot apply indexing operator to scalar NamedFunc "+Name());
558  if(func.IsVector()) ERROR("Cannot use vector "+func.Name()+" as index");
559  const auto &vec = VectorFunction();
560  const auto &index = func.ScalarFunction();
561  return NamedFunc("("+Name()+")["+func.Name()+"]", [vec, index](const Baby &b){
562  return vec(b).at(index(b));
563  });
564 }
565 
569  ReplaceAll(name_, " ", "");
570 }
571 
581  return f+=g;
582 }
583 
593  return f-=g;
594 }
595 
605  return f*=g;
606 }
607 
617  return f/=g;
618 }
619 
630  return f%=g;
631 }
632 
640  f.Name("+(" + f.Name() + ")");
641  return f;
642 }
643 
651  f.Name("-(" + f.Name() + ")");
652  f.Function(ApplyOp(f.ScalarFunction(), negate<ScalarType>()));
653  f.Function(ApplyOp(f.VectorFunction(), negate<ScalarType>()));
654  return f;
655 }
656 
666  f.Name("(" + f.Name() + ")==(" + g.Name() + ")");
667  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
669  equal_to<ScalarType>());
670  f.Function(fp.first);
671  f.Function(fp.second);
672  return f;
673 }
674 
684  f.Name("(" + f.Name() + ")!=(" + g.Name() + ")");
685  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
687  not_equal_to<ScalarType>());
688  f.Function(fp.first);
689  f.Function(fp.second);
690  return f;
691 }
692 
703  f.Name("(" + f.Name() + ")>(" + g.Name() + ")");
704  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
706  greater<ScalarType>());
707  f.Function(fp.first);
708  f.Function(fp.second);
709  return f;
710 }
711 
721  f.Name("(" + f.Name() + ")<(" + g.Name() + ")");
722  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
724  less<ScalarType>());
725  f.Function(fp.first);
726  f.Function(fp.second);
727  return f;
728 }
729 
741  f.Name("(" + f.Name() + ")>=(" + g.Name() + ")");
742  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
744  greater_equal<ScalarType>());
745  f.Function(fp.first);
746  f.Function(fp.second);
747  return f;
748 }
749 
761  f.Name("(" + f.Name() + ")<=(" + g.Name() + ")");
762  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
764  less_equal<ScalarType>());
765  f.Function(fp.first);
766  f.Function(fp.second);
767  return f;
768 }
769 
779  f.Name("(" + f.Name() + ")&&(" + g.Name() + ")");
780  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
782  logical_and<ScalarType>());
783  f.Function(fp.first);
784  f.Function(fp.second);
785  return f;
786 }
787 
797  f.Name("(" + f.Name() + ")||(" + g.Name() + ")");
798  auto fp = ApplyOp(f.ScalarFunction(), f.VectorFunction(),
800  logical_or<ScalarType>());
801  f.Function(fp.first);
802  f.Function(fp.second);
803  return f;
804 }
805 
813  f.Name("!(" + f.Name() + ")");
814  f.Function(ApplyOp(f.ScalarFunction(), logical_not<ScalarType>()));
815  f.Function(ApplyOp(f.VectorFunction(), logical_not<ScalarType>()));
816  return f;
817 }
818 
825 ostream & operator<<(ostream &stream, const NamedFunc &function){
826  stream << function.Name();
827  return stream;
828 }
829 
831  for(const auto &x: v){
832  if(x) return true;
833  }
834  return false;
835 }
836 
837 bool HavePass(const std::vector<NamedFunc::VectorType> &vv){
838  if(vv.size()==0) return false;
839  bool this_pass;
840  for(size_t ix = 0; ix < vv.at(0).size(); ++ix){
841  this_pass = true;
842  for(size_t iv = 0; this_pass && iv < vv.size(); ++iv){
843  if(ix>=vv.at(iv).size() || !vv.at(iv).at(ix)) this_pass = false;
844  }
845  if(this_pass) return true;
846  }
847  return false;
848 }
NamedFunc operator<=(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests if result of f is less than or equal to result of g.
Definition: named_func.cpp:760
NamedFunc operator/(NamedFunc f, NamedFunc g)
Divide two NamedFuncs.
Definition: named_func.cpp:616
std::vector< ScalarType > VectorType
Definition: named_func.hpp:16
NamedFunc operator%(NamedFunc f, NamedFunc g)
Get remainder form division of two NamedFuncs.
Definition: named_func.cpp:629
NamedFunc::VectorType VectorType
NamedFunc & operator*=(const NamedFunc &func)
Multiply *this by func.
Definition: named_func.cpp:512
NamedFunc operator>(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests if result of f is greater than result of g.
Definition: named_func.cpp:702
std::string name_
String representation of the function.
Definition: named_func.hpp:60
const std::string & Name() const
Get the string representation of this function.
Definition: named_func.cpp:376
Abstract base class for access to ntuple variables.
Definition: baby.hpp:16
void ReplaceAll(std::string &str, const std::string &orig, const std::string &rep)
Definition: utilities.cpp:52
ScalarType GetScalar(const Baby &b) const
Evaluate scalar function with b as argument.
Definition: named_func.cpp:460
STL namespace.
NamedFunc operator&&(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests if results of both f and g are true.
Definition: named_func.cpp:778
ScalarType(const Baby &) ScalarFunc
Definition: named_func.hpp:17
Combines a callable function taking a Baby and returning a scalar or vector with its string represent...
Definition: named_func.hpp:13
ostream & operator<<(ostream &stream, const NamedFunc &function)
Print NamedFunc to output stream.
Definition: named_func.cpp:825
NamedFunc operator<(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests if result of f is less than result of g.
Definition: named_func.cpp:720
NamedFunc operator>=(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests if result of f is greater than or equal to result of g.
Definition: named_func.cpp:740
double ScalarType
Definition: named_func.hpp:15
NamedFunc operator==(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests for equality of results of f and g.
Definition: named_func.cpp:665
pair< function< ScalarFunc >, function< VectorFunc > > ApplyOp(const function< ScalarFunc > &sfa, const function< VectorFunc > &vfa, const function< ScalarFunc > &sfb, const function< VectorFunc > &vfb, const logical_or< ScalarType > &)
Get a functor applying binary "||" to operands (sfa or vfa) and (sfb or vfb)
Definition: named_func.cpp:254
VectorType(const Baby &) VectorFunc
Definition: named_func.hpp:18
bool IsScalar() const
Check if scalar function is valid.
Definition: named_func.cpp:442
NamedFunc::VectorType VectorType
Definition: named_func.cpp:55
NamedFunc operator[](const NamedFunc &func) const
Apply indexing operator and return result as a NamedFunc.
Definition: named_func.cpp:556
NamedFunc::VectorFunc VectorFunc
#define ERROR(x)
Definition: utilities.hpp:17
NamedFunc operator!(NamedFunc f)
Gets NamedFunct returning logical inverse of result of f.
Definition: named_func.cpp:812
void CleanName()
Strip spaces from name.
Definition: named_func.cpp:568
NamedFunc operator!=(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests for inequality of results of f and g.
Definition: named_func.cpp:683
NamedFunc()=delete
VectorType GetVector(const Baby &b) const
Evaluate vector function with b as argument.
Definition: named_func.cpp:470
std::function< ScalarFunc > scalar_func_
Definition: named_func.hpp:61
NamedFunc operator||(NamedFunc f, NamedFunc g)
Gets NamedFunc which tests if result of f or g is true.
Definition: named_func.cpp:796
NamedFunc operator*(NamedFunc f, NamedFunc g)
Multiply two NamedFuncs.
Definition: named_func.cpp:604
NamedFunc operator-(NamedFunc f, NamedFunc g)
Add a NamedFunc from another.
Definition: named_func.cpp:592
NamedFunc & operator-=(const NamedFunc &func)
Subtract func from *this.
Definition: named_func.cpp:496
NamedFunc & Function(const std::function< ScalarFunc > &function)
Set function to given scalar function.
Definition: named_func.cpp:399
std::function< VectorFunc > vector_func_
Definition: named_func.hpp:62
bool IsVector() const
Check if vectorr function is valid.
Definition: named_func.cpp:450
NamedFunc operator+(NamedFunc f, NamedFunc g)
Add two NamedFuncs.
Definition: named_func.cpp:580
const std::function< VectorFunc > & VectorFunction() const
Return the (possibly invalid) vector function.
Definition: named_func.cpp:434
bool HavePass(const NamedFunc::VectorType &v)
Definition: named_func.cpp:830
NamedFunc::ScalarFunc ScalarFunc
NamedFunc & operator%=(const NamedFunc &func)
Set *this to remainder of *this divided by func.
Definition: named_func.cpp:544
NamedFunc & operator+=(const NamedFunc &func)
Add func to *this.
Definition: named_func.cpp:480
std::string ToString(const T &x)
Definition: utilities.hpp:74
NamedFunc & operator/=(const NamedFunc &func)
Divide *this by func.
Definition: named_func.cpp:528
Converts a string into a NamedFunc.
const std::function< ScalarFunc > & ScalarFunction() const
Return the (possibly invalid) scalar function.
Definition: named_func.cpp:426
NamedFunc::ScalarType ScalarType