C++ vector in class - c++

i'm new to C++ trying to learn parallel programming (coming from Basic), got stuck fairly early on.
class Particle{
private:
double p_x, p_y, v_x, v_y, mass
public:
Particle(double px, double py, double vx, double vy, double m) : p_x(px), p_y(px), v_x(vx), v_y(vx), mass(m) {};
vector<int> pos () {p_x, p_y}; //doesn't work, expects ';'
vector<int> vel () {v_x, v_y}; //doesn't work, expects ';'
};
I'm trying to create a class with properties pos and vel, both vectors. HNothing worked with what i'm trying to do - initializing vectors i guess.
Can anyone tell me how to make that work? Or if not that something like this:
class Particle{
private:
double p_x, p_y, v_x, v_y, mass
public:
Particle(double px, double py, double vx, double vy, double m) : p_x(px), p_y(px), v_x(vx), v_y(vx), mass(m) {};
void SetPos(int x, int y) //pseudo code based on Basic
void GetPos() as Vector //pseudo code based on Basic
};
Thanks in advance for your time, this has been a brick wall for me for a while. I've looked trough many other threads like this one around here but I don't know enough to adapt any of it to my needs i guess. To complicate things I'm using VS2012 Cuda 6.0 project which sometimes even acts differently than the standard C++ project. Reverted to 6.0 because chrono refused to work in 6.5. Would use the standard project but I don't know how (if possible) to integrate Cuda into it.

The () indicates that they're functions, not variables; and the rest of the syntax isn't valid for a function definition. Either make them variables:
vector<int> pos {p_x, p_y};
or valid functions:
vector<int> pos () {return {p_x, p_y};}
You probably want them to be functions, so that they don't duplicate the values of the other members, and give the expected results if the other members are modified.

Related

Calculating Inverse_chi_squared_distribution using boost

I'm trying to implement a function to calculate inverse_chi_squared_distribution, boost has a container named inverse_chi_squared_distribution, however, when I try to create an instance of the class I get this error too few template arguments for class template 'inverse_chi_squared_distribution'.
I'm on wsl:ubuntu-18.04 and other boost functions/containers work fine.
Here's the code generating the error:
boost::math::inverse_chi_squared_distribution<double> invChi(degValue);
Not exactly sure how to calculate it even if this instance is created (was gonna just hit and miss till I get it) so help using this to calculate the function would be much appreciated, thanks.
OK, do you want the inverse of a chi-squared distribution (ie its quantile) or do you want the "inverse chi squared distribution" which is a distribution in it's own right, also with an inverse/quantile!
If the former, then assuming v degrees of freedom, and probability p then this would do it:
#include <boost/math/distributions/chi_squared.hpp>
double chi_squared_quantile(double v, double p)
{
return quantile(boost::math::chi_squared(v), p);
}
If the latter, then example usages might be:
#include <boost/math/distributions/inverse_chi_squared.hpp>
double inverse_chi_squared_quantile(double v, double p)
{
return quantile(boost::math::inverse_chi_squared(v), p);
}
double inverse_chi_squared_pdf(double v, double x)
{
return pdf(boost::math::inverse_chi_squared(v), x);
}
double inverse_chi_squared_cdf(double v, double x)
{
return cdf(boost::math::inverse_chi_squared(v), x);
}
There are other options - you can calculate with types other than double then you would use boost::math::inverse_chi_squared_distribution<MyType> in place of the convenience typedef inverse_chi_squared.

C++ shared_ptr interesting behavior when passing into function (solved but curious)

Background
I'm writing some C++ code for a project that involves the simulation of a lot of State Space mathematical models. Because there are several different types of models that exist with varying degrees of complexity (ie non-linear/linear & time varying/non-varying) I created a polymorphic class structure that would be able to represent various features of each type while still keeping the common properties of the matrices bundled together nicely. This way I can generalize easily to various model types for simulation inside of OdeInt.
The current version of the simple base class looks like this:
class SS_ModelBase
{
public:
virtual Eigen::MatrixXd getA() = 0;
virtual Eigen::MatrixXd getB() = 0;
virtual Eigen::MatrixXd getC() = 0;
virtual Eigen::MatrixXd getD() = 0;
virtual Eigen::MatrixXd getX0() = 0;
virtual int getNumInputs() = 0;
virtual int getNumOutputs() = 0;
virtual int getNumStates() = 0;
private:
};
typedef boost::shared_ptr<SS_ModelBase> SS_ModelBase_sPtr;
Each derived class for the mentioned types then have their own variables for actually storing specific representations of the matrices A, B, C, D, & X0. The inputs, outputs, states are used for some dimensional information that might be needed for later manipulation. This has been working extremely well for me in practice.
An example of how I would use the model in the simulator is as shown:
Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt,
const SS_ModelBase_sPtr& model, const PID_Values pid)
{
/* Due to how Odeint works internally, it's not feasible to pass in a full state space model object
and run the algorithm directly on that. (Odeint REALLY dislikes pointers) Instead, a local copy of the
model will be made. For now, assume that only NLTIV models are handled. */
SS_NLTIVModel localModel(model);
/* Copy the relevant data from the model for cleaner code in main sim*/
Eigen::MatrixXd x = localModel.getX0();
Eigen::MatrixXd A = localModel.getA();
Eigen::MatrixXd B = localModel.getB();
Eigen::MatrixXd C = localModel.getC();
Eigen::MatrixXd D = localModel.getD();
//Other irrelevant code that actually performs numerical simulations
}
The custom copy constructor in the above code looks like this:
/* Copy constructor */
SS_NLTIVModel(const SS_ModelBase_sPtr& base)
{
inputs = base->getNumInputs();
outputs = base->getNumOutputs();
states = base->getNumStates();
A.resize(states, states); A.setZero(states, states);
B.resize(states, inputs); B.setZero(states, inputs);
C.resize(outputs, states); C.setZero(outputs, states);
D.resize(outputs, inputs); D.setZero(outputs, inputs);
X0.resize(states, 1); X0.setZero(states, 1);
U.resize(inputs, 1); U.setZero(inputs, 1);
}
Question
I noticed in some of my simulations that I would get memory access violation errors in the copy constructor when trying to resize the various matrices. std::malloc() gets called deep in the Eigen framework and was throwing errors. After many hours pounding my head against the wall trying to figure out why the Eigen software was suddenly not working, I stumbled upon a solution, but I don't know why it works or if there is a better way.
My old broken function signature looked like this:
Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt,
SS_ModelBase_sPtr model, PID_Values pid)
The new working function signature looks like this:
Eigen::MatrixXd StateSpaceSimulator::stepResponse(const double start, const double stop, const double dt,
const SS_ModelBase_sPtr& model, const PID_Values pid)
What's the run time difference between these two that could be causing my error? I know the first will increment the reference counter for the shared_ptr and the second will not, but other than that, I'm not sure what would change the behavior enough to cause my problem...thoughts?

erase-remove idiom problems for vector in a class

I am using class1 that contains a few governing variables and a vector of another class, class2. I would like to be able to flag various elements of the vector of class2 (using boolean variable 'delete_me') and then run the erase-remove idiom to eliminate those elements from the vector. I have found some examples of this on the web, but these are for simpler data structures than what I am using.
I am getting a type conversion error when I compile (using g++ v4.7.3).
Class2:
class Interval_structure {
//class uses default destructor
public:
float x1, x2, y1, y2;
float A;
float B;
float delta_x;
bool delete_me;
etc...
Class 1:
class CMR_Spline {
//class uses default destructor
public:
vector< Interval_structure > Interval;
int some_ints;
float some_floats;
bool IsMarkedToDelete( Interval_structure& o )
{
return o.delete_me;
}
void prune_Intervals() {
//intervals that have been slated for deletion are removed using the remove-erase idiom
Interval.erase( remove_if(Interval.begin(), Interval.end(), IsMarkedToDelete ), Interval.end() );
}
When I compile I get the following error, cited for the single line in the prune_Intervals routine using erase+remove_if:
error: cannot convert CMR_Spline::IsMarkedToDelete' from typebool (CMR_Spline::)(Interval_structure&) ' to type `bool (CMR_Spline::*)(Interval_structure&)'
I'm a little confused as to how I should write the IsMarkedToDelete function and prune_Intervals routine to correctly reflect the pointer that is used by remove-if to traverse the vector and evaluate IsMarkedToDelete.
How do I do this correctly using erase+remove_if, or if not that way please suggest an alternative approach. I am stumped and hindered by my limited programming experience. Thanks!
Make the function static:
static bool IsMarkedToDelete( Interval_structure& o )
{
return o.delete_me;
}

Calling constructors of certain classes based upon a common parameter c++

I'm currently working on class inheritance/polymorphism in my classes and I can't figure out this problem. Ok here it is: Let's say I have 2 mock classes, and I let the user choose a value that corresponds to the last parameter in the constructor:
class Planets {
private:
int x,y,z;
string a;
public:
Planets(string name, int diameter, int mass, int planet_kind) : a(name), x(diameter), y(mass), z(planet_kind) { }
Planets() { a="", x=0, y=0, z=0; }
//get and set functions to manipulate data
virtual void planet_creation(Planets& p1);
//function I want to modify depending on the planet
}
The thing to pay attention to is the planet_kind variable. I want the parent class to be a baseline for the others for example, gas giants would be 2, planets with life would be 1, etc... They would all have their own classes and constructors. For example in another class:
class Gas_giant : public Planets {
private:
int x,y,z;
string a;
public:
Gas_giant(string name, int diameter, int mass, int planet_kind) : a(name), x(diameter), y(mass), z(planet_kind) { }
Gas_giant() { a="Gas", x=0, y=0, z=2; }
//get and set functions to manipulate data
void planet_creation(Gas_giant& g);
//function I want to modify depending on the planet
//example: gas giants would be larger when created,have no solid mass,high gravity
}
basically I want the user to be able to input the kind of planet and the name, then depending on the kind they choose, call certain types of planets to be randomly generated in different ways. The functions aren't the problem, the issue I'm having is getting my program to choose different constructors based upon a parameter in a base constructor.
I don't want my program to create any "Type 0 " planets, it's just a class I'm trying to derive all the rest from.
Thanks in advance, and sorry if this is a dumb question.
There are languages in which a constructor can return a derived type, but C++ is not one of them. In C++ a constructor always constructs precisely its own type.
Anyway, it's not obvious that using a "planet_kind" integer is superior to using a different constructor. The different constructor option is likely to be quite a bit more readable:
Planet* henry = new GasGiant("Henry", ...);
Planet* bob = new Asteroid("Bob", ...);
...
If you really needed to use an enum for some reason (such as reading the data from a file), then you'll need a case statement:
for (;;) {
// read data into name, size, mass, kind
planets.emplace_back( make_planet(name, size, mass, kind) );
}
...
Planet* make_planet(std::string name, double radius, double mass, enum PlanetKind kind) {
switch (kind) {
case GIANT : return new GasGiant(name, radius, mass);
case ASTEROID: return new Asteroid(name, radius, mass);
// ...
default: // write an error message
}
}

Functions with many parameters - making them as structs

I'm writing an API for internal needs and so ease of use is one of the top priorities. I wonder if I'm pushing it too far as in the following example.
The function to solve the inverse geodetic problem takes in geocoordinates of two points and calculates distance between them and asimuths (angles) from each of the points to the other.
Ease-of-use-optimised conventional solution might look something like (please don't mind the length of the names, I know there's room for improvement):
class Angle;
class GeoCoordinate;
...
struct InverseGeodeticOut
{
Angle forwardAzimuth;
Angle backAzimuth;
double distance;
};
InverseGeodeticOut inverseGeodetic(const GeoCoordinate &firstPoint,
const GeoCoordinate &secondPoint);
// or
void inverseGeodetic(const GeoCoordinate &firstPoint,
const GeoCoordinate &secondPoint,
InverseGeodeticOut *result);
My question is how reasonable would it be to take it one step further to save user some typing:
class Angle;
class GeoCoordinate;
...
struct InverseGeodetic
{
InverseGeodetic();
InverseGeodetic(const GeoCoordinate &firstPoint,
const GeoCoordinate &secondPoint);
Angle forwardAzimuth;
Angle backAzimuth;
double distance;
};
// so the usages would be
InverseGeodeticOut inverse = inverseGeodetic(firstPoint, secondPoint);
InverseGeodeticOut inverse;
inverseGeodetic(firstPoint, secondPoint, &inverse);
InverseGeodetic inverse(firstPoint, secondPoint);
Perhaps in this particular example the difference is too small to be worth talking about but I wonder if such constructs are okay in general.
I like your 2nd code example, though I find the public constructor a bit confusing. Especially if there are other ways to construct an InverseGeodetic. I'd rather use a static factory method to construct it. That way you can give a more meaningful name to the method:
struct InverseGeodetic
{
Angle forwardAzimuth;
Angle backAzimuth;
double distance;
static InverseGeodetic FromTwoPoints(const GeoCoordinate &, const GeoCoordinate &);
};
// usage
auto inverse = InverseGeodetic::FromTwoPoints(a, b);
But then that might be my C# background bleeding through.