I would like to copy the 2 matrices. With a copy element by element through 2 for loops (row and column), after several mathematical operations and copies the final result is correct while using "memcpy" the final result is wrong in the decimal places. The code is as follows.
double **L_original;
double **L;
int nF,nU;
L = new double*[nU]();
L_original = new double*[nU]();
for(int i=0; i<nU; i++){
L_original[i] = new double[nF]();
L[i] = new double[nF]();
}
// copy element to element
/*for(int i=0; i<nU; i++)
for(int j=0; j<nF; j++)
L[i][j] = L_original[i][j];*/
memcpy(L, L_original, sizeof(L_original));
This is the correct result:Matrix Correct
This is the output: output when using memcpy
your L and L_original are 2D matrices, made of an array of pointers to separately allocated 1D vectors. These memory addresses may not be in a contiguous memory space. So you can't use a single memcpy to copy all subvectors.
you will have to use a for loop to apply memcpy between each L[i] and L_original[i].
also, your sizeof() operator is used incorrectly. what you need to copy is the byte length of the data (of the 1D subvector), not the length of the pointer. You need something like
for(int i=0; i<nU; i++)
memcpy(L[i],L_original[i], sizeof(double)*nF);
Related
I am very new to C++, but I have the task of translating a section of C++ code into python.
Going through the file, I found this section of code, which confuses me:
int n_a=(e.g 10)
int n_b=n_a-1;
int l_b[2*n_b];
int l_c[3*n_b];
int l_d[4*n_b];
for (int i=0; i<n_b; i++){
for (int j=0; j<2; j++) l_b[i*2+j]=0;
for (int j=0; j<3; j++) l_c[i*3+j]=0;
for (int j=0; j<4; j++) l_d[i*4+j]=0;
I know that it creates 3 arrays, the length of each defined by the action on the n_b variable, and sets all the elements to zero, but I do not understand what exactly this matrix is supposed to look like, e.g. if written on paper.
A common way to store a matrix with R rows and C columns is to store all elements in a vector of size R * C. Then when you need element (i, j) you just index the vector with i*C + j. This is not the only way your "matrix" could be stored in memory, but it is a common one.
In this code there are 3 C arrays that declared and initialized with zeros. The l_b array seems to be storage for a n_a x 2 matrix, the l_c array for a n_a x 3 matrix and the l_d array for a n_a x 4 matrix.
Of course, this is only an impression since to be sure we would need to see how these arrays are used later.
As in the comments, if you are going to convert this to python then you should probably use numpy for the matrices. In fact, the numpy arrays will store the elements in memory exactly like indexing I mentioned (by default, but you can also choose an alternative way passing an extra argument). You could do the same of this C++ code in oython with just
import numpy as np
n_a = (e.g 10)
l_b = np.zeros(shape=(n_a, 2))
l_c = np.zeros(shape=(n_a, 3))
l_d = np.zeros(shape=(n_a, 4))
These variables in numpy are 2D arrays and you can index them as usual.
Ex:
l_d[2, 1] = 15.5
We can also have a nice syntax for working with vector, matrices and linear algebra in C++ by using one of the available libraries. One such library is armadillo. We can create the three previous matrices of zeros using armadillo as
#include <armadillo>
int main(int argc, char *argv[]) {
unsigned int n_a = 10;
// A 10 x 3 matrix of doubles with all elements being zero
// The 'arma::fill::zeros' argument is optional and without it the matrix
// elements will not be initialized
arma::mat l_b(n_a, 2, arma::fill::zeros);
arma::mat l_c(n_a, 3, arma::fill::zeros);
arma::mat l_d(n_a, 4, arma::fill::zeros);
// We use parenthesis for index, since "[]" can only receive one element in C/C++
l_b(2, 1) = 15.5;
// A nice function for printing, but it also works with operator<<
l_b.print("The 'l_b' matrix is");
return 0;
}
If you inspect armadillo types in gdb you will see that it has a mem atribute which is a pointer. This is in fact a C array for the internal elements of the matrix and when you index the matrix in armadillo it will translate the indexes into the proper index in this internal 1D array.
You can print the elements in this internal arry in gdb. For instance, print l_b.mem[0] will print the first element, print l_b.mem[1] will print the second element, and so one.
say you have a matrix of dimensions x per y (per z) defined like:
int** tab = new int*[x];
for(int i=0; i<x; ++i) tab[i] = new int[y];
or
int*** tab = new int**[x];
for(int i=0; i<x; ++i) {
tab[i] = new int*[y];
for(int j=0; j<y; ++y) tab[i][j] = new int[z];
}
is there any smart way to access sub-matrix (get int**(*) without data copying, plain C++) which will have top-left(-front) corner [a,b(,c)] and size of [A, B(,C)]?
Here are (better or worse) graphical examples of the problem.
You are using what is called a jagged array. It is an array of arrays, where nothing besides runtime enforces that the sub arrays are the same size. Hence jagged, because you could have the subarrays vary in size.
In order to have a submatrix that is also a jagged array, you need for there to exist a jagged array of pointers pointing at the subarrays of the submatrix. These don't exist in general, so no, you cannot do this "without copying" at least some arrays of pointers to subarrays.
Had your matrix been not jagged array based, but instead single array with stride, then views of subarrays could be created without allocating new subarray pointer arrays. Also it would be more cache friendly.
To write the non-jagged matrix, start by writing an array view or span class that handles one dimension.
For two dimensions, you augment the span class to store a tuple of dimension sizes or strides. [] instead of returning a reference to the calculated element, creates a one-dimension-lower span instance pointing at the calculated position, until the dimension 0 case where you return a reference.
This will be highly efficient, permit efficient subarrays, but requires a few dozen or 100 lines of code to get right.
How do you fill with 0 a dynamic matrix, in C++? I mean, without:
for(int i=0;i<n;i++)for(int j=0;j<n;j++)a[i][j]=0;
I need it in O(n), not O(n*m) or O(n^2).
Thanks.
For the specific case where your array is going to to be large and sparse and you want to zero it at allocation time then you can get some benefit from using calloc - on most platforms this will result in lazy allocation with zero pages, e.g.
int **a = malloc(n * sizeof(a[0]); // allocate row pointers
int *b = calloc(n * n, sizeof(b[0]); // allocate n x n array (zeroed)
a[0] = b; // initialise row pointers
for (int i = 1; i < n; ++i)
{
a[i] = a[i - 1] + n;
}
Note that this is, of course, premature optimisation. It is also C-style coding rather than C++. You should only use this optimisation if you have established that performance is a bottleneck in your application and there is no better solution.
From your code:
for(int i=0;i<n;i++)for(int j=0;j<n;j++)a[i][j]=0;
I assume, that your matrix is two dimensional array declared as either
int matrix[a][b];
or
int** matrix;
In first case, change this for loop to a single call to memset():
memset(matrix, 0, sizeof(int) * a * b);
In second case, you will to do it this way:
for(int n = 0; n < a; ++n)
memset(matrix[n], 0, sizeof(int) * b);
On most platforms, a call to memset() will be replaced with proper compiler intrinsic.
every nested loop is not considered as O(n2)
the following code is a O(n),
No 1
for(int i=0;i<n;i++)for(int j=0;j<n;j++)a[i][j]=0;
imagine that you had all of the cells in matrix a copied into a one dimentional flat array and set zero for all of its elements by just one loop, what would be the order then? ofcouse you will say thats a O(n)
No 2 for(int i=0;i<n*m;i++) b[i]=0;
Now lets compare them, No 2 with No 1, ask the following questions from yourselves :
Does this code traverse matrix a cells more than once?
If I can measure the time will there be a difference?
Both answers are NO.
Both codes are O(n), A multi-tier nested loop on a multi-dimentional array produces a O(n) order.
In MATLAB inorder to access the odd or even rows and columns of a matrix we use
A = M(1:2:end,1:2:end);
Is there an equivalent for this in C++? or How do i do this in C++.
Basically what i want to do is in matlab i have
A(1:2:end,1:2:end) = B(1:2:end,:);
A(2:2:end,2:2:end) = B(2:2:end,:);
I want to implement the same in C++
This is available only in a fairly obscure class, std::valarray. You need a std::gslice (Generalized slice) with stride {2,2} to access the std::valarray.
In C++ the for loop is constructed as follows
for (initial state; condition for termination; increment)
So if you are looking for the odd elements, you can:
for (int i = 0; i < size; i += 2),
whereas if you are looking for the even elements:
for (int i = 1; i < size; i += 2).
Where size depends if you are looping through the rows or columns. Take into account that because C++ arrays start at index 0, your odd elements will correspond to even indexes and your even elements will correspond to odd indexes.
Now, the answer: If you want to get the elements of a matrix, in C++ you must loop through the matrix with a for loop. You can modify the elements you access by modifying the increment property of the for loop.
for(int i= 0; i < rows/2; i++)
for(int j= 0; j < columns/2; j++)
A[i][j] = M[i*2][j*2];
I want to map an array of double to an existing MatrixXd structure. So far I've managed to map the Eigen matrix to a simple array, but I can't find the way to do it back.
void foo(MatrixXd matrix, int n){
double arrayd = new double[n*n];
// map the input matrix to an array
Map<MatrixXd>(arrayd, n, n) = matrix;
//do something with the array
.......
// map array back to the existing matrix
}
I'm not sure what you want, but I'll try to explain.
You're mixing double and float in your code (a MatrixXf is a matrix where every entry is a float). I'll assume for the moment that this was unintentional amd that you want to use double everywhere; see below for if this was really your intention.
The instruction Map<MatrixXd>(arrayd, n, n) = matrix copies the entries of matrix into arrayd. It is equivalent to the loop
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
arrayd[i + j*n] = matrix(i, j);
To copy the entries of arrayd into matrix, you would use the inverse assignment: matrix = Map<MatrixXd>(arrayd, n, n).
However, usually the following technique is more useful:
void foo(MatrixXd matrix, int n) {
double* arrayd = matrix.data();
// do something with the array
}
Now arrayd points to the entries in the matrix and you can process it as any C++ array. The data is shared between matrix and arrayd, so you do not have to copy anything back at the end. Incidentally, you do not need to pass n to the function foo(), because it is stored in the matrix; use matrix.rows() and matrix.cols() to query its value.
If you do want to copy a MatrixXf to an array of doubles, then you need to include the cast explicitly. The syntax in Eigen for this is: Map<MatrixXd>(arrayd, n, n) = matrix.cast<double>() .
You do not need to do any reverse operation.
When using Eigen::Map you are mapping a raw array to an Eigen class.
This means that you can now read or write it using Eighen functions.
In case that you modify the mapped array the changes are already there. You can simply access the original array.
float buffer[16]; //a raw array of float
//let's map the array using an Eigen matrix
Eigen::Map<Eigen::Matrix4f> eigenMatrix(buffer);
//do something on the matrix
eigenMatrix = Eigen::Matrix4f::Identity();
//now buffer will contain the following values
//buffer = [1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1]