What is the difference between these two declarations of array? - c

I want to know the difference between theses two declarations of these arrays, one is defined like this (double array[a][b][c][d]), the other one is different (double array[a*b*c][d])
double weight4_5[LAYER4][LAYER5][LENGTH_KERNEL][LENGTH_KERNEL];
double weight5_6[LAYER5 * LENGTH_FEATURE5 * LENGTH_FEATURE5][OUTPUT];
if i want to load values to these two arrays with for loops, how can i do it ?

The first one is a 4 Dimensional array.
Access is by weight4_5[i][j][k][l]
The second one is a 2 Dimensional array. It is a flattened array.
Access is basically by weight5_6[x][y] But you need to do some calculations to get the value of x based on the 4D original array.
You can organise it multiple ways as you want, (e.g. row wise, column wise etc) One way is to have
x= ((((i*LAYER5)+j)*LENGTH_FEATURE5)+k)
y = l;

Related

Minizinc: create an array of int pairs

What is the Minizinc syntax to create an array of n int pairs like this:
{(x1,y1), (x2,y2),....(xn,yn)}
and how can I access to a specific element j to get, for example, its y value?
In MiniZinc you would currently use multi-dimensional arrays for this purpose. If, for example, you want to create n pairs of integer variables you can use:
array [1..n, 1..2] of var int: pairs;
You could then access each pair, but also each element. If, for example, you want to access pair j, then you can use the statement pairs[j]. This is an array of dimensions 1..2; you can access the second element (y), using pairs[j][y].
This approach allows you to use the variables directly, but you can also use pairs for predicates that call for arrays.

Correct Subscript Ordering for Two Dimensional Arrays

I am talking about a zero-indexed matrix of integers denoted by a pointer to pointer, i.e.
int **mat;
Then what is the correct way to represent the mat[m][n] element? Is it
*(*(mat+m)+n)
or is it
*(*(mat+n)+m)
Also, visually speaking, between m and n, which one is the row index or which one is the column index? Or do terms like row and column make any sense here? I am sure I have some conceptual gap here, and some help will be great.
The expression
mat[m][n]
is parsed as
(mat[m])[n]
which is equivalent to
(*(mat + m))[n]
which is in turn equivalent to
*(*(mat + m) + n)
so your initial guess is correct.
As for which of these mean rows and which of these mean columns - in some sense, this is up to you to decide. You're the one creating the array and you can assign it any semantics that you'd like.
On the other hand, if you create a 2D array like this:
int mat[A][B];
then in memory this will be laid out as
[0, 0][0, 1][0, 2]...[0, B-1][1, 0][1, 1][1, 2]... ... [A-1][B-1]
Because of locality of reference, if you read across this in the order shown above (do all of mat[0], then all of mat[1], etc.) than it is to iterate in the reverse order (do mat[0][0], then mat[1][0], then mat[2][0], etc.). In that sense, it's common to treat 2D arrays as having the first component select a row and the second select a column, since that more naturally aligns with how the memory is laid out.

Creating a cell array of different randomized matrices

I'm trying to create a cell array of size N,
where every cell is a randomized Matrix of size M,
I've tried using deal or simple assignments, but the end result is always N identical Matrices of size M
for example:
N=20;
M=10;
CellArray=cell(1,N);
CellArray(1:20)={rand(M)};
this yields identical matrices in each cell, iv'e tried writing the assignment like so:
CellArray{1:20}={rand(M)};
but this yields the following error:
The right hand side of this assignment has too few values to satisfy the left hand side.
the ends results should be a set of transition probability matrices to be used for a model i'm constructing,
there's a currently working version of the model, but it uses loops to create the matrices, and works rather slowly,
i'd be thankful for any help
If you don't want to use loops because you are interested in a low execution time, get rid of the cells.
RandomArray=rand(M,M,N)
You can access each slice, which is your intended MxM matrix, using RandomArray(:,:,index)
Use cellfun:
N = 20;
M = 10;
CellArray = cellfun(#(x) rand(M), cell(1,N), 'uni',0)
For every cell it newly calls rand(M) - unlike before, you were assigning the same rand(M) to every cell, which was just computed once.

How to pick a random element in a 2 dimensional array

Ok I want to pick a random point in the 2d array so it can be filled. Ive seen how to do this for a 1d array, and am wondering how this would be possible in a 2d array. All I have seen about this method is that the same position comes up again, which is a slight problem, but I don't know how to do it in the first place. The 2d array is essentially a grid, with the dimensions being the x and y coordinates. And the random element selecting a point within the boundaries (which is user selected but for the purposes of this problem can be 30x50.
EDIT:
import java.util.Random;
class pickRand{
public static String get (int x, int y){
int rndx = generator.nextInt(x) + 2;
int rndy = generator.nextInt(y) + 2;
}
}
So would this work, the x and y will correspond to the user generated number and have a raised boundary of 2 either side to prevent any objects going (partially outside or of the grid. Nothing needs to be returned right?
If you grid is of size M by N
Generate a random number between 0 and M-1 say i
Generate another random between 0 and N-1 say j
(i,j) will be a random element of the 2d array
What role does the array play here?
Essentially, the task is to pick... random integer 2D coordinates.
So if you want two coordinates, say i in 0...W-1 and j in 0...H-1, just draw two random integers. If you need more for higher dimensionality, draw more randoms.
Obviously, you can then access array[i][j].
In most languages, arrays can however be ragged, i.e. the rows/columns may have different lengths. This is however just as trivial to handle...

Matlab array of struct : Fast assignment

Is there any way to "vector" assign an array of struct.
Currently I can
edges(1000000) = struct('weight',1.0); //This really does not assign the value, I checked on 2009A.
for i=1:1000000; edges(i).weight=1.0; end;
But that is slow, I want to do something more like
edges(:).weight=[rand(1000000,1)]; //with or without the square brackets.
Any ideas/suggestions to vectorize this assignment, so that it will be faster.
Thanks in advance.
This is much faster than deal or a loop (at least on my system):
N=10000;
edge(N) = struct('weight',1.0); % initialize the array
values = rand(1,N); % set the values as a vector
W = mat2cell(values, 1,ones(1,N)); % convert values to a cell
[edge(:).weight] = W{:};
Using curly braces on the right gives a comma separated value list of all the values in W (i.e. N outputs) and using square braces on the right assigns those N outputs to the N values in edge(:).weight.
You can try using the Matlab function deal, but I found it requires to tweak the input a little (using this question: In Matlab, for a multiple input function, how to use a single input as multiple inputs?), maybe there is something simpler.
n=100000;
edges(n)=struct('weight',1.0);
m=mat2cell(rand(n,1),ones(n,1),1);
[edges(:).weight]=deal(m{:});
Also I found that this is not nearly as fast as the for loop on my computer (~0.35s for deal versus ~0.05s for the loop) presumably because of the call to mat2cell. The difference in speed is reduced if you use this more than once but it stays in favor of the for loop.
You could simply write:
edges = struct('weight', num2cell(rand(1000000,1)));
Is there something requiring you to particularly use a struct in this way?
Consider replacing your array of structs with simply a separate array for each member of the struct.
weights = rand(1, 1000);
If you have a struct member which is an array, you can make an extra dimension:
matrices = rand(3, 3, 1000);
If you just want to keep things neat, you could put these arrays into a struct:
edges.weights = weights;
edges.matrices = matrices;
But if you need to keep an array of structs, I think you can do
[edges.weight] = rand(1, 1000);
The reason that the structs in your example don't get initialized properly is that the syntax you're using only addresses the very last element in the struct array. For a nonexistent array, the rest of them get implicitly filled in with structs that have the default value [] in all their fields.
To make this behavior clear, try doing a short array with clear edges; edges(1:3) = struct('weight',1.0) and looking at each of edges(1), edges(2), and edges(3). The edges(3) element has 1.0 in its weight like you want; the others have [].
The syntax for efficiently initializing an array of structs is one of these.
% Using repmat and full assignment
edges = repmat(struct('weight', 1.0), [1 1000]);
% Using indexing
% NOTE: Only correct if variable is uninitialized!!!
edges(1:1000) = struct('weight', 1.0); % QUESTIONABLE
Note the 1:1000 instead of just 1000 when indexing in to the uninitialized edges array.
There's a problem with the edges(1:1000) form: if edges is already initialized, this syntax will just update the values of selected elements. If edges has more than 1000 elements, the others will be left unchanged, and your code will be buggy. Or if edges is a different type, you could get an error or weird behavior depending on its existing datatype. To be safe, you need to do clear edges before initializing using the indexing syntax. So it's better to just do full assignment with the repmat form.
BUT: Regardless of how you initialize it, an array-of-structs like this is always going to be inherently slow to work with for larger data sets. You can't do real "vectorized" operations on it because your primitive arrays are all broken up in to separate mxArrays inside each struct element. That includes the field assignment in your question – it is not possible to vectorize that. Instead, you should switch a struct-of-arrays like Brian L's answer suggests.
You can use a reverse struct and then do all operations without any errors
like this
x.E(1)=1;
x.E(2)=3;
x.E(2)=8;
x.E(3)=5;
and then the operation like the following
x.E
ans =
3 8 5
or like this
x.E(1:2)=2
x =
E: [2 2 5]
or maybe this
x.E(1:3)=[2,3,4]*5
x =
E: [10 15 20]
It is really faster than for_loop and you do not need other big functions to slow your program.

Resources