Error Passing `const` as `this` argument of `const double` discards qualifiers - c++

I have to work within some libraries and no matter what i do i keep getting the following error with this code.
passing `const amko::problem::launch' as 'this'argument of 'const double amko::problem::launch::ratio(double, double)' discards qualifiers
namespace amko { namespace problem {
launch::launch():base( 0.0, 20.0, 1 ) {}
base_ptr launch::clone() const
{
return base_ptr(new launch(*this));
}
const double launch::ratio( const double a, const double b)
{
const double area = a*b;
const double circumference = 2*a+2*b;
const double ratio = circumference/area;
return ratio;
}
void launch::objfun_impl(fitness_vector &f, const decision_vector &xv) const
{
amko_assert(f.size() == 1 && xv.size() == get_dimension());
const double x = xv[0];
const double y = launch::ratio(x,5);
f[0] = y;
}
while the following piece of code worked just fine.
namespace amko { namespace problem {
initialValueProblem::initialValueProblem():base( 0.0, 20.0, 1 ) {}
base_ptr initialValueProblem::clone() const
{
return base_ptr(new initialValueProblem(*this));
}
Eigen::VectorXd initialValueProblem::computeDerivative( const double time, const Eigen::VectorXd& state )
{
Eigen::VectorXd stateDerivative( 1 );
stateDerivative( 0 ) = state( 0 ) - std::pow( time, 2.0 ) + 1.0;
return stateDerivative;
}
void initialValueProblem::objfun_impl(fitness_vector &f, const decision_vector &xv) const
{
amko_assert(f.size() == 1 && xv.size() == get_dimension());
const double x = xv[0];
double intervalStart = 0.0;
double intervalEnd = 10.0;
double stepSize = 0.1;
Eigen::VectorXd initialState_;
initialState_.setZero( 1 );
initialState_( 0 ) = x;
numerical_integrators::EulerIntegratorXd integrator( boost::bind( &initialValueProblem::computeDerivative,
const_cast<initialValueProblem*>( this ), _1, _2 ), intervalStart, initialState_ );
Eigen::VectorXd finalState = integrator.integrateTo( intervalEnd, stepSize );
f[0] = fabs( finalState( 0 ) - 11009.9937484598 );
}
Thank you!

launch::objfun_impl is a const member function, it cannot change members or call other functions that do. That means it can't call non-const non-static member functions such as launch::ratio.
Because launch::ratio doesn't appear to access members at all, just its arguments, the simplest fix is to make it a static member function by changing the prototype inside the class definition:
static /* <- ADDED static HERE */ double launch::ratio(const double a, const double b);

The problem is that your ratio member function is not const, even though you are not modifying any member of the object (why is it a member function at all?). Inside objfun_impl you are calling ratio. Now, objfun_impl is const, and thus promises not to modify the object, but calling ratio would break that promise.

Related

boost error: expression cannot be used as a function

I am trying to use the boost RK4 integration together with the rigid body dynamics library.
I am getting a strange error I dont recognize, that I think has to do with the operator() override but I am not sure based on this post.
My code is similar to this example. Which makes me think that either I am missing something obvious. I think that it may be a compiler problem.
This is my class I use to convert from RBDL to boost.
class rbdlToBoost {
public:
rbdlToBoost(Model* model) : model(model)
{
q = VectorNd::Zero(model->dof_count);
qd = VectorNd::Zero(model->dof_count);
qdd = VectorNd::Zero(model->dof_count);
tau = VectorNd::Zero(model->dof_count);
}
//3c. Boost uses this 'operator()' function to evaluate the state
// derivative of the pendulum.
void operator() (const state_type &x, state_type &dxdt, const double t)
{
//do stuff
}
private:
Model* model;
VectorNd q, qd, qdd, tau;
};
This is my main I am using to test the integration. This is a minimal example I put together.
#include "rbdl/Model.h"
#include "rbdl/Dynamics.h"
#include "rbdl_model_tests/DynamicTesting.h"
int main(int argc, char const *argv[])
{
int nPts = 100;
double t0 = 0;
double t1 = 3;
double t = 0; //time
double ts = 0; //scaled time
double dtsdt = M_PI/(t1-t0); //dertivative scaled time
double tp = 0;
double dt = (t1-t0)/((double)nPts);
//Integration settings
double absTolVal = 1e-10;
double relTolVal = 1e-6;
double a_x = 1.0 , a_dxdt = 1.0;
Model* model = NULL;
model = new Model();
rbdlToBoost rbdlBoostModel(model);
state_type xState(2);
int steps = 0;
xState[0] = -M_PI/4.0;
xState[1] = 0;
controlled_stepper_type controlled_stepper(
default_error_checker< double , range_algebra , default_operations >
( absTolVal , relTolVal , a_x , a_dxdt )
);
integrate_adaptive(
controlled_stepper ,
model , xState , tp , t , (t-tp)/10 );//This seems to be the problem
tp = t;
return 0;
}
I am getting this error:
~/catkin_ws/src/ambf_control_system/rbdl_model_tests/src/tempDyn.cpp:37:47: required from here
/usr/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp:481:12: error: expression cannot be used as a function
sys( x , m_dxdt.m_v ,t );
It turns out it was a simple fix
I just had to change.
I was passing in the wrong variable into the function. I had to pass in my custom class variable (rbdlBoostModel) not my RBDL model (model).
integrate_adaptive(
controlled_stepper ,
model , xState , tp , t , (t-tp)/10 );//This seems to be the problem
to
integrate_adaptive(
controlled_stepper ,
rbdlBoostModel , xState , tp , t , (t-tp)/10 );

Thread calling function with non-static members failing

I created a function void top() to render out an image by sending a ray for each pixel. I wanted to put it on a thread. I used #include <thread> library but when I declared the thread in the main() method it gave me two errors: Error C2893 Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept() and Error C2672 'std::invoke': no matching overloaded function. I think it could possibly be because void top() calls both non-static and static methods. Just learning about threading so a bit confused about what is wrong. All the functions below are inside the main cpp file.
void top(int& samples_per_pixel, camera& cam, const color& background, hittable& world, const int& max_depth) {
for (float j = image_height - 1; j >= image_height/2; --j) {
for (int i = 0; i < image_width; ++i) {
color pixel_color(0, 0, 0);
for (int s = 0; s < samples_per_pixel; ++s) {
auto u = (i + random_double()) / (image_width - 1); //Random double is static. From other header file
auto v = (j + random_double()) / (image_height - 1);
ray r = cam.get_ray(u, v); //get_ray() is non-static and in camera class
pixel_color += ray_color(r, background, world, max_depth); //Ray_color defined above top() method in same main cpp file
pixel_color += color(0, 0, 0);
}
auto r = pixel_color.x();
auto g = pixel_color.y();
auto b = pixel_color.z();
auto scale = 1.0 / samples_per_pixel;
r = sqrt(scale * r);
g = sqrt(scale * g);
b = sqrt(scale * b);
int ir = static_cast<int>(256 * clamp(r, 0.0, 0.999));
int ig = static_cast<int>(256 * clamp(g, 0.0, 0.999));
int ib = static_cast<int>(256 * clamp(b, 0.0, 0.999));
pixels[index++] = ir; //pixels defined above top() class
pixels[index++] = ig;
pixels[index++] = ib;
}
}
}
...
int main(){
...
std::thread first(top,samples_per_pixel, cam, background, world, max_depth); //Two errors being called here
first.detach();
}
From `std::thread::thread:
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g., with std::ref or std::cref).
So, just wrap each variable that you take by reference in one of the wrappers.
Prefer std::cref if you are not changing the value inside he thread and adjust your function's signature accordingly.
Instead of passing a const int&, just pass an int.
Example:
// new signature:
void top(int samples_per_pixel, camera& cam, const color& background,
hittable& world, int max_depth);
// new starting call:
std::thread first(top, samples_per_pixel, std::ref(cam), std::cref(background),
std::ref(world), max_depth);

How to accept both modifiable and non-modifiable arguments?

I have a debugging macro where I give it a float reference, and expect it to modify that variable sometimes, if it can.
#define probe(x) implProbe(#x##GETLINE, (x))
void implProbe(const char * loc, float & x){
// this signature is a place holder
...
x = 4.f;
}
However, I would also like to use the same macro for temporary variables or literals such as probe(1 + 2) or probe(x + y). The macro wouldn't need to have the same effect in those cases, I don't expect to see an output from it, I only want it to not break.
float var = 0.f;
probe(var);
// var == 4.f
var = 0.f;
probe(var + 2.f); // this should be legal
// var == 0.f (didn't change)
probe(1.f); // this should be legal
Is there a way to accomplish this?
Implement two overloaded functions.
void implProbe(const char * loc, float & x){
...
x = 4.f;
}
void implProbe(const char * loc, const float & x){
...
}

Using boost::numeric::odeint to integrate a non-linear function f'(x, y, z) = a + b*I

I would like to integrate a function that maps a 3D point (parametrized by t) to a 2D point (complex plane) using an adaptative step scheme. There is no closed-form for the derivative of my function and it is non-linear.
I've tried the following to see if the code would work. It compiles but the result is wrong. The test function being integrated (t from 0 to 1; i is the complex number) is
Exp[ -Norm[ {1.1, 2.4, 3.6}*t ] * i ]
The expected result is
-0.217141 - 0.279002 i
#include <iostream>
#include <complex>
#include <boost/numeric/ublas/vector.hpp>
namespace ublas = boost::numeric::ublas;
#include <boost/numeric/odeint.hpp>
namespace odeint = boost::numeric::odeint;
typedef std::complex<double> state_type;
class Integrand {
ublas::vector<double> point_;
public:
Integrand(ublas::vector<double> point){
point_ = point;
}
void operator () (const state_type &x, state_type &dxdt, const double t){
point_ *= t;
const std::complex<double> I(0.0, 1.0);
dxdt = std::exp( -norm_2(point_)*I );
}
};
std::complex<double> integral(ublas::vector<double> pt) {
typedef odeint::runge_kutta_cash_karp54< state_type > error_stepper_type;
double err_abs = 1.0e-10;
double err_rel = 1.0e-6;
state_type x = std::complex<double>(1.0, 0.0);
return odeint::integrate_adaptive(
odeint::make_controlled<error_stepper_type>(err_abs, err_rel),
Integrand(pt), x, 0.0, 1.0, 0.001);
}
int main() {
ublas::vector<double> pt(3);
pt(0) = 1.1;
pt(1) = 2.4;
pt(2) = 3.6;
std::cout << integral(pt) << std::endl;
return 0;
}
The code outputs
5051 + 0 i
I suspect the problem is in my definition of x, the state vector. I don't know what it should be.
I suspect your problem is because you are modifying point_ everytime you call Integrand::operator().
Instead of:
point_ *= t;
dxdt = exp(-norm_2(point_)*I);
You probably meant:
dxdt = exp(-norm_2(point_ * t) * I);
Your Integrand::operator() should be marked as a const function when you don't member variables to change, that would help catch these errors in the future.
After looking at the docs for odeint, integrate_adaptive returns the number of steps performed. The input parameter x actually holds the final result so you want to do:
odeint::integrate_adaptive(
odeint::make_controlled<error_stepper_type>(err_abs, err_rel),
Integrand(pt), x, 0.0, 1.0, 0.001);
return x;
Running this prints (0.782859,-0.279002), which is still not the answer you're looking for. The answer you're looking for comes as a result of starting x at 0 instead of 1.
state_type x = std::complex<double>(0.0, 0.0);
odeint::integrate_adaptive(
odeint::make_controlled<error_stepper_type>(err_abs, err_rel),
Integrand(pt), x, 0.0, 1.0, 0.001);
return x;

C++ Boost using newton_raphson_iterate on a class member function

My code below doesn't compile and can't get it why. Is it because I'm using the newton_raphson_iterate in a wrong way?
Do I need to use binding ? Any examples of how using the newton raphson on a member class function is welcome.
class MyB{
struct funct{
double target;
double DerivativePrecision;
int mo;
bool isG;
MyB* bond;
public:
funct(double target_, double DerivativePrecision_, int mo_, bool isG_, MyB* bond_ ) :
target(target_), DerivativePrecision(DerivativePrecision_), mo(mo_), isG(isG_), bond(bond_)
{}
std::tr1::tuple<double,double> operator()(const double& x) const {
double localYtP = bond->yTp(x, mo, isG);
return std::tr1::make_tuple (
localYtP - target,
(bond->yTp(x+DerivativePrecision,mo, isG)-localYtP)/DerivativePrecision
);
}
};
public:
/*
.....
*/
double yTp(double x, int mo, int isG);
double pty(double p, int mo, int isG){
funct localFunc(p, 0.000001, mo, isG, this);
double y = boost::math::tools::newton_raphson_iterate(localFunc(p),
0.1,
-0.1,
0.4,
std::numeric_limits<double>::digits
);
return y;
}
}
int main()
{
system("pause");
return 0;
}
I get two error messages :
First :
\boost/math/tools/roots.hpp(202) : error C2064: term does not evaluate to a function taking 1 arguments
pointing to the last line of this code (BOOST):
template <class F, class T>
T newton_raphson_iterate(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter)
{
BOOST_MATH_STD_USING
T f0(0), f1, last_f0(0);
T result = guess;
T factor = static_cast<T>(ldexp(1.0, 1 - digits));
T delta = 1;
T delta1 = tools::max_value<T>();
T delta2 = tools::max_value<T>();
boost::uintmax_t count(max_iter);
do{
last_f0 = f0;
delta2 = delta1;
delta1 = delta;
boost::math::tie(f0, f1) = f(result);
...
The second :
see reference to function template instantiation 'T boost::math::tools::newton_raphson_iterate<std::tr1::tuple<_Arg0,_Arg1>,double>(F,T,T,T,int)' being compiled
pointing (in my class ) to
double y = boost::math::tools::newton_raphson_iterate(localFunc(p),
0.1,
-0.1,
0.4,
std::numeric_limits<double>::digits
);
The problem is you're calling localFunc when trying to invoke newton_raphson_iterate so end up passing a funct as the first template parameter, which is not callable. You should just pass localFunc directly:
newton_raphson_iterate(localFunc, 0.1, -0.1, 0.4, std::numeric_limits<double>::digits);