mbsim  4.0.0
MBSim Kernel
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 _TABULAR_FUNCTION_H_
21#define _TABULAR_FUNCTION_H_
22
23#include "mbsim/functions/function.h"
24#include "mbsim/utils/utils.h"
25
26namespace MBSim {
27
28 template<typename Sig> class TabularFunction;
29
30 template<typename Ret, typename Arg>
31 class TabularFunction<Ret(Arg)> : public Function<Ret(Arg)> {
32
33 public:
34 TabularFunction() { }
35 TabularFunction(const fmatvec::VecV &x_, const fmatvec::MatV &y_) : x(x_), y(y_), xIndexOld(0) { }
36 int getArgSize() const override { return 1; }
37 std::pair<int, int> getRetSize() const override { return std::make_pair(y.cols(),1); }
38 Ret operator()(const Arg& xVal_) override {
39 double xVal = ToDouble<Arg>::cast(xVal_);
40 int i = xIndexOld;
41 if (xVal <= x(0)) {
42 xIndexOld = 0;
43 return FromVecV<Ret>::cast(trans(y.row(0)));
44 }
45 else if (xVal >= x(x.size() - 1)) {
46 xIndexOld = x.size() - 1;
47 return FromVecV<Ret>::cast(trans(y.row(x.size() - 1)));
48 }
49 else if (xVal <= x(i)) {
50 while (xVal < x(i))
51 i--;
52 }
53 else {
54 do
55 i++;
56 while (xVal > x(i));
57 i--;
58 }
59 xIndexOld = i;
60 return FromVecV<Ret>::cast(trans(y.row(i) + (xVal - x(i)) * (y.row(i + 1) - y.row(i)) / (x(i + 1) - x(i))));
61 }
62 void initializeUsingXML(xercesc::DOMElement * element) override {
63 xercesc::DOMElement *e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"x");
64 if (e) {
65 setx(MBXMLUtils::E(e)->getText<fmatvec::Vec>());
66 e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"y");
67 sety(MBXMLUtils::E(e)->getText<fmatvec::Mat>(x.size(), 0));
68 }
69 e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"xy");
70 if (e) setxy(MBXMLUtils::E(e)->getText<fmatvec::Mat>());
71 }
72 void setx(const fmatvec::VecV &x_) { x <<= x_; }
73 void sety(const fmatvec::MatV &y_) { y <<= y_; }
74 void setxy(const fmatvec::MatV &xy) {
75 if(xy.cols() <= 1)
76 this->throwError("Dimension missmatch in size of xy");
77 x <<= xy.col(0);
78 y <<= xy(fmatvec::RangeV(0, xy.rows() - 1), fmatvec::RangeV(1, xy.cols() - 1));
79 }
80 void init(Element::InitStage stage, const InitConfigSet &config) override {
81 Function<Ret(Arg)>::init(stage, config);
82 if(stage==Element::preInit) {
83 for(int i=1; i<x.size(); i++)
84 if(x(i) <= x(i-1))
85 this->throwError("Values of x must be strictly monotonic increasing!");
86 if(y.rows() != x.size())
87 this->throwError("Dimension missmatch in size of x");
88 }
89 }
90 protected:
91 fmatvec::VecV x;
92 fmatvec::MatV y;
93 private:
94 int xIndexOld{0};
95 };
96}
97
98#endif
InitStage
The stages of the initialization.
Definition: element.h:62
@ preInit
Definition: element.h:64
Definition: utils.h:129
Definition: function.h:53
void init(Element::InitStage stage, const InitConfigSet &config) override
plots time series header
Definition: tabular_function.h:80
Definition: tabular_function.h:28
Definition: utils.h:61
namespace MBSim
Definition: bilateral_constraint.cc:30