Double buffer vs double array c++ - c++

I was asked to create a matrix with 5 rows and unknown column.
And my boss want me to use a 1 dimensional buffer. concatenated by 5 rows buffer.
I don't get what is that mean, can some one provide me a simple example please!
With array I can do
double[][] arr = new double[5][someNumber];
But he says then the size would be limited.
So I don't know what he means by using a DOUBLE buffer, I am not very good #C++
Thank you very much, an example would be nice!

For R rows and C columns declare double arr[R * C], and arr[i * C + j] is the element at cell [i, j].
This generalizes to arbitrary dimensions.
Flattening out an array like that can be a very useful optimization, especially when you use dynamic arrays such as std::vector, where you can get a single dynamic array rather than one for each row.

Sounds like you're saying
double *arr[5];
for(unsigned int x = 0; x < 5; ++x)
{
arr[x] = new double[someNumber];
}
Since, you know that you have 5 for sure, and an unknown part my assumption is this is how you're referring to it.

Related

C++: storing a matrix in a 1D array

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.

Turn a 2D array into a 1D array which has the sum of the values in the 2D array as its elements

The question is confusing and possibly not worded correctly. Let me clarify. If we have a 2-dimensional array vector<vector<int>> A = {{i, j, k}, {x, y, z}}. What is the fastest way to find a 1-dimensional array C such that that vector<int> C = {i + x, j + y, k + z}?
Additionally, in the problem I'm working on, I will have to carry numbers ie if we have a sum of 25, 2 will have to be carried into the next sum and 5 will remain as the current sum.
I've tried to use a for loop. However, it's very tedious and quite slow for large arrays.
Hopefully, there are some helpful functions out there?

C++ - A 3-d data structure - should I use vector of pointers or vector of vectors?

I have to maintain a data structure which is 3 dimensional. So let us say it's dimensions are :- l x m x n. In the program that I wish to write l and m will be known since the time the data structure is being constructed . But n has to be dynamic throughout runtime. And n may be different for the different vectors in the grid lxm. (Once this structure is created I never intend to destruct it as I will be needing it throughout).
For the moment let us assume it's a 2-dimensional data structure that I wish to make, should I make a vector<vector<int>> or a vector<vector<int>*> ? Also I know how I might initialise the vector to the required size in the first case, i.e I might do something like :-
vector<vector<int> > A(m)
to initialise the size of the outer dimension to m. But in the second case, once I have created a vector of pointers to vectors, how do I create the vectors to which the pointers point.
Carrying this to the 3-d case, should I use ,
a vector<vector<vector>> or a vector<vector<vector*>> or some other combination ?
Please, suggest any changes so that I may reframe the question if it's not framed properly.
You're better using a single vector (and not nested ones), since the memory is guaranteed to be contiguous in this case and your code will be way faster due to no cache misses. In this case, you need to map from 3D (2D) to 1D and vice-versa, but this is pretty straightforward
for 2D:
(x,y) <-> y*DIM_X + x;
for 3D:
(x,y,z) <-> z*(DIM_Y*DIM_X) + y*DIM_X + x;
If you really insist to use nested vectors, you can do something like:
#include <vector>
template<typename T>
using vec = std::vector<T>; // to save some typing
int main()
{
// creates a 5 x 4 x 3 vector of vector of vector
vec<vec<vec<double>>> v{5, vec<vec<double>>{4, vec<double>{3}}};
}
EDIT
Responding to your latest edit: use
std::vector<std::vector<double>> v{DIM_X*DIM_Y, std::vector<double>};
// address (x,y,z)
v[y*DIM_X+x, z] = val_x_y_z;
If you further happen to know the dimensions of the inner vectors, you can preallocate memory for them using std::vector::reserve. This will speed things up since there won't be any (slow) re-allocations.
No, use a proper multidimensional array: Boost MultiArray http://www.boost.org/doc/libs/1_59_0/libs/multi_array/doc/user.html
#include "boost/multi_array.hpp"
int main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<int, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
}

How do you fill with 0 a dynamic matrix, in C++?

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.

Offset calculation in 3D array

In the following code,
int arr[3][2][2]={1,2,3,4,5,6,7,8,9,10,11,12};
cout<<arr[0][0][5]<<endl;
cout<<arr[1][3][0]<<endl;
I get output as, 6 and 11.
How is it indexing an element out of its range?
eg- here the sizes are, depth= 3 col=2 row=2 , In thet case arr[0][0][5] means 5th row, which doesnt exist! Can anyone throw light on this.
Technically, you are invoking undefined behaviour.*
But, most likely, what's happening is that the compiler is calculating the address to read as:
(int *)arr + x*(2*2) + y*2 + z
because your 3D array is really stored in memory as a contiguous linear array.
So in your [0][0][5] case, it's simply reading the (0*4+0*2+5)=5th element (zero-based) of that linear array, which is 6.
Similarly for [1][3][0], it's reading the (1*4+3*2+0)=10th element, which is 11.
* This was discussed in a question I asked: One-dimensional access to a multidimensional array: well-defined C?.
Remember the last time you had a C-style string that you forgot to terminate?
char str[] = {'a','b','c'};
cout << str;
Remember how you printed "abc" then any random gubbins in memory after it because the program kept reading past the array?
It'll do that; it'll just keep going and pull out whatever happens to be there, even though doing so is undefined. The compiler simply doesn't need to warn you about this; you are supposed to figure it out for yourself.
In your case, the data for the next row probably happens to be in memory at that spot.
It's like that:
int arr[depth][col][row];
int temp = arr[x][y][z];
then temp = arr[x * (col * row) + y * row + z]