Eigen conservativeResize strange behavior - c++

I am using m.conservativeResize() to do the equivalent in Eigen as the reshape function in MatLab. So let N = 3, and then...
static MatrixXd m(N*N,1);
and then I assign this matrix some values, and it looks like this:
1
1
0
1
0
1
0
1
1
and then try to reshape it...
m.conservativeResize(N,N);
So now the same values should be there, but now in N rows and N columns rather than N*N rows and one column.
However that's not what I get. The first column has the first three values in the column vector - OK so far - but then the remaining values just look like garbage values from uninitialized memory:
1 3.08116e-309 0.420085
1 -2.68156e+154 1.2461e-47
0 -2.68156e+154 0.634626
Any idea what I am doing wrong?

conservativeResize() doesn't ``move" the elements around (in other words, doesn't work like MATLABs reshape, since it performs memory re-allocation even if the initial and final sizes are the same). From the documentation:
Resizes the matrix to rows x cols while leaving old values untouched.
...
Matrices are resized relative to the top-left element. In case values need to be appended to the matrix they will be uninitialized.
These statements seem a bit confusing. What it means is the following: think about the initial matrix as a rectangle, of size A x B. Then think about the resized matrix as another rectangle of size C x D. Then mentally overlap the two rectangles, making sure the top-left corner is common to both. The common elements of the intersection are the ones that are preserved by the conservativeResize. The rest just correspond to uninitialized memory.
In case you want a true reshaping, use resize() instead (making absolutely sure that A x B == C x D, otherwise reallocation takes place and all bets are off).

Related

Reshaping Fortran arrays

I have a huge m by 1 array (m is very large) called X which is a result of Fortran matmul operation. My problem is to store this apparently 2D array into an 1D array Y of size m.
I tried with Y = reshape(X, [[2]]) and this result some elements NaN. Can anyone point me to Fortran commands to do it quickly. The elements of X may be zero or non-zero.
The second argument of reshape (or the one with keyword shape=) is the shape of the function's result. In your call, you have requested shape [2].
An array with shape [2] is a rank-1 array with two elements. You want a rank-1 array with m elements:
Y = RESHAPE(X, [m])
Now, in this case there's no need to use reshape:
Y = X(:,1)
where the right-hand side is the rank-1 array section of X.
When you have Y=reshape(X,[2]), if Y is not allocatable and not of size 2 then you have a problem which may indeed result in your compiler deciding---as it is quite entitled to do---to give you a few NaNs.
Note also that you may not need to reshape your array, depending on how you intend to later use it.

Reordering of matrix in c++

I have a matrix in C++, A(n,n) and a vector P(n) which looks something like this:
P = [ 3 6 1 13 12 16 ... ]
it contains numbers 1:n but not in an ascending order but scrambled.
My aim is to change the rows and columns of matrix A to the same order. For example since P[0] = 3 I want the 3rd row and 3rd column to move to the 1st row and column in matrix A.
But because the matrix could be potentially really large, I can't use another matrix of size same as A because that would be wasteful.
In matlab this can be done simply by using the command:
A(P,P);
Any ideas on how to do the same thing in c++?
I will suggest using a level of indirection, to locate each matrix in a cell.
Let's say your matrix object is called M. Instead of using
M[R][C]
to refer to the cell in row R, column C (assuming row-major matrix ordering), you will have an associated pair of vectors, let's call them y and x, so the value of the cell in row R column C is:
M[y[R]][x[C]]
Initially, both y and x vectors map each "logical" row or column to the corresponding physical row and column, that is both y and x contain [0..max_row] and [0..max_col].
Then, to effect the swapping in your question, you simply copy your P vector to the y and x vectors.
You should implement your matrix not directly, as a two-dimensional std::vector, but as a standalone class:
class Matrix {
public:
// ...
auto operator()(size_t R, size_t C) const;
auto &operator()(size_t R, size_t C);
// ...
};
and implement the indirect mapping of rows and columns as part of the class implementation.
Easiest way is probably to just brute-force it. The best idea is probably to do it row by row. You'll need a helper array of length N which keeps track of the original row index, and one temporary row. Then, starting at row R=0, check if row R is in the right position. If not, copy it to the temporary row, copy the right row to row R (permuting it on the go), and copy the temporary row to the spot that was just freed. If a row happens to be in the right spot, copy it to the temporary row, and permute it when copying back.

Are functions on matrices applied to the entire matrix or each row in Fortran?

I've never written in Fortran, but I'm trying to adapt a script to R and the following lines are confusing me. So this is how the variable is defined:
real, dimension(n,nd) :: x
Does this mean x is n arrays filled with nd number of real values or a n x nd matrix?
Then
amax = maxval(abs(x))
x = x/amax
is applied. Is the variable amax a global max of the absolute values in x or is it an array of n max values, one for each row? This is important to know if the x = x/amax is being applied to each row or the entire matrix. The purpose of this function seems to be some type of normalization.
The question of the title is much more general than that of the body, so I'll come to that later.
The result of maxval(array) is a scalar, being the maximum value in array (if it's of non-zero size).
In your example, x is a single array of rank 2 (which is commonly thought of as being a matrix). Thus, maxval(x) is indeed what you call the global maximum of that matrix. An alternative form of maxval is required to give the row-by-row maxima: maxval(x,dim=2).
Now, there is something else to note from your example:
x = x/amax
has a requirement about the shapes of x and amax.
You don't give a declaration for amax but there are two possibilities:
amax has the same shape as x; or
amax is a scalar.
[Note that amax needn't be a scalar just because it is assigned a scalar result from that maxval reference. However, you will see that amax won't be declared as rank 1 with size the number of rows of x, so that's another clue that maxval is giving the global maximum.]
These two possibilities come from conformability rules for division. With amax a scalar each element of x is divided by that value; with amax an array each element of x is divided by the corresponding element in amax.
If you want to normalize each individual row of x then you just can't use that division expression with amax a rank 1 array.
Coming to the more general question: even though it's an either/or question the answer is "no". There is no single way. Each function acts as it is defined.
As a general rule, though, the intrinsic functions of Fortran rarely care about the specific case of arrays which have "rows". But one useful thought is that a function acts either:
on all elements individually, returning an array of the same shape;
on the array as a whole, returning a scalar.
Moderated by the fact that many will have this dim argument which causes the function to act on slices instead.
The first line means that the variable x is an array of two dimensions (n,nd) and not n arrays of nd values. The function maxval returns the maximum value in this array.
See page 130 (in the PDF not the printed number) in F90_notes.pdf (you will also find a whole chapter concerning the arrays in the same document).
To add to Baruchel's answer: x/amax divides each element of the 2D array x by the scalar amax.

(C++) Initializing and Declaring elements within a Two Dimensional Vector

I'm having an awkward result when I run my program after creating this 2D vector. The program actually crashes when it launches. But I'm basically trying to input a set of data for a 2D vector that is meant to retain the amount of bushels of certain crops in the first column (as ints), and then to retain the yield ratio of each crop (as an int). I haven't declared the yield ratio yet, but even if the 2nd column is left empty (in terms of each element's value) it shouldn't have a problem. Here's my code:
vector<vector<int> >crops(2, vector<int>(43));
crops[0][0]=0; //Arugula
crops[1][0]=2000000; //Beans
crops[2][0]=0; //Beets
crops[3][0]=0; //Cabbages
crops[4][0]=0; //Cammomile
crops[5][0]=0; //Carrots
crops[6][0]=0; //Catmint
crops[7][0]=0; //Celery
crops[8][0]=0; //Coriander
crops[9][0]=0; //Corn
crops[10][0]=0; //Cucumbers
crops[11][0]=0; //Eggplants
crops[12][0]=2000000; //Fennel
crops[13][0]=1500000; //Flax
crops[14][0]=0; //Garlix
crops[15][0]=0; //Greenwoad
crops[16][0]=0; //Hem
crops[17][0]=0; //Leeks
crops[18][0]=0; //Lettuce
crops[19][0]=0; //Madder
crops[20][0]=0; //Mint
crops[21][0]=0; //Mustard
crops[22][0]=5000000; //Oats
crops[23][0]=0; //Onions
crops[24][0]=0; //Parsnips
crops[25][0]=0; //Parsely
crops[26][0]=2500000; //Peas
crops[27][0]=0; //Poppy
crops[28][0]=0; //Potatoes
crops[29][0]=0; //Pumpkins
crops[30][0]=0; //Radishes
crops[31][0]=0; //Rutabagas
crops[32][0]=0; //Spinach
crops[33][0]=4000000; //Spring Barley
crops[34][0]=0; //Squash
crops[35][0]=0; //Tomatoes
crops[36][0]=0; //Turnips
crops[37][0]=0; //Vetches
crops[38][0]=0; //Weld
crops[39][0]=0; //Woad
crops[40][0]=6000000; //Barley - Winter Crop
crops[41][0]=5000000; //Mixtill - Winter Crop
crops[42][0]=4000000; //Wheat - Winter Crop
Though, I have to leave for work now, but I will be able to respond to any answers once I return tonight. Thank you for those who are trying to help! :)
Swap your subscript indices.
crops[13][0] -> crops[0][13]
When you declared
vector<vector<int> >crops(2, vector<int>(43));
You created a vector which is value-initialised with 2 vectors, each of which was value-initialised with 43 ints (meaning they are initialised to 0). There are two vectors in the outer vector so you can only do crops[0] or crops[1] without reading someone else's memory.
Alternatively, of course, you could just change the declaration to:
vector<vector<int> >crops(43, vector<int>(2));

in two dimensional array in c++ why we always have to mention number of columns?

this is a very simple question but whoever i ask it they cant answer it.
in two dimensional arrays we have to specify rows and columns,right?
for example:
void foo( int towers **[ ][ 3 ]** , int rings )
{
for (int ring = 0; ring < rings; ring++)
{
... towers[ ring ][ 0 ]...
}
}
in programming its okay if we dont write(mention) rows as you see in that piece of code,but we ALWYAS have to write number of columns no matter what.
so what is the logic reason that why we should write number of columns? what will happen if we dont?
Whenever you try to access a two dimensional array, you specify the two indices: array[a][b]. C++ ensures all the elements in array[n][...] are contiguous in memory for any n, then the next bit of memory is used for array[n+1][...] etc.. For example:
array[0][0] ((T*)array)
array[0][1] ((T*)array) + 1
array[0][2] ((T*)array) + 2
array[1][0] ((T*)array) + 3
array[1][1] ((T*)array) + 4
...
So, the absolute memory address of array[a][b], in an array T array[A][B] is:
((T*)array) + a * B + b;
See how the calculation needs B but not A? Similarly, the compiler is insisting you provide all but the left-most index.
In some ways, it would be nice if the compiler verified that you didn't try to index to a value of [a] at or past A, but the language makes no such checks - it's up to the programmer to ensure their code indexes the array safely. If you want safety you can use a std::vector<> and at() for runtime index checking, or even write a fixed-size-array mechanism that checks compile-time-constant indices at compile time (not very useful, as indices typically vary at runtime).
You know how two dimensional array is stored in the memory. If it is of size [n][m] then it just takes n x m consecutive cells in the memory. Afterwords when you get asked about element [a][b] there is the calculation that takes the element a * m + b from these consecutive cells. However this calculation can not be performed if you do not supply the number of columns (because otherwise the m will not be known).
On the other hand the number of columns and rows is not stored in the memory portion for the array and the number of columns can not be derived from the memory either. All this means that the computer will not know which memory address to serve you.