diff --git a/dune/fufem/test/dunepythontest.cc b/dune/fufem/test/dunepythontest.cc index 19a369142cedd8bea2b6e0a152980c529818db15..aa05e723031e8f34b382487a130d084283c268a5 100644 --- a/dune/fufem/test/dunepythontest.cc +++ b/dune/fufem/test/dunepythontest.cc @@ -718,16 +718,13 @@ int main(int argc, char** argv) } std::cout << std::endl; - std::cout << "Example 16: Creating Dune-functions functions manually *************************" << std::endl; + std::cout << "Example 16: Creating Dune-functions functions **********************************" << std::endl; { - // Functions implementing the interface in dune-functions can also be created manually - // - // it is also possible to import dictionaries of callable - // python objects into a map of functions. + // Functions implementing the interface in dune-functions can also be created + // directly using Domain = Dune::FieldVector<double, 3>; using Range = Dune::FieldVector<double, 2>; - using DerivativeRange = Dune::Functions::DefaultDerivativeTraits<Range(Domain)>::Range; pyMain.import("math"); pyMain.runStream() @@ -738,16 +735,29 @@ int main(int argc, char** argv) << std::endl << "fdf = (f, df)" << std::endl; - auto pyF = Python::Callable(pyMain.get("f")); - auto pyDF = Python::Callable(pyMain.get("df")); - - auto f = makeDifferentiableFunctionFromCallables( - Dune::Functions::SignatureTag<Range(Domain)>(), - [=](auto&& x) { return pyF(x).template toC<Range>();}, - [=](auto&& x) { return pyDF(x).template toC<DerivativeRange>();}); + // makeDifferentiableFunction automatically converts to Python::Callable + auto f = Python::makeDifferentiableFunction<Range(Domain)>(pyMain.get("f"), pyMain.get("df")); std::cout << "Result of calling a function FV<double,2>(FV<double,3>) : " << f({1, 2, 3}) << std::endl; std::cout << "Result of calling the derivative of a function FV<double,2>(FV<double,3>) : " << derivative(f)({1, 2, 3}) << std::endl; + + // functions can also be cretaed from labda expressions + auto pyG = Python::evaluate("lambda x: math.sin(x)"); + auto pyDG = Python::evaluate("lambda x: math.cos(x)"); + auto pyDDG = Python::evaluate("lambda x: -math.sin(x)"); + auto pyDDDG = Python::evaluate("lambda x: -math.cos(x)"); + + auto g = Python::makeDifferentiableFunction<double(double)>(pyG, pyDG, pyDDG, pyDDDG, pyG); + + std::cout << "Result of calling a function double(double) : " << g(0) << std::endl; + std::cout << "Result of calling the derivative of a function double(double) : " << derivative(g)(0) << std::endl; + std::cout << "Result of calling the 2nd derivative of a function double(double) : " << derivative(derivative(g))(0) << std::endl; + std::cout << "Result of calling the 3rd derivative of a function double(double) : " << derivative(derivative(derivative(g)))(0) << std::endl; + std::cout << "Result of calling the 4rd derivative of a function double(double) : " << derivative(derivative(derivative(derivative(g))))(0) << std::endl; + + // If you only need the function but no derivatives, you can also use makeFunction() + auto h = Python::makeFunction<double(double)>(Python::evaluate("lambda x: x*x")); + std::cout << "Result of calling a function double(double) : " << h(0.5) << std::endl; } // Before exiting you should stop the python interpreter.