I started using Armadillo relatively recently, and although I like it a lot, it would be useful if it had ways of storing 4D matrices. Is there something I'm missing, or a workaround for this?
The last dimension would just have a size of three, so in theory I could have something like:
std::vector<arma::cube> 4Dmatrix(3);
for (int index=0; index<3; index++)
4Dmatrix[index] = cube(size1, size2, size3);
However, it feels like there must be a better way.
Thanks in advance!
You could potentially use the field class which stores arbitrary objects as elements in a vector, matrix or cube structure. E.g. (from the documentation) to create a field containing vec vectors:
// create a field containing vectors
field<vec> F(3,2);
No, there is no built-in way. If you look at the source, you will see that there are individual implementations for vectors, matrices and cubes.
Maybe a Boost multi array could be of use to you.
Related
Looking for something in C++ for easy storage and access of matrices of different sizes. I typically use R, and in R I can use a loop and store a matrix in a list as follows (toy example)
myList <- list(1)
for(i in 1:10){
myList[[i]] <- matrix(rnorm(i^2),i,i)
}
This gives me a list where myList[[i]] will then give me the i-th matrix. Is there anything like this in C++? I have seen Boost functions that can do arrays of varying sizes, but fail to apply them to matrices. Trying to use either Eigen or Armadillo if that helps narrow responses.
There is 2 parts to the answer you're looking for, i.e.
The matrices.
The container holding all these matrices.
So, for the matrices: If you are planning on doing linear algebra operations I'd recommend using some special libraries, such as Armadillo which comes with a lot of pre-defined matrix functions (e.g. eigenvalue, matrix multiplication, etc.). If it's just basic 2D data storage with no special operation, then I'd recommend using a STL vector of vector to represent your matrices. These containers are dynamic in size (can be changed at will during execution) and all elements are accessible by index. As Patrick said, more info can be found here: cppreference.com.
An example of a 3x3 matrix of integer filled with 1s would be
std::vector< std::vector<int,int> > matrix(3,std::vector<int>(3,1));
Then, you have to store these matrices somewhere. For this, it is really going to depend on your needs. The simplest solution would be a vector of matrices (so a vector of vector of vector, really). Your code would behave exactly as in R, and you would be able to access matrix by index. The equivalent C++ code is
#include<vector>
using namespace std;
typedef vector< vector<int,int> > int_matrix_t;
...
vector<int_matrix_t> my_vector_of_matrices(10);
for (int i = 0; i<10; ++i) {
my_vector_of_matrices[i] = some_function_that_outputs_a_matrix(i);
}
But there is a lot of other container available. You should survey this chart and choose for yourself!
I believe you can use std::vector.
http://en.cppreference.com/w/cpp/container/vector
std::vector<Matrix> matrices;
matrices[i] = Matrix(data);
This is a very simple question - what is the best practice to work with triangle matrixes and to work with sparse matrices in C++?
For triangle matrix I suggest a data format as easy as
double* myMatrix;
int dimension;
as data structure in custom class. (I suggest that it was a square matrix in the full form.) And there will be methods for setting and accessing elements.
For sparse matrices - I know a couple of methods like saving just positions of elements in the row/column and their values. It's the question for your experience - which implementation of sparse matrix will be the best one?
P.S. Less memory, less CPU usage - that is my target, I am looking for the best solution, not the simplest one. All matrices will be used for solving systems of linear equations. And the size of matrices will be huge.
Thanks a lot for every advice!
If you have no idea about the structure of the matrix, then it is basically the same as a map. You could use std::map<std::pair<int,int>,double>. Or perhaps std::unordered_map if you have it.
I've created my own Matrix class were inside the class the information regarding the Matrix is stored in a STL vector. I've notice that while searching the web some people work with a vector of vectors to represent the Matrix information. My best guess tells me that so long as the matrix is small or skinny (row_num >> column_num) the different should be small, but what about if the matrix is square or fat (row_num << column_num)? If I were to create a very large matrix would I see a difference a run time? Are there other factors that need to be considered?
Thanks
Have you considered using an off-the-shelf matrix representation such as boost's instead of reinventing the wheel?
If you have a lot of empty rows for example, using the nested representation could save a lot of space. Unless you have specific information in actual use cases showing one way isn't meeting your requirements, code the way that's easiest to maintain and implement properly.
There are too many variables to answer your question.
Create an abstraction so that your code does not care how the matrix is represented. Then write your code using any implementation. Then profile it.
If your matrix is dense, the "vector of vectors" is very unlikely to be faster than a single big memory block and could be slower. (Chasing two pointers for random access + worse locality.)
If your matrices are large and sparse, the right answer to your question is probably "neither".
So create an abstract interface, code something up, and profile it. (And as #Mark says, there are lots of third-party libraries you should probably consider.)
If you store everything in a single vector, an iterator will traverse the entire matrix. If you use a vector of vectors, an iterator will only traverse a single dimension.
I'm trying to write a C++ program that needs to store and adjust data in a 3D array. The size is given by the user and doesn't change throughout the run, and I don't need to perform any complicated matrix operations on it. I just need it to be optimized to set and get from given 3D coordinates (I do quite some iterations over all the members, and it's a big array). What's the best way to go about defining that array? Vector of vector of vector? Arrays of vectors? CvMat/IplImage with multi channels? Should I even keep it as 3D or just turn it into one very long interleaved vector and calculate indexes accordingly?
Thanks!
I would go with your last option, a single large array with transformed indices. If all you want to do is read and write known indices, this is probably the most efficient structure, both in terms of storage and speed. You can also wrap this in a class and overload operator () to make it easy to access 3D coordinates, for eg. you could write a(1,2,3) = 10; and the overloaded operator could take care transforming the 3D coordinates into a linear index. Iterating over such an array would also be quite simple since there's only one dimension.
It depends on what you mean by efficient, but have you looked at KD Trees?
i want to store some kind of distance-matrix (2D), where each entry has some alternatives (different coordinates). So i want to access the distance for example x=1 with x_alt=3 and y=3 with y_alt=1, looking in a 4-dim multi-array with array[1][3][3][1].
The important thing to notice is the following: the 2 most inner arrays/vectors don't have the same size for different values of the outer ones.
After a first init step, where i calculate the values, no more modifying is needed!
This should be easily possible with the use of stl-vectors:
vector<vector<vector<vector<double> > > >`extended_distance_matrix;
where i can dynamically iterate over the outer 2 dimensions and fill only as much alternatives to the inner 2 dimensions as i need (e.g. with push_back()).
Questions:
Is this kind of data-structure definition possible with Boost.MultiArray? How?
Is it a good idea to use Boost.MultiArray instead of the nested vectors? Performance (especially lookups! (Memory-layout))? Easy of use?
Thanks for any input!
sascha
PS: The boost documentation didn't help me. Maybe one can use multi_array_ref to get already sized arrays into the whole 4D-structure?
Edit:
At the moment i'm thinking of another approach: flattening the alternatives -> one bigger matrix with all the distances between the alternatives. Then i only need to calc the number of alternatives per node, build up the prefix sum (which is describing the matrix position/shift) and can then access the information in a 2-step-way.
But my questions are still open.
it sounds like you need:
multi_array<ublas::matrix<type>,2>
Boost.MultiArray deals with contiguous memory (arranged logically in many dimensions) so it is difficult to add elements in the inner dimensions. MultiArrays can be dynamically resized, e.g. to add elements in any dimension, but this is a costly operation that almost certainly need (internally) reallocation and copying.
Because of that requirement MultiArray is not the best option. But from what you say it looks like a combination of the two would be appropriate to you.
boost::multi_array<std::vector<std::vector<type>>, 2> data
The very nice thing is that the indexing interface doesn't change with respect to boost::multi_array<type, 4>. For example data[1][2][3][4] still makes sense.
I don't know from your post how you handle the inner dimension but it could even make sense to use this:
boost::multi_array<boost::multi_array<type>, 2>, 2> data
In any case, unless you really need to do linear algebra I would stay away from boost::ublas::array, or at most use it for the internal array if type is numeric. boost::multi_array<boost::ublas::array<type>, 2> data which is mentioned in the other answer.