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)
116T 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 );
178template<
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;
431gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(
const gsFunctionExpr& other)
436 my =
new PrivateData_t(*other.my);
442gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(gsFunctionExpr&& other)
447 my = other.my; other.my = NULL;
454gsFunctionExpr<T> & gsFunctionExpr<T>::operator=(gsFunctionExpr other)
456 std::swap(my,other.my);
462gsFunctionExpr<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(c*stride + k,p) = Hmat(k,k);
617 result(c*stride + m++,p) = Hmat(k,l);
623 result(c*stride + k,p) = exprtk::
624 second_derivative<T>(my->expression[c], my->vars[k], 0.00001);
630 result(c*stride + m++,p) =
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);
Class defining a multivariate (real or vector) function given by a string mathematical expression.
Definition gsFunctionExpr.h:52
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
gsMatrix< T > laplacian(const gsMatrix< T > &u) const
Evaluate the Laplacian at points u.
Definition gsFunctionExpr.hpp:708
void set_w(T const &v) const
Sets the symbol "w" to a value.
Definition gsFunctionExpr.hpp:501
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
void addComponent(const std::string &strExpression)
Adds another component to this (vector) function.
Definition gsFunctionExpr.hpp:480
void set_v(T const &v) const
Sets the symbol "v" to a value.
Definition gsFunctionExpr.hpp:507
short_t targetDim() const
Dimension of the target space.
Definition gsFunctionExpr.hpp:474
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_z(T const &v) const
Sets the symbol "z" to a value.
Definition gsFunctionExpr.hpp:498
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
short_t domainDim() const
Dimension of the (source) domain.
Definition gsFunctionExpr.hpp:468
void set_u(T const &v) const
Sets the symbol "u" to a value.
Definition gsFunctionExpr.hpp:504
void set_x(T const &v) const
Sets the symbol "x" to a value.
Definition gsFunctionExpr.hpp:492
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
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition gsFunctionExpr.hpp:740
void set_t(T const &t) const
Sets the symbol "t" to a value.
Definition gsFunctionExpr.hpp:510
void set_y(T const &v) const
Sets the symbol "y" to a value.
Definition gsFunctionExpr.hpp:495
gsFunctionExpr()
Default empty constructor.
Definition gsFunctionExpr.hpp:338
index_t size() const
size
Definition gsFunction.h:295
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
Provides an exprtk adaptor for CoDiPack arithmetic types of autodiff.
Provides an exprtk adaptor for the Unum Posit arithmetic type.
Provides an exprtk adaptor for the Unum Posit arithmetic type.
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
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
#define gsWarn
Definition gsDebug.h:50
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
This is the main header file that collects wrappers of Eigen for linear algebra.
Provides declaration of input/output XML utilities struct.
char * makeValue(const std::string &value, gsXmlTree &data)
Helper to allocate XML value.
Definition gsXml.cpp:32
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition gsXml.cpp:54
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition gsXml.cpp:37
The G+Smo namespace, containing all definitions for the library.
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,...
Definition gsMemory.h:368