I am trying to write a set of generic math utility classes (root finders, integrators, etc.) that take in upon construction a pointer to a base class that defines the function I want the specific algorithm to operate on. The base class should only define a public virtual interface (abstract or with default trivial functionality) type operator()(type inputArg) that can be implemented by the user as needed. This would allow the user to just implement the needed functors and perform the needed computations. My mwe is below:
This first header defines the abstract interface class
// BaseFunctor.h
#ifndef _BASE_FUNCTOR_H_
#define _BASE_FUNCTOR_H_
class BaseFunctor
{
public:
virtual double operator() (double x) = 0;
};
#endif
This is the class for one of the solver methods
// NewtonsMethod.h
#ifndef _NEWTONS_METHOD_H_
#define _NEWTONS_METHOD_H_
class BaseFunctor;
class NewtonsMethod
{
public:
NewtonsMethod(BaseFunctor *rhsIn,
BaseFunctor *rhsPrimeIn,
double x0In);
~NewtonsMethod();
bool DetermineRoot(double &root);
private:
double x0;
BaseFunctor *rhs;
BaseFunctor *rhsPrime;
static const double EPSILON;
static const unsigned int MAX_ITER;
};
#endif
This is the solver implementation:
// NewtonsMethod.cpp
#include "NewtonsMethod.h"
#include "BaseFunctor.h"
#include <cmath>
const double NewtonsMethod::EPSILON = 1e-9;
const unsigned int NewtonsMethod::MAX_ITER = 30;
NewtonsMethod::NewtonsMethod(BaseFunctor *rhsIn,
BaseFunctor *rhsPrimeIn,
double x0In) :
rhs (rhsIn),
rhsPrime(rhsPrimeIn),
x0 (x0In)
{ }
NewtonsMethod::~NewtonsMethod() { }
bool NewtonsMethod::DetermineRoot(double &root)
{
// This is obviously not implemented
root = rhs(1.0) / rhsPrime(2.0);
return false;
}
And the main function where I make the derived class implementations:
// Main.cpp
#include "BaseFunctor.h"
#include "NewtonsMethod.h"
#include <iostream>
#include <iomanip>
class fOfX : public BaseFunctor
{
double operator() (double x)
{
return x * x - 2.0;
}
};
class fPrimeOfX : public BaseFunctor
{
double operator() (double x)
{
return 2.0 * x;
}
};
int main()
{
double x0 = 2.0;
BaseFunctor *f = new fOfX();
BaseFunctor *fPrime = new fPrimeOfX();
NewtonsMethod newton(f, fPrime, x0);
double root = 0.0;
bool converged = newton.DetermineRoot(root);
if (converged)
{
std::cout << "SUCCESS: root == " << std::setprecision(16) << root << std::endl;
}
else
{
std::cout << "FAILED: root == " << std::setprecision(16) << root << std::endl;
}
delete f;
delete fPrime;
}
I tried to make that as brief as possible, so sorry if it is too long. Basically I get the error:
g++ Main.cpp NewtonsMethod.cpp -o main
NewtonsMethod.cpp: In member function ‘bool NewtonsMethod::DetermineRoot(double&)’:
NewtonsMethod.cpp:29: error: ‘((NewtonsMethod*)this)->NewtonsMethod::rhs’ cannot be used as a function
NewtonsMethod.cpp:29: error: ‘((NewtonsMethod*)this)->NewtonsMethod::rhsPrime’ cannot be used as a function
How can I get this resolved keeping the desired functionality or deriving a class for the various needed functions?
Thanks
rhs and rhsPrime are pointers. You need to reference them in order for the function call operator to be invoked.
(*rhs)(1.0) / (*rhsPrime)(2.0)
If rhs and rhsPrime are required (i.e. cannot be NULL) and cannot be changed after the NewtonsMethod object has constructor you should declare them as references instead of pointers. This would also eliminate the need to dereference them to invoke the function call operator.
The example below shows how to use references to reference the functors.
class NewtonsMethod
{
public:
NewtonsMethod(BaseFunctor& rhsIn,
BaseFunctor& rhsPrimeIn,
double x0In);
~NewtonsMethod();
bool DetermineRoot(double &root);
private:
double x0;
BaseFunctor& rhs;
BaseFunctor& rhsPrime;
static const double EPSILON;
static const unsigned int MAX_ITER;
};
int main()
{
double x0 = 2.0;
fOfX f;
fPrimeOfX fPrime;
NewtonsMethod newton(f, fPrime, x0);
}
...or...
int main()
{
double x0 = 2.0;
BaseFunctor *f = new fOfX();
BaseFunctor *fPrime = new fPrimeOfX();
NewtonsMethod newton(*f, *fPrime, x0);
// ... other code including delete for the functors
}
Related
They asked me to implement a generic polymorphism to print the length and I don't know how to do it. I thought that for polymorphism it had to be more than one class, but they asked for onw class only
#include <iostream>
using namespace std;
class Line {
private:
double x1, x2;
double y1, y2;
double z1, z2;
double length;
public:
Line(double a, double b, double c, double d, double e, double f):x1(a), x2(d), y1(b), y2(e), z1(c), z2(f){
length = sqrt(pow(x2-x1, 2) + pow(y2-y1, 2) + pow(z2-z1, 2));
}
~Line(){cout << endl << "destroying line";}
};
int main() {
Line line1(2,3,4,9,7,12);
Line line2(12,16,7,25,32,16);
Line line3(5,2,13,24,18,15);
}
To answer the question as asked, first of all you need to expose the length, as it's currently encapsulated - you can add a function to the public: section of your class:
auto get_length() const { return length; }
Then you can use generic polymorphism to print the length (your "implement a generic polymorphism", taken pretty literally):
template <typename T>
void print_length(const T& t) {
std::cout << t.get_length() << '\n';
}
Then you can prove it works by adding some calls at the bottom of main():
print_length(line1);
print_length(line2);
print_length(line3);
All that said, it's also possible they didn't truly want "generic" polymorphism - not knowing "generic" tends to refer to polymorphism using templates - and were just expecting something like:
struct with_length {
virtual ~with_length() { }
virtual double get_length() const = 0;
};
class Line : with_length {
...
double get_length() const { return length; }
};
The compiler gives me: "the variable has incomplete type rotation2d"
class translation2d
{
public:
double x;
double y;
translation2d()
{
x=0;
y=0;
}
translation2d rotateBy(rotation2d rotation) //issue here
{
translation2d copy=*this;
copy=translation2d(x*rotation.cosM()-y*rotation.sinM(), x*rotation.sinM() + y*rotation.cosM());
return copy;
}
};
double kEpsilon = 0.000000009;
class translation2d;
class rotation2d
{
public:
double cosAngle;
double sinAngle;
public:
rotation2d()
{
cosAngle=1;
sinAngle=0;
}
rotation2d(translation2d& direction, bool norm)
{
cosAngle=direction.x;
sinAngle=direction.y;
if(norm)
normalize();
}
double cosM()
{
return cosAngle;
}
double sinM()
{
return sinAngle;
}
double tanM()
{
if(abs(cosAngle)<kEpsilon)
{
if(sinAngle>=0.0)
return std::numeric_limits<double>::infinity();
else
return -1*std::numeric_limits<double>::infinity();
}
return sinAngle/cosAngle;
}
}
To resolve circular dependencies in C++, forward declarations are invented for.
Somehow OP tried it but in a wrong way.
So, if
class translation2d needs class rotation2d
and
class rotation2d needs class translation2d
the second one has to be forward declared before the first.
struct rotation2d; // forward declaration -> incomplete type
struct translation2d {
void doSomethingWith(rotation2d rot);
};
struct rotation2d {
void doSomethingWith(translation2d trans);
};
Demo on Compiler Explorer
A forward declaration makes an incomplete type.
Incomplete types are restricted concerning what can be done with them.
Neither the size nor the contents of an incomplete type is known.
Hence, the compiler denies everything where this would be needed, e.g.
allocation of storage (i.e. makeing a variable or member variable of it)
access to contents (i.e. read/write member variables or call member functions).
It is allowed to use incomplete types for
pointers and references (with any qualification)
parameters of function declarations.
I must admit that I was not aware of the latter but found:
SO: Incomplete types as function parameters and return values
for my enlightment.
Please, note that parameters of function declarations may be incomplete but not parameters of function definitions. Hence, the second part of the fix is to make functions non- inline if incomplete types are needed in them.
struct rotation2d; // forward declaration -> incomplete type
struct translation2d {
void doSomethingWith(rotation2d rot);
};
struct rotation2d {
void doSomethingWith(translation2d trans)
{
trans; // will be processed somehow
}
};
// now both types are complete
void translation2d::doSomethingWith(rotation2d rot)
{
rot; // will be processed somehow
}
Demo on Compiler Explorer
The fixed and completed sample code of OP:
#include <iostream>
#include <limits>
#include <cmath>
class rotation2d; // forward declaration
class translation2d
{
public:
double x;
double y;
translation2d()
{
x=0;
y=0;
}
translation2d(double x, double y): x(x), y(y) { }
translation2d rotateBy(rotation2d rotation); //issue here fixed
};
double kEpsilon = 0.000000009;
class rotation2d
{
public:
double cosAngle;
double sinAngle;
public:
rotation2d()
{
cosAngle=1;
sinAngle=0;
}
rotation2d(const translation2d& direction, bool norm)
{
cosAngle=direction.x;
sinAngle=direction.y;
if(norm)
normalize();
}
double cosM()
{
return cosAngle;
}
double sinM()
{
return sinAngle;
}
double tanM()
{
if(abs(cosAngle)<kEpsilon)
{
if(sinAngle>=0.0)
return std::numeric_limits<double>::infinity();
else
return -1*std::numeric_limits<double>::infinity();
}
return sinAngle/cosAngle;
}
void normalize()
{
const double len = std::sqrt(cosAngle * cosAngle + sinAngle * sinAngle);
cosAngle /= len; sinAngle /= len;
}
};
// both types complete now -> circular dependency resolved
translation2d translation2d::rotateBy(rotation2d rotation)
{
translation2d copy=*this;
copy=translation2d(x*rotation.cosM()-y*rotation.sinM(), x*rotation.sinM() + y*rotation.cosM());
return copy;
}
int main()
{
translation2d t(1.0, 2.0);
rotation2d r(translation2d(0.0, 1.0), false);
translation2d tR = t.rotateBy(r);
std::cout << "tR: (" << tR.x << ", " << tR.y << ")\n";
}
Output:
tR: (-2, 1)
Live Demo on coliru
I am trying to avoid this repetitive code by writing a template function.
#include <algorithm>
class X {
public:
void get_amin(double *a){}
void set_amin(double a){}
void get_bmin(double *b){}
void set_bmin(double b){}
//...many pairs like above
};
int main(){
X *x1 = new X;
X *x2 = new X;
//code that will be repeated
{
double x1_amin;
x1->get_amin(&x1_amin);
double x2_amin;
x2->get_amin(&x2_amin);
x1->set_amin(std::min(x1_amin, x2_amin));
}
//repeatation
{
double x1_bmin;
x1->get_bmin(&x1_bmin);
double x2_bmin;
x2->get_bmin(&x2_bmin);
x1->set_bmin(std::min(x1_bmin, x2_bmin));
}
//
delete x1;
delete x2;
}
Now my attempts are below. It seems I am able to write the template but not able to use it. Other posts at stack overflow mostly focus on how to write the template. Also I could not find an example where a class member function is used.
#include <algorithm>
#include <functional>
class X {
public:
void get_amin(double *a){}
void set_amin(double a){}
void get_bmin(double *b){}
void set_bmin(double b){}
//...many pairs like above
};
template <typename F11,typename F12, typename F2>
void templatisedFunction(F12 f11,F12 f12,F2 f2)
{
double x1_amin;
f11(&x1_amin);
double x2_amin;
f12(&x2_amin);
f2(std::min(x1_amin, x2_amin));
}
int main(){
X *x1 = new X;
X *x2 = new X;
//templatisedFunction(x1->get_amin,x2->get_amin,x1->set_amin);
//templatisedFunction(x1->get_amin(double*),x2->get_amin(double*),x1->set_amin(double));
//templatisedFunction<x1->get_amin(double*),x2->get_amin(double*),x1->set_amin(double)>();
//templatisedFunction<x1->get_amin,x2->get_amin,x1->set_amin>();
std::function<void(X*)> memfun(&X::get_amin);//not sure here
//templatisedFunction<x1->get_amin,x2->get_amin,x1->set_amin>();
//
delete x1;
delete x2;
}
void (X::*getf)(double *) and void (X::*setf)(double) are the function signatures for the two pointer to member function that you need.
Using C++11:
int main()
{
X x1;
X x2;
auto lamb = [&](void (X::*getf)(double *), void (X::*setf)(double))
{
double x1_amin;
(x1.*getf)(&x1_amin);
double x2_amin;
(x2.*getf)(&x2_amin);
(x1.*setf)(std::min(x1_amin, x2_amin));
};
lamb(&X::get_amin, &X::set_amin);
lamb(&X::get_bmin, &X::set_bmin);
return 0;
}
You can use pointers to member functions to reduce repetition:
void set_min(X &x1, X &x2, void (X::*get_min)(double *), void (X::*set_min)(double)) {
double x1_amin;
(x1.*get_min)(&x1_amin);
double x2_amin;
(x2.*get_min)(&x2_amin);
(x1.*set_min)(std::min(x1_amin, x2_amin));
}
to be used like this:
set_min(*x1, *x2, &X::get_amin, &X::set_amin);
set_min(*x1, *x2, &X::get_bmin, &X::set_bmin);
If you have many pairs you could go even further and use a loop:
std::pair<void (X::*)(double *), void (X::*)(double)> get_set_pairs[] = {
{&X::get_amin, &X::set_amin},
{&X::get_bmin, &X::set_bmin},
};
for (auto &get_set_pair : get_set_pairs){
set_min(*x1, *x2, get_set_pair.first, get_set_pair.second);
}
first of all I know that this is not possible in C++. But I hope someone can tell be a workaround for my problem. I have a class which represents a mathematical function:
class myClass:
{
private:
public:
myClass() {};
double value(double, double){ /* doing some complicated calculation here */} };
double integrate { /*calc*/ return integral; };
}
In integrate() I want to create a struct with a reference to value(). The struct is defined as follows:
struct gsl_monte_function_struct {
double (*f)(double * x_array, size_t dim, void * params);
size_t dim;
void * params;
};
(I need this struct to call the Monte-Carlo integration routines from GSL)
As said before I know that this is forbidden in C++. But is there any possibility to use gsl_monte_function_struct with a member function of myClass? If it is not possible that myClass can integrate itself, is it possible to call gsl_monte_function_struct from outside the class with value() as reference? Thanks in advance!
If understand you corretly, you want a pointer to a member function of myClass. You can achieve this by declaring the member function pointer as:
double (myClass::*value)(double,double)
This function can later be called on an instance as:
(instance.*value)(x,y);
Alternatively you can use std::bind to create a function object which can be called as an ordinary function without having to keep track of the instance on which it is called after the call to std::bind:
auto& value = std::bind(myClass::value, instance);
// ....
value(x,y);
Ok so far I found two solutions:
1) (General solution) Using an abstract base class which has a static pointer to the current instance and a static function that calls a function of the derived class. The static function can be used with a function pointer.
Example:
struct gsl_monte{
double (*f)(double y);
};
class myBase {
private:
static myBase* instance;
public:
myBase(){};
static void setInstance(myBase* newOne);
virtual double value(double x) =0;
static double callValue(double x);//{return value(x);}
};
class myClass : public myBase {
public:
myClass(){};
double value(double x) { return x; };
};
myBase* myBase::instance = new myClass();
double myBase::callValue(double x){return instance->value(x);}
void myBase::setInstance(myBase* newOne){instance=newOne;};
double g(double xx) {return xx;};
int main(int argc, char** argv ){
double x[2]; x[0]=1.3; x[1]=1.3;
myClass* instance = new myClass();
myBase::setInstance(instance);
instance->value(3);
std::cout << "Test " << myBase::callValue(5) << std::endl;
gsl_monte T;
T.f=&myBase::callValue;
double (*f)(double y, void*) = &myBase::callValue;
}
2) (Solution specific to my problem) Fortunatly the desired function accepts a parameter pointer, which I can use to pass the current object:
#include <iostream>
#include <functional>
using namespace std::placeholders;
struct gsl_monte{
double (*f)(double y, void*);
};
class myClass {
public:
myClass(){};
double value(double x) { return x; };
};
double valueTT(double x, void* param) { return static_cast<myClass*>(param)->value(x); };
int main(int argc, char** argv ){
double x[2]; x[0]=1.3; x[1]=1.3;
myClass* instance = new myClass();
instance->value(3);
gsl_monte T;
T.f=&valueTT;
double (*f)(double y, void*) = &valueTT;
}
I've created a global function, CallPrice(args). I have a class, EuropeanOption, and I have a class function called CallPrice, which should call the global function using variables from the EuropeanOption class, and return the CallPrice. I'm getting an error, "the global scope has no "CallPrice".
I think this is a common problem. I searched other threads, which said adding :: should solve the problem, but it's not working here for me. Could you identify the cause of the error? Do I need to make this a friend function or some other workaround?
Thanks!
Header:
#ifndef EuropeanOption_HPP
#define EuropeanOption_HPP
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <boost/math/distributions/normal.hpp>
using namespace boost::math;
using namespace std;
namespace CLARK
{
struct EquityParms
{
double T; // years until expiry
double K; // strike price
double sig; // vol
double r; // risk free rate
double b; // cost of carry
};
// Global Call function
const double CallPrice(double T, double K, double sig, double r, double b, double EquityPrice);
class EuropeanOption
{
private:
double T; // years until expiry
double K; // strike price
double sig; // vol
double r; // risk free rate
double b; // cost of carry
double S; // current equity price
double ExactCallPrice;
public:
EuropeanOption(); // default constructor (empty)
EuropeanOption(const EquityParms& data, double EquityPrice); // constructor that sets parms
void copy(const EuropeanOption& source);
~EuropeanOption();
void init(const EquityParms& data, double EquityPrice); // initialize EquityParms
const double CallPrice(); // trying to call global function in this function
};
}
#endif
Source:
#include "EuropeanOption_H.hpp"
namespace CLARK
{
const double CallPrice(double T, double K, double sig, double r, double b, double EquityPrice)
{// Global Function
double temp = sig * sqrt(T);
double d1 = (log(EquityPrice / K) + (r + (sig*sig) * 0.5) * T) / temp;
double d2 = d1 - temp;
normal_distribution<> myNormal(0,1);
return (EquityPrice * cdf(myNormal,d1)) - (K * exp((b - r) * T) * cdf(myNormal, d2));
}
EuropeanOption::EuropeanOption()
{// default constructor
cout << "Default constructor call" << endl;
}
EuropeanOption::EuropeanOption(const EquityParms& data, double EquityPrice)
{// constructor that sets parms
init(data, EquityPrice);
}
void EuropeanOption::copy(const EuropeanOption& source)
{
T = source.T;
K = source.K;
sig = source.sig;
r = source.r;
S = source.S;
b = source.b;
}
EuropeanOption::~EuropeanOption()
{
}
void EuropeanOption::init(const EquityParms& data, double EquityPrice)
{
T = data.T;
K = data.K;
sig = data.sig;
r = data.r;
S = EquityPrice;
b = data.b;
}
const double EuropeanOption::CallPrice()
{ // trying to call global function in this function
return ::CallPrice(T, K, sig, r, b, S); // the global scope has no "CallPrice" ???
}
}
CallPrice is in namespace CLARK. So try
CLARK::CallPrice(/* ... */);
You have declared the global CallPrice in the namespace CLARK. The syntax ::CallPrice tries to use a function CallPrice defined in the global namespace, or an anonymous namespace. Instead, use CLARK::CallPrice.
You are in the namespace CLARK:
return CLARK::CallPrice(T, K, sig, r, b, S);