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

composite functions examples and solutions
composition of functions calculator
evaluating composite functions
composition of functions practice
function composition in python example
domain of composite functions
composition of functions worksheet
domain and range of composite functions

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.

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.

Composing functions (article), If i have a composition of functions f(f(f(f(x)))) how can i write it as function in C ? Is it possible to write it with recursive algorithm? For example  While creating a C function, you give a definition of what the function has to do. To use a function, you will have to call that function to perform the defined task. When a program calls a function, the program control is transferred to the called function.

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.

Finding composite functions (video), Uses worked examples to demonstrate how to compose functions It is simpler to evaluate a composition at a point because you can simplify as you go, since  The New C: Compound Literals. By Randy Meyers, June 01, 2001 Structs in C are not quite "first class types, but with the help of compound literals, they are at least a lot easier to use.

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);
}

Composite Functions in C, It is not a filled in dot: (g · f)(x), as that means multiply. Composed With Itself. We can even compose a function with itself! Example: f(x) = 2x+3. If T is a compound type (that is, array, function, object pointer, function pointer, member object pointer, member function pointer, reference, class, union, or enumeration, including any cv-qualified variants), provides the member constant value equal true. For any other type, value is false.

Composition of Functions: Composing Functions with Functions, The notation used for the composition of functions looks like this, (f g)(x). So what This means we need to make sure that we pay close attention to the way the. Composite functions take the output of one function and use it as input for another function, and we write this f(g(x)). We're going to evaluate f(g(x)) from the inside out, so we're going to

Composition of Functions, You can use your substitution abilities to simplify a composition of functions! This means that you're going to substitute the inner function, g(x), for x in the outer So now here's the game plan: we want to find a,b, and c so that g(f(x))=f(g​(x)). There are two ways to pass parameters to a function: Pass by Value: mechanism is used when you don't want to change the value of passed paramters. When parameters are passed by value then functions in C create copies of the passed in variables and do required processing on these copied variables.

[PDF] Composite Functions, In mathematics, function composition is an operation that takes two functions f and g and The resulting composite function is denoted g ∘ f : X → Z, defined by (g ∘ f )(x) = g(f(x)) for all x the function h(t), and the oxygen concentration at elevation x is given by the function c(x), then How to Prove It: A Structured Approach. A type in [SIMPOL] can be just a container of values and other structures, but it can also include methods. These are implemented outside the type definition, but must be part of the same compiled unit.

Comments
  • in general f_A() + f_B() is something completely different than f_A( f_B() ) which one do you want?
  • That's true, I would like f_A() + f_B() first.
  • in that case you just need an operator+ for whatever is the return type of these methods, what do they return? In your example it is double with means you dont have to do anything extra
  • Is covarianceFunction a virtual function inherited from Kernel?
  • In your example code you are trying to overload operator + that would somehow combine two other objects into third object. How is "covariance function compound of the previous ones" related to this? You don't even have functions to combine.
  • your approach is not composable in the sense that your operator+ returns a lambda on which you cannot call operator+ another time. What if you want to combine 3 or more kernels? auto D = A + B + C; wont work this way
  • uh sorry maybe I am wrong and it does (B+C returns lambda and A + (B+C) should be fine)
  • Wrapping this into std::function also has pretty severe performance implications. I would absolutely not want such a simple kernel calculation to be subject to that.
  • @MaxLanghof I also would not do it this way in my code, but for sake of simplicity and less LOC it did it without template magic
  • Okay, I'm sorry if I am not clear. I would like to implement kernels (in my case object which can compute the covariance between two random variable) and in a mathematical way, kernels can be combined with others kernels with some rules (addition, scaling, etc.) . So I have create a simple covariance method which return a double and I would like to create easily kernels with more complicated functions.
  • Hiding the inherited covarianceFunction is not good practice though. It should probably be virtual.
  • OP has not answered my question wether it is virtual in Kernel or not. Anyway, if it is then it will implicitly stay virtual. It will be overridden by any subclass. If it is not virtual on the other hand, it will be hidden by a subclass, no matter if the subclass declares it virtual or not
  • Oh my bad, you inherit from Kernel not GaussianKernel. In that case it is of course as correct as OP's version.