3

In my last question, Ilmari Karonen propose to me to solve the Laplace equation in discret mode. I'm using a grid and the four closest neighbours at each node to compute the unknown heights.

enter image description here

So the system to solve can be written with matrix :

A(matrix nxn) * U(vector n, unknowns) = b(vector n, settled)

last evening I looked around the web about linear algebra for C++. My choice is Armadillo. But for now "U" and "b" are std::map :

std::map<std::pair<float,float>,float> b;
std::map<std::pair<float,float>,float> U;
.
.
.
if(g/*grid*/->getNode(r,c)->status == TO_COMPUTE){
          U.insert(std::make_pair(std::make_pair(r,c),g->getNode(r,c)->y));
          /*right*/ if(g->getNode(r+1,c)->status == SETTLED) b.at(std::make_pair(r,c)) += g >getNode(r+1,c)->y;
          /*left */ if(g->getNode(r-1,c)->status == SETTLED) b.at(std::make_pair(r,c)) += g->getNode(r-1,c)->y;
          /*down */ if(g->getNode(r,c+1)->status == SETTLED) b.at(std::make_pair(r,c)) += g->getNode(r,c+1)->y;
          /*up   */ if(g->getNode(r,c-1)->status == SETTLED) b.at(std::make_pair(r,c)) += g->getNode(r,c-1)->y;
        }

and I think I will have then to get the size of "U" to create arma::vec and to parse the whole map with an std::iterator to transfer the values in my arma::vec. So I would like to know how to grow a arma::vec I'm looking for something like std::vector::push_back(), then I will replace my std::map. Also how can I get the size for a arma::vec?

note1 : the picture shows the contours and the points where I will compute the values, the grid with unknow value is at y=0, when the lower contour is at y=-0.2 and the upper contour at y=0.8

note2 : when my little (LINUX) program will be ready I will release the code on my bitbucket as a very tiny example of use of discret Laplace operator

Update 26 Nov. 2013:

you can get the link to the code here

Community
  • 1
  • 1
The Unholy Metal Machine
  • 1,093
  • 2
  • 17
  • 36
  • A `map<>` indexed by `pair`? You might want to read this to get some hints how to make that work reasonably (particularly Yakk's example): http://stackoverflow.com/questions/6684573/floating-point-keys-in-stdmap If, that is, you _really_ want to index by pairs of floats. – Joe Z Nov 22 '13 at 16:46
  • I see, usually I'm using `std::pair` I realize I was thinking in `int` I even wrote `+1` and `-1` instead of `+1.0f` and `-1.0f`. Thanks for pointing this out. If there is no way to grow a `arma::vec` I will rewrite this without `std::map` but I will create a structure for a better use and read – The Unholy Metal Machine Nov 22 '13 at 17:35
  • For performance critical code, functions like std::vector::push_back() are not very efficient. Sooner or later std::vector will need to re-allocate memory and copy all the data. It's more efficient to work out the required size first. – mtall Nov 23 '13 at 04:06

1 Answers1

4

See Armadillo's documentation. For example, you can use X.n_elem to get the length of vector X. To resize a vector while preserving the data, use .resize(). To add a row or column to a matrix, use .insert_rows() or .insert_cols().

Note that resizing objects inside performance critical loops (whether they're Armadillo matrices/vectors or std::vector) is not efficient. It's far better to work out the correct size beforehand.

mtall
  • 3,574
  • 15
  • 23