Automatic Differentiation of functions of complex variables - c++

I was wondering if it is possible to apply boost's automatic differentiation library:
#include <boost/math/differentiation/autodiff.hpp>
to functions which return std::complex<double> values?
For instance, consider the multivariate complex valued function:
#include <complex>
std::complex<double> complex_function(double a, double c){
// Assuming a < 0
return exp(sqrt(std::complex(a, 0.0))) + sin(c);
}
How can I take the derivative wrt to a or c using Boost's autodiff? Is that even possible?

is [it] possible to apply boost's automatic differentiation library to functions which return std::complex<double> values?
Not at the present time.
A version that did might look something like this:
// THIS DOES NOT COMPILE - FOR DISCUSSION ONLY
#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>
#include <complex>
namespace ad = boost::math::differentiation;
template <typename T0, typename T1>
auto complex_function(T0 a, T1 c){
// Assuming a < 0
return exp(sqrt(complex(a, 0.0))) + sin(c); // DOES NOT COMPILE
}
int main() {
auto const a = ad::make_fvar<double, 2>(-3);
auto const c = 0.0;
auto const answer = complex_function(a, c);
return 0;
}
This requires complex to be defined specific to autodiff::fvar template types, similar to how other mathematical functions (exp, sqrt, etc.) have overloads in the autodiff library, and are called via ADL.
As #user14717 pointed out in the comments, it is a special case of vector-valued autodiff since the return value isn't a single truncated Taylor polynomial, but rather a tuple of them.

Related

How to define the function composition in c++17?

I would like to compute the function composition -- f ( g (param) ). Here is what I tried:
auto fComposition(auto&& f, auto&& g, auto&&... params)
{
/* some stuff */
auto result = std::forward<decltype(f)>(f)(
std::forward<decltype(g)>(g)(
std::forward<decltype(params)>(param)
)
);
/* other stuff */
return result;
};
Compiling with
g++ -std=c++17 src.cpp
basic test
#include <random>
#include <math.h>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> distr(-1.0, 1.0);
auto xx = fComposition(round, distr, gen);
return 0;
}
I've got the message that it doesn't recognize the type of first function .
BTW, is this really your code? You're not expanding params so it should not compile.
I. The way you define composition, it is indistinguishable from a simple invocation: your fComposition(f, g, arg) is the same as f(g(arg)) except for extra characters typing. The real composition is usually a combinator that accepts two functions and returns a closure that, when invoked on actual arguments, applies them in succession. Something like:
template<class F, class G> auto comp(F f, G g) {
return [f, g](auto &&... args) {
return f(g(std::forward<decltype(args)>(args)...));
};
}
(Note by-values bindings. In C++17, they are more advanced than twenty years ago. :) You can add std::moves and std::forwards by taste.)
This way you compose two functions:
auto fg = comp(f, g);
and later invoke the result on arguments:
auto x = fg(arg1, arg2);
II. But really, why limit ourselves with two operands? In Haskell, (.) is a single binary function. In C++, we can have a whole tree of overloads:
template<class Root, class... Branches> auto comp(Root &&root, Branches &&... branches) {
return [root, branches...](auto &&...args) {
return root(branches(std::forward<decltype(args)>(args)...)...);
};
}
Now you can encapsulate any AST in a single callable:
int f(int x, int y) { return x + y; }
int g(int x) { return x * 19; }
int h(int x) { return x + 2; }
#include <iostream>
int main() {
auto fgh = comp(f, g, h);
std::cout << fgh(2) << '\n';
}
A similar technique was the only way known to me to have anonymous closures in C++ prior to 11 standard.
III. But wait, is there a library solution? In fact, yes. From std::bind's description
If the stored argument arg is of type T for which std::is_bind_expression<T>::value == true (for example, another bind expression was passed directly into the initial call to bind), then bind performs function composition: instead of passing the function object that the bind subexpression would return, the subexpression is invoked eagerly, and its return value is passed to the outer invokable object. If the bind subexpression has any placeholder arguments, they are shared with the outer bind (picked out of u1, u2, ...). Specifically, the argument vn in the std::invoke call above is arg(std::forward<Uj>(uj)...) and the type Vn in the same call is std::result_of_t<T cv &(Uj&&...)>&& (cv qualification is the same as that of g).
Sorry, no examples here at this moment. >_<
P.S. And yes, std::round is an overloaded function so you should typecast it to specify which exactly overload you need to be composed.
The include of random includes cmath, which in libstdc++ also defines several of the math operators (including round) in the default namespace as well as in the std namespace. (See this answer for the rationale.) And C++'s round has multiple overloads. As a result, you have several versions of round available, and your function doesn't know which round you want to use, thus the error message about ambiguity. The correct solution is to disambiguate which round you mean. You can do this with a static cast:
static_cast<double(*)(double)>(round)
Since you have to go through the trouble anyway, you may as well also use the cmath header instead of math.h and use std::round instead. At least then you know that it's going to be overloaded up front.

Eigen binaryExpr with eigen type output

I'm having a problem while trying to use binaryExpr. It is the first use I'm making of it so I have been following the Eigen documentation
For my use I need a functor with Eigen type inputs and outputs but this does not want to compile and I do not understand why. I've looked up the explanation in the code but I didn't think this would apply here because I use floats and an array of floats
// We require Lhs and Rhs to have "compatible" scalar types.
// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
// add together a float matrix and a double matrix.
Here is a short example of the use I would need that gets me the same compilation error:
#include <eigen3/Eigen/Dense>
using namespace std;
using namespace Eigen;
struct myBinaryFunctor {
EIGEN_EMPTY_STRUCT_CTOR(myBinaryFunctor)
typedef Vector2f result_type;
Vector2f operator()(const Matrix<float,9,1>& a,const float& f) const
{
float x = a.head(4).sum()*f;
float y = a.tail(5).sum()/f;
return Vector2f(x,y);
}
};
int main()
{
constexpr int n = 3;
Matrix<Matrix<float,9,1>,n,n> Ma;
Matrix<float,n,n> F;
Matrix<Vector2f,n,n> R;
for(size_t i = 0, sizeMa = Ma.size(); i<sizeMa; i++)
{
Ma(i).setOnes();
}
F.setConstant(n,n,2);
R = Ma.binaryExpr(F,myBinaryFunctor());
return 0;
}
The compilation output is :
/usr/local/include/eigen3/Eigen/src/Core/CwiseBinaryOp.h:107: erreur : static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
^
If you have a solution that could make this work this would be a huge help for me :) If not I would still enjoy an explanation to understand what is happening. Thanks a lot.
Adding:
namespace Eigen {
template<>
struct ScalarBinaryOpTraits<Matrix<float,9,1>,float,myBinaryFunctor> {
typedef Vector2f ReturnType;
};
}
will do the job. This is because implicit scalar conversion are explicitly disallowed within Eigen, so you must explicit say that two different scalar types are compatible. For instance adding a VectorXd to a VectorXf is disallowed.
Nonetheless, it seems to me that your abusing Eigen's features here.

Pass #define content as parameter

I have a long algorithm that should process some instruction described from more than one #define in order to reduce drastically my source-code. For example:
#define LongFunction(x, y, alg) return alg(x, y)
#define Alg1(x, y) ((x)+(y))
#define Alg2(x, y) ((x)^((x)-(y)))
And all I need to do is
LongFunction(x, y, Alg1);
LongFunction(x, y, Alg2);
I'd like to not pass a function as parameter because LongFunction is full of loops and I want that the code will be as fast as possible. How can I accomplish this task smartly?
There are many ways to parameterize on function.
Using macros might seem simple, but macros don't respect scopes, and there are problems with parameter substitution and side-effects, so they're Evil™.
In C++11 and later the most natural alternative is to use std::function and lambdas, like this:
#include <functional> // std::function
#include <math.h> // pow
using std::function;
auto long_function(
double const x,
double const y,
function<auto(double, double) -> double> alg
)
-> double
{
// Whatever.
return alg( x, y ); // Combined with earlier results.
}
auto alg1(double const x, double const y)
-> double
{ return x + y; }
auto alg2(double const x, double const y)
-> double
{ return pow( x, x - y ); }
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function( 3, 5, alg1 ) << endl;
}
Regarding “fast as possible”, with a modern compiler the macro code is not likely to be faster. But since this is important, do measure. Only measurements, for release build and in the typical execution environment, can tell you what's fastest and whether the speed is relevant to the end user.
Of old, and formally, you could use the inline specifier to hint to the compiler that it should machine code inline calls to a function. Modern compilers are likely to just ignore inline for this (it has another more guaranteed meaning wrt. ODR). But it probably won't hurt to apply it. Again, it's important to measure. And note that results can vary with compilers.
One alternative to the above is to pass a simple function pointer. That might be faster than std::function, but is less general. However, in the other direction, you can templatize on a type, with a member function, and that gives the compiler more information, more opportunity to inline, at the cost of not being able to e.g. select operations from array at runtime. I believe that when you measure, if this is important enough, you'll find that templatization yields fastest code. Or at least as fast as the above.
Example of templatizing on a type that provides the operation:
#include <math.h> // pow
template< class Op >
auto long_function( double const x, double const y )
-> double
{
// Whatever.
return Op()( x, y ); // Combined with earlier results.
}
struct Alg1
{
auto operator()(double const x, double const y)
-> double
{ return x + y; }
};
struct Alg2
{
auto operator()(double const x, double const y)
-> double
{ return pow( x, x - y ); }
};
#include <iostream>
using namespace std;
auto main() -> int
{
cout << long_function<Alg1>( 3, 5 ) << endl;
}
By the way, note that ^ is not an exponentiation operator in C++ (it is in e.g. Visual Basic). In C and C++ it's a bitlevel XOR operator. In the code above I've assumed that you really meant exponentiation, and used the pow function from <math.h>.
If, instead, you really meant bitlevel XOR, then the arguments would need to be integers (preferably unsigned integers), which then would indicate that you want argument types for long_function depending on the argument types for the specified operation. That's more thorny issue, but involves either overloading or templating, or both. If that's what you really want then please do elaborate on that.

Composite function with std::bind2nd in C++03

I would like to get some function/functor acts as a composite function/functor:
Specifically, I have functions f(x, y), and g(u, v), and I want to create a function pointer or functor h(t) = f(g(t,C1), C2), so that I can pass functor h into a for_each() loop, where C1, C2 are some constants.
Or, let's do it in my real example:
I have a function double g(T1 u, T2 v) which calculate something. I want to loop through all u from a vector vector<T1> vecInput, with fixed 2nd argument t2VConst. After calculating all these numbers, I want to save them into a vector vector<double> results.
I would like to do it with something similar to this:
foreach(vecInput.begin(), vecInput.end(), std::bind2nd(&results::push_back, std::bind2nd(g, t2VConst)))
Note that in this case, the f(x,y) function is really a member function vector::push_back. (It seems that push_back only have one argument. However, as a member function, it has an extra argument, which is the object itself.)
To make the case worse, I really have to do it in C++03, not C++11. Is there any solution? Moreover, I wish the solution can be cleaner (if it can be done in one line like above).
UPDATE
Related issue for bind2nd():
I got compile error, and now I reduce it to a simpler code to look at it:
#include <functional>
#include <algorithm>
#define CASE2 // choose define of CASE1 to CASE3
#ifdef CASE1
double g(double x, double y) // 1. OK
#endif
#ifdef CASE2
double g(double &x, double y) // 2. overload error
#endif
#ifdef CASE3
double g(double *x, double y) // 3. OK
#endif
{
#ifdef CASE2
x = 5.0;
#endif
#ifdef CASE3
*x = 5.0;
#endif
// Note: no case1, since in case 1, x is a local variable,
// no meaning to assign value to it.
return 3.0;
}
int main(int argc, char *argv[])
{
double t = 2.0;
double u;
#if defined(CASE1) || defined(CASE2)
u = std::bind2nd(std::ptr_fun(&g), 3.0)(t);
#endif
#ifdef CASE3
u = std::bind2nd(std::ptr_fun(&g), 3.0)(&t);
#endif
}
I don't know why CASE 2 fails...
I have functions f(x, y), and g(u, v), and I want to create a function pointer or functor h(t) = f(g(t,C1), C2). I have to do it in C++03.
It's not possible to compose functions using only the adapters available in the standard library of C++03. Obviously, nothing stops you from implementing this functionality on your own. However, if you want to utilize any of the existing libraries, and get a true one-liner, there are few alternatives:
Option #1: SGI extensions
libstdc++ is shipped with the standard library extensions from SGI. It provides several additional adapters and functors, namely: compose1, compose2 and constant1. They can be combined in the following way:
#include <functional>
#include <ext/functional>
int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;
__gnu_cxx::compose2(std::ptr_fun(&f)
, std::bind2nd(std::ptr_fun(&g), C1)
, __gnu_cxx::constant1<int>(C2)
)(arg);
Option #2: TR1 extensions
The initial implementation of C++11's std::bind can be also found in tr1 extension libraries:
#include <tr1/functional>
int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;
std::tr1::bind(&f
, std::tr1::bind(&g
, std::tr1::placeholders::_1
, C1)
, C2
)(arg);
Option #3: Boost library
Boost.Bind library is probably the most portable solution:
#include <boost/bind.hpp>
int f(int x, int y);
int g(int u, int v);
const int arg = 1;
const int C1 = 2;
const int C2 = 3;
boost::bind(&f, boost::bind(&g, _1, C1), C2)(arg);
The f(x,y) function is really a member function vector::push_back
When it comes to binding a member function in C++03 you would normally use std::mem_fun together with std::bind1st to bind the object parameter:
Class object;
std::bind1st(std::mem_fun(&Class::func), &object)(arg);
However, this will fail for member functions taking its parameter by reference. Once again, you could use Boost/TR1 instead:
boost::bind(&std::vector<double>::push_back
, &results
, boost::bind(&g, _1, C1)
)(arg);
Note that when switching to C++11 you'd need to manually resolve overloaded std::vector<double>::push_back.
But fortunately, your use-case qualifies to be replaced by std::transform algorithm with std::back_inserter, that will take care of calling push_back member function of your vector for transformed arguments.
#include <algorithm>
#include <functional>
#include <iterator>
int g(int u, int v);
const int C1 = 2;
std::vector<int> input, output;
std::transform(input.begin(), input.end()
, std::back_inserter(output)
, std::bind2nd(std::ptr_fun(&g), C1));
DEMO
It's important to remember that these library functions aren't magic, they just deduce rather involved types.
In your case, you don't need all this flexibility, if only because you know you'll need vector::push_back. Instead of deducing a rather involved type, just create a type explicitly to capture the function. There's even a library type which does this, std::back_insert_iterator, but in general you can do it yourself.
So, you'll end up with a template class that takes typenames T1 and T2, stores &g, T2 C2, and std::vector<double>&. It simply implements void operator()(T1 t1) { v.pus_back(g(t1, C2)); }.

add subtract multiply and divide template functions

I am trying to find template functions that do:
template <typename T>
T add(T lhs, T rhs) {
return lhs + rhs;
}
(for add, subtract, multiply, and divide).
I remember there being a standard set of functions for this-- do you remember what they are?
In the header <functional>, you'll find things like std::plus, std::minus, std::multiplies, and std::divides.
They're not functions, either. They're actually functors.
You need functors such as std::plus from the <functional> header. See Arithmetic operations here.
These are functors, not functions, so you need an instance to do anything useful:
#include <functional>
#include <iostream>
int main() {
std::multiplies<int> m;
std::cout << m(5,3) << "\n";
}
This seems like overkill in the above sample, but they are pretty useful with standard library algorithms. For example, find the product of elements in a vector:
std::vector<int> v{1,2,3,4,5,6};
int prod = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());