I am writing some code to integrate ODE's. This question is as much a request for coding advice as for a solution, so if you have an alternative suggestion to the one I am about to offer please let me know!
The "objects" to be integrated by the ODE integrator come in "blocks" of 6... The reason for this is that I have a std::vector of doubles, and they are arranged in the following way:
The first 3 doubles are position coordinates; x, y and z. The next 3 doubles are velocity coordinates; x, y and z.
So, now you know that, I have a function which takes pairs of "position" """vectors""" as arguments and returns some sort of result... See where I'm going with this?
Currently the function expects 2 lots of position coordinates in the following manner:
std::vector<double> magic_gravity_formula(const std::vector<double> &r1,
const std::vector<double> &r2, const double m1, const double m2)
I don't want to copy all the data in group of 3 to new vectors - that's a crazy (and very slow) way to program something.
I could use pointers to the raw data instead... and just pass a pointer to the x coordinate (first item in a block of 3 doubles) - this seems kind of okay to me but perhaps there's a better method? Kind of something like Python or Matlab array slicing? Can I do something like that?
I kind of want to pass a new vector (or some sort of wrapper class?), created from the data already stored in the array... Something kind of like
std::vector<double> sub_section_of_data = data[0..2] // Obviously pseudocode!
Okay so the above is nonsensical, because presumably a language which implemented that syntax would still make a copy operation, which is likely to be slow - exactly what I am trying to avoid...
So yeah I am not sure exactly the best way to proceed here - can anyone suggest a "good" solution? (In the non-subjective way!)
EDIT: To make this really clear - the problem is I don't want to do something like:
std::vector<double> r1_temp;
r1_temp.push_back(data[0]); // Copy ! Bad !
r1_temp.push_back(data[1]);
r1_temp.push_back(data[2]);
... same for an r2 ...
std::vector<double> force = magic_gravity_formula(r1, r2, m1, m2);
EDIT 2: Consider compiler options - would the compiler optimize my code for me by doing something like changing the function to accept arguments in the following way:
std::vector<double> super_gravity_formula(double x1, double y1, double z1, double x2, double y2, double z2, double m1, double m2)
In which case, perhaps this question isn't important? (Other than form a "make your code look nice to read" point of view.)
Edit 3: Therefore it is still important.
std::vector
and you want to use use the data from that to call the function with the signaturemagic_gravity_formula(const std::vector<double> &r1, const std::vector<double> &r2, const double m1, const double m2)
? If that's the case then I think Yakk's answer does exactly what you want. – StedfastCPU
cache by following pointers. – Gestalt