• C++ Programming for Financial Engineering
    Highly recommended by thousands of MFE students. Covers essential C++ topics with applications to financial engineering. Learn more Join!
    Python for Finance with Intro to Data Science
    Gain practical understanding of Python to read, understand, and write professional Python code for your first day on the job. Learn more Join!
    An Intuition-Based Options Primer for FE
    Ideal for entry level positions interviews and graduate studies, specializing in options trading arbitrage and options valuation models. Learn more Join!

Functors

doug reich

Some guy
Joined
4/23/08
Messages
684
Points
28
I thought a good way to get some C++ practice and solidify the numerical integration methods (and do the practice problems) in Chapter 2 of Dan's Primer book would be to write numerical integration functions for the midpoint, trapezoidal, and simpson's rules that take the function to be integrated as an argument.

The way to do this in C++ seems to be to use functors (Function object - Wikipedia, the free encyclopedia). The only place I've come across these is in the documentation for the for_each function in VS (and now in wikipedia, which gives a good overview). These give me the general idea, but does anybody have a good resource that covers these more thoroughly?
 
Hi Doug,

Functors come from math, more specifically lambda calculus. Functional languages usually cover functors in depth.

The most common application of functors in C++ is through callbacks.

I'm planning to cover an application with functors (using Dan's book) in the last class of the refresher but you can look at function pointers (that's how you implement functors in C),
 
I've studied functional languages in school, and I find it quite a pleasant logical exercise to use them.

By callbacks, I take it you mean function pointers. Is this "appropriate" C++ style? I suppose if it's used in the STL it must be OK. I only ask, because the syntax looks very C-like, which is to say, like a hack.
 
There are ways to do callbacks without using function pointers. You can use polymorphism instead. I will try to cover it in our last class.
 
I did this with C-style pointers, which is (IMHO) pretty straightforward. I came up with the following for a functor solution. I would think it would maybe involve have a base function class, and inherited classes that return a value, ie something like:

Class Function {
public:
Function(){};
virtual double operator()(double x) const=0;
virtual ~Function(){}
private:
}

And, say:

Class xSquared: public Function {
public:
xSquared(){};
virtual double operator()(double x) const {return x*x};
virtual ~xSquared(){}
//etc
}

And then have the numerical integration take a ref-to-Function argument. (This is a rough sketch at best, I'm sure there are some syntax errors)

I have to ask, is there anything gained by doing this over the C-style solution?
 
I just thought I'd post my Functor class for any C# converts. Delegates are another way to accomplish this but that can wait for another post. You can just stick in more f(x) into the else-if chain and label the f(x) with an int or a enum string if you choose. The del and del2 member functions come in handy. C# wouldn't let me overload the () operator, argh.

C++:
public class Functor
{
  Error e = new Error();
  int type_;
  double h_;
 
  public Functor() {}
  public Functor(int t) { type_=t; h_=.001; }
  public Functor(int t, double h) { type_=t; h_=h; }
  public void set(int t) { type_=t; h_=.001; }
  public void set(int t,double h) { type_=t; h_=h; }
 
  public double eval(double x)
  {
    if(type_==1) return Math.Pow(x,3.0)+4.0*x*x-10.0;
    else if(type_==2) return x*x+2.0*x+1.32;
    else if(type_==3) return 3.0*Math.Exp(-x)*Math.Sin(Math.Pow(x,2.0))+1.0;
    else if(type_==4) return Math.Exp(x);
    else if(type_==5) return 1.0/Math.Pow(1.0+x,3.0);
    else if(type_==6) return Math.Exp(-1.0*x*x);
    else if(type_==7) return x*x*x;
    else if(type_==8) return x*x;
 
    else { e.error("FUNCTOR EVAL: type not defined"); return 0; }
  }
  public double del(double x) 
  {
    return (eval(x+h_)-eval(x-h_))/(2.0*h_);
  }
  public double del2(double x) 
  {
    return (eval(x+h_)-2*eval(x)+eval(x-h_))/(h_*h_);
  }
}
 
I have the following code:

C++:
#include <iostream>
#include <cmath>

typedef double (*funcPtr)(double);

class SingleVarFunctor
{
private:
    funcPtr sFunction;
public:
    SingleVarFunctor();
    SingleVarFunctor( funcPtr _f );
    
    void setFunction( funcPtr _f );
    virtual double operator() (double _x ) const;
};

class Constant : public SingleVarFunctor
{
private:
    double c;
public:
    Constant();
    Constant( double constant );

    void setConstant( double _c );
    virtual double operator() ( double _x ) const;
};


double instantaneous( double _x )
{
    return 0.05 + _x;
}

using namespace std;

int main()
{
    SingleVarFunctor* a = new SingleVarFunctor( instantaneous );
    Constant *b = new Constant(7);

    cout << "a(3) = " << (*a)(3) << " b(3)= " << (*b)(3) << endl;
    *a = *b;
    cout << "a(3) = " << (*a)(3) << " b(3)= " << (*b)(3) << endl;

    return 0;
}

double zero( double _x ) {
    return 0;
}

SingleVarFunctor::SingleVarFunctor()
{
    sFunction = zero;

}

SingleVarFunctor::SingleVarFunctor( funcPtr _f )
{
    sFunction = _f;
}

void SingleVarFunctor::setFunction( funcPtr _f )
{
    sFunction = _f;
}

double SingleVarFunctor::operator() (double _x ) const
{
    return sFunction( _x );
}

Constant::Constant()
{
    c = 0;
}
Constant::Constant( double constant )
{
    c = constant;
}

void Constant::setConstant( double _c )
{
    c = _c;
}
double Constant::operator() ( double _x ) const
{
    return c;
}
When I run it I get output:
C++:
a(3) = 3.05 b(3)= 7
a(3) = 0 b(3)= 7
My question is: where did the polymorphism go wrong? At the end, shouldn't a run Constant::operator() and print 7?
 
In main, if I change
C++:
*a = *b;
to
C++:
a = b;
, everything works as expected. The second "a" output is 7. This make sense in the context of "slicing" from Savitch.

How do I go about both making a deep copy of b and also maintaining the polymorphism?

A virtual Clone function! Why didn't I think of that?http://www.informit.com/articles/article.aspx?p=31529&seqNum=5 Thanks to everyone who knows the answer but never got a chance to give it... :)
 
Incidentally, this is covered in Joshi's Design Patterns and Derivatives pricing. The "clone" is called a "virtual constructor".
 
Back
Top