9

I am going to initialize a 2D vector in a member function, where the input arguments are planned to be fed into determined indexes within the function argument. Furthermore, I'm not gonna use [] operator to member access due to safety stuffs. How can I use at() function in order to access to the index of a 2D vector, as below?

vector<vector<double>> weight;

void Connection::setWeight(const double& value, const double& i, const double& j)
{
    // The other scheme except: weight[i][j] = value;
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
User
  • 952
  • 2
  • 21
  • 43

2 Answers2

16

You can use at twice. Also note, if i and j are indexes, they really shouldn't be double.

void Connection::setWeight(const double value, const size_t i, const size_t j)
{
    weight.at(i).at(j) = value;
}
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
12

Risking to be downvoted for premature optimization, and because it doesn't really answers the question asked, still I would like to remind about a serious problem in such approach.

Like any multidimensional array, vector of vector is not contiguous, which makes its performance characteristics terribly bad because of lacking of spatial locality and associated cache misses.

You can trivially solve the problem by wrapping a single-dimensional array with a convenient interface of two-dimensional array.

template <class T>
class MyArray2D
{
    std::vector<T> data;
    size_t sizeX, sizeY;
public:

const T& at(int x, int y) const { return data.at(y + x * sizeY); }

T& at(int x, int y) { return data.at(y + x * sizeY); }

// wrap other methods you need of std::vector here
};

Note that code above written on the fly and wasn't compiled. Still, I believe you've got the idea.

See also:

Community
  • 1
  • 1
Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • _"Risking to be downvoted for premature optimization, ..."_ Well I give you an initial charge ;). Your points are valid and relevant. – πάντα ῥεῖ Sep 01 '14 at 19:26
  • @Drop: You asserted that the performance in this case is terrible... So what is your suggestion for a efficient data structure for linear algebra and matrix manipulation?! Could you please explain that why your snippet might be better than 2D vectors, in view of the performance? – User Sep 01 '14 at 19:26
  • @matinking Well, that "terrible performance" is actually a bad and unprofessional way of describing my subjective understanding of how multidimensional arrays work. Surely you need to profile and think in a context of your application. Maybe vector of vectors will work just fine for you and you need no introduce additional complexity in your code. But, as a starting point I would advise to try to make a such a custom wrapper to `std:vector` and compare its performance to original approach. Also, me personally find it helpful in many applications, from tetris grid ;) to complex math apps. – Ivan Aksamentov - Drop Sep 01 '14 at 19:33
  • 1
    @matinking CPU cache is very important in our days so we must not throw away any possibility to abuse it (along with multithreading, vectorization and branch prediction). There are very good explanations given if you follow the "See also" links, so I would not like to repeat it. (And I am probably not able to explain it better) – Ivan Aksamentov - Drop Sep 01 '14 at 19:36
  • @Drop: +1 for the clearance and the resources :D, even though I still can't consider the other approach for my case!... – User Sep 01 '14 at 19:44