22 Func1::Func1(
const Func1& right) :
26 m_parent(right.m_parent)
30 Func1& Func1::operator=(
const Func1& right)
38 m_parent = right.m_parent;
54 doublereal Func1::operator()(doublereal t)
const
60 doublereal Func1::eval(doublereal t)
const
65 Func1& Func1::derivative()
const
67 cout <<
"derivative error... ERR: ID = " << ID() << endl;
68 cout << write(
"x") << endl;
72 bool Func1::isIdentical(
Func1& other)
const
74 if (ID() != other.ID() || m_c != other.m_c) {
81 if (!m_f1->isIdentical(*other.m_f1)) {
89 if (!m_f2->isIdentical(*other.m_f2)) {
97 doublereal Func1::c()
const
103 void Func1::setC(doublereal c)
119 int Func1::order()
const
124 Func1& Func1::func1_dup()
const
129 Func1& Func1::func2_dup()
const
134 Func1* Func1::parent()
const
139 void Func1::setParent(Func1* p)
146 string Sin1::write(
const string& arg)
const
149 return fmt::format(
"\\sin({})", arg);
151 return fmt::format(
"\\sin({}{})", m_c, arg);
158 Func1* r = &newTimesConstFunction(*c, m_c);
166 Func1* r = &newTimesConstFunction(*s, -m_c);
170 std::string Cos1::write(
const std::string& arg)
const
173 return fmt::format(
"\\cos({})", arg);
175 return fmt::format(
"\\cos({}{})", m_c, arg);
185 return newTimesConstFunction(*f, m_c);
191 std::string Exp1::write(
const std::string& arg)
const
194 return fmt::format(
"\\exp({})", arg);
196 return fmt::format(
"\\exp({}{})", m_c, arg);
207 }
else if (m_c == 1.0) {
211 r = &newTimesConstFunction(*f, m_c);
218 Tabulated1::Tabulated1(
size_t n,
const double* tvals,
const double* fvals,
219 const std::string& method) :
222 std::copy(tvals, tvals + n,
m_tvec.begin());
223 for (
auto it = std::begin(
m_tvec) + 1; it != std::end(
m_tvec); it++) {
224 if (*(it - 1) > *it) {
226 "time values are not increasing monotonically.");
230 std::copy(fvals, fvals + n,
m_fvec.begin());
231 if (method ==
"linear") {
233 }
else if (method ==
"previous") {
237 "interpolation method '{}' is not implemented",
243 size_t siz =
m_tvec.size();
247 }
else if (t >=
m_tvec[siz-1]) {
251 while (t >
m_tvec[ix+1]) {
268 size_t siz =
m_tvec.size();
272 for (
size_t i=1; i<siz; i++) {
275 tvec.push_back(
m_tvec[i-1]);
279 tvec.push_back(
m_tvec[siz-1]);
283 tvec.push_back(
m_tvec[0]);
284 tvec.push_back(
m_tvec[siz-1]);
288 return *(
new Tabulated1(tvec.size(), &tvec[0], &dvec[0],
"previous"));
293 string Func1::write(
const std::string& arg)
const
295 return fmt::format(
"<unknown {}>({})", ID(), arg);
298 string Pow1::write(
const std::string& arg)
const
301 return "\\sqrt{" + arg +
"}";
304 return "\\frac{1}{\\sqrt{" + arg +
"}}";
307 return fmt::format(
"\\left({}\\right)^{{{}}}", arg, m_c);
313 string Tabulated1::write(
const std::string& arg)
const
315 return fmt::format(
"\\mathrm{{Tabulated}}({})", arg);
318 string Const1::write(
const std::string& arg)
const
320 return fmt::format(
"{}", m_c);
323 string Ratio1::write(
const std::string& arg)
const
325 return "\\frac{" + m_f1->write(arg) +
"}{"
326 + m_f2->write(arg) +
"}";
329 string Product1::write(
const std::string& arg)
const
331 string s = m_f1->write(arg);
333 s =
"\\left(" + s +
"\\right)";
335 string s2 = m_f2->write(arg);
337 s2 =
"\\left(" + s2 +
"\\right)";
342 string Sum1::write(
const std::string& arg)
const
344 string s1 = m_f1->write(arg);
345 string s2 = m_f2->write(arg);
347 return s1 +
" - " + s2.substr(1,s2.size());
349 return s1 +
" + " + s2;
353 string Diff1::write(
const std::string& arg)
const
355 string s1 = m_f1->write(arg);
356 string s2 = m_f2->write(arg);
358 return s1 +
" + " + s2.substr(1,s2.size());
360 return s1 +
" - " + s2;
364 string Composite1::write(
const std::string& arg)
const
366 string g = m_f2->write(arg);
367 return m_f1->write(g);
370 string TimesConstant1::write(
const std::string& arg)
const
372 string s = m_f1->write(arg);
374 s =
"\\left(" + s +
"\\right)";
383 if (n >=
'0' && n <=
'9') {
384 s =
"\\left(" + s +
"\\right)";
386 return fmt::format(
"{}{}", m_c, s);
389 string PlusConstant1::write(
const std::string& arg)
const
392 return m_f1->write(arg);
394 return fmt::format(
"{} + {}", m_f1->write(arg), m_c);
397 doublereal Func1::isProportional(TimesConstant1& other)
404 doublereal Func1::isProportional(Func1& other)
413 static bool isConstant(Func1& f)
415 if (f.ID() == ConstFuncType) {
422 static bool isZero(Func1& f)
424 if (f.ID() == ConstFuncType && f.c() == 0.0) {
431 static bool isOne(Func1& f)
433 if (f.ID() == ConstFuncType && f.c() == 1.0) {
440 static bool isTimesConst(Func1& f)
442 if (f.ID() == TimesConstantFuncType) {
449 static bool isExp(Func1& f)
451 if (f.ID() == ExpFuncType) {
458 static bool isPow(Func1& f)
460 if (f.ID() == PowFuncType) {
467 Func1& newSumFunction(Func1& f1, Func1& f2)
469 if (f1.isIdentical(f2)) {
470 return newTimesConstFunction(f1, 2.0);
480 doublereal c = f1.isProportional(f2);
483 return *(
new Const1(0.0));
485 return newTimesConstFunction(f1, c + 1.0);
488 return *(
new Sum1(f1, f2));
491 Func1& newDiffFunction(Func1& f1, Func1& f2)
497 if (f1.isIdentical(f2)) {
500 return *(
new Const1(0.0));
502 doublereal c = f1.isProportional(f2);
505 return *(
new Const1(0.0));
507 return newTimesConstFunction(f1, 1.0 - c);
510 return *(
new Diff1(f1, f2));
513 Func1& newProdFunction(Func1& f1, Func1& f2)
523 if (isZero(f1) || isZero(f2)) {
526 return *(
new Const1(0.0));
528 if (isConstant(f1) && isConstant(f2)) {
529 doublereal c1c2 = f1.
c() * f2.c();
532 return *(
new Const1(c1c2));
534 if (isConstant(f1)) {
535 doublereal c = f1.c();
537 return newTimesConstFunction(f2, c);
539 if (isConstant(f2)) {
540 doublereal c = f2.c();
542 return newTimesConstFunction(f1, c);
545 if (isPow(f1) && isPow(f2)) {
546 Func1& p = *(
new Pow1(f1.c() + f2.c()));
552 if (isExp(f1) && isExp(f2)) {
553 Func1& p = *(
new Exp1(f1.c() + f2.c()));
559 bool tc1 = isTimesConst(f1);
560 bool tc2 = isTimesConst(f2);
563 doublereal c1 = 1.0, c2 = 1.0;
564 Func1* ff1 = 0, *ff2 = 0;
567 ff1 = &f1.func1_dup();
574 ff2 = &f2.func1_dup();
579 Func1& p = newProdFunction(*ff1, *ff2);
582 return newTimesConstFunction(p, c1*c2);
587 return *(
new Product1(f1, f2));
591 Func1& newRatioFunction(Func1& f1, Func1& f2)
597 return *(
new Const1(0.0));
599 if (f1.isIdentical(f2)) {
602 return *(
new Const1(1.0));
604 if (f1.ID() == PowFuncType && f2.ID() == PowFuncType) {
605 return *(
new Pow1(f1.c() - f2.c()));
607 if (f1.ID() == ExpFuncType && f2.ID() == ExpFuncType) {
608 return *(
new Exp1(f1.c() - f2.c()));
610 return *(
new Ratio1(f1, f2));
613 Func1& newCompositeFunction(Func1& f1, Func1& f2)
618 return *(
new Const1(0.0));
620 if (isConstant(f1)) {
624 if (isPow(f1) && f1.c() == 1.0) {
628 if (isPow(f1) && f1.c() == 0.0) {
631 return *(
new Const1(1.0));
633 if (isPow(f1) && isPow(f2)) {
634 doublereal c1c2 = f1.
c() * f2.c();
637 return *(
new Pow1(c1c2));
639 return *(
new Composite1(f1, f2));
642 Func1& newTimesConstFunction(Func1& f, doublereal c)
646 return *(
new Const1(0.0));
651 if (f.ID() == TimesConstantFuncType) {
655 return *(
new TimesConstant1(f, c));
658 Func1& newPlusConstFunction(Func1& f, doublereal c)
664 doublereal cc = f.
c() + c;
666 return *(
new Const1(cc));
668 if (f.ID() == PlusConstantFuncType) {
672 return *(
new PlusConstant1(f, c));