All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
two_dimensional_tabular_function.h
1 /* Copyright (C) 2004-2009 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: markus.ms.schneider@gmail.com
18  */
19 
20 #ifndef _TWO_DIMENSIONAL_TABULAR_FUNCTION_H_
21 #define _TWO_DIMENSIONAL_TABULAR_FUNCTION_H_
22 
23 #include "mbsim/functions/function.h"
24 #include "mbsim/utils/utils.h"
25 
26 namespace MBSim {
27 
28  template<typename Sig> class TwoDimensionalTabularFunction;
29 
30  template<typename Ret, typename Arg1, typename Arg2>
31  class TwoDimensionalTabularFunction<Ret(Arg1, Arg2)> : public Function<Ret(Arg1, Arg2)> {
32  public:
33  TwoDimensionalTabularFunction() : x0Index(0), x1Index(0), y0Index(0), y1Index(0), zVal(4,fmatvec::INIT,1), zInd(4,fmatvec::INIT,0), zFac(4, 4,fmatvec::INIT,0) { }
34  /* INHERITED INTERFACE OF FUNCTION2 */
35  virtual void initializeUsingXML(xercesc::DOMElement *element) {
36  xercesc::DOMElement * e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"x");
37  if(e) {
38  setx(Element::getVec(e));
39  e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"y");
40  sety(Element::getVec(e));
41  e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"z");
42  setz(Element::getMat(e, y.size(), x.size()));
43  }
44  e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"xyz");
45  if(e) setxyz(Element::getMat(e));
46  }
47  virtual Ret operator()(const Arg1& xVal_, const Arg2& yVal_) {
48  double xVal = ToDouble<Arg1>::cast(xVal_);
49  double yVal = ToDouble<Arg2>::cast(yVal_);
50  calcIndex(xVal, x, x.size(), x0Index, x1Index);
51  calcIndex(yVal, y, y.size(), y0Index, y1Index);
52 
53  zVal(1) = xVal;
54  zVal(2) = yVal;
55  zVal(3) = xVal * yVal;
56  const double x0 = x(x0Index);
57  const double x1 = x(x1Index);
58  const double y0 = y(y0Index);
59  const double y1 = y(y1Index);
60  const double nenner = (x0 - x1) * (y0 - y1);
61  zInd(0) = z(y0Index, x0Index);
62  zInd(1) = z(y0Index, x1Index);
63  zInd(2) = z(y1Index, x0Index);
64  zInd(3) = z(y1Index, x1Index);
65  zFac(0, 0) = x1 * y1;
66  zFac(0, 1) = -x0 * y1;
67  zFac(0, 2) = -x1 * y0;
68  zFac(0, 3) = x0 * y0;
69  zFac(1, 0) = -y1;
70  zFac(1, 1) = y1;
71  zFac(1, 2) = y0;
72  zFac(1, 3) = -y0;
73  zFac(2, 0) = -x1;
74  zFac(2, 1) = x0;
75  zFac(2, 2) = x1;
76  zFac(2, 3) = -x0;
77  zFac(3, 0) = 1.;
78  zFac(3, 1) = -1.;
79  zFac(3, 2) = -1.;
80  zFac(3, 3) = 1.;
81 
82  return FromDouble<Ret>::cast((trans(zFac*zInd)*zVal)/nenner);
83  }
84  /***************************************************/
85  /* GETTER / SETTER */
86  void setx(const fmatvec::VecV &x_) { x = x_; }
87  void sety(const fmatvec::VecV &y_) { y = y_; }
88  void setz(const fmatvec::MatV &z_) { z = z_; }
89  void setxyz(const fmatvec::MatV &xyz) {
90  if(xyz.rows() <= 1 or xyz.cols() <= 1)
91  THROW_MBSIMERROR("Dimension missmatch in size of xyz");
92  x = xyz.row(0)(fmatvec::RangeV(1,xyz.cols()-1)).T();
93  y = xyz.col(0)(fmatvec::RangeV(1,xyz.rows()-1));
94  z = xyz(fmatvec::RangeV(1,xyz.rows()-1),fmatvec::RangeV(1,xyz.cols()-1));
95  }
96 
97  double getxMin() { return x(0); }
98  double getxMax() { return x(x.size() - 1); }
99  double getyMin() { return y(0); }
100  double getyMax() { return y(y.size() - 1); }
101  /***************************************************/
102 
103  void init(Element::InitStage stage) {
105  if(stage==Element::preInit) {
106  if (z.cols() != x.size())
107  THROW_MBSIMERROR("Dimension missmatch in size of x");
108  if (z.rows() != y.size())
109  THROW_MBSIMERROR("Dimension missmatch in size of y");
110  for (int i = 1; i < x.size(); i++)
111  if (x(i - 1) >= x(i))
112  THROW_MBSIMERROR("x values must be strictly monotonic increasing!");
113  for (int i = 1; i < y.size(); i++)
114  if (y(i - 1) >= y(i))
115  THROW_MBSIMERROR("y values must be strictly monotonic increasing!");
116  }
117  }
118  protected:
119  fmatvec::VecV x;
120  fmatvec::VecV y;
121  fmatvec::MatV z;
122 
123  int x0Index, x1Index;
124  int y0Index, y1Index;
125 
126  fmatvec::VecV zVal;
127  fmatvec::VecV zInd;
128  fmatvec::MatV zFac;
129 
130  void calcIndex(double x, const fmatvec::VecV &X, int xSize, int &xIndexMinus, int &xIndexPlus) {
131  if (x <= X(0)) {
132  xIndexPlus = 1;
133  xIndexMinus = 0;
134  fmatvec::Atom::msg(fmatvec::Atom::Warn) << "TwoDimensionalTabularFunction: Value (" << x << ") is smaller than the smallest table value(" << X(0) << ")!" << std::endl;
135  }
136  else if (x >= X(xSize - 1)) {
137  xIndexPlus = xSize - 1;
138  xIndexMinus = xSize - 2;
139  fmatvec::Atom::msg(fmatvec::Atom::Warn) << "TwoDimensionalTabularFunction: Value (" << x << ") is greater than the greatest table value(" << X(xSize - 1) << ")!" << std::endl;
140  }
141  else {
142  if (x < X(xIndexPlus))
143  while (x < X(xIndexPlus - 1) && xIndexPlus > 1)
144  xIndexPlus--;
145  else if (x > X(xIndexPlus))
146  while (x > X(xIndexPlus) && xIndexPlus < xSize - 1)
147  xIndexPlus++;
148  xIndexMinus = xIndexPlus - 1;
149  }
150  }
151  };
152 }
153 
154 #endif
void init(Element::InitStage stage)
plots time series header
Definition: two_dimensional_tabular_function.h:103
std::ostream & msg(MsgType type)
Definition: utils.h:153
InitStage
The stages of the initialization.
Definition: element.h:97
Definition: utils.h:197
Definition: planar_contour.h:31
Definition: element.h:100
Definition: two_dimensional_tabular_function.h:28

Impressum / Disclaimer / Datenschutz Generated by doxygen 1.8.5 Valid HTML