I am writing a c++ program which uses boost library for matrix operations. I have a need were by i have to dynamically expand the size of the initial matrix.
Example:
if my matrix size was:
matrix<float> m(3,3);
and later my matrix will expand and i'll need a 4*4 matrix. The naive approach i could think of is allocate a new matrix with size 4,4 and and copy all elements of 3*3 matrix to it. Isn't there any better way of doing this in boost?
Please, consider using the resize() function: "The existing elements of the matrix are preseved (sic) when specified."
Here is an example code from Boost.
This is one of ways.
matrix<int> A; // Matrix size would be zero by zero
A.resize(2, 3); // Matrix size became 2 by 3
Why not just create a matrix using the no arg constructor and call the resize method as needed?
http://www.boost.org/doc/libs/1_47_0/libs/numeric/ublas/doc/matrix.htm
Related
I have a 3D vector and I want to be able to chose which dimension to plot as a function of another dimension.
So far, I am doing this manually: I create a second 3D vector and re-organize the data accordingly. This solution is not very practical since I need to switch the indexes (inside the nested loop) every time I want to switch the dimensions...
Is there a better/cleaner solution ?
Thanks.
C++ does not provide multidimensional containers for the same reason that containers like std::vector do not provide a standard operator+ etc.: there is no standard that fits everyone's needs (in the case of a + operator, this could be concatenation, element-wise addition, increasing the dimensionality, who knows). If instead of a vector you take a class
<template typename T>
class volume {
private:
std::vector<T> data; // e.g. 3x2 array { 0, 1, 2, 3, 4, 5 }
std::vector<size_t> sizes; // e.g. 3x2 array { 3, 2 }
std::vector<size_t> strides; // e.g. 3x2 array { 1, 3 }
};
then you have all the flexibility you want - no need to stop at 3D!
As an example the data vector of a 3x2 array could be the first 6 natural numbers, the sizes vector would be { 3, 2 } and the strides array { 1, 3 }: in a row (of which there are 2) the elements are next to each other, to increase the row you need to move 3 positions forward.
In the general n-dimensional case you can make an at() operator that takes a vector (or an initializer_list) as a position argument, and the offset corresponding to that position is its inner product with strides.
If you don't feel like programming this from scratch then libraries like Blitz++ already provide this functionality.
No.
<RANT> C++ has no notion of multidimensional vectors. And has poor support for multidimensional arrays, because arrays are far from first class objects. So you are left with vectors of vectors [of vectors ...] and have to carefully control that all vectors in a containing vector have the same size (the language will not help you there). Or with multidimentional raw arrays... provided that the size for all dimensions but the last are known at compile time. </RANT>
As the number of dimensions are known (3D) I would go with a dedicated container using a 1D vector of size l*m*n (where l, m, and n are the size in the 3 dimensions). And a dedicated accessor function data(i,j,k). For there, it is possible to build another accessor tool that gives the data in one dimension starting from another one...
If you do not really like all that boiler plate code, you could have a look at the boost libraries. I do not use it, but if I correctly remember it contains a matrix class...
I wish to convert a simple 2D array into a SparseMatrix, in order to improve performance and run time, since I am dealing with an array of a size around 50,000-70,000.
So far what I have:
SparseMatrix<double> sp;
sp.resize(numCells,numCells);
double Matrix[numCells,numCells];
Matrix = Map<SparseMatrix>(Matrix,numCells,numCells);
The compiler returns type mismatch value at argument 1 in template parameter list for 'template class Eigen::Map'.
I understand I am missing something here, but I can not figure it out.
Make a dense matrix and convert it into a sparse matrix:
double matrix[numCells * numCells]; // 1d array representation of your matrix
SparseMatrix<double> sp = Map<MatrixXd>(matrix,numCells,numCells).sparseView();
I am trying to solve a simple least square of type Ax = b. The c++ eigen library offers several functionalities regarding this and I have seen some kind of solutions here: Solving system Ax=b in linear least squares fashion with complex elements and lower-triangular square A matrix and here: Least Squares Solution of Linear Algerbraic Equation Ax = By in Eigen C++
What I want to do is that using dynamic version of the matrix A and b. The elements of matrix A are floating points in my case and has 3 columns, but the number of data items (i.e. rows) will be dynamic (inside a loop).
It will be helpful to have a short code snippet of basic declaration of A, b and filling out values.
If you need dynamic matrices/vectors, just use:
MatrixXd m1(5,7); // double
VectorXd v1(23); // double
MatrixXf m2(3,5); // floating
VectorXf v2(12); // floating
Those variables will all be saved in heap.
If you need square matrices or vectors with fixed size (but be careful, they aren't dynamic!) use the following syntax:
Matrix3d m3; // double, size 3x3
Vector3d v3; // double, size 1x3
Matrix4d m4; // double, size 4x4
Vector4d v4; // double, size 1x4
I want to multiply 5 matrix ( all are not of same size) in c++, so what i can do?
will i have to use loop 5 times or is there any simple method like as in matlab?
sizes of matrix are
1st : 1x4
2nd : 4x4
3rd : 4x4
4th : 4x4
5th : 4x1
You could use boost linear algebra library which defines both matrix and vector types and has multiplication with operator *.
matrix<int> m1(1,4);
matrix<int> m2(4,4);
matrix<int> m3(4,4);
matrix<int> m4(4,1);
//... initialize your matrices here
matrix<int> result = m1*m2*m3*m4;
Write a function that performs the matrix multiplication for matrices of arbitrary size (with a sanity check).
Use the function four times, once for each multiplication.
Alternatively, you can define the * operator for the type matrix that you defined yourself, so that you could just write a*b*c*d
all
I am using multidimensional STL vector to store my data in C++. What I have is a 3D vector
vector<vector<vector<double>>> vec;
What I want to retrieve from it is :
&vec[][1][]; // I need a pointer that points to a 2D matrix located at column 1 in vec
Anyone has any idea to do so? I would be extremly appreciate any help!
Regards
Long
It is best to consider vec just as a vector whose elements happen to be
vectors-of-vectors-of-double, rather than as a multi-dimensional structure.
You probably know, but just in case you don't I'll mention it,
that this datatype does not necessarily represent a rectangular cuboid.
vec will only have that "shape" if you ensure that all the vectors are
the same size at each level. The datatype is quite happy for the vector vec[j]
to be a different size from the one at vec[k] and likewise for vec[j][n]
to be a vector of different size from vec[j][m], so that your structure is "jagged".
So you want to get a pointer to the vector<vector<double>> that is at
index 1 in vec. You can do that by:
vector<vector<double>> * pmatrix = &vec[1];
However this pointer will be an unnecessarily awkward means of accessing that
vector<vector<double>>. You certainly won't be able to write the
like of:
double d = pmatrix[j][k];
and expect to get a double at coordinates (j,k) in the "matrix addressed
by a pmatrix". Because pmatrix is a pointer-to-a-vector-of-vector-of-double;
so what pmatrix[j] refers to is the vector-of-vector-of-double (not vector-of-double)
at index j from pmatrix, where the index goes in steps of
sizeof(vector<vector<double>>). The statement will reference who-knows-what
memory and very likely crash your program.
Instead, you must write the like of:
double d = (*pmatrix)[j][k];
where (*pmatrix) gives you the vector-of-vector-of-double addressed by pmatrix,
or equivalently but more confusingly:
double d = pmatrix[0][j][k];
Much simpler - and therefore, the natural C++ way - is to take a reference,
rather than pointer, to the vector<vector<double>> at index 1 in vec. You
do that simply by:
vector<vector<double>> & matrix = vec[1];
Now matrix is simply another name for the vector<vector<double>> at index 1 in vec,
and you can handle it matrix-wise just as you'd expect (always assuming
you have made sure it is a matrix, and not a jagged array).
Another thing to consider was raised in a comment by manu343726. Do you
want the code that receives this reference to vec[1] to be able to
use it to modify the contents of vec[1] - which would include changing its
size or the size of any of the vector<double>s within it?
If you allow modification, that's fine. If you don't then you want to get
a const reference. You can do that by:
vector<vector<double> > const & matrix = vec[1];
Possibly, you want the receiving code to be able to modify the doubles
but not the sizes of the vectors that contain them? In that case, std::vector
is the wrong container type for your application. If that's your position I
can update this answer to offer alternative containers.
Consider using matrix from some linear algebra library. There are some directions here