Error when using a function as an argument of a function - c++

I'm trying to create a program to numerically integrate a function between two limits. I've created a minimal example (where the "integral" is always 1.0) to illustrate an error I get. The code below tries to use a function whose arguments are two doubles and a function from doubles to doubles:
#include <iostream>
#include <math.h>
double cons(double a, double b, double c(double d))
{
return 1.0;
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f(x));
std::cout << I << "";
}
This results in an error on cpp.sh:
14:31: error: cannot convert 'double' to 'double ()(double)' for argument '3' to 'double cons(double, double, double ()(double))'
Obviously, the difference between doubles and double-valued functions is causing a problem here. How can I get this working?

You need to pass the function, not call it.
#include <iostream>
#include <math.h>
double cons(double a, double b, double c(double d))
{
return 1.0;
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f);
std::cout << I << "";
}

You didn't pass a function but the result of a function, a double. Second, you didn't correctly declared a function pointer as argument.
If you want to pass a double then declare a double as argument:
double cons(double a, double b, double c)
{
return 1.0*a*b*c;
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f(x));
std::cout << I << "";
}
If you want to pass a function (aka function pointer as C++ is not a functional language):
double cons(double a, double b, double (*c)(double d))
{
return 1.0*c(a);
}
double f(double x)
{
return x*x;
}
int main()
{
double x;
double I = cons(0, 1, f);
std::cout << I << "";
}

Your problem in this case is that you are calling the function with:
double I = cons(0, 1, f(x));
so you actually give cons the return value of f() instead of the actual function. So you need to write this insteed:
double I = cons(0, 1, f);
As an alternativ you could also use lambda expressions for your problem. For example something like this:
#include <iostream>
#include <math.h>
#include <functional>
double cons(double a, double b, const std::function<double(double)>& callback)
{
// do something
}
int main()
{
double x;
double I = cons(0, 1, [](double x){ return x*x});
std::cout << I << "";
}

Related

Calling functions and passing arguments through map in c++?

I've been trying to figure out how I can use std::map to call functions and pass arguments to said functions based on a key.
I'm translating a project I made in Python to C++, but I've been stuck on this, and I really don't want to resort to a mess of if-elses.
The way I did that in Python was as so:
return_operation = {
"*": Operations.multiply,
"^": Operations.exponent,
"**": Operations.exponent
etc...
}
result = return_operation["*"](num_1, num_2)
Is there some sort of way to accomplish this is C++? I've tried using std::map but I keep getting:
Error C2276 '&': illegal operation on bound member function expression.
I'm still very new to C++ and I'm totally lost.
namespace std{
class Calculator {
public:
void multiply(double num_1, double num_2) {
cout << "MULTIPLYING!" << endl;
// Normally it would return the result of multiplying the two nums
// but it only outputs to the console until I can figure this out.
}
void initialize() {
void (Calculator::*funcPtr)();
funcPtr = &multiply;
unordered_map<string, Calculator()> operator_function = {
{"*", &multiply}
};
}
};
}
First off, you can't add custom types to the std namespace. Only specializations of existing templates.
Second, you are using the wrong mapped type for the unordered_map. Try something more like this instead:
class Calculator {
private:
typedef double (Calculator::*FuncType)(double, double);
unordered_map<string, FuncType> operator_function = {
{"*", &Calculator::multiply},
{"^", &Calculator::exponent},
{"**", &Calculator::exponent}
// and so on ...
};
double multiply(double num_1, double num_2) {
cout << "MULTIPLYING!" << endl;
return num_1 * num_2;
}
double exponent(double num_1, double num_2) {
cout << "EXPONENT!" << endl;
return pow(num_1, num_2);
}
public:
double do_math(string op, double num_1, double num_2) {
FuncType func = operator_function[op];
return (this->*func)(num_1, num_2);
}
};
Then, to call a function in the map, you can do this:
Calculator calc;
...
double result = calc.do_math("*", num_1, num_2);
Online Demo
Alternatively, Calculator doesn't really need to be stateful in this example, so the methods could be static to avoid needing an actual Calculator object:
class Calculator {
private:
typedef double (*FuncType)(double, double);
static unordered_map<string, FuncType> operator_function;
static double multiply(double num_1, double num_2) {
cout << "MULTIPLYING!" << endl;
return num_1 * num_2;
}
static double exponent(double num_1, double num_2) {
cout << "EXPONENT!" << endl;
return pow(num_1, num_2);
}
public:
static double do_math(string op, double num_1, double num_2) {
FuncType func = operator_function[op];
return func(num_1, num_2);
}
};
unordered_map<string, Calculator::FuncType> Calculator::operator_function = {
{"*", &Calculator::multiply},
{"^", &Calculator::exponent},
{"**", &Calculator::exponent}
// and so on ...
};
double result = Calculator::do_math("*", num_1, num_2);
Online Demo
Alternatively, you could use lambdas instead of class methods, eg:
class Calculator {
private:
using FuncType = std::function<double(double, double)>;
static unordered_map<string, FuncType> operator_function;
public:
static double do_math(string op, double num_1, double num_2) {
if (op == "**") op = "^";
FuncType func = operator_function[op];
return func(num_1, num_2);
}
};
unordered_map<string, Calculator::FuncType> Calculator::operator_function = {
{"*", [](double num_1, double num_2)
{
cout << "MULTIPLYING!" << endl;
return num_1 * num_2;
}
},
{"^", [](double num_1, double num_2)
{
cout << "EXPONENT!" << endl;
return pow(num_1, num_2);
}
}
// and so on ...
};
double result = Calculator::do_math("*", num_1, num_2);
Online Demo
If you're looking for a straight translation of your python code, then I'd go with something like this:
#include <cmath>
#include <functional>
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, std::function<double (double, double)>> return_operation{
{ "*", [](double a, double b) { return a * b; } },
{ "^", [](double a, double b) { return std::pow(a, b); } },
};
double r = return_operation["*"](5, 3); // r == 15
std::cout << r << std::endl;
return 0;
}
From a learning perspective, I totally recommend the answer by Remy Lebeau.

Errors in implementing an integral function from x to infinity from scratch in CPP with substitution

So I am trying to implement an integration function from scratch in CPP. I have been stuck on this for 2 days.
I am not sure how to do an integration computation from x to +inf. My plan was to use the sigmoid function as a substitution for the integration which should mathematically work but it didn't work computationally. Formula reference: https://en.wikipedia.org/wiki/Integration_by_substitution#Definite_integrals
My questions are 1). why my method didn't work? 2). Is there a better method/function to be used for the substitution?
Reproducible Code
which can be accessed via https://onlinegdb.com/F3rzIEReA with explanations as comments
#include <iostream>
#include <cmath>
const double PI = 3.14159265358979323846;
using namespace std;
// I have an interface for a real function named RealFunction which
// is used to be fed into the integral function
class RealFunction {
public:
virtual ~RealFunction() {};
virtual double evaluate( double x ) = 0;
};
// integral function that utilises the rectangular rule
double integral( RealFunction& f,
double a,
double b,
int nPoints ) {
double h = (b-a)/nPoints;
double x = a + 0.5*h;
double totalHeight = 0.0;
for (int i=0; i<nPoints; i++) {
double height = f.evaluate(x);
totalHeight+=height;
x+=h;
}
return h*totalHeight;
}
// a probability normal distribution function
class NormPDF : public RealFunction {
public:
NormPDF(double mu, double sigma) :
mu(mu), sigma(sigma){}
NormPDF() :
mu(0.0), sigma(1.0){}
double mu;
double sigma;
double evaluate(double x){
return exp(-0.5*pow((x-mu)/sigma,2.0))/(sigma*sqrt(2*PI));
}
};
// my chosen substitution function - sigmoid function
double sigmoidFunction(double x) {
return 1/(1+exp(-x));
}
// implementing the integral to infinity function with
// the sigmoid function
double integralToInfinity( RealFunction& f,
double x,
int nPoints) {
class SigmoidInfusedFunction : public RealFunction {
public:
SigmoidInfusedFunction(RealFunction& f) :
f(f) {
}
RealFunction &f;
double evaluate(double x) {
// d(sig)/dx = exp(-x) / pow(1+exp(-x),2)
return f.evaluate(sigmoidFunction(x)) * exp(-x) / pow(1+exp(-x),2);
}
};
SigmoidInfusedFunction sigmoidInfusedFunc(f);
return integral(sigmoidInfusedFunc, sigmoidFunction(x), 1, 1000);
}
int main() {
// Test for integrate - result: 0.95004 expected: 0.95 (CORRECT)
NormPDF normPDF;
cout << integral(normPDF, -1.96, 1.96, 1000) << endl;
// Test for infinity - result: 0.0688965 expected: 0.5 (INCORRECT)
cout << integralToInfinity(normPDF, 0, 1000) << endl;
return 0;
}

c++ return two arrays from the function

I find a solution to the equation using the bisection method.
And I need to find the value of a and b on some iterations. Therefore, I made two arrays for these points, respectively.
in order to "pull out" the number of iterations from the function, I had no problems. They are displayed on the screen. But how do I "pull out" these two arrays?Please tell me how to do it. Thank you in advance!
double f1(double x){
return x*x-5*sin(x);
}
double f2(double x){
return exp(x)-pow(10,x);
}
double f3(double x){
return sin(x)-x+0.15;
}
double f4(double x){
return x-pow(9+x,0.5)+x*x-4;
}
double dihotom (double a , double b , double e , double(*fp)(double),int &iter,double &points_a[],double &points_b[]){
double c , fc , fa = fp(a);
iter=(log10((b-a)/e))/log10(2);
int step = iter/3;
int step_current = step;
int it=0;
int k=0;
do{
c=(a+b)/2;
fc=fp(c);
if (fa*fc<=0) b = c ; else a = c;
it++;
if(it==step_current){
points_a[k]=a;
points_b[k]=b;
k++;
step_current=step_current+step;
}
fa=fp(a);
printf ("it %d: a = %lf,b = %lf\n",iter,a,b);
}while (fabs(a-b)>=e);
return c;
}
int main(int argc, char *argv[]) {
int int_s=0;
double points_a[3];
double points_b[3];
double k3= dihotom (0.5,1,0.0001,f3,int_s,points_a[3],points_b[3]);
printf("For F3 - root = %lf, F3(%.2lf)=%lf ;iter =%d\n", k3, k3 ,f3(k3),int_s);
int i=0;
for(i=0;i<3;i++){
printf("step : %d , a: %lf, b: %lf ", i,points_a[i],points_b[i]);
}
return 0;
}
In your case, you should take the arrays by reference:
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double (&points_a)[3], double (&points_b)[3]) {
// ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
You could also let the arrays decay into pointers:
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double points_a[], double points_b[]) {
or
double dihotom(double a, double b, double e, double (*fp)(double), int &iter,
double* points_a, double* points_b) {
But by taking them by reference, you make sure that you only accept arrays of the correct size.
In either case, the call to the function will simply be:
double k3 = dihotom(0.5, 1, 0.0001, f3, int_s, points_a, points_b);
Demo
If you want to return two arrays from a function then make a struct with two vectors. Something like this. The way you are doing it is harder to maintain, who will allocate the arrays and delete them for example?
// todo for you : create better names then points_a and points_b
struct my_result_t
{
std::vector<double> points_a;
std::vector<double> points_b;
};
my_result_t function();
{
my_result_t result;
result.points_a.push_back(1.0);
result.points_b.push_back(2.0);
return result;
}
int main()
{
auto result = function();
std::cout << result.points_a[0];
}

LawOfCosines solving for c, but getting odd answer

I have been trying to code a program that can solve for c using the Law Of Cosines. The program runs correctly, but the answer I get is ridiculously big, noted by how it was in scientific notation.
Here is my code:
#include <iostream>
#include <cmath>
using namespace std;
class TrigMath
{
private:
double a;
double b;
double y;
public:
double LawOfCos()
{
return sqrt(pow(a,2) + pow(b,2) - 2*a*b*cos(y));
}
void seta(double A)
{
A = a;
}
void setb(double B)
{
B = b;
}
void sety(double Y)
{
Y = y;
}
};
int main()
{
TrigMath triangle1;
triangle1.seta(3);
triangle1.setb(4);
triangle1.sety(60);
cout << "c is equal to " << triangle1.LawOfCos() << endl;
return 0;
}
The cos() function there takes input as radians not as degrees.
Try to convert degrees to radians and then supply it as input.
In the class functions seta, setb and sety you have written A = a, B = b and Y = y.
You have to change them to a = A, b = B and Y = y.
So after applying all the changs the code should be like
#include <iostream>
#include <cmath>
using namespace std;
class TrigMath
{
private:
double a = 0;
double b = 0;
double y = 0;
public:
double LawOfCos()
{
return sqrt(pow(a,2) + pow(b,2) - 2*a*b*cos(y));
}
void seta(double A)
{
a = A;
}
void setb(double B)
{
b = B;
}
void sety(double Y)
{
y = Y*3.14/180;
}
};
int main()
{
TrigMath triangle1;
triangle1.seta(3.0);
triangle1.setb(4.0);
triangle1.sety(60.0);
cout << "c is equal to " << triangle1.LawOfCos() << endl;
return 0;
}

Making an array of function pointers [duplicate]

This question already has answers here:
How define an array of function pointers in C
(5 answers)
Closed 4 years ago.
My problem is: I want to write a program which create an array function pointers. I know how to make pointer to function, but don't know how to make array of them.
This is what I tried up to now:
double add(double a, double b) { return a + b; }
double sub(double a, double b) { return a - b; }
double mult(double a, double b) { return a * b; }
double div(double a, double b) { return a/b; }
int main() {
double(*Padd)(double a, double b);
double(*Psub)(double a, double b);
double(*Pmult)(double a, double b);
double(*Pdiv)(double a, double b);
Padd = &add;
Psub = ⊂
Pmult = &mult;
Pdiv = &div;
}
In my code I create these pointers to functions in an array like e.g.
double Tpointers[3];
Tpointers[0] = Padd;
Tpointers[1] = Psub;
Tpointers[2] = Pmult;
Tpointers[3] = Pdiv;
How do I do this?
Simply declare a new type 'Tpointers' that represent a pointer to a function that give two double and return a double.
And in the code you can create an array of functions.
#include<iostream>
// The function pointer type!
typedef double (*Tpointers)(double, double);
double add(double a, double b) { return a + b; }
double sub(double a, double b) { return a - b; }
double mult(double a, double b) { return a * b; }
double div(double a, double b) { return a / b; }
int main() {
// A functions pointers array .
Tpointers fun_array[4];
// Assign the values
fun_array[0] = &add;
fun_array[1] = ⊂
fun_array[2] = &mult;
fun_array[3] = &div;
// A little test
std::cout << fun_array[2](3, 3) << " " << fun_array[3](3,3) << " " << fun_array[1](3,3)
<< std::endl;
return 0;
}
In c++ you can also create an std::vector of functions pointer ... or any containers from the std libraries of "Tpointers".