27 #define exprtk_disable_comments
32 #define exprtk_disable_break_continue
36 #define exprtk_disable_sc_andor
43 #if !defined(NDEBUG) || defined(__MINGW32__)
44 #define exprtk_disable_enhanced_features
50 #define exprtk_disable_string_capabilities
52 #define exprtk_disable_rtl_io_file
53 #define exprtk_disable_rtl_vecops
64 #if defined(GISMO_WITH_ADIFF)
65 #define DScalar gismo::ad::DScalar2<real_t,-1>
66 #include <exprtk_ad_forward.hpp>
69 #if defined(gsMpfr_ENABLED)
70 #include <exprtk_mpfr_forward.hpp>
73 #if defined(gsGmp_ENABLED)
74 #include <exprtk_gmp_forward.hpp>
77 #if defined(gsCoDiPack_ENABLED)
81 #if defined(gsUniversal_ENABLED)
87 #if defined(GISMO_WITH_ADIFF)
88 #include <exprtk_ad_adaptor.hpp>
91 #if defined(gsMpfr_ENABLED)
92 #include <exprtk_mpfr_adaptor.hpp>
95 #if defined(gsGmp_ENABLED)
96 #include <exprtk_gmp_adaptor.hpp>
99 #if defined(gsCoDiPack_ENABLED)
103 #if defined(gsUniversal_ENABLED)
115 template <
typename T>
116 T mixed_derivative(
const exprtk::expression<T>& e,
118 const double& h = 0.00001)
120 T num = (T)(0.0), tmp;
124 x = x_init + (T)(2.0) * h;
125 y = y_init + (T)(2.0) * h;
127 y = y_init - (T)(2.0) * h;
129 x = x_init - (T)(2.0) * h;
131 y = y_init + (T)(2.0) * h;
143 num += (T)(64.0) * tmp;
145 x = x_init + (T)(2.0) * h;
150 x = x_init - (T)(2.0) * h;
155 y = y_init + (T)(2.0) * h;
160 y = y_init - (T)(2.0) * h;
164 num += (T)(8.0) * tmp;
168 return num / ( (T)(144.0)*h*h );
178 template<
typename T>
class gsFunctionExpr<T>::gsFunctionExprPrivate
182 #ifdef GISMO_WITH_ADIFF
183 typedef DScalar Numeric_t;
188 typedef exprtk::symbol_table<Numeric_t> SymbolTable_t;
189 typedef exprtk::expression<Numeric_t> Expression_t;
190 typedef exprtk::parser<Numeric_t> Parser_t;
194 gsFunctionExprPrivate(
const short_t _dim)
197 GISMO_ENSURE( dim <= N_VARS,
"The number of variables can be at most 7 (x,y,z,w,u,v,t)." );
201 gsFunctionExprPrivate(
const gsFunctionExprPrivate & other)
202 : vars(), dim(other.dim)
204 GISMO_ASSERT (
string.
size() == expression.size(),
"Corrupted FunctionExpr");
207 string .reserve(
string.
size());
208 expression.reserve(
string.
size());
209 for (
size_t i = 0; i!= other.string.size(); ++i)
215 string.push_back( strExpression );
216 std::string & str =
string.back();
217 str.erase(std::remove(str.begin(), str.end(),
' '), str.end() );
221 expression.push_back(Expression_t());
222 Expression_t & expr = expression.back();
224 expr.register_symbol_table(symbol_table);
230 bool success = parser.compile(str, expr);
232 gsWarn<<
"gsFunctionExpr error: " <<parser.error() <<
" while parsing "<<str<<
"\n";
251 symbol_table.add_variable(
"x",vars[0]);
252 symbol_table.add_variable(
"y",vars[1]);
253 symbol_table.add_variable(
"z",vars[2]);
254 symbol_table.add_variable(
"w",vars[3]);
255 symbol_table.add_variable(
"u",vars[4]);
256 symbol_table.add_variable(
"v",vars[5]);
257 symbol_table.add_variable(
"t",vars[6]);
259 symbol_table.add_pi();
264 mutable Numeric_t vars[N_VARS];
265 SymbolTable_t symbol_table;
266 std::vector<Expression_t> expression;
267 std::vector<std::string> string;
271 gsFunctionExprPrivate();
272 gsFunctionExprPrivate operator= (
const gsFunctionExprPrivate & other);
343 : my(new PrivateData_t(ddim))
345 my->addComponent(expression_string);
350 const std::string & expression_string2,
352 : my(new PrivateData_t(ddim))
354 my->addComponent(expression_string1);
355 my->addComponent(expression_string2);
360 const std::string & expression_string2,
361 const std::string & expression_string3,
363 : my(new PrivateData_t(ddim))
365 my->addComponent(expression_string1);
366 my->addComponent(expression_string2);
367 my->addComponent(expression_string3);
372 const std::string & expression_string2,
373 const std::string & expression_string3,
374 const std::string & expression_string4,
376 : my(new PrivateData_t(ddim))
378 my->addComponent(expression_string1);
379 my->addComponent(expression_string2);
380 my->addComponent(expression_string3);
381 my->addComponent(expression_string4);
386 const std::string & expression_string2,
387 const std::string & expression_string3,
388 const std::string & expression_string4,
389 const std::string & expression_string5,
390 const std::string & expression_string6,
391 const std::string & expression_string7,
392 const std::string & expression_string8,
393 const std::string & expression_string9,
395 : my(new PrivateData_t(ddim))
397 my->addComponent(expression_string1);
398 my->addComponent(expression_string2);
399 my->addComponent(expression_string3);
400 my->addComponent(expression_string4);
401 my->addComponent(expression_string5);
402 my->addComponent(expression_string6);
403 my->addComponent(expression_string7);
404 my->addComponent(expression_string8);
405 my->addComponent(expression_string9);
411 : my(new PrivateData_t(ddim))
413 for (
size_t i = 0; i!= expression_string.size(); ++i)
414 my->addComponent(expression_string[i]);
420 my =
new PrivateData_t(*other.my);
422 #if EIGEN_HAS_RVALUE_REFERENCES
427 my = other.my; other.my = NULL;
431 gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(
const gsFunctionExpr& other)
436 my =
new PrivateData_t(*other.my);
442 gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(gsFunctionExpr&& other)
447 my = other.my; other.my = NULL;
454 gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(gsFunctionExpr other)
456 std::swap(my,other.my);
462 gsFunctionExpr<T>::~gsFunctionExpr()
476 return static_cast<short_t>(my->string.size());
482 my->addComponent(strExpression);
488 return my->string[i];
515 GISMO_ASSERT ( u.rows() == my->dim,
"Inconsistent point dimension (expected: "
516 << my->dim <<
", got "<< u.rows() <<
")\n"<< *
this);
519 result.resize(n, u.cols());
521 #pragma omp critical (gsFunctionExpr_run)
522 for (
index_t p = 0; p!=u.cols(); p++ )
524 copy_n(u.col(p).data(), my->dim, my->vars);
526 for (
short_t c = 0; c!= n; ++c)
527 # ifdef GISMO_WITH_ADIFF
528 result(c,p) = my->expression[c].value().getValue();
530 result(c,p) = my->expression[c].value();
538 GISMO_ASSERT ( u.rows() == my->dim,
"Inconsistent point dimension (expected: "
539 << my->dim <<
", got "<< u.rows() <<
")");
542 "Given component number is higher then number of components");
544 result.resize(1, u.cols());
545 # pragma omp critical (gsFunctionExpr_run)
546 for (
index_t p = 0; p!=u.cols(); ++p )
548 copy_n(u.col(p).data(), my->dim, my->vars);
550 # ifdef GISMO_WITH_ADIFF
551 result(0,p) = my->expression[comp].value().getValue();
553 result(0,p) = my->expression[comp].value();
563 GISMO_ASSERT ( u.rows() == my->dim,
"Inconsistent point dimension (expected: "
564 << my->dim <<
", got "<< u.rows() <<
")");
567 result.resize(d*n, u.cols());
568 # pragma omp critical (gsFunctionExpr_run)
569 for (
index_t p = 0; p!=u.cols(); p++ )
571 # ifdef GISMO_WITH_ADIFF
573 my->vars[k].setVariable(k,d,u(k,p));
574 for (
short_t c = 0; c!= n; ++c)
575 my->expression[c].value().gradient_into(result.block(c*d,p,d,1));
578 copy_n(u.col(p).data(), my->dim, my->vars);
579 for (
short_t c = 0; c!= n; ++c)
580 for (
short_t j = 0; j!=d; j++ )
582 exprtk::derivative<T>(my->expression[c], my->vars[j], 0.00001 ) ;
591 GISMO_ASSERT ( u.rows() == my->dim,
"Inconsistent point dimension (expected: "
592 << my->dim <<
", got "<< u.rows() <<
")");
595 const index_t stride = d + d*(d-1)/2;
596 result.resize(stride*n, u.cols() );
597 # pragma omp critical (gsFunctionExpr_run)
598 for (
index_t p = 0; p!=u.cols(); p++ )
600 # ifndef GISMO_WITH_ADIFF
601 copy_n(u.col(p).data(), my->dim, my->vars);
604 for (
short_t c = 0; c!= n; ++c)
606 # ifdef GISMO_WITH_ADIFF
608 my->vars[v].setVariable(v,d,u(v,p));
609 const DScalar & ads = my->expression[c].value();
610 const DScalar::Hessian_t & Hmat = ads.getHessian();
614 result(k,p) = Hmat(k,k);
617 result(m++,p) = Hmat(k,l);
623 result(k,p) = exprtk::
624 second_derivative<T>(my->expression[c], my->vars[k], 0.00001);
631 mixed_derivative<T>( my->expression[c], my->vars[k],
632 my->vars[l], 0.00001 );
646 GISMO_ASSERT ( u.cols() == 1,
"Need a single evaluation point." );
648 GISMO_ASSERT ( u.rows() == my->dim,
"Inconsistent point dimension (expected: "
649 << my->dim <<
", got "<< u.rows() <<
")");
653 # pragma omp critical (gsFunctionExpr_run)
655 # ifdef GISMO_WITH_ADIFF
657 my->vars[v].setVariable(v, d, u(v,0) );
658 my->expression[coord].value().hessian_into(res);
660 copy_n(u.data(), my->dim, my->vars);
664 second_derivative<T>( my->expression[coord], my->vars[j], 0.00001);
666 for(
index_t k = 0; k!=j; ++k )
667 res(k,j) = res(j,k) =
668 mixed_derivative<T>( my->expression[coord], my->vars[k],
669 my->vars[j], 0.00001 );
681 GISMO_ASSERT ( u.rows() == my->dim,
"Inconsistent point size.");
685 # pragma omp critical (gsFunctionExpr_run)
686 for(
index_t p=0; p!=res->cols(); ++p )
688 # ifndef GISMO_WITH_ADIFF
689 copy_n(u.col(p).data(), my->dim, my->vars);
692 for (
short_t c = 0; c!= n; ++c)
694 # ifdef GISMO_WITH_ADIFF
695 for (
index_t v = 0; v!=my->dim; ++v)
696 my->vars[v].setVariable(v, my->dim, u(v,p) );
697 (*res)(c,p) = my->expression[c].value().getHessian()(k,j);
700 mixed_derivative<T>( my->expression[c], my->vars[k], my->vars[j], 0.00001 ) ;
711 GISMO_ASSERT ( u.rows() == my->dim,
"Inconsistent point size.");
715 # pragma omp critical (gsFunctionExpr_run)
716 for(
index_t p = 0; p != res.cols(); ++p )
718 # ifndef GISMO_WITH_ADIFF
719 copy_n(u.col(p).data(), my->dim, my->vars);
722 for (
short_t c = 0; c!= n; ++c)
724 # ifdef GISMO_WITH_ADIFF
725 for (
index_t v = 0; v!=my->dim; ++v)
726 my->vars[v].setVariable(v, my->dim, u(v,p) );
727 res(c,p) = my->expression[c].value().getHessian().trace();
730 for (
index_t j = 0; j!=my->dim; ++j )
732 second_derivative<T>( my->expression[c], my->vars[j], 0.00001 );
743 if( my->string.empty() )
749 for (
short_t k = 1; k<targetDim(); ++k)
750 os <<
", " << my->string[k];
765 typedef gsFunctionExpr<T> Object;
767 GSXML_COMMON_FUNCTIONS(Object);
768 static std::string tag () {
return "Function"; }
769 static std::string type () {
return "FunctionExpr"; }
771 GSXML_GET_POINTER(Object);
773 static void get_into (gsXmlNode * node, Object & obj)
775 GISMO_ASSERT( node->first_attribute(
"dim"),
"Reading gsFunctionExpr XML: No dim found" ) ;
776 const int d = atoi( node->first_attribute(
"dim")->value() );
778 std::vector< std::string > expr_strings;
780 gsXmlNode * child = node->first_node(
"c");
784 for (; child; child = child->next_sibling() )
785 expr_strings.push_back( child->value() );
788 expr_strings.push_back( node->value() );
790 obj = gsFunctionExpr<T>( expr_strings, d );
793 static gsXmlNode * put (
const Object & obj,
796 gsXmlNode * func =
makeNode(
"Function", data);
797 func->append_attribute(
makeAttribute(
"dim", obj.domainDim(), data));
798 func->append_attribute(
makeAttribute(
"type",
"FunctionExpr", data));
800 const short_t tdim = obj.targetDim();
804 func->value(
makeValue(obj.expression(), data) );
809 for (
short_t c = 0; c!=tdim; ++c)
811 cnode =
makeNode(
"c", obj.expression(c), data);
812 func->append_node(cnode);
gsMatrix< T > laplacian(const gsMatrix< T > &u) const
Evaluate the Laplacian at points u.
Definition: gsFunctionExpr.hpp:708
virtual void eval_component_into(const gsMatrix< T > &u, const index_t comp, gsMatrix< T > &result) const
Evaluate the function for component comp in the target dimension at points u into result...
Definition: gsFunctionExpr.hpp:536
virtual void deriv2_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate second derivatives of the function at points u into result.
Definition: gsFunctionExpr.hpp:588
virtual void deriv_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate derivatives of the function at points u into result.
Definition: gsFunctionExpr.hpp:559
void set_z(T const &v) const
Sets the symbol "z" to a value.
Definition: gsFunctionExpr.hpp:498
short_t targetDim() const
Dimension of the target space.
Definition: gsFunctionExpr.hpp:474
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
#define short_t
Definition: gsConfig.h:35
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the function at points u into result.
Definition: gsFunctionExpr.hpp:513
void set_u(T const &v) const
Sets the symbol "u" to a value.
Definition: gsFunctionExpr.hpp:504
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
void string_replace(std::string &str, const std::string &oldStr, const std::string &newStr)
Replaces appearance of oldStr with newStr inside the string str.
Definition: gsUtils.h:171
void addComponent(const std::string &strExpression)
Adds another component to this (vector) function.
Definition: gsFunctionExpr.hpp:480
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
index_t size() const
size
Definition: gsFunction.h:295
void set_y(T const &v) const
Sets the symbol "y" to a value.
Definition: gsFunctionExpr.hpp:495
Provides an exprtk adaptor for the Unum Posit arithmetic type.
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void set_v(T const &v) const
Sets the symbol "v" to a value.
Definition: gsFunctionExpr.hpp:507
gsMatrix< T > * mderiv(const gsMatrix< T > &u, const index_t k, const index_t j) const
Mixed derivative wrt variables k and j.
Definition: gsFunctionExpr.hpp:677
#define gsWarn
Definition: gsDebug.h:50
short_t domainDim() const
Dimension of the (source) domain.
Definition: gsFunctionExpr.hpp:468
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition: gsXml.cpp:37
void copy_n(T begin, const size_t n, U *result)
Small wrapper for std::copy mimicking memcpy (or std::copy_n) for a raw pointer destination, copies n positions starting from begin into result. The latter is expected to have been allocated in advance.
Definition: gsMemory.h:368
Provides an exprtk adaptor for the Unum Posit arithmetic type.
void set_t(T const &t) const
Sets the symbol "t" to a value.
Definition: gsFunctionExpr.hpp:510
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition: gsXml.cpp:54
void set_x(T const &v) const
Sets the symbol "x" to a value.
Definition: gsFunctionExpr.hpp:492
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsFunctionExpr.hpp:740
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition: gsXml.cpp:32
Class defining a multivariate (real or vector) function given by a string mathematical expression...
Definition: gsFunctionExpr.h:51
This is the main header file that collects wrappers of Eigen for linear algebra.
gsFunctionExpr()
Default empty constructor.
Definition: gsFunctionExpr.hpp:338
Provides declaration of input/output XML utilities struct.
void set_w(T const &v) const
Sets the symbol "w" to a value.
Definition: gsFunctionExpr.hpp:501