-
August 23rd, 2010, 09:03 PM
#1
Class inside the same class
Hi,
I am writing a simulation code. I have a class called "particle" which hold gas particles. Each gas particle has its neighbouring gas particles. And its neighbouring gas particles have their own neighbouring particles. I tried to write the "particle" class like below to hold neighbouring particles also:
Code:
class particle {
int x; // particle location
int y;
int z;
particle *neighbour; // I have taken one neighbour particle for simplicity to illustrate the problem.
// Actually, it is vector of particles.
};
Is it valid? Any other idea will be appreciated.
Thanks.
-
August 24th, 2010, 12:03 AM
#2
Re: Class inside the same class
You can have multimap of particles:
http://www.cplusplus.com/reference/stl/multimap/
Code:
class particle {
int x; // particle location
int y;
int z;
};
std::multimap<particle> particle_tree;
-
August 24th, 2010, 01:30 AM
#3
Re: Class inside the same class
Originally Posted by manojg
Hi,
I am writing a simulation code. I have a class called "particle" which hold gas particles. Each gas particle has its neighbouring gas particles. And its neighbouring gas particles have their own neighbouring particles. I tried to write the "particle" class like below to hold neighbouring particles also:
Code:
class particle {
int x; // particle location
int y;
int z;
particle *neighbour; // I have taken one neighbour particle for simplicity to illustrate the problem.
// Actually, it is vector of particles.
};
Is it valid? Any other idea will be appreciated.
Thanks.
You may use a class inside itself under 2 conditions:
1 - You don't include it by value, or else your class would have infinite size
2 - You only reference it by pointer semantics, ie: you don't need anything more than a forward declaration:
Code:
class particle {
int x; // particle location
int y;
int z;
particle *neighbour; //OK: Pointer to a particle type.
particle neighbor_by_value; //KO: contains itself by value
vector<particle> vector_of_particles; //KO: Requires the full definition of particle
vector<particle*> vector_of_star_particles; //OK
};
I'm not actually 100% sure you can't use a vector<particle>, but that wouldn't really work as a solution anyways, since you want references (pointers) to the neighbors.
I'm not entirely sure your approach is the best. I'm not sure the gas particles should be the ones keeping track of their neighbors. Maybe an external multimap would be a better design? Just an idea, but I wouldn't know. I think you should take the time to check your options before committing to your design though.
Last edited by monarch_dodra; August 24th, 2010 at 01:33 AM.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
August 24th, 2010, 02:56 AM
#4
Re: Class inside the same class
In multiagent systems, if you code in traditional C style, it becomes really hard to
1.read
2.maintain, modify
3.debug
etc
If this is an academic project then its harder for your students to expand (I know, I used to be a student)
I am thinking if it's possible to separate them completely into different classes then use OOP features to wrap them up (no pointer to itself), a vector of agents will be used later to calculate forces and coordinates among them easier.
STL is powerful, other libraries like Boost are awesome, but I don't abuse them. For most of the problems I run into myself, such containers and container-like holders as set, map and vector are enough for me...perhaps I know still less but I am satisfied somehow...
-
August 24th, 2010, 05:17 AM
#5
Re: Class inside the same class
Originally Posted by manojg
Hi,
I am writing a simulation code. I have a class called "particle" which hold gas particles. Each gas particle has its neighbouring gas particles. And its neighbouring gas particles have their own neighbouring particles. I tried to write the "particle" class like below to hold neighbouring particles also:
Code:
class particle {
int x; // particle location
int y;
int z;
particle *neighbour; // I have taken one neighbour particle for simplicity to illustrate the problem.
// Actually, it is vector of particles.
};
Is it valid? Any other idea will be appreciated.
Thanks.
I don't think your design is the best idea. Consider what happens when you have a high number of particles. Each particles holds a vector of pointers to particals, when you add one more particle to the system, you will need to run through all particles to figure out which particles are neighbours and then update each appropriate neighbour vector.
Furthermore, you are not currently considering particle momentum, which you will need to do for a proper simulation. In this case, everytime you move to the next time frame, you will need to recalculate which particles each particle considers its neighbours. For a high number of particles your simulation computation time will increase significantly past a linear increase.
It would perhaps be a better design if you had a container of particles.
Code:
std::vector<particle> particles_
Where from a data model point of view Particle is defined as follows
Code:
struct particle
{
Location loc;
Momenta m;
};
and Location is defined as
Code:
struct location
{
int x;
int y;
int z;
};
and momenta is defined as:
Code:
struct momenta
{
double mass;
float p_x;
float p_y;
float p_z;
};
Note that particle physics uses four-momenta:
http://en.wikipedia.org/wiki/Four-momentum
However, since you are not dealing with relativistic calculations, it makes more sense in your case to use the particle rest mass. You can then calculate velocities as
Code:
v_x = p_x/m;
v_y = p_y/m;
v_z = p_z/m;
Anyway, effectively if you do the above, then your vector of particles will be a snapshot in time. You will be able to use the momenta and location of each particle to make efficient elastic collision calculations with neighbouring particles using discrete changes in time. You will also be able to make particle tracks.
I'm not sure if this is more than you want, but anyway, that's for you to decide.
Last edited by PredicateNormative; August 24th, 2010 at 05:20 AM.
-
August 24th, 2010, 10:51 AM
#6
Re: Class inside the same class
Hi all,
Thanks everybody for your helpful suggestions. I figured out to do this way which similar to previous one:
I created a base class for just one gas particle, "singleParticle", and another class for gas particle including its neighbours, "particle", which is derived from "singleParticle".
Code:
class singleParticle {
double x;
double y;
double z;
};
Code:
class particle : public singleParticle {
particle *neighbour; // it is a pointer, so do not have infinite loop
};
So, every gas particle is of type "particle".
Thanks.
-
August 24th, 2010, 10:57 AM
#7
Re: Class inside the same class
While that may work, it doesn't look like the most logical use of inheritance. You're saying that every particle IS-A singleParticle, which is fine; but since you didn't give singleParticle a virtual destructor, it's unsafe to view a particle solely as a singleParticle if it's dynamically allocated.
-
August 24th, 2010, 11:05 AM
#8
Re: Class inside the same class
HI Lindley,
Thanks for reminding me. I have assigned a virtual distructor but I forgot to write in detail here.
Code:
class singleParticle {
private:
double x;
double y;
double z;
public:
singleParticle();
virtual ~singleParticle();
........ other methods
};
Code:
class particle : public singleParticle {
private:
particle *neighbour; // it is a pointer, so do not have infinite loop
public:
particle();
virtual ~particle();
........... other methods
};
-
August 24th, 2010, 11:46 AM
#9
Re: Class inside the same class
Originally Posted by PredicateNormative
I don't think your design is the best idea. Consider what happens when you have a high number of particles. Each particles holds a vector of pointers to particals, when you add one more particle to the system, you will need to run through all particles to figure out which particles are neighbours and then update each appropriate neighbour vector.
Furthermore, you are not currently considering particle momentum, which you will need to do for a proper simulation. In this case, everytime you move to the next time frame, you will need to recalculate which particles each particle considers its neighbours. For a high number of particles your simulation computation time will increase significantly past a linear increase.
It would perhaps be a better design if you had a container of particles.
Code:
std::vector<particle> particles_
Where from a data model point of view Particle is defined as follows
Code:
struct particle
{
Location loc;
Momenta m;
};
and Location is defined as
Code:
struct location
{
int x;
int y;
int z;
};
and momenta is defined as:
Code:
struct momenta
{
double mass;
float p_x;
float p_y;
float p_z;
};
Note that particle physics uses four-momenta:
http://en.wikipedia.org/wiki/Four-momentum
However, since you are not dealing with relativistic calculations, it makes more sense in your case to use the particle rest mass. You can then calculate velocities as
Code:
v_x = p_x/m;
v_y = p_y/m;
v_z = p_z/m;
Anyway, effectively if you do the above, then your vector of particles will be a snapshot in time. You will be able to use the momenta and location of each particle to make efficient elastic collision calculations with neighbouring particles using discrete changes in time. You will also be able to make particle tracks.
I'm not sure if this is more than you want, but anyway, that's for you to decide.
I like the design with Location and Momenta but I don't think that the vector of 'neighbors' isn't a bad idea but it could be added to the particle class as an additional - though redundant - means to improve calculations.
Assume you add each particle in a sorted way to the all particles vector. The sort criteria might be the distance to the origin (0, 0, 0). Then new particles easily could be added to the all vector by using a binary search. Also the neighbors could be found fastly that way. When a single particle was moving you could check all neighbors much faster than you could do with the all vector alone. And you could find potential new neighbors more easily cause canditates for the new neighbors you could find by evaluating the neighbors of those of neighbor particles you were moving towards to (where the distance to would decrease or where the distance vector changes orientation).
A quite different modeling would be to store the particles as a graph with vertices and edges. While a vertex is equivalent to a particle you may have edges for all neighbor relations between the particles. The advantage of that approach is that you can use all algorithms and methods of graph theory - though I actually don't know whether that was valuable for a simulation of gas particles.
-
August 25th, 2010, 01:51 AM
#10
Re: Class inside the same class
Originally Posted by manojg
Hi all,
Thanks everybody for your helpful suggestions. I figured out to do this way which similar to previous one:
I created a base class for just one gas particle, "singleParticle", and another class for gas particle including its neighbours, "particle", which is derived from "singleParticle".
Code:
class singleParticle {
double x;
double y;
double z;
};
Code:
class particle : public singleParticle {
particle *neighbour; // it is a pointer, so do not have infinite loop
};
So, every gas particle is of type "particle".
Thanks.
This looks even worst. What's wrong with:
Code:
class singleParticle {
double x;
double y;
double z;
std::vector<particle*> neighbours;
};
What is the point of splitting things up?
If your answer is to keep single particles instances smaller, then it is a bad reason (that I'll only take the time to explain, if it was)
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
August 25th, 2010, 06:55 AM
#11
Re: Class inside the same class
Originally Posted by itsmeandnobodyelse
I like the design with Location and Momenta but I don't think that the vector of 'neighbors' isn't a bad idea but it could be added to the particle class as an additional - though redundant - means to improve calculations.
Assume you add each particle in a sorted way to the all particles vector. The sort criteria might be the distance to the origin (0, 0, 0). Then new particles easily could be added to the all vector by using a binary search. Also the neighbors could be found fastly that way. When a single particle was moving you could check all neighbors much faster than you could do with the all vector alone. And you could find potential new neighbors more easily cause canditates for the new neighbors you could find by evaluating the neighbors of those of neighbor particles you were moving towards to (where the distance to would decrease or where the distance vector changes orientation).
A quite different modeling would be to store the particles as a graph with vertices and edges. While a vertex is equivalent to a particle you may have edges for all neighbor relations between the particles. The advantage of that approach is that you can use all algorithms and methods of graph theory - though I actually don't know whether that was valuable for a simulation of gas particles.
I agree that something has to be responsible for monitoring which particles are neighbours, but I was thinking that could be done by a class external to the container. I was thinking that a statistical cost (or weighted distance) could be calculated in some kind of association matrix, and that matrix would supply the closest neighbouring particles. Perhaps the statistical cost could be a combination of position and momenta information, possibly calculated using a Kalman filter... but then maybe I'm going too far?
-
August 26th, 2010, 10:15 AM
#12
Re: Class inside the same class
Hi monarch_dodra,
You are right, it is just splitting the class. I wrote this way to solve one of my problem temporarily (I was writing the data in a file, a type of formate which can also write class.). But it crashes when I do not split the class. By splitting, I can write all particle as a "singleParticle". This way it does not crash. However, I have no clue how efficient it will be compared to other methods. Still working.
Thanks.
-
August 26th, 2010, 11:04 AM
#13
Re: Class inside the same class
Hopefully you aren't doing file IO by the widespread but incorrect "cast to char*" method.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|