Is there a way to compound functions in C++? - c++

General question :
If there are two objects A and B with respective functions f_A(arg list) and f_B(arg list).
What's the best way to create an object C with a function compounded of f_A(...) and f_B(...) ?
for example : f_C() = f_A() + f_B() or f_C() = f_A(f_B())
Is it possible to overload the "+" operator such that we can create the object C doing something like that ?
auto object_c = object_a + object_b
Here is a sample of my code :
class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double X,
double Y
)
{
double result;
result = m_scale * exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;
}
GaussianKernel operator+(const GaussianKernel& b) {
/*Here I would like to overload the + operator such that
I can create a kernel from two others kernels,
I mean with a covariance function compound of the previous ones
*/
}
private:
double m_sigma;
double m_scale;
};
Thanks you.

Given two methods f_A and f_B you can get f_C returning the sum of the others by using for example a lambda:
auto f_C = [](/*param*/){ return f_A(/*param*/) + f_B(/*param*/); };
auto sum_result = f_C(param);
To get the compound method it would be this:
auto f_C = [](/*param*/){ return f_B( f_A(/*param*/)); };
auto compound_result = f_C(param);
PS: I know that this is not directly applicable to your example, still trying to find out what exactly you want to do.

I would start with prototype solution like this:
class FooKernel : public Kernel {
public:
FooKernel (std::function<double(double, double)> fun) : fun_(fun) {}
double covarianceFunction(
double X,
double Y
) const {
return fun_(X, Y);
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
std::function<double(double, double)> fun_;
};
class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double X,
double Y
) const
{
double result;
result = m_scale * exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
double m_sigma;
double m_scale;
};
No longer lambdas are used, but now uses Your function as You wished.
Later on I would try to remove the std::function as it may have quite big performance impact. Instead I would make the FooKernel a class template, that stores callable by value.

I would suggest another subclass of Kernel:
class CompoundGaussianKernel : public Kernel {
public:
CompoundGaussianKernel(GaussianKernel const& kernel1, GaussianKernel const& kernel2)
: m_kernel1(kernel1), m_kernel2(kernel2)
{}
double covarianceFunction(double X, double Y)
{
return m_kernel1.covarianceFunction(X, Y) + m_kernel2.covarianceFunction(X, Y);
// or any other composition than "+"
}
private:
GaussianKernel m_kernel1;
GaussianKernel m_kernel2;
};
I recommend not to define operator+ inside of a class but as a free function.
CompoundGaussianKernel operator+(GaussianKernel const& kernel1, GaussianKernel const& kernel2)
{
return CompoundGaussianKernel(kernel1, kernel2);
}

Related

c++ avoid code duplication operator overloading

My Question is the following, let's say I have this classes:
class ID3OBJ
{
public:
const double X;
const double Y;
const double Z;
ID3OBJ(double x, double y, double z);
ID3OBJ();
const ID3OBJ operator+ (const ID3OBJ param) const;
}
class Vector : public ID3OBJ
{
public:
Vector(double x, double y, double z);
Vector();
/*const Vector const operator+ (const Vector param); */
}
class Point : public ID3OBJ
{
public:
Point(double x, double y, double z);
Point();
}
class Plane : public ID3OBJ
{
public:
Point Origin;
Vector Direction1;
Vector Direction2;
Vector NormalVector;
Plane(Point Origin, Vector Normalvector);
Plane(Point Origin, Vector Direction1, Vector Direction2);
Plane();
}
class D3GON : public ID3OBJ, public Plane
{
public:
std::vector<Point> EdgePoints;
D3GON(Point P1, Point P2, Point P3);
};
In my current code I have to redefine the operator overload for each class, how can I avoid this code-duplication?
Do I have to add convert-functions?
I use const member-values, to deny objects changes after creation. Meaning if any low-level object has to be changed it has to be replaced by a new one. See my operator overload below:
// operator overwrites:
const ID3OBJ ID3OBJ::operator+ (const ID3OBJ param) const { double newX, newY, newZ; newX = X + param.X; newY = Y + param.Y; newZ = Z + param.Z; return ID3OBJ(newX, newY, newZ); }
Thank you :)
The Curiously recurring template pattern is the way to go here. It is slightly more complex because you want multiple derivation levels. But here is a code example:
template <class T>
class ID3OBJ
{
public:
double X,Y,Z;
T operator+(const T& obj) const {
T t;
t.X = X + obj.X;
t.Y=Y+obj.Y;
t.Z=z+obj.Z;
return t;
}
};
class Vector : public ID3OBJ<Vector>
{
public:
// some stuff
};
class Point : public Vector, public ID3OBJ<Point>
{
public:
// X, Y and Z exist twice, once in Vector, once in ID3OBJ<Point>, so we must disambiguate
using ID3OBJ<Point>::X;
using ID3OBJ<Point>::Y;
using ID3OBJ<Point>::Z;
};
You can add Vector (and you'll get Vector) or just Point and you'll get Point. More interestingly, if you add Point and Vector, you get an Vector result because the overloaded operator + resolution will select Vector::operator +

Make a c++ class work with generic user defined inputs

I feel like this question must have been asked before but I couldn't find an answer from poking around on google. If it has please direct me to a link and I will remove this post.
Consider this minimal example that represents a larger problem I have. Say I created a simple "Point" and "Printer" class like so:
class Point {
public:
double x, y;
Point() {x = y = 0;}
Point(double x, double y) {
this->x = x; this->y = y;
}
};
template<typename T>
class Printer {
public:
T* mData;
int mSize;
// Constructor
Printer(std::vector<T> &input) {
mData = &input[0];
mSize = input.size();
}
// Simple Print function
void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
const T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, item.x, item.y);
}
}
};
I could use the printer class like this:
std::vector<Point> points; // fill the vector, and then...
Printer<Point> pointsPrinter(points); pointsPrinter.Print();
Now say someone else comes along and wants to use the Printer class with there own "Point" class declared like so:
class Pnt {
public:
double mX, mY;
// other stuff
};
If they try to do this:
vector<Pnt> pnts; // Fill the pnts, and then...
Printer<Pnt> pntsPrinter(pnts);
pntsPrinter.Print(); // COMPILE ERROR HERE!
Obviously this will fail because Pnt has no x or y members. Does there exist a way I can rewrite the Printer class to work with all generic user types? What I DONT want to do is copy a Pnt vector into a Points vector.
EDIT:
The only way I can think to make this work would be to pass in functions pointers. Something like this:
template<typename T>
class Printer {
public:
T* mData;
int mSize;
double* (*mXFunc) (T*);
double* (*mYFunc) (T*);
Printer(std::vector<T> &input,
double* (*xFunc) (T*),
double* (*yFunc) (T*))
{
mData = &input[0];
mSize = input.size();
mXFunc = xFunc;
mYFunc = yFunc;
}
void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, *mXFunc(&item), *mYFunc(&item));
}
}
};
// Could then use it like so
inline double* getXPointVal(Point *point) {return &point->x;}
inline double* getYPointVal(Point *point) {return &point->y;}
inline double* getXPntVal(Pnt *point) {return &point->mX;}
inline double* getYPntVal(Pnt *point) {return &point->mY;}
Printer<Pnt> pntPrinter(pnts, getXPntVal, getYPntVal);
Printer<Point> pointsPrinter(points, getXPointVal, getYPointVal);
pntPrinter.Print();
pointsPrinter.Print();
The problem with this is that it looks ugly and also possibly introduces the function call overhead. But I guess the function call overhead would get compiled away? I was hoping a more elegant solution existed...
If you choose cout instead of printf to write your output, you can allow all printable types to define an overload for the << operator and use that generically inside Printer::print(). An overload could look like this:
std::ostream& operator<<(std::ostream &out, Point& p){
out << "Point(" << p.x << ", " << p.y << ")";
return out;
}
On a side note, I advise against storing a pointer to a vector's internal storage and size member. If the vector needs to reallocate, your pointer will be left dangling and invalid. Instead, you should pass the vector temporarily as a reference or keep a const reference.
You could define free (non-member) functions for each Point class you want to use. The advantage of this is that free functions can be defined later, without making changes to existing classes.
Example:
namespace A {
class Point {
public:
Point (int x, int y) : x_(x), y_(y) {}
int getX () const { return x_; }
int getY () const { return y_; }
private:
int x_, y_;
};
// in addition, we provide free functions
int getX (Point const & p) { return p.getX(); }
int getY (Point const & p) { return p.getY(); }
}
namespace B {
class Pnt {
public:
Pnt (int x, int y) : x_(x), y_(y) {}
int get_x () const { return x_; }
int get_y () const { return y_; }
private:
int x_, y_;
};
// Pnt does not have free functions, and suppose we
// do not want to add anything in namespace B
}
namespace PointHelpers {
// free functions for Pnt
int getX (Pnt const & p) { return p.get_x (); }
int getY (Pnt const & p) { return p.get_y (); }
}
// now we can write
template <class PointTy>
void printPoint (PointTy const & p) {
using PointHelpers::getX;
using PointHelpers::getY;
std::cout << getX (p) << "/" << getY (p) << std::endl;
}
A::Point p1 (2,3);
B::Pnt p2 (4,5);
printPoint (p1);
printPoint (p2);
If the free functions live in the same namespace as the corresponding class, they will be found by argument-dependent name lookup. If you do not want to add anything in that namespace, create a helper namespace and add the free functions there. Then bring them into scope by using declarations.
This approach is similar to what the STL does for begin and end, for instance.
Don't expect from the templates to know which members of given class/structure corresponds to your x and y...
If you want to create generic solution you could tell your printer function how to interpret given object as your Point class using e.g. lambda expression (c++11 solution):
#include <iostream>
class Point {
public:
double x, y;
Point() {x = y = 0;}
Point(double x, double y) {
this->x = x; this->y = y;
}
};
class Pnt {
public:
double mX, mY;
// other stuff
};
template <class P, class L>
void Print(const P &p, L l) {
Print(l(p));
}
void Print(const Point &p) {
std::cout << p.x << ", " << p.y << std::endl;
}
int main() {
Print(Point(1, 2));
Print(Pnt{4, 5}, [](const Pnt &p) -> Point {return Point(p.mX, p.mY);});
}

C++ Passing a function to a function using functors

I have two functors:
class SFunctor {
public:
SFunctor(double a) { _a = a; }
double operator() (double t) { return _a * sin(t); }
private:
double _a;
};
class CFunctor {
public:
CFunctor(double b) { _b = b; }
double operator() (double t) { return _b * cos(t); }
private:
double _b;
};
I want to pass one or the other of these functions to another function:
double squarer(double x, ??______?? func) {
double y = func(x);
return y * y;
}
In my main program I want to make a call like this:
CFunctor sine(2.);
SFunctor cosine(4.);
double x= 0.5;
double s = squarer(x, sine);
double c = squarer(x, cosine);
How do I specify the function fund, that is what goes in front of it in place of ??_?? ?
You can simply do it with templates
template <class F>
double squarer(double x, F& func) {
double y = func(x);
return y * y;
}
I'm not knocking on the above template answer. In fact, it may be the better choice of the two, but I wanted to point out that this can be done with polymorphism as well. For example...
#include <math.h>
#include <iostream>
using std::cout;
using std::endl;
class BaseFunctor {
public:
virtual double operator() (double t) = 0;
protected:
BaseFunc() {}
};
class SFunctor : public BaseFunctor {
public:
SFunctor(double a) { _a = a; }
double operator() (double t) { return _a * sin(t); }
private:
double _a;
};
class CFunctor : public BaseFunctor {
public:
CFunctor(double b) { _b = b; }
double operator() (double t) { return _b * cos(t); }
private:
double _b;
};
double squarer(double x, BaseFunctor& func) {
double y = func(x);
return y * y;
}
int main() {
SFunctor sine(.2);
CFunctor cosine(.4);
double x = .5;
cout << squarer(x,sine) << endl;
cout << squarer(x,cosine) << endl;
}
I ensured that this was a full working demo, so you can just copy it to test it. You will indeed observe two different numbers print to the terminal, thus proving that polymorphism can be used with functors. Again, I'm not saying this is better than the template answer, I just wanted to point out that it isn't the only answer. Even though the question has been answered, I hope this helps inform anyone who wants to be informed.

C++0x Designated Initializers

I could find a way to do Designated Initializers in C++0x with only one member initializing.
Is there a way for multiple member initializing ?
public struct Point3D
{
Point3D(float x,y) : X_(x) {}
float X;
};
I want :
public struct Point3D
{
Point3D(float x,y,z) : X_(x), Y_(y), Z_(z) {}
float X_,Y_,Z_;
};
You have a few mistakes in your constructor, here is how you should write it:
/* public */ struct Point3D
// ^^^^^^
// Remove this if you are writing native C++ code!
{
Point3D(float x, float y, float z) : X_(x), Y_(y), Z_(z) {}
// ^^^^^ ^^^^^
// You should specify a type for each argument individually
float X_;
float Y_;
float Z_;
};
Notice, that the public keyword in native C++ has a meaning which is different from the one you probably expect. Just remove that.
Moreover, initialization lists (what you mistakenly call "Designated Initializers") are not a new feature of C++11, they have always been present in C++.
#Andy explained how you should be doing this if you're going to define your own struct.
However, there is an alternative:
#include <tuple>
typedef std::tuple<float, float, float> Point3D;
and then define some function as:
//non-const version
float& x(Point3D & p) { return std::get<0>(p); }
float& y(Point3D & p) { return std::get<1>(p); }
float& z(Point3D & p) { return std::get<2>(p); }
//const-version
float const& x(Point3D const & p) { return std::get<0>(p); }
float const& y(Point3D const & p) { return std::get<1>(p); }
float const& z(Point3D const & p) { return std::get<2>(p); }
Done!
Now you would use it as:
Point3D p {1,2,3};
x(p) = 10; // changing the x component of p!
z(p) = 10; // changing the z component of p!
Means instead of p.x, you write x(p).
Hope that gives you some starting point as to how to reuse existing code.

Real functions implementation in C++ and operator+ overloading

I would like to implement real functions in C++. In particular I would like to evaluate, differentiate, add, multiply such objects. Here is my implementation
class RealFunc {
public:
virtual int Eval(const double& x, double& result) = 0;
virtual int Diff(const double& x, double& result) = 0;
};
class Sqrt : public RealFunc {
public:
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
};
int Sqrt::Eval(const double& x, double& result) {
if(x<0) return 0;
else {
result = sqrt(x);
return 1;
}
};
int Sqrt::Diff(const double& x, double& result) {
if(x<=0) return 0;
else {
result = 0.5/sqrt(x);
return 1;
}
};
It gets tricky when I try to add RealFunc objects. I have to create a sum class that inherits from RealFunc
RealFunc operator+(const RealFunc& f, const RealFunc& g) {
Sum_RealFunc h(f,g);
return h;
};
class Sum_RealFunc : public RealFunc {
public:
Sum_RealFunc(const RealFunc& f_, const RealFunc& g_) : f(f_), g(g_) {};
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
private:
RealFunc f;
RealFunc g;
};
int Sum_RealFunc::Eval(const double& x, double& result) {
double temp_f,temp_g;
int success_f,success_g;
success_f = f.Eval(x,temp_f);
success_g = g.Eval(x,temp_g);
result = temp_f+temp_g;
return success_f*success_g;
};
// Same for Sum_RealFunc::Diff
My issue here is that I cannot use f,g as members in Sum_RealFunc since RealFunc is abstract... How should I proceed to get a clean implementation ?
PS : The code I put is a light version of what I am working on (functions from RxR->R with all differentiation directions, finite difference if stepsize member is not zero and other side functions)
The problem you are facing is that you need both a feature that works well with value objects (operator overloading) and features that only works with pointers (inheritance/polymorphism).
As a solution, you'd need to have a value object with overloaded operators as a wrapper for polymorphic objects managed via pointers:
class RealFuncImpl {
public:
virtual ~RealFuncImpl(); // don't forget this for polymorphic objects
virtual int Eval(const double& x, double& result) = 0;
virtual int Diff(const double& x, double& result) = 0;
};
class RealFunc {
std::shared_ptr<RealFuncImpl> impl;
public:
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
};
You'd derive your Sum_RealFuncImpl from RealFuncImpl and implement your operators for RealFunc. You should probably hide away your Impl classes in some "detail" namespace, as your code's end user should never see them.
EDIT:
Your Sum_RealFuncImpl would contain two std::shared_ptr<RealFuncImpl> members.
Try
class Sum_RealFunc : public RealFunc {
public:
Sum_RealFunc(RealFunc& f_, RealFunc& g_) : f(f_), g(g_) {};
int Eval(const double& x, double& result);
int Diff(const double& x, double& result);
private:
RealFunc& f;
RealFunc& g;
};
Now f and g are refernces instead which is fine.
Since you initialize them in the constructors initializer list, you can make the member variables references.
You have two possibilities:
Do as wolfgang suggested: use only a wrapper around a shared pointer. This way you can create copies without really having to copy the derived function objects.
Make the derived classes themselves copyable through a base-class pointer, by implementing a clone member. That's most conveniently done with deriving from a CRTP class instead of directly from the base class. I'd make it a local class, to not confuse things:
struct RealFunc {
virtual std::pair<double,bool> operator() //IMO better than this
(double x)const =0; // reference-argument hackery
virtual std::pair<double,bool> Diff
(double x)const =0;
virtual RealFunc* clone()const =0;
template<class Derived>
struct implementation : RealFunc {
RealFunc* clone() {
return new Derived(*static_cast<const Derived*>(this));
}
};
virtual ~RealFunc(){}
};
Now you just have to derive your function objects from implementation, to make them clonable:
struct Sqrt : RealFunc::implementation<Sqrt> {
std::pair<double,bool> operator()(double x) {
return x>=0
? std::make_pair(sqrt(x), true)
: std::make_pair(0., false);
}
...
}
Your sum function can now be done nicely with std::unique_ptr:
class Sum_RealFunc : public RealFunc::implementation<Sum_RealFunc> {
std::vector<std::unique_ptr<RealFunc>> summands;
public:
std::pair<double,bool> operator()(double x) {
double result=0;
for(auto& f: summands) {
auto r = (*f)(x);
if(r.second) result += r.first;
else return std::make_pair(0., false);
}
return std::make_pair(result, true);
}
Sum_RealFunc(const Sum_RealFunc& cpy) {
for(auto& f: cpy.summands)
summands.push_back(f->clone());
}
//friend operator+=(RealFunc& acc, const RealFunc& add); //doesn't work
};
Unfortunately, this is not enough indirection to allow writing simple sum expressions. I did something in a recent project that solved pretty much all of these issues, but was yet a bit more complicated: I gave every instance the option to override its behaviour with any other instance. Like
class RealFunc {
std::unique_ptr<RealFunc> override;
public:
virtual std::pair<double,bool> operator()(double x)const {
return (*override)(x);
}
virtual std::pair<double,bool> Diff(double x)const {
return override->Diff(x);
}
auto implemented() -> RealFunc* {
return implement_override? override->implemented() : this; }
auto implemented()const -> const RealFunc* {
return implement_override? override->implemented() : this; }
virtual RealFunc* clone()const =0;
template<class Derived>
struct implementation : RealFunc {
virtual std::pair<double,bool> operator()(double x)const =0;
virtual std::pair<double,bool> Diff(double x)const =0;
RealFunc* clone() {
return new Derived(*static_cast<const Derived*>(this));
}
};
virtual ~RealFunc(){}
};
That's not all, you need to include a lot of checks for override everywhere with this approach. But in the end, it allows you to combine functions very smoothly, like
RealFunc f = const_realfunc(7.);
for(auto& omega: omegas)
f += sine_angfreq(omega);
RealFunc g = f + noise_func(.3);
...