C++ Error: no matching function for call - c++

I am trying to solve a quadratic equation using the bisection method. When trying to evaluate the roots I get this error: "no matching function for call".
#include "assign4.h"
#include <iostream>
using namespace std;
int main(int argc, char * argv[]){
solution s;
double root;
cout << "Enter interval endpoints: ";
cin >> s.xLeft >> s.xRight;
cout << "Enter tolerance: ";
cin >> s.epsilon;
root = s.bisect (s.xLeft, s.xRight, s.epsilon, s.f, s.error);
if (!(s.error))
cout << "Root found at " << root << "\nValue of f(x) at root is: " << s.f(root);
else
cout << "The solution of a quadratic equation with coefficients: " << endl;
cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
cout << "has not been found." << endl;
return 0;
}
The error occurs where root = ... it seems to have a problem with my function f but I don't understand what is wrong. The following two bits of code are my class and class implementation files. We just started working with classes so I am uncertain if my problem lies there or simply in the above code.
#ifndef ASSIGN4_H
#define ASSIGN4_H
class solution {
public:
double xLeft, xRight;
double epsilon;
bool error;
double bisect(double, double, double, double f(double), bool&);
double f(double);
};
#endif // ASSIGN4_H
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "assign4.h"
#include <iostream>
#include <cmath>
using namespace std;
double solution::bisect (double xLeft, double xRight, double epsilon, double func(double), bool& error) {
double xMid;
double fLeft, fRight;
double fMid;
fLeft = f(xLeft);
fRight = f(xRight);
error = (fLeft * fRight) > 0;
if (error)
return -999.0;
while (fabs (xLeft - xRight) > epsilon) {
xMid = (xLeft + xRight) / 2.0;
fMid = f (xMid);
if (fMid == 0.0)
return xMid;
else if (fLeft * fMid < 0.0)
xRight = xMid;
else
xLeft = xMid;
cout << "New Interval is [" << xLeft << ", " << xRight << "]" << endl;
}
return (xLeft + xRight) / 2.0;
}
double solution::f (double x) {
return ((5 * pow(x,2.0)) + (5 * x) + 3);
}

The 4th parameter is a function pointer,
double bisect(double, double, double, double f(double), bool&);
When you call this function:
root = s.bisect (s.xLeft, s.xRight, s.epsilon, s.f, s.error);
While the member fiction double f(double) is not the same type as that parameter because this is C++ member function and not static, so the 'this' parameter is added this member function when compiling.
type add the static key word to the function.

The syntax for a function pointer is usually: double (*f)(double). Aside from that, you are attempting to pass a member function through a non-member-function pointer. Since your function does not use any member variables, the simplest solution would be to make it static:
class solution {
// ...
static double f(double);
};

If you want to use pointers to member functions.
Change
double bisect(double, double, double, double f(double), bool&);
to
double bisect(double, double, double, double (solution::*f)(double), bool&);
in declaration and definition.
Change the call from
root = s.bisect (s.xLeft, s.xRight, s.epsilon, s.f, s.error);
to
root = s.bisect (s.xLeft, s.xRight, s.epsilon, &solution::f, s.error);
This is what I have that compiles and links successfully for me.
#include <iostream>
#include <typeinfo>
#include <math.h>
using namespace std;
class solution {
public:
double xLeft, xRight;
double epsilon;
bool error;
double bisect(double, double, double, double (solution::*f)(double), bool&);
double f(double);
};
using namespace std;
double solution::bisect (double xLeft, double xRight, double epsilon, double (solution::*func)(double), bool& error) {
double xMid;
double fLeft, fRight;
double fMid;
fLeft = (this->*func)(xLeft);
fRight = (this->*func)(xRight);
error = (fLeft * fRight) > 0;
if (error)
return -999.0;
while (fabs (xLeft - xRight) > epsilon) {
xMid = (xLeft + xRight) / 2.0;
fMid = (this->*func)(xMid);
if (fMid == 0.0)
return xMid;
else if (fLeft * fMid < 0.0)
{
xRight = xMid;
fRight = fMid;
}
else
{
xLeft = xMid;
fLeft = fMid;
}
cout << "New Interval is [" << xLeft << ", " << xRight << "]" << endl;
}
return (xLeft + xRight) / 2.0;
}
double solution::f (double x) {
return ((5 * pow(x,2.0)) + (5 * x) + 3);
}
int main(int argc, char * argv[]){
solution s;
double root;
cout << "Enter interval endpoints: ";
cin >> s.xLeft >> s.xRight;
cout << "Enter tolerance: ";
cin >> s.epsilon;
root = s.bisect (s.xLeft, s.xRight, s.epsilon, &solution::f, s.error);
if (!(s.error))
cout << "Root found at " << root << "\nValue of f(x) at root is: " << s.f(root) << endl;
else
{
cout << "The solution of a quadratic equation with coefficients: " << endl;
// cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
cout << "has not been found." << endl;
}
return 0;
}

I believe it has to do with your callback function. Typically you get that kind of compiler error when you use an incorrect function call. If you want this kind of callback function, you may want to look into function pointers.
http://www.cprogramming.com/tutorial/function-pointers.html

Related

VS2022 code analysis error using uninitialized memory C++ [duplicate]

This question already has answers here:
Uninitialized variable behaviour in C++
(4 answers)
What happens when I print an uninitialized variable in C++? [duplicate]
(4 answers)
Calling function with variable that is being initialized [duplicate]
(1 answer)
Closed 5 months ago.
Here are the errors on the following code after the VS2022(v143) upgrade:
Could someone please suggest what is wrong here and how to fix it?
//Cricle properties problem
#include <iostream>
using namespace std;
float Qradius(float diameter)
{
float radius = diameter / 2;
return radius;
}
float Warea(float radius)
{
float area = (radius *radius) *3.14;
return area;
}
float Ecircumference(float diameter)
{
float circumference = 3.14 * diameter;
return circumference;
}
float Rarclength(float arcangle, float circumference)
{
float arclength = (circumference *arcangle) / 360;
return arclength;
}
int main()
{
float diameter, arcangle;
float area, circumference, arclength, radius;
cout << "Type the diameter ";
cin >> diameter;
cout << "Type the arcangle ";
cin >> arcangle;
cout << "The radius of the circle is " << Qradius(diameter) << endl;
cout << "The area is " << Warea(radius) << endl;
cout << "The circumference is " << Ecircumference(diameter) << endl;
cout << "The arc length is " << Rarclength(arcangle, circumference) << endl;
}
I solved the warnings and explained why they were coming up in the comments in the code. Also do not use using namespace std;
#include <iostream>
float Qradius(float diameter)
{
float radius = diameter / 2;
return radius;
}
float Warea(float radius)
{
// if no f is specified, the compiler assumes it is a double
// the warning tells you that it converts a double to float
// which could lead to loss of data (C4244)
float area = (radius *radius) * 3.14f;
return area;
}
float Ecircumference(float diameter)
{
// same as aboth
float circumference = 3.14f * diameter;
return circumference;
}
float Rarclength(float arcangle, float circumference)
{
float arclength = (circumference *arcangle) / 360;
return arclength;
}
int main()
{
float diameter, arcangle;
// area and arclength are unused (C4101)
float /*area,*/ circumference, /*arclength,*/ radius;
std::cout << "Type the diameter ";
std::cin >> diameter;
std::cout << "Type the arcangle ";
std::cin >> arcangle;
// radius and circumference is never set
// and later used without setting any value (C6001)
radius = Qradius(diameter);
circumference = Ecircumference(diameter);
std::cout << "The radius of the circle is " << radius << std::endl;
std::cout << "The area is " << Warea(radius) << std::endl;
std::cout << "The circumference is " << circumference << std::endl;
std::cout << "The arc length is " << Rarclength(arcangle, circumference) << std::endl;
}

error: cannot convert ‘float (*)(int)’ to ‘float’

My program converts temperature from the Fahrenheit scale to the Celcius scale and finally to absolute value scale.
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int farh;
float cels(int a)
{
float c;
const int m0 = 32;
const float m1 = 0.5555;
c=(a-m0)/m1;
return c;
}
float ab(float a)
{
const float m2 = 273.15;
float d;
d=a-m2;
return d;
}
int main() {
const int WIDTH = 16;
cout << setiosflags ( ios :: left );
cout << setw(WIDTH) << "Fahrenheit" << setw(WIDTH) << "Celcius" << setw(WIDTH) << "Absolute Value" << '\n';
cout.setf(ios::fixed);
cout.precision(2);
for (farh = 0 ; farh <= 300 ; farh = farh + 20) {
cout.width(16);
cout << farh << cels(farh) << ab(cels) << "\n";
}
return 0;
}
The Compile time error message I receive is:
d26.cc: In function ‘int main()’:
d26.cc:38:40: error: cannot convert ‘float (*)(int)’ to ‘float’ for argument ‘1’ to ‘float ab(float)’
cout << farh << cels(farh) << ab(cels) << "\n";
Why am I receiving this error?
ab takes a float and returns a float:
float ab(float a)
But cels isn't a float, it's a function:
float cels(int a)
You probably meant
ab(cels(farh))
Or to take a temporary:
float cur_cels = cels(farh);
cout << farh << cur_cels << ab(cur_cels) << "\n";
Side-note, ab should probably be named kelvin.
Actually you have passed a funtion pointer to ab. if your intent is to pass the function ( clearly not! ) you can use the following syntax :
float ab(float(*callback)(int),int pass) {
callback(pass); /* It calls the function indirectly with <pass> */
}
Its great for menu creation for example if you have two options:
1. Fahrenheit to Cell
2. Fahrenheit to Kelvin it will be useful
You can search callback functions in C with google.

Newton method for computing an inverse

This is following the question I asked in this thread : Link error missing vtable
I defined a class 'function' and two others classes 'polynomial' and 'affine' that inherit from 'function'.
class function {
public:
function(){};
virtual function* clone()const=0;
virtual float operator()(float x)const=0; //gives the image of a number by the function
virtual function* derivative()const=0;
virtual float inverse(float y)const=0;
virtual ~function(){}
};
class polynomial : public function {
protected:
int degree;
private:
float *coefficient;
public:
polynomial(int d);
virtual~polynomial();
virtual function* clone()const;
int get_degree()const;
float operator[](int i)const; //reads coefficient number i
float& operator[](int i); //updates coefficient number i
virtual float operator()(float x)const;
virtual function* derivative()const;
virtual float inverse(float y)const;
};
class affine : public polynomial {
int a;
int b;
//ax+b
public:
affine(int d,float a_, float b_);
function* clone()const;
float operator()(float x)const;
function* derivative()const;
float inverse(float y)const;
~affine(){}
};
Method inverse in polyomial does not seem to work fine. It is based on the Newton method applied to the function x->f(x)-y for fixed y (the element for which we're computing the inverse) and the current polynomial f.
float polynomial::inverse(float y)const
{
int i=0;
float x0=1;
function* deriv=derivative();
float x1=x0+(y-operator()(x0))/(deriv->operator()(x0));
while(i<=100 && abs(x1-x0)>1e-5)
{
x0=x1;
x1=x0+(y-operator()(x0))/(deriv->operator()(x0));
i++;
}
if(abs(x1-x0)<=1e-5)
{
//delete deriv; //I get memory problems when I uncomment this line
return x1;
}
else
{
cout<<"Maximum iteration reached in polynomial method 'inverse'"<<endl;
//delete deriv; //same here
return -1;
}
}
double polynomial::operator()(double x)const
{
double value=0;
for(int i=0;i<=degree;i++) value+=coefficient[i]*pow(x,i);
return value;
}
polynomial* polynomial::derivative()const
{
if(degree==0)
{
return new affine(0,0,0);
}
polynomial* deriv=new polynomial(degree-1);
for(int i=0;i<degree;i++)
deriv[i]=(i+1)*coefficient[i+1];
return deriv;
}
I test this method with p:x->x^3 :
#include "function.h"
int main(int argc, const char * argv[])
{
polynomial p(3);
for(int i=0;i<=2;i++) p[i]=0;
p[3]=1;
cout<<"27^(1/3)="<<p.inverse(27);
return 0;
}
This script outputs 27^(1/3)=Maximum iteration reached in polynomial method 'inverse'
-1 even if I put 10,000 instead of 100. I've read some articles on the internet and it seems that it's a common way to compute the inverse.
the abs function prototype is: int abs(int)
So a test like abs(x1-x0)<=1e-5 won't behave as you expect; you compare a int with a float. In this case the float will be converted to int so it the same as abs(x1-x0)<=0
This is probably why you don't get the expected result - I suggest adding a few more printouts to get to the bottom of things.
Well, the problem was in method 'derivative'. Instead of using the 'operator[]' that I redefined, I used '->coefficient[]' and the main script worked fine for p.inverse(27) (only 14 iterations). I just replaced deriv[i]=(i+1)*coefficient[i+1]; with deriv->coefficient[i]=(i+1)*coefficient[i+1];
Check This Code :
#include<iostream>
#include<cmath>
#include<math.h>
using namespace std;
void c_equation(int choose, double x);
void Processes(double x, double fx1, double fdx1, int choose);
void main()
{
int choose,choose2;
double x;
system("color A");
cout << " " << endl;
cout << "=============================================================" << endl;
cout << "Choose Equation : " << endl;
cout << "_____________________________________" << endl;
cout << "1- x-2sin(x)" << endl;
cout << "2- x^2 + 10 cos(x)" << endl;
cout << "3- e^x - 3x^2" << endl;
cout << " " << endl;
cin >> choose;
cout << "If you have values press 1/ random press 2 :" << endl;
cin >> choose2;
if (choose2 == 1)
{
cout << " " << endl;
cout << "Enter Xo : " << endl;
cin >> x;
c_equation(choose, x);
}
else if (choose2 == 2)
{
x = rand() % 20;
cout << "Xo = " << x << endl;
c_equation(choose, x);
choose2 = NULL;
}
else
{
cout << "Worng Choice !! " << endl;
choose = NULL;
choose2 = NULL;
main();
}
}
void c_equation(int choose, double x)
{
double fx;
double fdx;
double fddx;
double result;
if (choose == 1)
{
fx = x - 2 * sin(x);
fdx = 1 - 2 * cos(x);
fddx = 2 * sin(x);
result = abs((fx * fddx) / pow(fdx, 2));
}
else if (choose == 2)
{
fx = pow(x, 2) + 10 * cos(x);
fdx = 2 * x - 10 * sin(x);
fddx = 2 - 10 * cos(x);
result = abs((fx * fddx) / pow(fdx, 2));
}
else if (choose == 3)
{
fx = exp(x) - 3 * pow(x, 2);
fdx = exp(x) - 6 * x;
fddx = exp(x) - 6;
result = abs((fx * fddx) / pow(fdx, 2));
}
else
{
cout << " " << endl;
}
//------------------------------------------------------------
if (result < 1)
{
cout << "True Equation :) " << endl;
Processes(x, fx, fdx , choose);
}
else
{
system("cls");
cout << "False Equation !!" << endl;
choose = NULL;
x = NULL;
main();
}
}
void Processes(double x, double fx, double fdx , int choose)
{
double xic;
for (int i = 0; i < 3; i++)
{
xic = x - (fx / fdx);
cout << " " << endl;
cout << "Xi = " << x << " " << "F(Xi) = " << fx << " " << " F'(Xi) = " << fdx << " " << " Xi+1 = " << xic << endl;
x = xic;
if (choose == 1)
{
fx = xic - 2 * sin(xic);
fdx = 1 - 2 * cos(xic);
}
else if (choose == 2)
{
fx = pow(xic, 2) + 10 * cos(xic);
fdx = 2 * xic - 10 * sin(xic);
}
else if (choose == 3)
{
fx = exp(xic) - 3 * pow(xic, 2);
fdx = exp(xic) - 6 * xic;
}
}
}

converting to int from float

#include <iostream>
using namespace std;
int main(){
float const PI = 3.1415926;
int radius = 4;
int peri = 0;
int area = 0;
peri =(float) (PI * 2)* radius;
area = (float) PI * (radius * radius);
cout << "Radius is " << radius << endl;
cout << "Perimeter is " << peri << endl;
cout << "Area is " << area << endl;
return 0;
};
peri and area are not converting to float and always receiving a warning "converting to int from float" what seems to be the problem ..
If you really want to truncate peri and area to integers, you should do so explicitly:
peri=static_cast<int>(2*PI*radius);
area=static_cast<int>(PI*radius*radius);
Otherwise, you'll get a warning and it will look like a mistake to anyone who reads your code.

issue with ofstream dataout

In my program, my dataout: void outfile is not writing to the file, can anyone figure out why?
using namespace std;
#include<iostream>
#include<cmath>
#include<iomanip>
#include<fstream>
// Declaration of functions used
void writetable (double, double, double, double);
void tableout (double, double, double, double);
void secant(double, double, double, double, double, double, double, double, double, double&, int&);
void writedata (double, double, double);
void outfile(double, double, double&);
double fx( double, double, double, double, double, double, double);
const double tol=0.0001; // Tolerance for convergence
const int max_iter=50; // Maximum iterations allowed
// main program
int main()
{
int iteration; // Number of iterations
double kr, uc, q, b, radians;
double x0, x1; // Starting values for x
double root; // Root found by secant method
const double PI = 4.0*atan(1.0);
ifstream datain ("shuttle.txt");
ofstream dataout ("results.txt");
datain >> kr >> uc >> q >> b;
x0= 1000;
x1 = 200;
writetable(kr, uc, q, b);
tableout(kr, uc, q, b);
for (double angle = 10; angle <= 70; angle += 15)
{
for (double velocity = 16000; velocity <= 17500; velocity += 500)
{
radians= angle * PI/180 ;
//cout << velocity << endl;
// cout << radians << endl;
// cout << angle << endl;
secant (radians, velocity, kr, uc, q, b, x0, x1, angle, root, iteration);
writedata(angle, velocity, root);
}
}
system("pause");
}
// Definition of function "secant"
// Receives a, b, c, d and x0 values from main program
// Returns root and the iterations required
void secant(double radians, double velocity, double kr, double uc, double q, double b, double x0, double x1, double angle, double& root, int& iteration)
{
double xnminus1, xnplus1, xn; // Local variables
iteration=0; // Initialize iterations
xnminus1=x0;
xn=x1;
do
{
++iteration;
xnplus1 = xn - fx(radians, velocity, kr, uc, q, b, xn)*(xn-xnminus1)/
(fx(radians, velocity, kr, uc, q, b, xn)-fx(radians, velocity, kr, uc, q, b, xnminus1));
//cout<<"x"<<iteration+1<<" = "<<xnplus1<<endl;
xnminus1 = xn;
xn=xnplus1;
}
while ((fabs(fx(radians, velocity, kr, uc, q, b, xnplus1)) >= tol )&& (iteration < max_iter));
root=xnplus1;
//cout<<"\nThe root is = "<<root<<endl;
//cout<<"The number of iterations was = "<<iteration<<endl;
//cout<<"The value of f(x) at the root = "<<fx(radians, velocity, kr, uc, q, b, root)<<endl<<endl;
outfile(angle, velocity, root);
}
// Defines "fx"
double fx(double radians,double velocity, double kr, double uc, double q, double b, double ts)
{
return kr * pow(ts,4.0) + uc * ts - q - pow((velocity / b), 2.0) * sin(radians);
}
void writetable(double kr, double uc, double q, double b)
{
cout <<endl << "Input Parameters:" <<endl;
cout<< "Kr(1/K^2)=" << kr << endl << "uc(1/K)=" << uc <<endl << "q(unitless)=" << q << endl << "b(mph)=" << b<< endl;
cout << " angle..............velocity...........surface temp..............safe..........";
cout << " degs...............mph................Kelvin.....................?............";
cout << "--------------------------------------------------------------------------------";
}
void writedata (double angle, double velocity, double root)
{
cout << left << " " << angle << " "<< velocity << " "<< fixed << setprecision(0) << setw(5) <<root<< " ";
if(root <1000)
cout << "safe"<< endl;
else
cout << "unsafe" <<endl;
}
void tableout(double kr, double uc, double q, double b)
{
ofstream dataout ("results.txt");
dataout<<endl << "Input Parameters:" <<endl;
dataout<< "Kr(1/K^2)=" << kr << endl << "uc(1/K)=" << uc <<endl << "q(unitless)=" << q << endl << "b(mph)=" << b<< endl;
dataout << " angle..............velocity...........surface temp..............safe.........."<< endl;
dataout << " degs...............mph................Kelvin.....................?............"<< endl;
dataout << "--------------------------------------------------------------------------------"<< endl;
}
void outfile (double angle, double velocity, double& root)
{
ofstream dataout ("results.txt");
dataout << left << " " << angle << " "<< velocity << " "<< fixed << setprecision(0) << setw(5) <<root<< " ";
if(root <1000)
dataout << "safe"<< endl;
else
dataout << "unsafe" <<endl;
}
Is the open in outfile succeeding. You've opened the file for output in main; some systems won't allow the same file to be opened twice, or opened twice for output. (Since you don't use the open file in main, why open it there?)