All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
piecewise_defined_function.h
1 /* Copyright (C) 2004-2014 MBSim Development Team
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16  *
17  * Contact: martin.o.foerg@gmail.com
18  */
19 
20 #ifndef _PIECEWISE_DEFINED_FUNCTIONS_H_
21 #define _PIECEWISE_DEFINED_FUNCTIONS_H_
22 
23 #include "mbsim/functions/function.h"
24 
25 namespace MBSim {
26 
27  template<typename Sig> class LimitedFunction;
28 
29  template <typename Ret, typename Arg>
30  struct LimitedFunction<Ret(Arg)> {
31  LimitedFunction(Function<Ret(Arg)> *function_, double limit_) : function(function_), limit(limit_) { }
32  Function<Ret(Arg)> *function;
33  double limit;
34  };
35 
36  template<typename Sig> class PiecewiseDefinedFunction;
37 
38  template<typename Ret>
39  class PiecewiseDefinedFunction<Ret(double)> : public Function<Ret(double)> {
41  public:
42  PiecewiseDefinedFunction() : shiftAbscissa(false), shiftOrdinate(false) { a.push_back(0); }
44  for(unsigned int i=0; i<function.size(); i++)
45  delete function[i];
46  }
47  void addLimitedFunction(const LimitedFunction<Ret(double)> &limitedFunction) {
48  function.push_back(limitedFunction.function);
49  limitedFunction.function->setParent(this);
50  a.push_back(limitedFunction.limit);
51  }
52  Ret zeros(const Ret &x) { return Ret(x.size()); }
53  Ret operator()(const double &x) {
54  for(unsigned int i=0; i<function.size(); i++)
55  if(x<=a[i+1])
56  return y0[i] + (*function[i])(x-x0[i]);
57  throw MBSimError("(PiecewiseDefinedFunction::operator()): x out of range! x= "+numtostr(x)+", upper bound= "+numtostr(a[function.size()]));
58  }
59  typename B::DRetDArg parDer(const double &x) {
60  for(unsigned int i=0; i<function.size(); i++)
61  if(x<=a[i+1])
62  return function[i]->parDer(x-x0[i]);
63  throw MBSimError("(PiecewiseDefinedFunction::parDer): x out of range! x= "+numtostr(x)+", upper bound= "+numtostr(a[function.size()]));
64  }
65  typename B::DRetDArg parDerDirDer(const double &xDir, const double &x) {
66  for(unsigned int i=0; i<function.size(); i++)
67  if(x<=a[i+1])
68  return function[i]->parDerDirDer(xDir,x-x0[i]);
69  throw MBSimError("(PiecewiseDefinedFunction::parDerDirDer): x out of range! x= "+numtostr(x)+", upper bound= "+numtostr(a[function.size()]));
70  }
71  typename B::DDRetDDArg parDerParDer(const double &x) {
72  for(unsigned int i=0; i<function.size(); i++)
73  if(x<=a[i+1])
74  return function[i]->parDerParDer(x-x0[i]);
75  throw MBSimError("(PiecewiseDefinedFunction::parDerParDer): x out of range! x= "+numtostr(x)+", upper bound= "+numtostr(a[function.size()]));
76  }
77 
78  void initializeUsingXML(xercesc::DOMElement *element) {
79  xercesc::DOMElement *e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"limitedFunctions");
80  xercesc::DOMElement *ee=e->getFirstElementChild();
81  while(ee && MBXMLUtils::E(ee)->getTagName()==MBSIM%"LimitedFunction") {
82  addLimitedFunction(LimitedFunction<Ret(double)>(ObjectFactory::createAndInit<Function<Ret(double)> >(MBXMLUtils::E(ee)->getFirstElementChildNamed(MBSIM%"function")->getFirstElementChild()),Element::getDouble(MBXMLUtils::E(ee)->getFirstElementChildNamed(MBSIM%"limit"))));
83  ee=ee->getNextElementSibling();
84  }
85  e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"shiftAbscissa");
86  if(e) shiftAbscissa=Element::getBool(e);
87  e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"shiftOrdinate");
88  if(e) shiftOrdinate=Element::getBool(e);
89  }
90  void init(Element::InitStage stage) {
92  for(typename std::vector<Function<Ret(double)> *>::iterator it=function.begin(); it!=function.end(); it++)
93  (*it)->init(stage);
94  if(stage==Element::preInit) {
95  if(shiftAbscissa) {
96  for(unsigned int i=1; i<a.size(); i++)
97  a[i] += a[i-1];
98  x0 = a;
99  }
100  else
101  x0.resize(a.size());
102  y0.resize(a.size(),zeros((*function[0])(0)));
103  if(shiftOrdinate) {
104  for(unsigned int i=1; i<a.size(); i++)
105  y0[i] = (*this)(a[i]);
106  }
107  }
108  }
109  private:
110  std::vector<Function<Ret(double)> *> function;
111  std::vector<double> a, x0;
112  std::vector<Ret> y0;
113  bool shiftAbscissa, shiftOrdinate;
114  };
115 
116  template<>
117  inline double PiecewiseDefinedFunction<double(double)>::zeros(const double &x) { return 0; }
118 
119  template<typename Ret, typename Arg>
120  class PiecewiseDefinedFunction<Ret(Arg)> : public Function<Ret(Arg)> {
122  public:
123  PiecewiseDefinedFunction() : shiftAbscissa(false), shiftOrdinate(false) { a.push_back(0); }
125  for(unsigned int i=0; i<function.size(); i++)
126  delete function[i];
127  }
128  void addLimitedFunction(const LimitedFunction<Ret(Arg)> &limitedFunction) {
129  function.push_back(limitedFunction.function);
130  limitedFunction.function->setParent(this);
131  a.push_back(limitedFunction.limit);
132  }
133  int getArgSize() const { return 1; }
134  Ret zeros(const Ret &x) { return Ret(x.size()); }
135  Ret operator()(const Arg &x) {
136  for(unsigned int i=0; i<function.size(); i++)
137  if(ToDouble<Arg>::cast(x)<=a[i+1])
138  return y0[i] + (*function[i])(x-FromDouble<Arg>::cast(x0[i]));
139  throw MBSimError("(PiecewiseDefinedFunction::operator()): x out of range! x= "+numtostr(x)+", upper bound= "+numtostr(a[function.size()]));
140  }
141  typename B::DRetDArg parDer(const Arg &x) {
142  for(unsigned int i=0; i<function.size(); i++)
143  if(ToDouble<Arg>::cast(x)<=a[i+1])
144  return function[i]->parDer(x-FromDouble<Arg>::cast(x0[i]));
145  throw MBSimError("(PiecewiseDefinedFunction::parDer): x out of range! x= "+numtostr(x)+", upper bound= "+numtostr(a[function.size()]));
146  }
147  typename B::DRetDArg parDerDirDer(const Arg &xDir, const Arg &x) {
148  for(unsigned int i=0; i<function.size(); i++)
149  if(ToDouble<Arg>::cast(x)<=a[i+1])
150  return function[i]->parDerDirDer(xDir,x-FromDouble<Arg>::cast(x0[i]));
151  throw MBSimError("(PiecewiseDefinedFunction::parDerDirDer): x out of range! x= "+numtostr(x)+", upper bound= "+numtostr(a[function.size()]));
152  }
153 
154  void initializeUsingXML(xercesc::DOMElement *element) {
155  xercesc::DOMElement *e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"limitedFunctions");
156  xercesc::DOMElement *ee=e->getFirstElementChild();
157  while(ee && MBXMLUtils::E(ee)->getTagName()==MBSIM%"LimitedFunction") {
158  addLimitedFunction(LimitedFunction<Ret(Arg)>(ObjectFactory::createAndInit<Function<Ret(Arg)> >(MBXMLUtils::E(ee)->getFirstElementChildNamed(MBSIM%"function")->getFirstElementChild()),Element::getDouble(MBXMLUtils::E(ee)->getFirstElementChildNamed(MBSIM%"limit"))));
159  ee=ee->getNextElementSibling();
160  }
161  e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"shiftAbscissa");
162  if(e) shiftAbscissa=Element::getBool(e);
163  e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"shiftOrdinate");
164  if(e) shiftOrdinate=Element::getBool(e);
165  }
166  void init(Element::InitStage stage) {
168  for(typename std::vector<Function<Ret(Arg)> *>::iterator it=function.begin(); it!=function.end(); it++)
169  (*it)->init(stage);
170  if(stage==Element::preInit) {
171  if(shiftAbscissa) {
172  for(unsigned int i=1; i<a.size(); i++)
173  a[i] += a[i-1];
174  x0 = a;
175  }
176  else
177  x0.resize(a.size());
178  y0.resize(a.size(),zeros((*function[0])(Arg(1))));
179  if(shiftOrdinate) {
180  for(unsigned int i=1; i<a.size(); i++)
181  y0[i] = (*this)(FromDouble<Arg>::cast(a[i]));
182  }
183  }
184  }
185  private:
186  std::vector<Function<Ret(Arg)> *> function;
187  std::vector<double> a, x0;
188  std::vector<Ret> y0;
189  bool shiftAbscissa, shiftOrdinate;
190  };
191 
192  template <>
193  inline double PiecewiseDefinedFunction<double(fmatvec::VecV)>::zeros(const double &x) { return 0; }
194 
195 }
196 
197 #endif
Definition: piecewise_defined_function.h:27
Definition: utils.h:153
void init(Element::InitStage stage)
plots time series header
Definition: piecewise_defined_function.h:90
InitStage
The stages of the initialization.
Definition: element.h:97
Definition: utils.h:197
Definition: planar_contour.h:31
Definition: element.h:100
void init(Element::InitStage stage)
plots time series header
Definition: piecewise_defined_function.h:166
virtual void init(InitStage stage)
plots time series header
Definition: element.cc:70
static ContainerType * createAndInit(const xercesc::DOMElement *element)
Definition: objectfactory.h:87
basic error class for mbsim
Definition: mbsim_event.h:38
Definition: piecewise_defined_function.h:36

Impressum / Disclaimer / Datenschutz Generated by doxygen 1.8.5 Valid HTML