Trying to get code that was compilable in g++ to compile in VS2015. I looked around SO & Google with not much luck, yet cmath is documented in MSDN. I'm guessing I'm missing something really obvious or simple.
cmath is throwing a lot of errors most of the errors I'm getting during compilation, and half are in the form:
the global scope has no "<function>"
others are in the form
'<function>': redefinition; different exception specification
'<function>': identifier not found
'<function>': is not a member of "global namespace"
I don't understand why these errors are being thrown, but, if I use math.h, most of my compilation errors go away (including some in other standard libs that are crapping out, too).
Edit: As requested, the code. I'm using the sqrt & pow functions:
#include "vector.h"
#include <cmath>
using namespace vectormath;
vector::vector()
{
this->_x = 0;
this->_y = 0;
this->_z = 0;
this->_length = 0;
}
vector::vector(float x, float y, float z)
{
this->_x = x;
this->_y = y;
this->_z = z;
this->_length = sqrt(pow(_x, 2) + pow(_y, 2) + pow(_z, 2));
}
vector * vectormath::crossproduct(vector * a, vector * b)
{
vector * result = new vector();
result->_x = a->_y * b->_z - a->_z * b->_y;
result->_y = a->_z * b->_x - a->_x * b->_z;
result->_z = a->_x * b->_y - a->_y * b->_x;
return result;
}
point::point()
{
this->_x = 0.0;
this->_y = 0.0;
this->_z = 0.0;
}
point::point(float x, float y, float z)
{
this->_x = x;
this->_y = y;
this->_z = z;
}
float vectormath::dotproduct(vector a, vector b)
{
return a._x * b._x + a._y * b._y + a._z * b._z;
}
vector * vectormath::add(point * a, vector * b)
{
vector * c = new vector();
c->_x = a->_x + b->_x;
c->_y = a->_y + b->_y;
c->_z = a->_z + b->_z;
return c;
}
Edit: and vector.h
namespace vectormath
{
struct vector
{
float _x;
float _y;
float _z;
float _length;
vector();
vector(float x, float y, float z);
};
struct point
{
float _x;
float _y;
float _z;
point();
point(float x, float y, float z);
};
vector * crossproduct(vector*, vector*);
float dotproduct(vector a, vector b);
vector * add(point * a, vector * b);
}
The difference between
#include <math.h>
and
#include <cmath>
is that the former puts things like sqrt and pow into the global namespace (i.e., you refer to them just by saying sqrt or pow) and the latter puts them into namespace std (i.e., you refer to them by saying std::sqrt or std::pow).
If you want not to have to prefix them with std:: all the time, you can put individual ones in the global namespace explicitly:
using std::sqrt;
or (though this is not recommended) you can pull in the whole of std like this:
using namespace std;
The trouble with that is that there are a lot of names in std and you probably don't really want them all.
Related
I'm writing a simple C++ class called Vector2f. I have a class file called Vector2f.cpp and a header file called Vector2f.h.
My Vector2f class has a function called abs which returns a new Vector2f with the absolute value of each of the components of the original Vector2f. I am using the cmath library. However when I try to use cmath's abs function, it thinks I'm referring to some undefined function Vector2f::abs(float) rather than cmath's abs function. Why is there a naming conflict here? Shouldn't C++ be able to resolve that a function called abs that takes a float is only defined in cmath and not in Vector2f.h
Here is my code:
My header file:
//Vector2f.h
#ifndef VECTOR2F_H
#define VECTOR2F_H
class Vector2f
{
private:
float x;
float y;
public:
Vector2f(float x, float y);
float length();
float dot(Vector2f r);
Vector2f normalized();
Vector2f rot(float angle);
Vector2f add(Vector2f r);
Vector2f add(float r);
Vector2f sub(Vector2f r);
Vector2f sub(float r);
Vector2f mul(Vector2f r);
Vector2f mul(float r);
Vector2f div(Vector2f r);
Vector2f div(float r);
Vector2f abs();
float getX();
float getY();
};
#endif // VECTOR2F_H
My class file:
//Vector2f.cpp
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif // M_PI
#include "Vector2f.h"
#include <cmath>
Vector2f::Vector2f(float x, float y)
{
this -> x = x;
this -> y = y;
}
float Vector2f::length()
{
return (float)sqrt(x * x + y * y);
}
float Vector2f::dot(Vector2f r)
{
return x * r.getX() + y * r.getY();
}
Vector2f Vector2f::normalized()
{
float length = Vector2f::length();
float xnormal = x/length;
float ynormal = y/length;
return Vector2f(xnormal, ynormal);
}
Vector2f Vector2f::rot(float angle)
{
double rad = angle * M_PI / 180.0;
double c = cos(rad);
double s = sin(rad);
return Vector2f((float)(x * c - y * s), (float)(x * s + y * c));
}
Vector2f Vector2f::add(Vector2f r)
{
return Vector2f(x + r.getX(), y + r.getY());
}
Vector2f Vector2f::add(float r)
{
return Vector2f(x + r, y + r);
}
Vector2f Vector2f::sub(Vector2f r)
{
return Vector2f(x - r.getX(), y - r.getY());
}
Vector2f Vector2f::sub(float r)
{
return Vector2f(x - r, y - r);
}
Vector2f Vector2f::mul(Vector2f r)
{
return Vector2f(x * r.getX(), y * r.getY());
}
Vector2f Vector2f::mul(float r)
{
return Vector2f(x * r, y * r);
}
Vector2f Vector2f::div(Vector2f r)
{
return Vector2f(x / r.getX(), y / r.getY());
}
Vector2f Vector2f::div(float r)
{
return Vector2f(x / r, y / r);
}
Vector2f Vector2f::abs()
{
//I get the error, "error: no matching function for call to 'Vector2f::abs(float&)'", here
//when trying to call abs(x) and abs(y)
float xabs = abs(x);
float yabs = abs(y);
return Vector2f(xabs, yabs);
}
float Vector2f::getX()
{
return x;
}
float Vector2f::getY()
{
return y;
}
My main file:
//main.cpp
#include <iostream>
#include "Vector2f.h"
using namespace std;
int main()
{
Vector2f a(1.0f,2.0f);
cout<<a.getX()<<','<<a.getY()<<endl;
cout<<a.abs()<<endl;
return 0;
}
Any help would be appreciated.
Edit:
Error message:
error: no matching function for call to 'Vector2f::abs(float&)'
at line 80:
float xabs = abs(x);
error: no matching function for call to 'Vector2f::abs(float&)'
at line 81:
float yabs = abs(y);
The compiler does an unqualified lookup of abs. What happens then depends on what you include and if there is a using declaration (and interestingly on the compiler). Everything in cmath is defined in namespace std, so you have to qualify your call with std::.
Vector2f Vector2f::abs()
{
//I get the error, "undefined reference to `Vector2f::abs(float)'", here
//when trying to call abs(x) and abs(y)
float xabs = std::abs(x);
float yabs = std::abs(y);
return Vector2f(xabs, yabs);
}
If you have a using std::abs or using namespace std somewhere before Vector2d::abs, you can qualify with ::abs only. Compilers are allowed to declare C functions such as abs in the global namespace in addition to namespace std, so depending on the compiler using ::abs may work or not without using declarations at all. Clang 3.8 accepts the code, gcc does not.
PS: I would expect a function Vector2f::abs to compute the vector norm and not a vector with absolute values of the original components. But then I am not a mathematician.
I have this C++ program:
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
using namespace std;
double dx2(int t, int x, int dx)
{
return (-9.8*cos(x));
}
int square(int x)
{
return (x*x);
}
double RK4(float t, float x, float dx, float h)
{
double k1, k2, k3, k4, l1, l2, l3, l4, diff1, diff2;
k1 = h*dx2(t,x,dx);
l1 = h*k1;
k2 = h*dx2(t+h/2,x+l1/2,dx+k1/2);
l2 = h*k2;
k3 = h*dx2(t+h/2,x+l2/2,dx+k2/2);
l3 = h*k3;
k4 = h*dx2(t+h,x+l3,dx+k3);
l4 = h*k4;
diff1 = (l1+2*l2+2*l3+l4)/float(6);
diff2 = (k1+2*k2+2*k3+k4)/float(6);
double OUT[] = {diff1, diff2};
return OUT;
}
int main()
{
double diff, t, t0, t1, x, x0, dx, dx0, h, N;
N = 1000;
t0 = 0;
t = t0;
t1 = 10;
x0 = 0;
x = x0;
dx0 = 0;
dx = dx0;
h = (t1 - t0) / float(N);
for(int i = 1; i<=N; i++) {
diff = RK4(t,x,dx,h);
x = x + diff;
t = t + h;
}
cout << diff;
return 0;
}
As you can see in this program I am solving the 2nd-order differential equation (if there is a way to insert LaTeX equations into my question please tell me):
d2x/dt2= -9.8 cos(x)
which is an example of the simple pendulum's equations of motion. The problem lines are 33 and 34. In it I am attempting to define the first element of the OUT array as diff1 and the second element as diff2. Whenever I compile this program (named example.cpp) I get the error:
g++ -Wall -o "example" "example.cpp" (in directory: /home/fusion809/Documents/CodeLite/firstExample)
example.cpp: In function ‘double RK4(float, float, float, float)’:
example.cpp:33:9: error: cannot convert ‘double*’ to ‘double’ in return
return OUT;
^~~
Compilation failed.
Exactly, since you're returning an array of double's, that decays to double*, but the function is defined to return double. An array of type T and the type T are different types in C++, and they can't be converted between, generally speaking.
In this case, you might be better off with a std::pair<T1, T2> (#include <utility>) since you're using C++ and the standard library, or a structure with two fields of type double. Look up std::pair<> and std::tie<>, the former being used to make pairs of elements of different types, and the latter being used to make tuples of different types of arbitrary size.
When you write the std::pair's elements to std::cout, use the first, second members to access the pair's fields. A std::pair can't be directly output using the overloaded stream operator for std::cout.
Edit:
#include <utility>
std::pair<double, double> RK4(float t, float x, float dx, float h)
{
/* snip */
diff1 = (l1+2*l2+2*l3+l4)/float(6);
diff2 = (k1+2*k2+2*k3+k4)/float(6);
return {diff1, diff2};
}
int main()
{
double x, dx;
/* snip */
for(int i = 1; i<=N; i++) {
std::pair<double, double> diff = RK4(t,x,dx,h);
// or use with C++11 and above for brevity
auto diff = RK4(t,x,dx,h);
x = x + diff.first;
dx = dx + diff.second;
t = t + h;
}
cout << x << " " << dx << "\n" ;
return 0;
}
The return type of your RK4 function is double, which is a single value, but you're trying to return an array of two of them. That won't work. You could change the return type to double* and use new double[2] to allocate an array, but it'd be simpler and safer to use std::pair<double, double> as the return type. Then you can just do return { diff1, diff2 };.
To return several values from function you have several choice:
as all you returned type are identical, you may return array:
std::array<double, 2> RK4(float t, float x, float dx, float h)
{
// ...
return {{diff1, diff2}};
}
or std::vector
std::vector<double> RK4(float t, float x, float dx, float h)
{
// ...
return {{diff1, diff2}};
}
You may return std::tuple or std::pair (limited to 2 elements):
std::pair<double, double> RK4(float t, float x, float dx, float h)
{
// ...
return {{diff1, diff2}};
}
or
std::tuple<double, double> RK4(float t, float x, float dx, float h)
{
// ...
return {{diff1, diff2}};
}
You may also create a custom class
struct RK4Result
{
double diff1;
double diff2;
};
RK4Result RK4(float t, float x, float dx, float h)
{
// ...
return {diff1, diff2};
}
And for type expensive to move, you may use any previous method, but by out parameters:
struct RK4Result
{
double diff1;
double diff2;
};
void RK4(float t, float x, float dx, float h, RK4Result& res)
{
// ...
res = {diff1, diff2};
}
I am making a program that converts rectangular coordinates into polar coordinates and whenever I go to run the program it tells me that the "angle" is undeclared even though I am sure I have declared it. As well I know that the program isn't returning anything, I just want to be able to run it for now.
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;
double random_float(double min, double max);
void rect_to_polar(double x, double y, double &distance, double &angle);
int main() {
double x, y;
x = random_float(-1, 1);
y = random_float(-1, 1);
rect_to_polar(x, y, distance, angle);
}
double random_float(double min, double max) {
unsigned int n = 2;
srand(n);
return ((double(rand()) / double(RAND_MAX)) * (max - min)) + min;
}
void rect_to_polar(double x, double y, double &distance, double &angle) {
const double toDegrees = 180.0/3.141593;
distance = sqrt(x*x + y*y);
angle = atan(y/x) * toDegrees;
}
You did not declare anything called angle in your main(), but still used the name angle there. Thus the error.
You might want to read up on scopes.
You should declare distance and angle in your main.
int main() {
double x, y, angle, distance;
x = random_float(-1, 1);
y = random_float(-1, 1);
rect_to_polar(x, y, distance, angle);
}
I am getting the following error message when I try to run the following code when I try to add the function RK4 using a header file.
C:\Documents\C code\RK4\addRK4.h|7|error: expected ')' before '(' token|
There are a bunch of other error messages after that but I don't think they are important. I can't figure out what's wrong, especially since when I define the prototype of RK4 in main.cpp, everything runs just fine. The relevant code is below. Any help on this matter (or if you have any other suggestions since I am pretty new to c++) would be greatly appreciated!
main.cpp
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include "gnuplot.h"
#include "addfitzhough.h"
#include "addRK4.h"
using namespace std;
using namespace Eigen;
int main()
{
//int mydims = 2;
double u = 0;
double *Iion;
double h = .5;
double y1ans[800];
double y2ans[800];
double tans[800];
Vector2d ycurr;
Vector2d Ynot, yplus;
Ynot << .2,
.1;
y1ans[0] = Ynot(0);
y2ans[0] = Ynot(1);
tans[0] = 0.0;
for(int i = 1;i<800;i++){
tans[i] = tans[i-1] + h;
ycurr << y1ans[i-1],
y2ans[i-1];
yplus = RK4(fitzhough,tans[i],ycurr,h,u,Iion,2);
y1ans[i] = yplus(0);
y2ans[i] = yplus(1);
}
}
addRK4.h
#ifndef RK4
#define RK4
using namespace Eigen;
VectorXd RK4(VectorXd (*f) (double t, Vector2d Y, double u, double * Iion), double t, VectorXd z, double h, double u, double *Iion, int d);
#endif // RK4
RK4.cpp
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
Vector2d RK4(Vector2d (*f)(double, Vector2d, double, double*), double t, VectorXd z, double h, double u, double *Iion, int d){
VectorXd Y1(d), Y2(d), Y3(d), Y4(d), Y1buf(d), Y2buf(d), Y3buf(d);
Y1 = z;
Y1buf = (*f)(t,Y1,u, Iion);
Y2 = z + 0.5*h*Y1buf;
Y2buf = (*f)(t+.5*h,Y2,u, Iion);
Y3 = z + 0.5*h*Y2buf;
Y3buf = (*f)(t+.5*h,Y3,u, Iion);
Y4 = z + h*Y3buf;
Vector2d yn = z + (h/6.0)*(Y1buf + 2.0*Y2buf + 2.0*Y3buf + (*f)(t+h,Y4,u, Iion));
return yn;
}
fitzhough.cpp
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
Vector2d fitzhough(double t, Vector2d Y, double u, double * Iion){
Vector2d dy;
double v = Y(0);
double w = Y(1);
double a = .13;
double b = .013;
double c1 = .26;
double c2 = .1;
double d = 1.0;
dy(0) = c1*v*(v-a)*(1-v)-c2*w*v + u;
dy(1) = b*(v-d*w);
*Iion = dy(0)-u;
return dy;
}
You have a symbol clash.
You #define the symbol RK4 and then you try to create a function with that name. Because you have defined it as an empty macro, it will be replaced with nothing. Then the compiler sees this as your function declaration:
VectorXd (VectorXd (*f) (double t, Vector2d Y, double u, double * Iion), double t, VectorXd z, double h, double u, double *Iion, int d);
It's a good idea to add extra characters for your header cages. Something like:
#ifndef RK4__H
#define RK4__H
It appears to be something wrong with the types Vector2d and VectorXd.
Edit: good catch #Paddy. Leaving the rest of the answer here since it is still valid.
Also, your declaration in addRK4.h doesnt match the definition in RK4.cpp. This will be the next error you will be fixing.
I am trying to get area of circle using my program. But area is not coming in decimals.
#include<iostream>
using namespace std;
float AreaOfCircle(float r);
int AreaOfCircle(int r);
int main()
{int rad;
cout<<"Enter the Radius of Crircle: ";
cin>>rad;
cout<<"The Are of the Cirlcle: "<<AreaOfCircle(rad);
}
float AreaOfCircle(float r)
{
int area=0;
area=2*3.1456*r*r;
return area;
}
int AreaOfCircle(int r)
{
int area=0;
area=2*3.1456*r*r;
return area;
}
But I need answer to some decimal point.
You're not calling the float version of the method.
Either declare your variable as float
float rad;
or cast it to float before you call the method.
AreaOfCircle((float)rad);
You also need to use float instead of int inside the overloaded method:
float AreaOfCircle(float r)
{
float area=0; // <--- float here
area=2*3.1456*r*r;
return area;
}
Also:
area = pi * r * r
length = 2 * pi * r
pi ~= 3.1415
In addition to answer by #Luchian, you need to change the returned value to a float:
float AreaOfCircle(float r)
{
int area=0; // <<----- float area = 0;
area=2*3.1456*r*r;
return area;
}
change to:
float AreaOfCircle(float r)
{
float area=0;
area=2*3.1456*r*r;
return area;
}
or just:
float AreaOfCircle(float r) { return 2*3.1456*r*r; }
The compiler will call the overload it feels is the best match to the types of parameters it is passed. Because you passed an int, it assumed you wanted the int version.
By casting to a float as Luchian suggested (or using a float in the first place) you are telling the compiler that you intend the parameter to be a float type - thus, it picks the float version.