What I am trying to do in this question is in line with what I was trying to do in: Dynamic Eigen vectors in Boost::odeint. However now I am trying to encapsulate it all in a class as follows:
#include <iostream>
#include <Eigen/Core>
#include <cstdlib>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/eigen/eigen_algebra.hpp>
namespace odeint = boost::numeric::odeint;
typedef odeint::runge_kutta_dopri5<Eigen::VectorXd, double, Eigen::VectorXd, double, odeint::vector_space_algebra> stepper;
class foo
{
private:
Eigen::VectorXd m_x;
Eigen::MatrixXd m_A;
double m_t, m_dt;
public:
foo(int nr_of_states){ //ctor
m_t = 0;
m_dt = 1.0;
m_x = Eigen::VectorXd(nr_of_states);
m_A = Eigen::MatrixXd(nr_of_states, nr_of_states);
srand(365);
for (int i = 0; i < m_A.size(); i++){
*(m_A.data()+i) = ((double)rand()/(double)RAND_MAX);}
for (int i = 0; i < m_x.size(); i++){
*(m_x.data()+i) = i;}
}
void ODE_function(const Eigen::VectorXd &x, Eigen::VectorXd &dxdt, double){
dxdt = m_A * x;}
void next_step(){
odeint::integrate_adaptive(stepper(), ODE_function, m_x, m_t, (m_t+(1*m_dt)), m_dt);}
Eigen::VectorXd get_states(){
return m_x;}
};
int main()
{
int nr_of_states;
std::cout << "How many (random) states would you like to simulate?: ";
std::cin >> nr_of_states;
std::cout << std::endl;
foo f1(nr_of_states);
for (int i = 0; i < 100; i++){
f1.next_step();}
std::cout <<std::endl << "final state vector: " << std::endl << f1.get_states() << std::endl;
return 0;
}
I am using the MinGW 64 bit compiler to compile above code when I get the following error message:
\boost\boost_1_59_0\boost\numeric\odeint\stepper\base\explicit_error_stepper_fsal_base.hpp|297|error:
must use '.' or '->' to call pointer-to-member function in 'sys
(...)', e.g. '(... ->* sys) (...)'|
Is what I am trying to do here in principle possible? If yes, how should above code be adapted?
Related
I'm just revisiting C++, and I have a question about overloading of the [] operator, and more specifically why my program doesn't work.
Given the following code in vec.cpp:
double Vec::operator[](unsigned int i) const {
return this->values[i];
}
double & Vec::operator[](unsigned int i) {
return this->values[i];
}
These are defined in vec.h as methods to the Vec class, and if I do not use the operator in my main.cpp, all is fine and dandy. It compiles just as normal with no errors.
However once I do this in my main function (which is using std::cout and std::endl):
cout << a[0] << endl;
Things go wrong. The errors I get are a bunch of
candidate function template not viable: no known conversion from 'Vec' to 'char' for 2nd argument
operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
where you can replace 'char' with any primitive data type.
Here is a working example
// In vec.h
#pragma once
#include <string>
#include <iostream>
class Vec {
private:
int dims;
double *values;
public:
Vec(int dims, double values[]);
double operator [](unsigned int i) const;
double& operator[](unsigned int i);
};
// In vec.cpp
#include <iostream>
#include <string>
#include <cmath>
#include "vec.h"
using std::cerr, std::endl, std::cout;
Vec::Vec(int dims, double values[]) {
this->dims = dims;
this->values = new double[dims];
for(int i = 0; i < dims; i++) {
this->values[i] = values[i];
}
}
double Vec::operator[](unsigned int i) const {
if(i >= this->dims) {
cerr << "Elem out of range" << endl;
}
return this->values[i];
}
double & Vec::operator[](unsigned int i) {
if(i >= this->dims) {
cerr << "Elem out of range" << endl;
}
return this->values[i];
}
// In main.cpp
#include <iostream>
#include <string>
#include "vec.h"
using std::cout, std::endl;
int main() {
double avals[2];
avals[0] = 1.0;
avals[1] = 2.0;
Vec *a = new Vec(2, avals);
cout << a[0] << endl; // Error occurs here
return 0;
}
Can anyone help me sort this out?
In this declaration
Vec *a = new Vec(2, avals);
there is declared a pointer of the type Vec *. So an expression with the dereferenced pointer has the type Vec.
So in this statement
cout << a[0] << endl;
the expression a[0] has the type Vec.
It seems you mean
( *a )[0]
or
a[0][0]
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;
}
I would like to return an array to a pointer, in a virtual function that is a member of a derived class of a template class. In details, my classes definition is:
Sampler.h
#ifndef SAMPLER_H
#define SAMPLER_H
template <class T>
class Sampler
{
public:
virtual T getnumber()=0;
virtual T* simulation(int n)=0;
};
class UniformSampler:public Sampler<double>
{
public:
virtual double getnumber();
virtual double* simulation(int n);
UniformSampler(double a=0.0, double b=1.0);
private:
double low_bound;
double up_bound;
};
#endif
The class Sampler is a template class in order to be able to derive an other sampler with vectors later. The implementation is:
Sampler.cpp
#include "Sampler.h"
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
//Uniform
UniformSampler::UniformSampler(double a, double b)
{
low_bound=a;
up_bound=b;
}
double UniformSampler::getnumber()
{
int myrand=rand();
while((myrand==0)||(myrand==RAND_MAX)){myrand = rand(); } //We want a number in (0, RAND_MAX).
double myuni = myrand/static_cast<double>(RAND_MAX); //Create a number in (0,1).
return low_bound + myuni*(up_bound-low_bound);
}
double* UniformSampler::simulation(int n){
double simulations[n];
for(int i=0; i<n; i++){
simulations[i] = this->getnumber();
}
return simulations;
}
My problem is that, when I try to call this program in the main(), it looks like the assignment of the pointer doesn't work. Here is my main.cpp:
#include <iostream>
#include <math.h>
#include <cstdlib>
#include <time.h>
using namespace std;
#include "Sampler.h"
int main(){
srand(time(0));
int n=10;
double *unif = new double[n];
UniformSampler uni;
unif = uni.simulation(n);
for ( int i = 0; i < n; i++ ) {
cout << "*(p + " << i << ") : ";
cout << *(unif + i) << endl;
}
delete[] unif;
return 0;
}
When I run it, it doesn't print any of the elements that unif points to. I don't understand what is wrong there.
UniformSampler::simulation is twice wrong:
double simulations[n]; uses VLA extension, so not C++ standard compliant.
you return pointer on local variable, so dangling pointer.
Solution: use std::vector instead.
#include <vector>
template <class T>
class Sampler
{
public:
virtual ~Sampler() = default;
virtual T getnumber() = 0;
virtual std::vector<T> simulation(int n) = 0;
};
class UniformSampler:public Sampler<double>
{
public:
explicit UniformSampler(double a=0.0, double b=1.0);
double getnumber() overrid;
std::vector<double> simulation(int n) override
{
std::vector<double> res(n);
for (auto& val : res){
res = getnumber();
}
return res;
}
private:
double low_bound;
double up_bound;
};
int main(){
srand(time(0));
constexpr int n = 10;
UniformSampler uni;
auto unif = uni.simulation(n);
for (int i = 0; i < n; i++ ) {
std::cout << "p[" << i << "]: " << unif[i] << endl;
}
}
Im trying to use stable_sort in order to sort a vector of pointers
to a certain class. I've a code like this :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class B
{
public :
B(int y, int j) {x = y, r = j;};
void getVal() {cout << x << endl; };
int x;
int r;
};
bool compareB(B* b1, B* b2)
{
return b1->getVal() < b2->getVal();
}
int main()
{
B b1(3, 4), b2(-5, 7), b3(12, 111);
vector<B*> myVec;
myVec.push_back(&b1);
myVec.push_back(&b2);
myVec.push_back(&b3);
std::stable_sort(myVec.begin(), myVec.end(), compareB);
for (size_t size = 0; size < myVec.size(); ++size)
{
myVec[size]->getVal();
}
return 0;
}
However, I get the foolowing error while compiling it :
"error: invalid operands of types 'void' and 'void' to binary 'operator<'
return b1->getVal() < b2->getVal();"
Can someone help me ?
The problem is with
void getVal() {cout << x << endl; };
It returns void instead of some value.
When you use it in return b1->getVal() < b2->getVal(); it boils down to return void < void; which will not compile.
You should be able to change it to
int getVal() { return x; };
I want to be able to create not only a Chart, but a BarChart, and to pass in a vector of doubles and have that data put into the private member data. How would I do this in the BarChart (child) class of Chart? Also I am still confused as to pass by pointers, reference, or value, so I'm not sure if I am passing it correctly here. Please let me know how to fix this mess. Thank you for your help!
#include <vector>
using namespace std;
class Chart
{
public:
Chart(vector<double> &d) : data(d) {}
virtual void draw() const;
protected:
double value_at(int index) const; // ... only allows access, not modification
int get_size() const
{
return data.size();
}
private:
vector<double> &data; // Now data is safely private
};
class BarChart : public Chart
{
public:
virtual void draw() const
{
for (int x = 0; x < get_size() - 1; x++)
{
cout << value_at(x) << " ";
for (int y = 0; y < value_at(x); y++)
{
cout << "*";
}
cout << endl;
}
}
};
#include <iostream>
#include "chart.h"
#include <vector>
int main(int argc, char** argv)
{
vector<double> doubles;
doubles.resize(4);
for (int x = 0; x < 4; x++)
{
doubles[x] = x + 1.7;
}
BarChart c(doubles);
return 0;
}
I think this is what you want now. By the way you have to read these things for your future :)
How access modifiers works in inheritance
How constructors initialize in inheritance
What is the difference between pass by reference and pass by value.
These all you can read in the internet. Only thing is need to spend some time for find and read.
#include <vector>
#include <iostream>
class Chart
{
public:
Chart(std::vector<double> &d) : data(d) {}
virtual void draw(){}
double value_at(int index) const{ return data[index];}
int get_size() const{return data.size();}
private:
std::vector<double> &data;
};
class BarChart : public Chart
{
public:
BarChart(std::vector<double> &d):Chart(d)
{
}
virtual void draw()
{
for (int x = 0; x < get_size() - 1; x++)
{
std::cout << value_at(x) << " ";
for (int y = 0; y < value_at(x); y++)
{
std::cout << "*";
}
std::cout << std::endl;
}
}
};
int main()
{
std::vector<double> barchartData;
barchartData.push_back(10);
barchartData.push_back(20);
BarChart barchart(barchartData);
std::cout << "Barchart size :" << barchart.get_size() << std::endl;
std::vector<double> chartData;
chartData.push_back(500);
chartData.push_back(600);
Chart chart(chartData);
std::cout << "Chart size :" << chart.get_size() << std::endl;
return 0;
}