Resources

vector of matrices

0

I would like to define vector of matrices with different dimensions. Can it be done directly or I need to define 3-dimensional array accompanied by additional array of real dimensions?

Tags: asked May 16, 2014

4 Answers

0

I am not certain I am understanding your question, so here are a couple possibilities depending upon exactly what you are trying to do.

Multidimensional array case
If, for example, you have 2 matrices that are 3x4, then the multidimensional array syntax is pretty straightforward.

//for repeatable random numbers
rndseed 234532;

num_mats = 2;
num_rows = 3;
num_cols = 4;

//create the data for the array
//as a 6x4 matrix
x = rndn(num_mats*num_rows, num_cols);

//reshape the 6x4 matrix into an
//array that is 2x3x4
a = areshape(x, num_mats|num_rows|num_cols);

After the code above, the matrix x will equal:

-1.711 -0.939 -0.275 -0.286 
-0.134 -1.428  0.353  1.188 
-1.571  0.612 -0.238  1.930 
 0.099  0.660  0.878  2.252 
-1.004  0.308  1.882 -0.084 
-2.708  0.545  1.480  1.076 

and the array a will equal:

Plane [1,.,.] 

-1.711 -0.939 -0.275 -0.286 
-0.134 -1.428  0.353  1.188 
-1.571  0.612 -0.238  1.930 

Plane [2,.,.] 

 0.099  0.660  0.878  2.252 
-1.004  0.308  1.882 -0.084 
-2.708  0.545  1.480  1.076

You can think about the first index of this three dimensional array as which matrix you are referencing. The second index would be which row in that matrix and the final index would be which column. For example:

print a[2, 3, 4];

would return:

1.076

and

print a[1, 2, 3];

would return:

0.353

Structure case
If the matrices are different sizes, then you will want to create a structure. Besides the ability to group together data of different dimensions, structures also allow you to give clear descriptive names to each member and allow you to mix, matrices with strings and string arrays as well.

For example, let's say your model uses data for several countries GDP, imports and exports. However, for some of these variables you have more data than others which makes the dimensions different. In this case you could create a structure like this:

//define structure
struct country {
   matrix GDP;
   matrix imports;
   matrix exports;
   matrix years;
};

//declare an instance of the structure
struct country albania;

//fill in the structure
albania.years = { 2005, 2006, 2007, 2008, 2009 };
albania.GDP = {   3 2.2 1.5 0.8,
                2.7 2.3 1.7 1.1,
                2.9 2.5 1.4 1.3,
                2.8 2.7 1.6 1.7 };
albania.imports = { 1017,
                    1125,
                     995,
                    1030 };

You can also make arrays of structures as well if you needed to. The structures tutorials on this page could be of help.

aptech
352
0

I will clarify the problem. Let's assume we have 2 matrices, the first is 2x2 zero matrix, the second is 3x3 identity matrix. Now we want to create a vector that consist of these matrices, so that, for example v[1] is the first matrix and v[2] is the second.

Furthermore, let's think about procedure, where the input should contain a number of matrices, each of different dimensions, but the number of matrices is not fixed. This is the reason, why it would be useful for me, to have one variable which is vector of matrices. Can I use directly multidimensional arrays or structures in order to have vector of matrices with different dimensions as in the aforementioned example?

By the way, I have realised that in my case matrices have one dimension fixed whereas the other is bounded. So I can try to circumvent the problem by concatenating the matrices (in one big matrix with fixed dimensions) and preserving the information on actual dimensions in an additional vector, which needs to be an input to my procedure.

Thank you for your help,
Piotr

0

It depends upon how many matrices will be needed all the time and how many at most. If you will need 3 matrices all the time, but will not need more than 7 for instance, then I would create a structure with 7 matrix elements and only fill in what is needed, like this:

//define structure
struct parameters {
   matrix alpha;
   matrix beta;
   matrix gamma;
   matrix delta;
   matrix epsilon;
   matrix zeta;
   matrix eta;
};

//declare structure instance
struct parameters p1;

//assign required members
p1.alpha = zeros(10, 10);
p2.beta = eye(10);
p3.gamma = rndn(10, 5);

//Set the remaining members only when needed
//p1.delta = ones(10, 20);
//p1.epsilon = rndu(10, 40);
//...
//...

proc (1) = myProcedure(struct parameters p1);
   local out;
   
   //perform some calculations
   out = p1.alpha + p1.beta .* p1.gamma;
   .
   .
   .
   retp(out);
endp;

If you have no idea how many matrices will be needed, then you could make a struct that just took a matrix as a member and then reshape it into an array of structures like this:

//define structure
struct matrix_data {
   matrix x;
};

//declare structure instance
struct matrix_data md;

//reshape into 12x1 array of structures
num_mats = 12;
md = reshape(md, num_mats, 1);

//Set the members
md[1].x = zeros(10,10);
md[2].x = eye(10);
.
.
.

proc (1) = myProcedure(struct matrix_data md);
   local out;
   
 //perform some calculations
   out = md[1].x + md[2].x .* md[3].x;
   .
   .
   .
   retp(out);
endp;

You can also mix these options. You could either pass in two structures into your main procedure: the first containing the minimum members and the second being an array of structures like in the second example.

struct parameters {
   matrix alpha;
   matrix beta;
};
struct matrix_data {
   matrix x;
};

struct parameters p;
struct matrix_data md;

p.alpha = zeros(10, 1);
p.beta = eye(10);

md = reshape(md, 2, 1);
md[1].x = rndn(10, 10);
md[2].x = rndu(10, 200);

proc (1) = myProcedure(struct parameters p, struct matrix_data md);
   .
   .
   .
endp;

Or you could make a structure like the my_data structure be a member of your main structure.

struct matrix_data {
   matrix x;
};

struct parameters {
   matrix alpha;
   matrix beta;
   struct matrix_data extra_matrices;
};

struct parameters p;
struct matrix_data mats;

p.alpha = zeros(10, 15);
p.beta = eye(10);

mats = reshape(mats, 2, 1);
mats[1].x = rndn(10, 10);
mats[2].x = rndn(10, 200);

p.extra_matrices = mats;

proc (1) = myProcedure(struct parameters p);
   local out;
   
   out = p.alpha + p.beta .* p.extra_matrices[1].x + p.extra_matrices[2].x;
   .
   .
   .
   retp(out);
endp;
aptech
352
0

Arrays of structures works fine. Thank you very much!

Since GAUSS is used in time-series econometrics and cross-sectional analyses i.e., therefore, in my opinion, it would be desirable, if objects could be nested simpler then by arrays of structures. So it would be nice, if variables like vector of matrices or vector of vectors of vectors could be created and refered to similarly like 2-dimensional matrices. For example
Amat = zeros(2,3);
Bmat = eye(4);
v = zeros(2,1); // ?? or some declaration?
v[1] = Amat;
v[2] = Bmat;

Best regards,
Piotr