Applying callback to call gsl_integration - c++

I am a newbie in c++ and I am trying to modify a code and use gsl_integration library of c in a class called Cosmology. In order to assign member functions to to form a pointer for gsl, I used callback procedure I found by looking up in internet
Update: Cosmology.h
#include <cmath>
#include <gsl/gsl_integration.h>
struct CCallbackHolder
{
Cosmology* cls;
void* data;
};
class Cosmology {
private:
static const double c = 299792458.0, Mpc2Km = 3.08567758e+19, Yrs2Sec = 3.15569e7;
double H0 = 67.77, OmegaM = (0.022161+0.11889)/(H0*H0), OmegaL = 0.6914, OmegaG = 8.24e-5, OmegaK = 0.0009;
double Ez(double z);
double Hz(double z, void* params);
static double CCallback(double z,void* param)
{
CCallbackHolder* h = static_cast<CCallbackHolder*>(param);
return h->cls->Hz(h->data);
}
public:
double distH, timeH;
Cosmology();
Cosmology(double);
Cosmology(double , double );
Cosmology(double , double , double );
Cosmology(double , double , double , double );
Cosmology(double , double , double , double , double );
double distC(double);
} cosmo;
Cosmology.cpp
#include <cmath>
#include <gsl/gsl_integration.h>
#include "Cosmology.h"
#include<iostream>
using namespace std;
double Cosmology::Hz(double z, void* params) {
double result = 1.0/pow(OmegaL + pow(1.0+z,3.0)*OmegaM + pow(1.0+z,4.0)*OmegaG + pow(1.0+z,2.0)*OmegaK, 0.5);
return result;
}
double Cosmology::distC(double z) {
double lower_limit = 0.0, abs_error = 1.0e-8, rel_error = 1.0e-8, alpha = 0.0, result, error;
gsl_integration_workspace *work_ptr = gsl_integration_workspace_alloc(1000);
gsl_function Hz_function;
void* params_ptr = α
Hz_function.function = &Cosmology::CCallback;
Hz_function.params = params_ptr;
gsl_integration_qags(&Hz_function, lower_limit, z, abs_error, rel_error, 1000, work_ptr, &result, &error);
return distH*result;
}
using namespace std;
int main () {
Cosmology cosmo;
cout << "Comoving Distance: " << cosmo.distC (0.3);
return 0;
}
I am getting the following errors when I tried to compile the code:
Cosmology.h:10: error: ISO C++ forbids declaration of ‘Cosmology’ with no type
Cosmology.h:10: error: expected ‘;’ before ‘*’ token
Cosmology.h:16: error: ISO C++ forbids declaration of ‘constexpr’ with no type
Cosmology.h:16: error: expected ‘;’ before ‘double’
Cosmology.h:17: error: ISO C++ forbids declaration of ‘constexpr’ with no type
Cosmology.h:17: error: expected ‘;’ before ‘double’
In file included from Universe.cpp:3:
Cosmology.h: In static member function ‘static double Cosmology::CCallback(double, void*)’:
by compiling with this line : g++ -Wall -pedantic Cosmology.cpp -o Cosmology std=c++0x. How could I fix the code?

The main problem with your program is that you initialize non-static variables that are class members while declaring them, which is not a legal C++ operation. To be specific, the problem are these lines:
static constexpr double c = 299792458.0, Mpc2Km = 3.08567758e+19, Yrs2Sec = 3.15569e7;
double H0 = 67.77, OmegaM = (0.022161+0.11889)/(H0*H0), OmegaL = 0.6914, OmegaG = 8.24e-5, OmegaK = 0.0009;
c, Mpc2Km, Yrs2Sec, H0, OmegaM, OmegaL, OmegaG, OmegaK are non-static, non-const and double. If you want to initialize them (i.e. assign values to them), you have to do it within the Cosmology class constructor or move them outside of the class declaration and thus make them global, but note that you should avoid global variables unless you know what you do and there's no other way.
If you want to initialize them in the header file like you tried to do, they must be of integral type - won't work for doubles.
Shortly: the first line won't work because the type is double (only integral static const types can be initialized inside class declaration); the second won't work since the type is non-const, non-static and double.
The rest of the errors will probably vanish as soon as these lines are fixed.

Related

Can't fix static linkage issue by adding static to function prototype

I am trying to get GPS data from "/mavros/global_position/global" using the following codes below:
This is a header file:
#pragma once
#include <sensor_msgs/NavSatFix.h>
#include <ros/ros.h>
class Localization{
public:
// Functions
void receiver(const sensor_msgs::NavSatFixConstPtr& data);
// Constructors
Localization(ros::NodeHandle);
private:
// Data types
double latitiude;
double longitude;
double altitude;
const std::string topic {"/mavros/global_position/global"};
};
void Localization::receiver(const sensor_msgs::NavSatFixConstPtr& fix){
if (fix->status.status == sensor_msgs::NavSatStatus::STATUS_NO_FIX) {
ROS_INFO("No fix.");
return;
}
latitiude = (*fix).latitude;
longitude = (*fix).longitude;
altitude = (*fix).altitude;
ROS_INFO("Latitude: %f | Longitude: %f | Altitude: %f", latitiude, longitude, altitude);
};
Localization::Localization(ros::NodeHandle nh){
ros::Subscriber location = nh.subscribe(topic, 1, receiver);
};
When I tried to build the entire program using catkin_make I get the following error:
error: cannot declare member function ‘void Localization::receiver(const NavSatFixConstPtr&)’ to have static linkage [-fpermissive]
static void Localization::receiver(const sensor_msgs::NavSatFixConstPtr& fix){
I searched online and found a rather simple solution to this issue which is to add static to the void receiver function prototype. However, if I do so, I can not also access the private class members.
I used changed the constructor definition to:
Localization::Localization(ros::NodeHandle nh){
ros::Subscriber location = nh.subscribe(topic, 1, Localization::receiver, this);
};
This gave me a similar error:
error: invalid use of non-static member function ‘void Localization::receiver(const NavSatFixConstPtr&)’
ros::Subscriber location = nh.subscribe(topic, 1, Localization::receiver, this);
^
/home/kannachan/drone/src/quantum_drone/scripts/missions/gps.h:11:9: note: declared here
void receiver(const sensor_msgs::NavSatFixConstPtr& data);

Random number example from Stroustrup has compilation error

I'm using this random number example from Stroustrup C++ 4th Ed Page 1182. The compiler is reporting an error on the line with auto, stating that auto cannot be used with non-static members of classes. I'm confused on what the type of this bind results in. Does anyone know how to resolve the error so the random number generator can be used?
#include <random>
using namespace std;
class Rand_int {
public: // added
Rand_int(int lo, int hi) : p{lo,hi} { }
int operator()() const { return r(); }
private:
uniform_int_distribution<>::param_type p;
auto r = bind(uniform_int_distribution<>{p},default_random_engine{});
};
int main()
{
Rand_int ri {0,10};
int pz = ri();
return 0;
}
Compilation error:
clang++ -Wall -std=c++11 -pedantic test252.cc && ./a.out
test252.cc:11:5: error: 'auto' not allowed in non-static class member
auto r = bind(uniform_int_distribution<>{p},default_random_e...
^~~~
You can't use auto for the type of a non-static member of a class, so the code example is wrong.
Instead, you can do:
class Rand_int {
private:
std::function<int()> r = bind(uniform_int_distribution<>{p},default_random_engine{});
// ...
};
This converts the return type of std::bind to a void function returning an int, which is the desired behavior.
Here's a demo.

Error in C++ : redefinition of class constructor

I've encountered these two error when trying to compile..
anyone knows whats wrong ?
Was thinking maybe I #include the wrong header file ?
the sample of the codes and error as per following:
Error:
Square.cpp:8: error: redefinition of ‘Square::Square(bool, Point*, std::string, int)’
Square.h:21: error: ‘Square::Square(bool, Point*, std::string, int)’ previously defined here
Square.cpp: In member function ‘Point Square::getCoord()’:
Square.cpp:22: error: expected primary-expression before ‘]’ token
Square.cpp: In member function ‘void Square::setCoord(Point*)’:
Square.cpp:32: error: expected primary-expression before ‘]’ token
Square.cpp:32: error: expected primary-expression before ‘]’ token
cpp file
#include "Square.h"`
#include <cmath>
using namespace std;
Square::Square(bool containsWarpSpace, Point coord[], string shapeName, int vertPoint):ShapeTwoD(shapeName, containsWarpSpace) {
vertPoint = vertPoint;
coord[] = coord[];
}
int Square::getVertPoint()
{
return vertPoint;
}
Point Square::getCoord()
{
return coord[];
}
void Square::setVertPoint(int verticleP)
{
vertPoint = verticleP;
}
void Square::setCoord(Point coord[])
{
coord[] = coord[];
}
header:
#include "ShapeTwoD.h"
class Square : public ShapeTwoD
{
private:
int vertPoint;
Point coord[];
public:
//Accessor
int getVertPoint();
Point getCoord();
//Mutator
void setVertPoint(int vertP);
void setCoord(Point coord[]);
//virtual member
virtual double computeArea(Point x, Point y);
Square(bool containsWarpSpace, Point coord[], std::string shapeName = "Square", int vertPoint = 4):ShapeTwoD(shapeName, containsWarpSpace){}
};
You are defining the constructor twice, once in the header and once in the implementation file. In the header, you just need to declare it like this:
Square(bool containsWarpSpace,
Point coord[],
std::string shapeName = "Square",
int vertPoint = 4);
You also need to fix the handling of coord, maybe something like changing coord to
Point* coord;
and use
Point* Square::getCoord()
{
return coord;
}
and
this->coord = coord;
in the constructor and setCoord().
Please note that your way of handling coord seems strange and dangerous to me, but without further information about what you are actually trying to do it's hard to give specific advise. Generally, consider using the standard containers over manual memory/array management.
The compiler clearly tells you the problem:
You defined the constructor twice once in header file and once in cpp file.
Also, What exactly do you intend to do with:
coord[] = coord[];
You should understand each and every statement of code that you write. Think about, What do you intend this statement to do? & then match it to the language grammar that you learnt.
Source File:
Square::Square(bool containsWarpSpace, Point coord[],
string shapeName, int vertPoint)
:ShapeTwoD(shapeName, containsWarpSpace)
{
vertPoint = vertPoint;
coord[] = coord[];
}
Header File:
Square(bool containsWarpSpace, Point coord[],
std::string shapeName = "Square", int vertPoint = 4)
:ShapeTwoD(shapeName, containsWarpSpace)
{}
Looks like two different version of the same function.
The one in the header file calls the base class constructor but does not have any code in the body of the constructor.

c++ Set not compiling properly

I am creating a data structure but when I try and compile I get an error saying that I haven't specified that type of set that I am initializing.
I am working with the NTL library with is used for large numbers.
This is my code:
#include <set>
#include ...
NTL_CLIENT
using namespace std;
using namespace NTL;
const RR ZERO = to_RR(0);
const RR ONE = to_RR(1);
const RR TWO = to_RR(2);
class tenTree
{
public:
tenTree(string newName = "", int newLevel = 0);
~tenTree();
void put(string prefix, RR power);
bool get(string prefix, RR & output);
void display(int depth);
bool isKnown(RR power){return (powers.find(power) != powers.end());};
private:
tenTree* children [10];
set<int> powers;
int level;
string name;
bool child[10];
};
When I try to compile it comes back with an error saying:
twoPow.cpp:47: error: ISO C++ forbids declaration of \u2018set\u2019 with no type
twoPow.cpp:47: error: expected \u2018;\u2019 before \u2018<\u2019 token
twoPow.cpp: In member function \u2018bool tenTree::isKnown(NTL::RR)\u2019:
twoPow.cpp:44: error: \u2018powers\u2019 was not declared in this scope
Is there something that I am missing here?
It was just a matter of the scope. All I had to do was add an std:: before the set and it compiled correctly.

error: expected unqualified-id before ‘.’ token - std :: vector

Code:
#include <vector>
#include <iostream>
typedef struct
{
std :: string latitude;
std :: string longitude;
} coordinate;
std :: vector <coordinate> previousPoints;
int main ()
{
coordinate.latitude = latitude;
coordinate.longitude = longitude;
previousPoints.push_back (coordinate);
return 0;
}
Output:
anisha#linux-y3pi:~> g++ -Wall demo.cpp
demo.cpp: In function ‘int main()’:
demo.cpp:14:12: error: expected unqualified-id before ‘.’ token
demo.cpp:15:12: error: expected unqualified-id before ‘.’ token
demo.cpp:16:38: error: expected primary-expression before ‘)’ token
What's the point that I am missing?
You need to create an actual variable to be added to your vector:
int main ()
{
coordinate c;
c.latitude = latitude;
c.longitude = longitude;
previousPoints.push_back (c);
typedef struct
{
std :: string latitude;
std :: string longitude;
} coordinate;
coordinate is typedef on anonymous struct, not object. You should create object of coordinate in your function, or not use typedef, i.e.
struct coord
{
std :: string latitude;
std :: string longitude;
} coordinate;
now, coordinate is object. And one question, why you type spaces after std and after ::? It's legal, but strange.
coordinate.latitude = latitude;
You need an object to access a members of it, but coordinate just names a struct. Also on the right hand side you don't have a value... You need something like:
coordinate c;
c.latitude = "120";
c.longitude = "10";
previousPoints.push_back(c);