Chapter 1 Data Structures
1.1 Matrices and Arrays
1.1.1 Array Reshape, Repeat and Expand Examples
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.1.1.1 Basic Examples of Reshape
a = [1,2,3,4,5,6]';
b = reshape(a, [3,2])
b = 3x2
1 4
2 5
3 6
b(:)
ans = 6x1
1
2
3
4
5
6
a = [1,2,3;4,5,6;7,8,9;10,11,12]'
a = 3x4
1 4 7 10
2 5 8 11
3 6 9 12
b = reshape(a, [6,2])
b = 6x2
1 7
2 8
3 9
4 10
5 11
6 12
1.1.1.2 Stack Two Matrix of Equal Column Count Together
a = [1,2;3,4];
a_stacked = [a;a;a];
disp(a_stacked);
1 2
3 4
1 2
3 4
1 2
3 4
1.1.1.3 Repeat/Duplicate Matrix Downwards
There is a 2 by 3 matrix, to be repeated 4 times, downwards. This is useful for replicating data matrix for say counterfactual purposes.
Below, we have two ways of repeating a matrix downwards. Copy as whole, or copy row by row.
row_count = 2;
col_count = 3;
repeat_mat_count = 2;
data_vec = 1:(row_count*col_count);
searchMatrix = reshape(data_vec,row_count,col_count);
% To repeat matrix downwards
rep_rows_idx = [1:row_count]'*ones(1,repeat_mat_count);
rep_rows_idx = rep_rows_idx(:);
rep_cols_idx = [1:col_count];
rep_cols_idx = rep_cols_idx(:);
searchMatrixRep_stack = searchMatrix(rep_rows_idx, rep_cols_idx);
% To insert repeated rows following original rows
rep_rows_idx = ([1:row_count]'*ones(1,repeat_mat_count))';
rep_rows_idx = rep_rows_idx(:);
searchMatrixRep_dup = searchMatrix(rep_rows_idx, rep_cols_idx);
disp(searchMatrix)
1 3 5
2 4 6
disp(searchMatrixRep_stack)
1 3 5
2 4 6
1 3 5
2 4 6
disp(searchMatrixRep_dup)
1 3 5
1 3 5
2 4 6
2 4 6
1.1.1.4 Index Dimension Transform
it_inner_fin = 5; it_outter_fin = 3;
it_inner_cur = it_outter_fin it_outter_cur = it_inner_fin
ar_it_cols_idx = 1:1:(it_inner_fin*it_outter_fin) ar_it_cols_inner_dim = repmat(1:it_inner_cur, \[it_outter_cur, 1\]) ar_it_cols_inner_dim(:)’
mt_it_cols_idx = reshape(ar_it_cols_idx, \[it_inner_cur, it_outter_cur\])’ mt_it_cols_idx(:)’
it_inner_fin = 5;
it_outter_fin = 3;
ar_it_cols_idx = 1:1:(it_inner_fin*it_outter_fin)
ar_it_cols_idx = 1x15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
mt_it_cols_idx = reshape(ar_it_cols_idx, [it_outter_fin, it_inner_fin])'
mt_it_cols_idx = 5x3
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
mt_it_cols_idx(:)'
ans = 1x15
1 4 7 10 13 2 5 8 11 14 3 6 9 12 15
1.1.2 Array Index Slicing and Subsetting to Replace and Expand
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.1.2.1 Find the First Negative Element of Array
There is an array with positive, negative and NaN values, find the first negative number’s index, and the last positive number index. Use the find function.
for it_array=1:1:2
% Construct Array
if (it_array == 1)
ar_alpha_sum_devi_one = [0.1, 0.7, -0.001, NaN, NaN];
elseif (it_array ==2)
ar_alpha_sum_devi_one = [0.1, 0.7, 0.001, NaN, NaN];
end
% Find last positive
it_last_pos_idx = find(ar_alpha_sum_devi_one > 0, 1, 'last');
% Find first negative
it_first_neg_idx = find(ar_alpha_sum_devi_one < 0, 1, 'first');
if (isempty(it_first_neg_idx))
it_first_neg_idx = NaN;
end
disp(['it_last_pos_idx=' num2str(it_last_pos_idx) ...
', it_first_neg_idx=' num2str(it_first_neg_idx)])
end
it_last_pos_idx=2, it_first_neg_idx=3
it_last_pos_idx=3, it_first_neg_idx=NaN
1.1.2.2 First the First Negative Element of Last Segment of Array
There is an array with some negative numbers, then some positive numbers, then some negative numbers again. Find the first element of the final segment of negative numbers.
for it_array=1:5
% Construct Array
if (it_array == 1)
ar_alpha_sum_devi_one = [0.1, 0.7, -0.001, NaN, NaN];
elseif (it_array ==2)
ar_alpha_sum_devi_one = [0.1, 0.7, 0.001, NaN, NaN];
elseif (it_array ==3)
ar_alpha_sum_devi_one = [-0.001, 0.1, 0.7, 0.001, NaN, NaN];
elseif (it_array ==4)
ar_alpha_sum_devi_one = [-0.001, 0.1, 0.7, 0.001, -0.0002, -0.05, NaN, NaN];
elseif (it_array ==5)
ar_alpha_sum_devi_one = [NaN, NaN, -0.001, 0.1, 0.7, 0.001, -0.0002, NaN];
end
% Find last positive
it_last_pos_idx = find(ar_alpha_sum_devi_one > 0, 1, 'last');
% Find first negative
it_first_neg_idx = find(ar_alpha_sum_devi_one < 0, 1, 'first');
% Find first negative of last negative segment
ar_alpha_sum_after_last_pos = ...
ar_alpha_sum_devi_one(it_last_pos_idx:length(ar_alpha_sum_devi_one));
it_first_neg_last_neg_seg_idx = it_last_pos_idx - 1 + ...
find(ar_alpha_sum_after_last_pos < 0, 1, 'first');
if (isempty(it_first_neg_idx))
it_first_neg_idx = NaN;
end
if (isempty(it_first_neg_last_neg_seg_idx))
it_first_neg_last_neg_seg_idx = NaN;
end
disp(['it_last_pos_idx=' num2str(it_last_pos_idx) ...
', it_first_neg_idx=' num2str(it_first_neg_idx)...
', it_first_neg_last_neg_seg_idx=' num2str(it_first_neg_last_neg_seg_idx)])
end
it_last_pos_idx=2, it_first_neg_idx=3, it_first_neg_last_neg_seg_idx=3
it_last_pos_idx=3, it_first_neg_idx=NaN, it_first_neg_last_neg_seg_idx=NaN
it_last_pos_idx=4, it_first_neg_idx=1, it_first_neg_last_neg_seg_idx=NaN
it_last_pos_idx=4, it_first_neg_idx=1, it_first_neg_last_neg_seg_idx=5
it_last_pos_idx=6, it_first_neg_idx=3, it_first_neg_last_neg_seg_idx=7
1.1.2.3 Index Select Rows and Columns of a 2D matrix
In the example below, select by entire rows and columns:
% There is a 2D Matrix
rng(123);
randMatZ = rand(3,6);
disp(randMatZ);
0.6965 0.5513 0.9808 0.3921 0.4386 0.7380
0.2861 0.7195 0.6848 0.3432 0.0597 0.1825
0.2269 0.4231 0.4809 0.7290 0.3980 0.1755
% Duplicate Select Row sand Columns of Elements
disp(randMatZ([1,2,3,3,3,2], [1,1,2,2,2,1]))
0.6965 0.6965 0.5513 0.5513 0.5513 0.6965
0.2861 0.2861 0.7195 0.7195 0.7195 0.2861
0.2269 0.2269 0.4231 0.4231 0.4231 0.2269
0.2269 0.2269 0.4231 0.4231 0.4231 0.2269
0.2269 0.2269 0.4231 0.4231 0.4231 0.2269
0.2861 0.2861 0.7195 0.7195 0.7195 0.2861
1.1.2.4 Index Select Set of Elements from 2D matrix
Rather than selecting entire rows and columns, suppose we want to select only one element at row 1 col 2, the element at row 2 col 4, element at row 5 col 1, etc.
% Select Subset of Elements
it_row_idx = [1,2,3,1,3,2];
it_col_idx = [1,1,5,4,2,3];
% Select sub2idx
ar_lin_idx = sub2ind(size(randMatZ), it_row_idx, it_col_idx);
ar_sel_val = randMatZ(ar_lin_idx);
disp(ar_sel_val');
0.6965
0.2861
0.3980
0.3921
0.4231
0.6848
1.1.2.5 Find Closest Element of Array to Each Element of Another Array
Given scalar value, find the cloest value in array:
fl_a = 3.4;
ar_bb = [1,2,3,4];
[fl_min, it_min_idx] = min(abs(ar_bb-fl_a));
disp(it_min_idx);
3
Given a scalar value and an array, find the closest smaller value in the array to the scalar value:
fl_a = 2.1;
ar_bb = [1,2,3,4];
disp(sum(ar_bb<fl_a));
2
Array A is between 0 and 1, on some grid. Array B is also between 0 and 1, but scattered. Find for each element of B the index of the cloest value on A that is smaller than the element in B.
rng(1234);
ar_a = linspace(0,10,5);
ar_b = rand([5,1])*10;
mt_a_less_b = ar_a<ar_b;
mt_a_less_b_idx = sum(ar_a<ar_b, 2);
disp(ar_a);
0 2.5000 5.0000 7.5000 10.0000
disp(ar_b);
1.9152
6.2211
4.3773
7.8536
7.7998
disp(mt_a_less_b);
1 0 0 0 0
1 1 1 0 0
1 1 0 0 0
1 1 1 1 0
1 1 1 1 0
disp(mt_a_less_b_idx);
1
3
2
4
4
1.1.2.6 Matlab Index based Replacement of Subset of Matrix Values
rng(123);
randMatZ = rand(3,6)+1;
randMat = rand(3,6)-0.5;
output = max(-randMat,0);
randMatZ(output==0) = 999;
min(randMatZ,[],2);
randMatZ((max(-randMat,0))==0) = 999;
disp(randMatZ);
999.0000 999.0000 999.0000 1.3921 1.4386 1.7380
999.0000 999.0000 1.6848 1.3432 1.0597 1.1825
999.0000 999.0000 1.4809 999.0000 1.3980 1.1755
disp(min(randMatZ,[],2));
1.3921
1.0597
1.1755
1.1.2.7 Matlab Matrix Index Based Matrix Expansion (Manual)
In the example below, we start with a 4 by 2 matrix, than we expand specific rows and columns of the matrix. Specifically, we expand the matrix such that the result matrix repeats the 1st, 2nd, 1st, 2nd, then 3rd, than 1st, 1st, and 1st rows. And repeats column 1, then 2nd, then 2nd, then 2nd, and finally the first column.
% Original Matrix
Z = 2;
N = 2;
Q = 2;
base_mat = reshape(1:(Z*N*Q),Z*N,Q);
disp(base_mat);
1 5
2 6
3 7
4 8
% Expanded Matrix
base_expand = base_mat([1,2,1,2,3,1,1,1],[1,2,2,2,1]);
disp(base_expand);
1 5 5 5 1
2 6 6 6 2
1 5 5 5 1
2 6 6 6 2
3 7 7 7 3
1 5 5 5 1
1 5 5 5 1
1 5 5 5 1
1.1.2.8 Duplicate Matrix Downwards N times Using Index
The example here has the same idea, but we do the operations above in a more automated way. This could be done using alternative methods.
% Original Matrix
Z = 2;
N = 2;
Q = 2;
base_mat = reshape(1:(Z*N*Q),Z*N,Q);
disp(base_mat);
1 5
2 6
3 7
4 8
% Generate row Index many times automatically depending on how many times
% to replicate
vmat_repeat_count = 3;
vmat_reindex_rows_repeat = [1:(Z*N)]'* ones(1,vmat_repeat_count);
vmat_reindex_rows_repeat = vmat_reindex_rows_repeat(:);
disp(vmat_reindex_rows_repeat');
1 2 3 4 1 2 3 4 1 2 3 4
% Duplicate Matrix by the Rows specified above, and using the same number
% of columns.
mat_repdown = base_mat(vmat_reindex_rows_repeat(:), 1:Q);
disp(mat_repdown');
1 2 3 4 1 2 3 4 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8
1.1.2.9 Given ND Array, Get Row and Column (and other dimension) Index With Value Conditioning
There is a matrix where some values are equal to 1 (based on some prior selection), get the row and column index of the matrix.
% Some matrix with 1s
rng(123);
mt_some_ones = rand(3,3);
disp(mt_some_ones);
0.6965 0.5513 0.9808
0.2861 0.7195 0.6848
0.2269 0.4231 0.4809
% find the location of the ones
[r_idx, c_idx] = find(mt_some_ones<0.5);
% the set of locations
disp([r_idx,c_idx]);
2 1
3 1
3 2
3 3
Now do the same three with a three dimensional array:
% Some matrix with 1s
rng(123);
mn3_some_ones = rand(3,3,3);
disp(mn3_some_ones);
(:,:,1) =
0.6965 0.5513 0.9808
0.2861 0.7195 0.6848
0.2269 0.4231 0.4809
(:,:,2) =
0.3921 0.4386 0.7380
0.3432 0.0597 0.1825
0.7290 0.3980 0.1755
(:,:,3) =
0.5316 0.8494 0.7224
0.5318 0.7245 0.3230
0.6344 0.6110 0.3618
% find the location of the ones
[d1_idx, d2_idx, d3_idx] = ind2sub(size(mn3_some_ones), find(mn3_some_ones<0.5));
% the set of locations
disp([d1_idx, d2_idx, d3_idx]);
2 1 1
3 1 1
3 2 1
3 3 1
1 1 2
2 1 2
1 2 2
2 2 2
3 2 2
2 3 2
3 3 2
2 3 3
3 3 3
1.1.2.10 Max of Matrix column by Column Linear to 2d Index
Finding max of matrix column by column, then obtain the linear index associated with the max values.
randMat = rand(5,3);
disp(randMat);
0.2283 0.4309 0.8934
0.2937 0.4937 0.9442
0.6310 0.4258 0.5018
0.0921 0.3123 0.6240
0.4337 0.4264 0.1156
[maxVal maxIndex] = max(randMat);
linearIndex = sub2ind(size(randMat),maxIndex,(1:1:size(randMat,2)))
linearIndex = 1x3
3 7 12
randMat(linearIndex)
ans = 1x3
0.6310 0.4937 0.9442
t_pV = [1,2;3,4;5,6];
t_pV_Ind = [1,1;0,0;1,1];
[maxVal maxIndex] = max(t_pV(t_pV_Ind==1))
maxVal = 6
maxIndex = 4
1.1.2.11 Given Array of size M, Select N somewhat equi-distance elements
% Subset count
it_n = 5;
% Example 1, long array
ar_fl_a = 1:1.1:100;
ar_it_subset_idx = unique(round(((0:1:(it_n-1))/(it_n-1))*(length(ar_fl_a)-1)+1));
ar_fl_a_subset = ar_fl_a(ar_it_subset_idx);
disp(ar_fl_a_subset);
1.0000 26.3000 50.5000 75.8000 100.0000
% Example 2, Short Array
ar_fl_a = 1:1.1:3;
ar_it_subset_idx = unique(round(((0:1:(it_n-1))/(it_n-1))*(length(ar_fl_a)-1)+1));
ar_fl_a_subset = ar_fl_a(ar_it_subset_idx);
disp(ar_fl_a_subset);
1.0000 2.1000
% Write As function
f_subset = @(it_subset_n, it_ar_n) unique(round(((0:1:(it_subset_n-1))/(it_subset_n-1))*(it_ar_n-1)+1));
% Select 5 out of 10
disp(f_subset(5, 10));
1 3 6 8 10
% Select 10 out of 5
disp(f_subset(10, 5));
1 2 3 4 5
% Select 5 out of 5
disp(f_subset(5, 5));
1 2 3 4 5
1.1.3 Maximum of Matrix Columns, Sort Matrix Columns
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.1.3.1 Max Value from a Matrix
Given a matrix of values, what is the maximum element, what are the row and column indexes of this max element of the matrix.
rng(123);
N = 3;
M = 4;
mt_rand = rand(M,N);
disp(mt_rand);
0.6965 0.7195 0.4809
0.2861 0.4231 0.3921
0.2269 0.9808 0.3432
0.5513 0.6848 0.7290
[max_val, max_idx] = max(mt_rand(:));
[max_row, max_col] = ind2sub(size(mt_rand), max_idx)
max_row = 3
max_col = 2
1.1.3.2 MAX Value from Each Column
There is a matrix with N columns, and M rows, with numerical values. Generate a table of sorted index, indicating in each column which row was the highest in value, second highest, etc. (1) sort each column. (2) show the row number from descending or ascending sort for each column as a matrix.
% Create a 2D Array
rng(123);
N = 2;
M = 4;
mt_rand = rand(M,N);
disp(mt_rand);
0.6965 0.7195
0.2861 0.4231
0.2269 0.9808
0.5513 0.6848
Use the maxk function to generate sorted index:
% maxk function
[val, idx] = max(mt_rand);
disp(val);
0.6965 0.9808
disp(idx);
1 3
1.1.3.3 MAXK Sorted Sorted Index for Each Column of Matrix
There is a matrix with N columns, and M rows, with numerical values. Generate a table of sorted index, indicating in each column which row was the highest in value, second highest, etc. (1) sort each column. (2) show the row number from descending or ascending sort for each column as a matrix.
% Create a 2D Array
rng(123);
N = 2;
M = 4;
mt_rand = rand(M,N);
disp(mt_rand);
0.6965 0.7195
0.2861 0.4231
0.2269 0.9808
0.5513 0.6848
Use the maxk function to generate sorted index:
% maxk function
[val, idx] = maxk(mt_rand, M);
disp(val);
0.6965 0.9808
0.5513 0.7195
0.2861 0.6848
0.2269 0.4231
disp(idx);
1 3
4 1
2 4
3 2
1.1.4 Array Broadcast and Expansion Examples
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
Matrix broadcasting was added to matlab’s recent editions. This is an important step for vectorizing codes. Proper usage of broadcasting reduces memory allocation requirements for matrix matrix operations.
1.1.4.1 Broadcasting with A Row and a Column
Below we add together a 1 by 3 and 4 by 1 array, that should not work. With broadcasting, it is assumed that we will mesh the arrays and then sum up the meshed matrixes.
clear all
ar_A = [1,2,3];
ar_B = [4,3,2,1]';
disp(size(ar_A));
1 3
disp(size(ar_B));
4 1
mt_A_B_broadcast = ar_A + ar_B;
disp(mt_A_B_broadcast);
5 6 7
4 5 6
3 4 5
2 3 4
mt_A_B_broadcast_product = ar_A.*ar_B;
disp(mt_A_B_broadcast_product);
4 8 12
3 6 9
2 4 6
1 2 3
1.1.4.2 Broadcasting with One Row and One Matrix
Below we add together a 1 by 3 and 4 by 3 matrix, that should not work. With broadcasting, it is assumed that we will repeat the array four times, duplicating the single row four times, so the matrix dimensions match up.
clear all
ar_A = [1,2,3];
mt_B = [4,3,2,1;5,4,3,2;6,5,4,3]';
disp(size(ar_A));
1 3
disp(size(mt_B));
4 3
mt_A_B_broadcast = ar_A + mt_B;
disp(mt_A_B_broadcast);
5 7 9
4 6 8
3 5 7
2 4 6
mt_A_B_broadcast_product = ar_A.*mt_B;
disp(mt_A_B_broadcast_product);
4 10 18
3 8 15
2 6 12
1 4 9
1.1.4.3 Broadcasting with One Column and One Matrix
Below we add together a 4 by 1 and 4 by 3 matrix, that should not work. With broadcasting, it is assumed that we will repeat the column three times, duplicating the single column three times, so the matrix dimensions match up.
clear all
ar_A = [4,3,2,1]';
mt_B = [4,3,2,1;5,4,3,2;6,5,4,3]';
disp(size(ar_A));
4 1
disp(size(mt_B));
4 3
mt_A_B_broadcast = ar_A + mt_B;
disp(mt_A_B_broadcast);
8 9 10
6 7 8
4 5 6
2 3 4
mt_A_B_broadcast_product = ar_A.*mt_B;
disp(mt_A_B_broadcast_product);
16 20 24
9 12 15
4 6 8
1 2 3
1.1.4.4 Expand with Broadcast, Percentage Choice grids
clear all
ar_w_perc = [0.1,0.5,0.9]
ar_w_perc = 1x3
0.1000 0.5000 0.9000
ar_w_level = [-2,0,2]
ar_w_level = 1x3
-2 0 2
fl_b_bd = -4
fl_b_bd = -4
ar_k_max = ar_w_level - fl_b_bd
ar_k_max = 1x3
2 4 6
ar_ak_perc = [0.1,0.3,0.7,0.9]
ar_ak_perc = 1x4
0.1000 0.3000 0.7000 0.9000
mt_k = (ar_k_max'*ar_ak_perc)'
mt_k = 4x3
0.2000 0.4000 0.6000
0.6000 1.2000 1.8000
1.4000 2.8000 4.2000
1.8000 3.6000 5.4000
mt_a = (ar_w_level - mt_k)
mt_a = 4x3
-2.2000 -0.4000 1.4000
-2.6000 -1.2000 0.2000
-3.4000 -2.8000 -2.2000
-3.8000 -3.6000 -3.4000
1.1.4.5 Expand Matrix Twice
clear all
% Same as above
ar_w_level = [-2,-1,-0.1]
ar_w_level = 1x3
-2.0000 -1.0000 -0.1000
fl_b_bd = -4
fl_b_bd = -4
ar_k_max = ar_w_level - fl_b_bd
ar_k_max = 1x3
2.0000 3.0000 3.9000
ar_ak_perc = [0.001, 0.1,0.3,0.7,0.9, 0.999]
ar_ak_perc = 1x6
0.0010 0.1000 0.3000 0.7000 0.9000 0.9990
mt_k = (ar_k_max'*ar_ak_perc)'
mt_k = 6x3
0.0020 0.0030 0.0039
0.2000 0.3000 0.3900
0.6000 0.9000 1.1700
1.4000 2.1000 2.7300
1.8000 2.7000 3.5100
1.9980 2.9970 3.8961
mt_a = (ar_w_level - mt_k)
mt_a = 6x3
-2.0020 -1.0030 -0.1039
-2.2000 -1.3000 -0.4900
-2.6000 -1.9000 -1.2700
-3.4000 -3.1000 -2.8300
-3.8000 -3.7000 -3.6100
-3.9980 -3.9970 -3.9961
% fraction of borrowing for bridge loan
ar_coh_bridge_perc = [0, 0.5, 0.999];
% Expand matrix to include coh percentage dimension
mt_k = repmat(mt_k, [1, length(ar_coh_bridge_perc)])
mt_k = 6x9
0.0020 0.0030 0.0039 0.0020 0.0030 0.0039 0.0020 0.0030 0.0039
0.2000 0.3000 0.3900 0.2000 0.3000 0.3900 0.2000 0.3000 0.3900
0.6000 0.9000 1.1700 0.6000 0.9000 1.1700 0.6000 0.9000 1.1700
1.4000 2.1000 2.7300 1.4000 2.1000 2.7300 1.4000 2.1000 2.7300
1.8000 2.7000 3.5100 1.8000 2.7000 3.5100 1.8000 2.7000 3.5100
1.9980 2.9970 3.8961 1.9980 2.9970 3.8961 1.9980 2.9970 3.8961
mt_a = repmat(mt_a, [1, length(ar_coh_bridge_perc)])
mt_a = 6x9
-2.0020 -1.0030 -0.1039 -2.0020 -1.0030 -0.1039 -2.0020 -1.0030 -0.1039
-2.2000 -1.3000 -0.4900 -2.2000 -1.3000 -0.4900 -2.2000 -1.3000 -0.4900
-2.6000 -1.9000 -1.2700 -2.6000 -1.9000 -1.2700 -2.6000 -1.9000 -1.2700
-3.4000 -3.1000 -2.8300 -3.4000 -3.1000 -2.8300 -3.4000 -3.1000 -2.8300
-3.8000 -3.7000 -3.6100 -3.8000 -3.7000 -3.6100 -3.8000 -3.7000 -3.6100
-3.9980 -3.9970 -3.9961 -3.9980 -3.9970 -3.9961 -3.9980 -3.9970 -3.9961
mt_a = mt_a
mt_a = 6x9
-2.0020 -1.0030 -0.1039 -2.0020 -1.0030 -0.1039 -2.0020 -1.0030 -0.1039
-2.2000 -1.3000 -0.4900 -2.2000 -1.3000 -0.4900 -2.2000 -1.3000 -0.4900
-2.6000 -1.9000 -1.2700 -2.6000 -1.9000 -1.2700 -2.6000 -1.9000 -1.2700
-3.4000 -3.1000 -2.8300 -3.4000 -3.1000 -2.8300 -3.4000 -3.1000 -2.8300
-3.8000 -3.7000 -3.6100 -3.8000 -3.7000 -3.6100 -3.8000 -3.7000 -3.6100
-3.9980 -3.9970 -3.9961 -3.9980 -3.9970 -3.9961 -3.9980 -3.9970 -3.9961
% bridge loan component of borrowing
ar_brdige_a = (ar_coh_bridge_perc'*ar_w_level)'
ar_brdige_a = 3x3
0 -1.0000 -1.9980
0 -0.5000 -0.9990
0 -0.0500 -0.0999
ar_brdige_a = ar_brdige_a(:)'
ar_brdige_a = 1x9
0 0 0 -1.0000 -0.5000 -0.0500 -1.9980 -0.9990 -0.0999
% borrowing choices excluding bridge loan
mt_a_nobridge = mt_a - ar_brdige_a
mt_a_nobridge = 6x9
-2.0020 -1.0030 -0.1039 -1.0020 -0.5030 -0.0539 -0.0040 -0.0040 -0.0040
-2.2000 -1.3000 -0.4900 -1.2000 -0.8000 -0.4400 -0.2020 -0.3010 -0.3901
-2.6000 -1.9000 -1.2700 -1.6000 -1.4000 -1.2200 -0.6020 -0.9010 -1.1701
-3.4000 -3.1000 -2.8300 -2.4000 -2.6000 -2.7800 -1.4020 -2.1010 -2.7301
-3.8000 -3.7000 -3.6100 -2.8000 -3.2000 -3.5600 -1.8020 -2.7010 -3.5101
-3.9980 -3.9970 -3.9961 -2.9980 -3.4970 -3.9461 -2.0000 -2.9980 -3.8962
1.1.5 Grid States, Choices and Optimal Choices Example
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.1.5.1 Generate State Grid
There many multiple individuals, each individual’s value for each state space variable is different. We duplicate that by shockCount and choicecount:
stateCount = 2;
shockCount = 3;
choiceCount = 4;
state1 = rand(1,stateCount)
state1 = 1x2
0.0571 0.6694
states1ShkDup = state1(ones(shockCount*choiceCount,1),:)
states1ShkDup = 12x2
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
0.0571 0.6694
states1ShkDup(:)
ans = 24x1
0.0571
0.0571
0.0571
0.0571
0.0571
0.0571
0.0571
0.0571
0.0571
0.0571
1.1.5.2 Generate Choices
Generate Choice Grid, Example: Each individual has minimal protein and maximal protein they can get Generate a evenly set grid of choices for each individual from min to max. Individual min and max choice is a function of some component of their state-space, such as wealth/income level, and choice is the quantity of good to purchase.
stateCount = 2;
shockCount = 3;
choiceCount = 4;
% 1. Min and Max Choices for each state
minprot_n = floor(rand(1,stateCount)*10)
minprot_n = 1x2
7 7
maxprot_n = minprot_n + floor(rand(1,stateCount)*10)
maxprot_n = 1x2
14 12
% 2. Choice Ratios, ratios of max-min difference
protChoiceGrid = linspace(0,1,choiceCount)
protChoiceGrid = 1x4
0 0.3333 0.6667 1.0000
% 3. Each column is a different state.
searchMatrix = (protChoiceGrid'*(maxprot_n-minprot_n)+minprot_n(ones(choiceCount,1),:))
searchMatrix = 4x2
7.0000 7.0000
9.3333 8.6667
11.6667 10.3333
14.0000 12.0000
% 4. Each column is a different state, each set of rows is a different shock% for the state. In this structure, shocks (to preference for example), do% not change choice grid for a given state
searchMatrix = searchMatrix([1:choiceCount]'* ones(1,shockCount), [1:stateCount]' * ones(1,1))
searchMatrix = 12x2
7.0000 7.0000
9.3333 8.6667
11.6667 10.3333
14.0000 12.0000
7.0000 7.0000
9.3333 8.6667
11.6667 10.3333
14.0000 12.0000
7.0000 7.0000
9.3333 8.6667
searchMatrix(:)
ans = 24x1
7.0000
9.3333
11.6667
14.0000
7.0000
9.3333
11.6667
14.0000
7.0000
9.3333
1.1.5.3 Average Utility over Shocks
Average of Shocks, E(value) For each STATE and CHOICE, x number of shocks. Need to average over shocks; The raw value output is: STATES * SHOCKS * CHOICES; Code below turn into various things, see MATLAB CODE STRUCTURE in oneNOTE GCC working notes
shockCount = 2;
choiceCount = 3;
stateCount = 4;
% 1. VALUE vector (STATES * SHOCKS * CHOICES by 1), this is generated by utility% evaluation function that takes as input STATES, SHOCKS, and CHOICES
valuesOri = sort(rand(choiceCount*shockCount*stateCount,1))
valuesOri = 24x1
0.0296
0.1141
0.1472
0.1514
0.1826
0.1936
0.2526
0.2911
0.3257
0.3352
% 2. CHOICES by STATES * SHOCKS (ST1 SK1, ST1 SK2; ST2 SK1, etc), each% column are values for different choices given the same state and shock.
values = reshape(valuesOri,[choiceCount,shockCount*stateCount])
values = 3x8
0.0296 0.1514 0.2526 0.3352 0.5939 0.7065 0.8791 0.9204
0.1141 0.1826 0.2911 0.3480 0.5992 0.7267 0.9001 0.9508
0.1472 0.1936 0.3257 0.4578 0.6576 0.7792 0.9018 0.9658
% 3. SHOCKS by CHOICES * STATES (CH1 ST1, CH1 ST2; CH2 ST1, etc), each% column are two shocks for each state given the same choice. Note this% assumes that for different shocks of the same state choice vector is the% same.
values = reshape(values',[shockCount, choiceCount*stateCount])
values = 2x12
0.0296 0.2526 0.5939 0.8791 0.1141 0.2911 0.5992 0.9001 0.1472 0.3257 0.6576 0.9018
0.1514 0.3352 0.7065 0.9204 0.1826 0.3480 0.7267 0.9508 0.1936 0.4578 0.7792 0.9658
% 4. AVG: 1 by CHOICES * STATES (CH1 ST1, CH1 ST2; CH2 ST1, etc), take% average over shocks for each state and choice combo
valuesMn = mean(values,1)
valuesMn = 1x12
0.0905 0.2939 0.6502 0.8997 0.1483 0.3196 0.6629 0.9254 0.1704 0.3918 0.7184 0.9338
% 5. AVG: CHOICES * STATES. From this matrix, one can now pick maximum% utility, and match that to the index on choice vector
valuesMn = reshape(valuesMn, [stateCount, choiceCount])'
valuesMn = 3x4
0.0905 0.2939 0.6502 0.8997
0.1483 0.3196 0.6629 0.9254
0.1704 0.3918 0.7184 0.9338
1.1.5.4 Pick Optimal Choice
choiceCount = 3;
stateCount = 4;
% 1. Matrix, each column is a state, each row is a choice
randMat = rand(choiceCount,stateCount)
randMat = 3x4
0.0733 0.5905 0.1731 0.1795
0.0550 0.8539 0.1340 0.3175
0.3232 0.2871 0.9947 0.5683
% 2. Maximum Value and Maximum Index
[maxVal maxIndex] = max(randMat)
maxVal = 1x4
0.3232 0.8539 0.9947 0.5683
maxIndex = 1x4
3 2 3 3
% 3. Linear index
linearIdx = maxIndex + ((1:stateCount)-1)*choiceCount
linearIdx = 1x4
3 5 9 12
% 4. Optimal Choices
randMat(linearIdx)
ans = 1x4
0.3232 0.8539 0.9947 0.5683
1.1.6 Accumarray Examples
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.1.6.1 Accumarry Basic Example
There are three unique values in ar_a, sum up the probabilities for each of the unique states. This is equivalent to sorting a matrix with a and prob, and computing sum for each.
ar_a = [3,2,1,3]';
ar_prob = [0.1,0.2,0.31,0.39]';
ar_sumprob = accumarray(ar_a, ar_prob);
tb_summed_prob = table(sort(unique(ar_a)), ar_sumprob);
disp(tb_summed_prob);
Var1 ar_sumprob
____ __________
1 0.31
2 0.2
3 0.49
1.1.6.2 Accumarry For Discrete Random Variable
Upon solving a model, if we look for the mass at certain choices or states, accumarray could help aggregate up probabilities
a1 = [1,1,2,2]
a1 = 1x4
1 1 2 2
a2 = [3,2,1,3]
a2 = 1x4
3 2 1 3
a3 = [1,2,3,3]
a3 = 1x4
1 2 3 3
a = [a1;a2;a3]'/2
a = 4x3
0.5000 1.5000 0.5000
0.5000 1.0000 1.0000
1.0000 0.5000 1.5000
1.0000 1.5000 1.5000
prob_a = zeros(size(a)) + 1/12
prob_a = 4x3
0.0833 0.0833 0.0833
0.0833 0.0833 0.0833
0.0833 0.0833 0.0833
0.0833 0.0833 0.0833
[ar_idx_full, ~, ar_idx_of_unique] = unique(a)
ar_idx_full = 3x1
0.5000
1.0000
1.5000
ar_idx_of_unique = 12x1
1
1
2
2
3
2
1
3
1
2
mt_idx_of_unique = reshape(ar_idx_of_unique, size(a))
mt_idx_of_unique = 4x3
1 3 1
1 2 2
2 1 3
2 3 3
accumarray(mt_idx_of_unique(:,1), prob_a(:,1))
ans = 2x1
0.1667
0.1667
accumarray(mt_idx_of_unique(:,2), prob_a(:,2))
ans = 3x1
0.0833
0.0833
0.1667
accumarray(mt_idx_of_unique(:,3), prob_a(:,3))
ans = 3x1
0.0833
0.0833
0.1667
1.1.7 Matlab Miscellaneous and Basic Numeric and Array Operations
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.1.7.1 Divisor, Quotient and Remainder
Given an array of integer values, and some divisor, find the quotient and remainder.
it_divisor = 10;
for bl_int=[0,1]
if (bl_int == 1)
ar_integers = int16([1,2,3, 11,12,13, 21,22,23]);
else
ar_integers = [1,2,3, 11,12,13, 21,22,23];
end
for it_integer=ar_integers
% Modulus and quotient
if(isinteger(it_integer))
it_quotient = idivide(it_integer, it_divisor);
else
it_quotient = fix(it_integer/it_divisor);
end
it_remainder = rem(it_integer, it_divisor);
if (it_remainder == 1)
fl_power = 1.0;
elseif (it_remainder == 2)
fl_power = 1.5;
elseif (it_remainder == 3)
fl_power = 2.0;
end
if (it_quotient == 0)
fl_base = 2;
elseif (it_quotient == 1)
fl_base = exp(1);
elseif (it_quotient == 2)
fl_base = 10;
end
fl_value = fl_base^fl_power;
% Print
st_print = strjoin(...
["Divide test:", ...
['bl_int=' num2str(bl_int)], ...
['it_integer=' num2str(it_integer)], ...
['it_remainder=' num2str(it_remainder)], ...
['it_quotient=' num2str(it_quotient)], ...
['fl_value=' num2str(fl_value)], ...
], ";");
disp(st_print);
end
end
Divide test:;bl_int=0;it_integer=1;it_remainder=1;it_quotient=0;fl_value=2
Divide test:;bl_int=0;it_integer=2;it_remainder=2;it_quotient=0;fl_value=2.8284
Divide test:;bl_int=0;it_integer=3;it_remainder=3;it_quotient=0;fl_value=4
Divide test:;bl_int=0;it_integer=11;it_remainder=1;it_quotient=1;fl_value=2.7183
Divide test:;bl_int=0;it_integer=12;it_remainder=2;it_quotient=1;fl_value=4.4817
Divide test:;bl_int=0;it_integer=13;it_remainder=3;it_quotient=1;fl_value=7.3891
Divide test:;bl_int=0;it_integer=21;it_remainder=1;it_quotient=2;fl_value=10
Divide test:;bl_int=0;it_integer=22;it_remainder=2;it_quotient=2;fl_value=31.6228
Divide test:;bl_int=0;it_integer=23;it_remainder=3;it_quotient=2;fl_value=100
Divide test:;bl_int=1;it_integer=1;it_remainder=1;it_quotient=0;fl_value=2
Divide test:;bl_int=1;it_integer=2;it_remainder=2;it_quotient=0;fl_value=2.8284
Divide test:;bl_int=1;it_integer=3;it_remainder=3;it_quotient=0;fl_value=4
Divide test:;bl_int=1;it_integer=11;it_remainder=1;it_quotient=1;fl_value=2.7183
Divide test:;bl_int=1;it_integer=12;it_remainder=2;it_quotient=1;fl_value=4.4817
Divide test:;bl_int=1;it_integer=13;it_remainder=3;it_quotient=1;fl_value=7.3891
Divide test:;bl_int=1;it_integer=21;it_remainder=1;it_quotient=2;fl_value=10
Divide test:;bl_int=1;it_integer=22;it_remainder=2;it_quotient=2;fl_value=31.6228
Divide test:;bl_int=1;it_integer=23;it_remainder=3;it_quotient=2;fl_value=100
1.1.7.2 Check if Array is All Above or Below Zero
There is an array that contains possible NaN values, check if all elements of array are positive, or all elements are negative, ignoring the NaN values.
for it_arrays=[1,2,3,4,5,6]
if (it_arrays == 1)
ar_values = [0.0001, 0.0002, 0.0005, 0.0012, 0.0013, NaN, NaN, NaN, NaN];
elseif (it_arrays == 2)
ar_values = [NaN, -0.0002, -0.0005, -0.0012, -0.0013, NaN, NaN, NaN, NaN];
elseif (it_arrays == 3)
ar_values = [0.0001, 0.0002, 0.0005, 0.0012, 0.0013];
elseif (it_arrays == 4)
ar_values = [-0.0002, -0.0005, -0.0012, -0.0013];
elseif (it_arrays == 5)
ar_values = [-0.0002, 0.0005, -0.0012, -0.0013];
elseif (it_arrays == 6)
ar_values = [-0.0002, 0.0005, -0.0012, NaN, -0.0013];
end
bl_all_pos = min(ar_values(~isnan(ar_values))>=0);
bl_all_neg = min(ar_values(~isnan(ar_values))<=0);
st_print = ['str=' num2str(it_arrays) ...
' has bl_all_pos=' num2str(bl_all_pos) ' and bl_all_neg=' num2str(bl_all_neg)];
disp(st_print);
end
str=1 has bl_all_pos=1 and bl_all_neg=0
str=2 has bl_all_pos=0 and bl_all_neg=1
str=3 has bl_all_pos=1 and bl_all_neg=0
str=4 has bl_all_pos=0 and bl_all_neg=1
str=5 has bl_all_pos=0 and bl_all_neg=0
str=6 has bl_all_pos=0 and bl_all_neg=0
1.1.7.3 Check Parameter Types
There parameter input can either be a cell array or an integer, conditional processing based on parameter input type. To distinguish between an array or container map, for example, can use isnumeric or isfloat.
% Float and Cell
curEstiParamA = 1;
curEstiParamB = {146, 'R3'};
curEstiParamC = rand([1,5]);
curEstiParamD = [1,2,3,4.5];
curEstiParamE = containers.Map('KeyType','char', 'ValueType','any');
param_map('share_unbanked_j') = 12;
param_map('equi_r_j') = 2;
% test if is float
st_test = strjoin(...
["", ...
['isfloat(curEstiParamA)=' num2str(isfloat(curEstiParamA))], ...
['isfloat(curEstiParamB)=' num2str(isfloat(curEstiParamB))], ...
['isfloat(curEstiParamC)=' num2str(isfloat(curEstiParamC))], ...
['isfloat(curEstiParamD)=' num2str(isfloat(curEstiParamD))], ...
['isfloat(curEstiParamE)=' num2str(isfloat(curEstiParamE))], ...
], ";");
disp(st_test);
;isfloat(curEstiParamA)=1;isfloat(curEstiParamB)=0;isfloat(curEstiParamC)=1;isfloat(curEstiParamD)=1;isfloat(curEstiParamE)=0
% test if is cell
st_test = strjoin(...
["", ...
['iscell(curEstiParamA)=' num2str(iscell(curEstiParamA))], ...
['iscell(curEstiParamB)=' num2str(iscell(curEstiParamB))], ...
['iscell(curEstiParamC)=' num2str(iscell(curEstiParamC))], ...
['iscell(curEstiParamD)=' num2str(iscell(curEstiParamD))], ...
['iscell(curEstiParamE)=' num2str(iscell(curEstiParamE))], ...
], ";");
disp(st_test);
;iscell(curEstiParamA)=0;iscell(curEstiParamB)=1;iscell(curEstiParamC)=0;iscell(curEstiParamD)=0;iscell(curEstiParamE)=0
% test if is numeric
st_test = strjoin(...
["", ...
['isnumeric(curEstiParamA)=' num2str(isfloat(curEstiParamA))], ...
['isnumeric(curEstiParamB)=' num2str(isfloat(curEstiParamB))], ...
['isnumeric(curEstiParamC)=' num2str(isfloat(curEstiParamC))], ...
['isnumeric(curEstiParamD)=' num2str(isfloat(curEstiParamD))], ...
['isnumeric(curEstiParamE)=' num2str(isfloat(curEstiParamE))], ...
], ";");
disp(st_test);
;isnumeric(curEstiParamA)=1;isnumeric(curEstiParamB)=0;isnumeric(curEstiParamC)=1;isnumeric(curEstiParamD)=1;isnumeric(curEstiParamE)=0
1.1.7.4 Check if a value is an array of single scalar boolean
A function could take an array, if the array parameter input is boolean and false, then generate the array needed by the function in a different way. All that is needed is a NaN checker, works for scalar or array of NaN.
rng(123);
it_len = 3;
for it_case=[1,2,3]
if (it_case == 1)
ob_val = rand(1,it_len);
elseif (it_case == 2)
% Single NaN
ob_val = NaN;
elseif (it_case == 3)
% Single NaN
ob_val = NaN(1,it_len);
end
if (~isnan(ob_val))
% Input is the output vector since input is not NaN
ob_val_out = ob_val;
else
% Generates random output vector since input is not provided
ob_val_out = rand(1, it_len);
end
st_test = strjoin(...
["", ...
['ob_val=' num2str(ob_val)], ...
['ob_val_out=' num2str(ob_val_out)], ...
], ";");
disp(st_test);
end
;ob_val=0.69647 0.28614 0.22685;ob_val_out=0.69647 0.28614 0.22685
;ob_val=NaN;ob_val_out=0.55131 0.71947 0.42311
;ob_val=NaN NaN NaN;ob_val_out=0.98076 0.68483 0.48093
1.1.7.5 Compare Array Values That are Approximately Similar
What is the best way to compare floats for almost-equality in Python?
rel_tol is a relative tolerance, it is multiplied by the greater of the magnitudes of the two arguments; as the values get larger, so does the allowed difference between them while still considering them equal.
abs_tol is an absolute tolerance that is applied as-is in all cases. If the difference is less than either of those tolerances, the values are considered equal.
rel_tol=1e-09;
abs_tol=0.0;
if_is_close = @(a,b) (abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol));
disp(['1 and 1, if_is_close:' num2str(if_is_close(1,1))]);
1 and 1, if_is_close:1
disp(['1e-300 and 1e-301, if_is_close:' num2str(if_is_close(1e-300,1e-301))]);
1e-300 and 1e-301, if_is_close:0
disp(['1+1e-9 and 1+1e-10, if_is_close:' num2str(if_is_close(1+1e-9,1+1e-10))]);
1+1e-9 and 1+1e-10, if_is_close:1
1.1.7.6 Imaginary Number Examples
rng(123);
% Imaginary array
ar_img = rand([1,7]) + 1i*rand([1,7]);
% Regular Array
ar_real = rand([1,10]);
% Combine arrays
ar_full = [ar_real ar_img];
ar_full = ar_full(randperm(length(ar_full)));
disp(ar_full);
Columns 1 through 6
0.6344 + 0.0000i 0.1755 + 0.0000i 0.5316 + 0.0000i 0.2861 + 0.4809i 0.7380 + 0.0000i 0.1825 + 0.0000i
Columns 7 through 12
0.6965 + 0.6848i 0.2269 + 0.3921i 0.7245 + 0.0000i 0.8494 + 0.0000i 0.6110 + 0.0000i 0.4231 + 0.4386i
Columns 13 through 17
0.9808 + 0.0597i 0.5318 + 0.0000i 0.3980 + 0.0000i 0.5513 + 0.3432i 0.7195 + 0.7290i
% real index
disp(~imag(ar_full));
1 1 1 0 1 1 0 0 1 1 1 0 0 1 1 0 0
% Get Real and not real Components
disp(ar_full(imag(ar_full) == 0));
0.6344 0.1755 0.5316 0.7380 0.1825 0.7245 0.8494 0.6110 0.5318 0.3980
disp(ar_full(imag(ar_full) ~= 0));
Columns 1 through 6
0.2861 + 0.4809i 0.6965 + 0.6848i 0.2269 + 0.3921i 0.4231 + 0.4386i 0.9808 + 0.0597i 0.5513 + 0.3432i
Column 7
0.7195 + 0.7290i
1.2 ND Dimensional Arrays
1.2.1 Joint Arrays All Combinations and by Random Subset
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.2.1.1 Given Several Arrays, General all Possible Combinations
There are several parameters, might want to simulate at all possible combinations. In the example below, there are four parmeters, generate a table with all possible combinations of the four parameters.
%% A. Quadc linh refh and refsd parameter grids
[it_p1, it_p2, it_p3] = deal(4, 3, 3);
ar_p1 = linspace(-0.09, -0.02, it_p1);
ar_p2 = linspace( 0.020, 0.100, it_p2);
ar_p3 = linspace(-0.100, -0.020, it_p3);
ar_p4 = [0.05];
%% B. Mesh Parameters together
% ndgrid mesh together
[mn_p1, ~] = ndgrid(ar_p1, ar_p2, ar_p3, ar_p4);
% combine
[ar_p1_idx, ar_p2_idx, ar_p3_idx, ar_p4_idx] = ind2sub(size(mn_p1), find(mn_p1));
% Index and values
ar_p1_flat = ar_p1(ar_p1_idx)';
ar_p2_flat = ar_p2(ar_p2_idx)';
ar_p3_flat = ar_p3(ar_p3_idx)';
ar_p4_flat = ar_p4(ar_p4_idx)';
mt_paramsmesh_long = [ar_p1_idx(:), ar_p1_flat(:), ...
ar_p2_idx(:), ar_p2_flat(:), ...
ar_p3_idx(:), ar_p3_flat(:), ...
ar_p4_idx(:), ar_p4_flat(:)];
% Sort by a and z
mt_paramsmesh_long = sortrows(mt_paramsmesh_long, [1,3, 5]);
% C. Create Table
tb_paramsmesh_long = array2table(mt_paramsmesh_long);
cl_col_names_a = {'quadc_idx', 'quadc_val', ...
'linh_idx', 'linh_val', ...
'refh_idx', 'rehfh_val', ...
'refsd_idx', 'rehfsd_val'};
tb_paramsmesh_long.Properties.VariableNames = cl_col_names_a;
% D. Display Table
disp(tb_paramsmesh_long);
quadc_idx quadc_val linh_idx linh_val refh_idx rehfh_val refsd_idx rehfsd_val
_________ _________ ________ ________ ________ _________ _________ __________
1 -0.09 1 0.02 1 -0.1 1 0.05
1 -0.09 1 0.02 2 -0.06 1 0.05
1 -0.09 1 0.02 3 -0.02 1 0.05
1 -0.09 2 0.06 1 -0.1 1 0.05
1 -0.09 2 0.06 2 -0.06 1 0.05
1 -0.09 2 0.06 3 -0.02 1 0.05
1 -0.09 3 0.1 1 -0.1 1 0.05
1 -0.09 3 0.1 2 -0.06 1 0.05
1 -0.09 3 0.1 3 -0.02 1 0.05
2 -0.066667 1 0.02 1 -0.1 1 0.05
2 -0.066667 1 0.02 2 -0.06 1 0.05
2 -0.066667 1 0.02 3 -0.02 1 0.05
2 -0.066667 2 0.06 1 -0.1 1 0.05
2 -0.066667 2 0.06 2 -0.06 1 0.05
2 -0.066667 2 0.06 3 -0.02 1 0.05
2 -0.066667 3 0.1 1 -0.1 1 0.05
2 -0.066667 3 0.1 2 -0.06 1 0.05
2 -0.066667 3 0.1 3 -0.02 1 0.05
3 -0.043333 1 0.02 1 -0.1 1 0.05
3 -0.043333 1 0.02 2 -0.06 1 0.05
3 -0.043333 1 0.02 3 -0.02 1 0.05
3 -0.043333 2 0.06 1 -0.1 1 0.05
3 -0.043333 2 0.06 2 -0.06 1 0.05
3 -0.043333 2 0.06 3 -0.02 1 0.05
3 -0.043333 3 0.1 1 -0.1 1 0.05
3 -0.043333 3 0.1 2 -0.06 1 0.05
3 -0.043333 3 0.1 3 -0.02 1 0.05
4 -0.02 1 0.02 1 -0.1 1 0.05
4 -0.02 1 0.02 2 -0.06 1 0.05
4 -0.02 1 0.02 3 -0.02 1 0.05
4 -0.02 2 0.06 1 -0.1 1 0.05
4 -0.02 2 0.06 2 -0.06 1 0.05
4 -0.02 2 0.06 3 -0.02 1 0.05
4 -0.02 3 0.1 1 -0.1 1 0.05
4 -0.02 3 0.1 2 -0.06 1 0.05
4 -0.02 3 0.1 3 -0.02 1 0.05
1.2.1.2 Matlab Draw Random with and without Replacement
%Generate a matrix named foo, with limited numbers
rng(1234);
foo = unique((round((randn(5,1)+1)*100)));
disp(foo);
5
78
154
219
232
% draw 10 random samples without replacement
index = randsample(1:length(foo), 4);
bar_rand_noreplace = foo(index,:);
% draw 1000 random samples with replacement
index = randsample(1:length(foo), 4, true);
bar_rand_replace = foo(index,:);
% Display
disp(table(bar_rand_noreplace, bar_rand_replace));
bar_rand_noreplace bar_rand_replace
__________________ ________________
5 78
78 154
154 219
232 219
1.2.1.3 Matrix Meshgrid to Loop Permutated Vectors
Meshgrid to generate all permutations of arrays.
k = linspace(1,10,10);
kp = linspace(1,10,10);
z = linspace(0,1,10);
[kM kpM zM] = meshgrid(k,kp,z);
kMVec = kM(:);
kMpVec = kpM(:);
zMVec = zM(:);
outputVec = zeros(size(zMVec));
for a=1:length(zMVec)
outputVec(a) = kMVec(a)+kMpVec(a)+zMVec(a);
end
outputTens = reshape(outputVec,size(kM));
disp(outputTens);
(:,:,1) =
2 3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13 14 15
7 8 9 10 11 12 13 14 15 16
8 9 10 11 12 13 14 15 16 17
9 10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19 20
(:,:,2) =
2.1111 3.1111 4.1111 5.1111 6.1111 7.1111 8.1111 9.1111 10.1111 11.1111
3.1111 4.1111 5.1111 6.1111 7.1111 8.1111 9.1111 10.1111 11.1111 12.1111
4.1111 5.1111 6.1111 7.1111 8.1111 9.1111 10.1111 11.1111 12.1111 13.1111
5.1111 6.1111 7.1111 8.1111 9.1111 10.1111 11.1111 12.1111 13.1111 14.1111
6.1111 7.1111 8.1111 9.1111 10.1111 11.1111 12.1111 13.1111 14.1111 15.1111
7.1111 8.1111 9.1111 10.1111 11.1111 12.1111 13.1111 14.1111 15.1111 16.1111
8.1111 9.1111 10.1111 11.1111 12.1111 13.1111 14.1111 15.1111 16.1111 17.1111
9.1111 10.1111 11.1111 12.1111 13.1111 14.1111 15.1111 16.1111 17.1111 18.1111
10.1111 11.1111 12.1111 13.1111 14.1111 15.1111 16.1111 17.1111 18.1111 19.1111
11.1111 12.1111 13.1111 14.1111 15.1111 16.1111 17.1111 18.1111 19.1111 20.1111
(:,:,3) =
2.2222 3.2222 4.2222 5.2222 6.2222 7.2222 8.2222 9.2222 10.2222 11.2222
3.2222 4.2222 5.2222 6.2222 7.2222 8.2222 9.2222 10.2222 11.2222 12.2222
4.2222 5.2222 6.2222 7.2222 8.2222 9.2222 10.2222 11.2222 12.2222 13.2222
5.2222 6.2222 7.2222 8.2222 9.2222 10.2222 11.2222 12.2222 13.2222 14.2222
6.2222 7.2222 8.2222 9.2222 10.2222 11.2222 12.2222 13.2222 14.2222 15.2222
7.2222 8.2222 9.2222 10.2222 11.2222 12.2222 13.2222 14.2222 15.2222 16.2222
8.2222 9.2222 10.2222 11.2222 12.2222 13.2222 14.2222 15.2222 16.2222 17.2222
9.2222 10.2222 11.2222 12.2222 13.2222 14.2222 15.2222 16.2222 17.2222 18.2222
10.2222 11.2222 12.2222 13.2222 14.2222 15.2222 16.2222 17.2222 18.2222 19.2222
11.2222 12.2222 13.2222 14.2222 15.2222 16.2222 17.2222 18.2222 19.2222 20.2222
(:,:,4) =
2.3333 3.3333 4.3333 5.3333 6.3333 7.3333 8.3333 9.3333 10.3333 11.3333
3.3333 4.3333 5.3333 6.3333 7.3333 8.3333 9.3333 10.3333 11.3333 12.3333
4.3333 5.3333 6.3333 7.3333 8.3333 9.3333 10.3333 11.3333 12.3333 13.3333
5.3333 6.3333 7.3333 8.3333 9.3333 10.3333 11.3333 12.3333 13.3333 14.3333
6.3333 7.3333 8.3333 9.3333 10.3333 11.3333 12.3333 13.3333 14.3333 15.3333
7.3333 8.3333 9.3333 10.3333 11.3333 12.3333 13.3333 14.3333 15.3333 16.3333
8.3333 9.3333 10.3333 11.3333 12.3333 13.3333 14.3333 15.3333 16.3333 17.3333
9.3333 10.3333 11.3333 12.3333 13.3333 14.3333 15.3333 16.3333 17.3333 18.3333
10.3333 11.3333 12.3333 13.3333 14.3333 15.3333 16.3333 17.3333 18.3333 19.3333
11.3333 12.3333 13.3333 14.3333 15.3333 16.3333 17.3333 18.3333 19.3333 20.3333
(:,:,5) =
2.4444 3.4444 4.4444 5.4444 6.4444 7.4444 8.4444 9.4444 10.4444 11.4444
3.4444 4.4444 5.4444 6.4444 7.4444 8.4444 9.4444 10.4444 11.4444 12.4444
4.4444 5.4444 6.4444 7.4444 8.4444 9.4444 10.4444 11.4444 12.4444 13.4444
5.4444 6.4444 7.4444 8.4444 9.4444 10.4444 11.4444 12.4444 13.4444 14.4444
6.4444 7.4444 8.4444 9.4444 10.4444 11.4444 12.4444 13.4444 14.4444 15.4444
7.4444 8.4444 9.4444 10.4444 11.4444 12.4444 13.4444 14.4444 15.4444 16.4444
8.4444 9.4444 10.4444 11.4444 12.4444 13.4444 14.4444 15.4444 16.4444 17.4444
9.4444 10.4444 11.4444 12.4444 13.4444 14.4444 15.4444 16.4444 17.4444 18.4444
10.4444 11.4444 12.4444 13.4444 14.4444 15.4444 16.4444 17.4444 18.4444 19.4444
11.4444 12.4444 13.4444 14.4444 15.4444 16.4444 17.4444 18.4444 19.4444 20.4444
(:,:,6) =
2.5556 3.5556 4.5556 5.5556 6.5556 7.5556 8.5556 9.5556 10.5556 11.5556
3.5556 4.5556 5.5556 6.5556 7.5556 8.5556 9.5556 10.5556 11.5556 12.5556
4.5556 5.5556 6.5556 7.5556 8.5556 9.5556 10.5556 11.5556 12.5556 13.5556
5.5556 6.5556 7.5556 8.5556 9.5556 10.5556 11.5556 12.5556 13.5556 14.5556
6.5556 7.5556 8.5556 9.5556 10.5556 11.5556 12.5556 13.5556 14.5556 15.5556
7.5556 8.5556 9.5556 10.5556 11.5556 12.5556 13.5556 14.5556 15.5556 16.5556
8.5556 9.5556 10.5556 11.5556 12.5556 13.5556 14.5556 15.5556 16.5556 17.5556
9.5556 10.5556 11.5556 12.5556 13.5556 14.5556 15.5556 16.5556 17.5556 18.5556
10.5556 11.5556 12.5556 13.5556 14.5556 15.5556 16.5556 17.5556 18.5556 19.5556
11.5556 12.5556 13.5556 14.5556 15.5556 16.5556 17.5556 18.5556 19.5556 20.5556
(:,:,7) =
2.6667 3.6667 4.6667 5.6667 6.6667 7.6667 8.6667 9.6667 10.6667 11.6667
3.6667 4.6667 5.6667 6.6667 7.6667 8.6667 9.6667 10.6667 11.6667 12.6667
4.6667 5.6667 6.6667 7.6667 8.6667 9.6667 10.6667 11.6667 12.6667 13.6667
5.6667 6.6667 7.6667 8.6667 9.6667 10.6667 11.6667 12.6667 13.6667 14.6667
6.6667 7.6667 8.6667 9.6667 10.6667 11.6667 12.6667 13.6667 14.6667 15.6667
7.6667 8.6667 9.6667 10.6667 11.6667 12.6667 13.6667 14.6667 15.6667 16.6667
8.6667 9.6667 10.6667 11.6667 12.6667 13.6667 14.6667 15.6667 16.6667 17.6667
9.6667 10.6667 11.6667 12.6667 13.6667 14.6667 15.6667 16.6667 17.6667 18.6667
10.6667 11.6667 12.6667 13.6667 14.6667 15.6667 16.6667 17.6667 18.6667 19.6667
11.6667 12.6667 13.6667 14.6667 15.6667 16.6667 17.6667 18.6667 19.6667 20.6667
(:,:,8) =
2.7778 3.7778 4.7778 5.7778 6.7778 7.7778 8.7778 9.7778 10.7778 11.7778
3.7778 4.7778 5.7778 6.7778 7.7778 8.7778 9.7778 10.7778 11.7778 12.7778
4.7778 5.7778 6.7778 7.7778 8.7778 9.7778 10.7778 11.7778 12.7778 13.7778
5.7778 6.7778 7.7778 8.7778 9.7778 10.7778 11.7778 12.7778 13.7778 14.7778
6.7778 7.7778 8.7778 9.7778 10.7778 11.7778 12.7778 13.7778 14.7778 15.7778
7.7778 8.7778 9.7778 10.7778 11.7778 12.7778 13.7778 14.7778 15.7778 16.7778
8.7778 9.7778 10.7778 11.7778 12.7778 13.7778 14.7778 15.7778 16.7778 17.7778
9.7778 10.7778 11.7778 12.7778 13.7778 14.7778 15.7778 16.7778 17.7778 18.7778
10.7778 11.7778 12.7778 13.7778 14.7778 15.7778 16.7778 17.7778 18.7778 19.7778
11.7778 12.7778 13.7778 14.7778 15.7778 16.7778 17.7778 18.7778 19.7778 20.7778
(:,:,9) =
2.8889 3.8889 4.8889 5.8889 6.8889 7.8889 8.8889 9.8889 10.8889 11.8889
3.8889 4.8889 5.8889 6.8889 7.8889 8.8889 9.8889 10.8889 11.8889 12.8889
4.8889 5.8889 6.8889 7.8889 8.8889 9.8889 10.8889 11.8889 12.8889 13.8889
5.8889 6.8889 7.8889 8.8889 9.8889 10.8889 11.8889 12.8889 13.8889 14.8889
6.8889 7.8889 8.8889 9.8889 10.8889 11.8889 12.8889 13.8889 14.8889 15.8889
7.8889 8.8889 9.8889 10.8889 11.8889 12.8889 13.8889 14.8889 15.8889 16.8889
8.8889 9.8889 10.8889 11.8889 12.8889 13.8889 14.8889 15.8889 16.8889 17.8889
9.8889 10.8889 11.8889 12.8889 13.8889 14.8889 15.8889 16.8889 17.8889 18.8889
10.8889 11.8889 12.8889 13.8889 14.8889 15.8889 16.8889 17.8889 18.8889 19.8889
11.8889 12.8889 13.8889 14.8889 15.8889 16.8889 17.8889 18.8889 19.8889 20.8889
(:,:,10) =
3 4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13 14 15
7 8 9 10 11 12 13 14 15 16
8 9 10 11 12 13 14 15 16 17
9 10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19 20
12 13 14 15 16 17 18 19 20 21
1.2.1.4 Given Integer Arrays, All Possible Combinations
given any sizes arrays, N of them, create all possible combinations
ar_it_a = 1:3;
ar_it_b = 1:2;
ar_it_c = 2:4;
ar_it_d = -1:-1:-2;
ar_it_e = 0.1;
cl_ar_all = {ar_it_a, ar_it_b, ar_it_c, ar_it_d, ar_it_e};
cl_mt_all = cl_ar_all;
[cl_mt_all{:}] = ndgrid(cl_ar_all{:});
mt_it_allcombo = cell2mat(cellfun(@(m) m(:), cl_mt_all, 'uni', 0));
disp(mt_it_allcombo)
1.0000 1.0000 2.0000 -1.0000 0.1000
2.0000 1.0000 2.0000 -1.0000 0.1000
3.0000 1.0000 2.0000 -1.0000 0.1000
1.0000 2.0000 2.0000 -1.0000 0.1000
2.0000 2.0000 2.0000 -1.0000 0.1000
3.0000 2.0000 2.0000 -1.0000 0.1000
1.0000 1.0000 3.0000 -1.0000 0.1000
2.0000 1.0000 3.0000 -1.0000 0.1000
3.0000 1.0000 3.0000 -1.0000 0.1000
1.0000 2.0000 3.0000 -1.0000 0.1000
2.0000 2.0000 3.0000 -1.0000 0.1000
3.0000 2.0000 3.0000 -1.0000 0.1000
1.0000 1.0000 4.0000 -1.0000 0.1000
2.0000 1.0000 4.0000 -1.0000 0.1000
3.0000 1.0000 4.0000 -1.0000 0.1000
1.0000 2.0000 4.0000 -1.0000 0.1000
2.0000 2.0000 4.0000 -1.0000 0.1000
3.0000 2.0000 4.0000 -1.0000 0.1000
1.0000 1.0000 2.0000 -2.0000 0.1000
2.0000 1.0000 2.0000 -2.0000 0.1000
3.0000 1.0000 2.0000 -2.0000 0.1000
1.0000 2.0000 2.0000 -2.0000 0.1000
2.0000 2.0000 2.0000 -2.0000 0.1000
3.0000 2.0000 2.0000 -2.0000 0.1000
1.0000 1.0000 3.0000 -2.0000 0.1000
2.0000 1.0000 3.0000 -2.0000 0.1000
3.0000 1.0000 3.0000 -2.0000 0.1000
1.0000 2.0000 3.0000 -2.0000 0.1000
2.0000 2.0000 3.0000 -2.0000 0.1000
3.0000 2.0000 3.0000 -2.0000 0.1000
1.0000 1.0000 4.0000 -2.0000 0.1000
2.0000 1.0000 4.0000 -2.0000 0.1000
3.0000 1.0000 4.0000 -2.0000 0.1000
1.0000 2.0000 4.0000 -2.0000 0.1000
2.0000 2.0000 4.0000 -2.0000 0.1000
3.0000 2.0000 4.0000 -2.0000 0.1000
1.2.2 3D, 4D, ND Arrays Reshape and Rearrange Dimensions
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.2.2.1 3D Array to Cell Array of Matrix Split by Last Dimension
Convert Multi-dimensional arrays to a cell array consistent of two dimensional arrays. In this example, we split by the 3rd dimension, so the number of output matrixes is equal to the length of the 3rd dimension.
First create a three dimensional array, two matrixes that are 4 by 3 each:
% Create a 3D Array
rng(123);
mn_rand = rand(4,3,2);
disp(mn_rand);
(:,:,1) =
0.6965 0.7195 0.4809
0.2861 0.4231 0.3921
0.2269 0.9808 0.3432
0.5513 0.6848 0.7290
(:,:,2) =
0.4386 0.1825 0.6344
0.0597 0.1755 0.8494
0.3980 0.5316 0.7245
0.7380 0.5318 0.6110
Now convert the 3 dimensional array to a 2 by 1 cell array that contains matrixes in each cell:
% Squeece 3D array to a Cell array of matrixes
cl_mn_rand = squeeze(num2cell(mn_rand, [1,2]));
celldisp(cl_mn_rand);
cl_mn_rand{1} =
0.6965 0.7195 0.4809
0.2861 0.4231 0.3921
0.2269 0.9808 0.3432
0.5513 0.6848 0.7290
cl_mn_rand{2} =
0.4386 0.1825 0.6344
0.0597 0.1755 0.8494
0.3980 0.5316 0.7245
0.7380 0.5318 0.6110
1.2.2.2 4D Array to Cell Array of Matrix Split by Last Two Dimensions
Convert 4D Multi-dimensional arrays to a cell array consistent of two dimensional arrays. In this example, the first two dimensions determine the resulting matrix size, the the 3rd and the 4th dimensions are categorical.
First create a four dimensional array, four matrixes stored each matrix is 2 by 2:
% Create a 3D Array
rng(123);
mn_rand = rand(2,2,2,2);
disp(mn_rand);
(:,:,1,1) =
0.6965 0.2269
0.2861 0.5513
(:,:,2,1) =
0.7195 0.9808
0.4231 0.6848
(:,:,1,2) =
0.4809 0.3432
0.3921 0.7290
(:,:,2,2) =
0.4386 0.3980
0.0597 0.7380
Now convert the 4 dimensional array to a 2 by 2 cell array that contains matrixes in each cell:
% Squeece 3D array to a Cell array of matrixes
cl_mn_rand = squeeze(num2cell(mn_rand, [1,2]));
celldisp(cl_mn_rand);
cl_mn_rand{1,1} =
0.6965 0.2269
0.2861 0.5513
cl_mn_rand{2,1} =
0.7195 0.9808
0.4231 0.6848
cl_mn_rand{1,2} =
0.4809 0.3432
0.3921 0.7290
cl_mn_rand{2,2} =
0.4386 0.3980
0.0597 0.7380
1.2.2.3 4D Array to Cell Array of Matrix Split by First and Fourth Dimensions Rearrange Dimensions
Suppose we store policy and value function given four state variables. The first one is age, the second one is asset, the third one is shock, and the fourth one is the number of kids. We start out with a four dimensional matrix. The objective is to create a two dimensional cell array as output where indexed by the 1st and 4th dimension of the underlying numeric array, and the elements of the 2D cell array are matrixes.
This is achieved by the permute function. We first rearrange the matrix, so that the 2nd and 3rd dimensions become the 1st and 2nd, then we use the technique used above to squeeze out the first two dimensions as matrixes with the last two as categories.
First, generate the 2 by 2 by 2 by 2, (Age, A, Z, Kids Count), matrix:
% Create a 3D Array
rng(123);
% (Age, A, Z, Kids Count)
mn_rand = rand(2,2,2,2);
Second, loop out the (A,Z) matrix by Age and Kids Count, this shows us what we want to achieve. Note that each row is Age, each column is A, each submatrix is z, and each super-matrix is kid-count. So from slicing, each column printed out are different value of A, the two submatrixes printed out are for each z. For the output structure where we want a (A,Z) matrix, the columns need to become rows, and the submatrix need to become columns.
% Show Matrix by Age and Kids
for it_age = 1:size(mn_rand,1)
for it_kids = 1:size(mn_rand,4)
disp(strcat(['it_age:' num2str(it_age) ', it_kids:' num2str(it_kids)]))
disp(mn_rand(it_age,:,:,it_kids));
end
end
it_age:1, it_kids:1
(:,:,1) =
0.6965 0.2269
(:,:,2) =
0.7195 0.9808
it_age:1, it_kids:2
(:,:,1) =
0.4809 0.3432
(:,:,2) =
0.4386 0.3980
it_age:2, it_kids:1
(:,:,1) =
0.2861 0.5513
(:,:,2) =
0.4231 0.6848
it_age:2, it_kids:2
(:,:,1) =
0.3921 0.7290
(:,:,2) =
0.0597 0.7380
Third, we permutate the matrix and squeeze to arrive at the 2 by 2 cell, note that step two is just to show via loop what we should get:
% Rearrange dimensions
mn_rand_2314 = permute(mn_rand, [2,3,1,4]);
% Squeeze the first two dimensiosn as before
cl_mn_rand = squeeze(num2cell(mn_rand_2314, [1,2]));
% show
celldisp(cl_mn_rand);
cl_mn_rand{1,1} =
0.6965 0.7195
0.2269 0.9808
cl_mn_rand{2,1} =
0.2861 0.4231
0.5513 0.6848
cl_mn_rand{1,2} =
0.4809 0.4386
0.3432 0.3980
cl_mn_rand{2,2} =
0.3921 0.0597
0.7290 0.7380
1.2.2.4 ND Array Summarize in Table
Given an ND dataframe, summarize the first two dimensions. For each possible combination of the 3rd and 4th dimension, generate mean, sd, min and max over the matrix of the first two dimensions. This is similar to a tabulation function.
First, we generate several array of information:
% Initialize and Squeeze
rng(123);
mn_rand = rand(2,2,2,2);
cln_mt_rand = squeeze(num2cell(mn_rand, [1,2]));
cl_mt_rand = cln_mt_rand(:);
celldisp(cl_mt_rand);
cl_mt_rand{1} =
0.6965 0.2269
0.2861 0.5513
cl_mt_rand{2} =
0.7195 0.9808
0.4231 0.6848
cl_mt_rand{3} =
0.4809 0.3432
0.3921 0.7290
cl_mt_rand{4} =
0.4386 0.3980
0.0597 0.7380
Second, create two arrays that tracks for each element of cl_mt_rand, which one of the 3rd and 4th dimensions they correspond to:
ar_dim_3 = [31,32]';
ar_dim_4 = [41,42]';
[mt_dim_3, mt_dim_4] = ndgrid(ar_dim_3, ar_dim_4);
ar_dim_3 = mt_dim_3(:);
ar_dim_4 = mt_dim_4(:);
Third, summarize each matrix:
% Over of matrix and summarize
ar_mean = zeros(size(cl_mt_rand));
ar_std = zeros(size(cl_mt_rand));
for it_mt=1:length(cl_mt_rand)
mt_cur = cl_mt_rand{it_mt};
ar_mean(it_mt) = mean(mt_cur, 'all');
ar_std(it_mt) = std(mt_cur, [], 'all');
end
Fourth Construct a Table
% Constructe Table
tb_rowcols_tab = array2table([(1:length(cl_mt_rand))', ...
ar_dim_3, ar_dim_4, ar_mean, ar_std]);
tb_rowcols_tab.Properties.VariableNames = ...
matlab.lang.makeValidName(["i", "dim3", "dim4", "mean", "std"]);
disp(tb_rowcols_tab);
i dim3 dim4 mean std
_ ____ ____ _______ _______
1 31 41 0.44019 0.22156
2 32 41 0.70204 0.2281
3 31 42 0.48632 0.17157
4 32 42 0.40857 0.27764
1.2.2.5 ND Array Two-Way Summarize in Table
Given dataframe as above, but we now want to add to the resulting summary table additional columns, rather than taking the means of the entire matrix in the first two dimensions, we only take average with respect to the rows, the first dimension, the second dimension show up as coumn statistics names, still multiple stats. The results worked out here are embedded in the fx_summ_nd_array function of the MEconTools Package.
First, we generate several array of information:
% dimension names
st_title = 'Summarize values over a conditional on z (columns) and kids and marriage (rows)';
st_dim_1 = 'a';
st_dim_2 = 'z';
st_dim_3 = 'kid';
st_dim_4 = 'marriage';
% 3rd and fourth dimension values
ar_dim_2 = [-3, -1, 1, 3];
ar_dim_3 = [1,2,3];
ar_dim_4 = [0,1];
% Initialize and Squeeze
rng(123);
mn_rand = rand(10,4,3,2);
cln_mt_rand = squeeze(num2cell(mn_rand, [1,2]));
cl_mt_rand = cln_mt_rand(:);
Second, create two arrays that tracks for each element of cl_mt_rand, which one of the 3rd and 4th dimensions they correspond to:
[mt_dim_3, mt_dim_4] = ndgrid(ar_dim_3', ar_dim_4');
ar_dim_3 = mt_dim_3(:);
ar_dim_4 = mt_dim_4(:);
Third, summarize each matrix:
% Over of matrix and summarize
mt_mean = zeros(length(cl_mt_rand), size(mn_rand,2));
mt_std = zeros(length(cl_mt_rand), size(mn_rand,2));
for it_mt=1:length(cl_mt_rand)
mt_cur = cl_mt_rand{it_mt};
mt_mean(it_mt,:) = mean(mt_cur, 1);
mt_std(it_mt,:) = std(mt_cur, [], 1);
end
Fourth Construct a Table
% Constructe Table
tb_rowcols_tab = array2table([(1:length(cl_mt_rand))', ...
ar_dim_3, ar_dim_4, mt_mean, mt_std]);
% Column Names
cl_col_names_cate_dims = [string(st_dim_3), string(st_dim_4)];
cl_col_names_mn = strcat('mean_', st_dim_2, string(ar_dim_2));
cl_col_names_sd = strcat('sd_', st_dim_2, string(ar_dim_2));
tb_rowcols_tab.Properties.VariableNames = ...
matlab.lang.makeValidName(["group", cl_col_names_cate_dims, cl_col_names_mn, cl_col_names_sd]);
% disp(['xxx ' st_title ' xxxxxxxxxxxxxxxxxxxxxxxxxxx']);
disp(tb_rowcols_tab);
group kid marriage mean_z_3 mean_z_1 mean_z1 mean_z3 sd_z_3 sd_z_1 sd_z1 sd_z3
_____ ___ ________ ________ ________ _______ _______ _______ _______ _______ _______
1 1 0 0.5442 0.41278 0.53795 0.49542 0.22935 0.22945 0.21653 0.25245
2 2 0 0.51894 0.52262 0.52544 0.45066 0.26787 0.23615 0.25833 0.31178
3 3 0 0.48248 0.5238 0.50392 0.46534 0.27009 0.26676 0.26644 0.29449
4 1 1 0.58343 0.50529 0.54361 0.5006 0.29578 0.30182 0.30952 0.27317
5 2 1 0.58408 0.45941 0.50466 0.40081 0.25026 0.34704 0.31039 0.28693
6 3 1 0.51148 0.49531 0.48963 0.47698 0.3271 0.24336 0.34498 0.34004
1.2.3 Multidimensional ND Array to 2D Matrix with Wide to Long
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.2.3.1 2D Matrix Wide to Long
There is a 2D matrix, the rows and columns are state variables (savings levels and shocks) for storage and graphing purposes, convert the 2D matrix where each row is a savings level and each column is a shock level to a 2D table where the first column records savings state, second column the level of shocks, and the third column stores the optimal policy or value at that particular combination of savings level and shock level.
First, generate a random 2D matrix:
% Create a 3D Array
it_z_n = 3;
it_a_n = 5;
% shock savings and shock array
ar_a = linspace(0.1, 50, it_a_n);
ar_z = linspace(-3, 3, it_z_n);
% function of a and z
mt_f_a_z = ar_a' + exp(ar_z);
% Display
disp(mt_f_a_z);
0.1498 1.1000 20.1855
12.6248 13.5750 32.6605
25.0998 26.0500 45.1355
37.5748 38.5250 57.6105
50.0498 51.0000 70.0855
Second, from linear index to row and column index:
% Row and Column index for each matrix value
% Only keep non-NAN values
ar_id_isnan = isnan(mt_f_a_z);
[ar_a_idx, ar_z_idx] = ind2sub(size(mt_f_a_z), find(~ar_id_isnan));
% Display
disp([ar_a_idx, ar_a(ar_a_idx)', ar_z_idx, ar_z(ar_z_idx)']);
1.0000 0.1000 1.0000 -3.0000
2.0000 12.5750 1.0000 -3.0000
3.0000 25.0500 1.0000 -3.0000
4.0000 37.5250 1.0000 -3.0000
5.0000 50.0000 1.0000 -3.0000
1.0000 0.1000 2.0000 0
2.0000 12.5750 2.0000 0
3.0000 25.0500 2.0000 0
4.0000 37.5250 2.0000 0
5.0000 50.0000 2.0000 0
1.0000 0.1000 3.0000 3.0000
2.0000 12.5750 3.0000 3.0000
3.0000 25.0500 3.0000 3.0000
4.0000 37.5250 3.0000 3.0000
5.0000 50.0000 3.0000 3.0000
Third, generate a 2d matrix in "table" format:
% Index and values
mt_policy_long = [ar_a_idx, ar_a(ar_a_idx)', ar_z_idx, ar_z(ar_z_idx)', mt_f_a_z(~ar_id_isnan)];
% Sort by a and z
mt_policy_long = sortrows(mt_policy_long, [1,3]);
Fourth, generate a Table with Column names:
% Create Table
tb_policy_long = array2table(mt_policy_long);
cl_col_names_a = {'a_idx', 'a_val', 'z_idx', 'z_val', 'pol_at_a_z'};
tb_policy_long.Properties.VariableNames = cl_col_names_a;
disp(tb_policy_long);
a_idx a_val z_idx z_val pol_at_a_z
_____ ______ _____ _____ __________
1 0.1 1 -3 0.14979
1 0.1 2 0 1.1
1 0.1 3 3 20.186
2 12.575 1 -3 12.625
2 12.575 2 0 13.575
2 12.575 3 3 32.661
3 25.05 1 -3 25.1
3 25.05 2 0 26.05
3 25.05 3 3 45.136
4 37.525 1 -3 37.575
4 37.525 2 0 38.525
4 37.525 3 3 57.611
5 50 1 -3 50.05
5 50 2 0 51
5 50 3 3 70.086
1.2.3.2 A Multidimensional ND Array with Many NaN Values
Continue with the previous exercise, but now we have more than 2 state variables.
Create a multidimensional Array with Many NaN Values. For example, we could have a dynamic lifecycle model with three endogenous varaibles, years of education accumulated, years of experiencesin blue and white collar jobs. By age 22, after starting to work at age 16, there are different possible combinations of G (schooling), X1 (white-collar), and X2 (blue-collar) jobs. These are exclusive choices in each year, so at age 16, assume that G = 0, X1 = 0 and X2 = 0. At age 16, they can choose to stay at home, school, or X1, or X2, exclusively. G, X1, X2 accumulate over time.
For each age, we can create multi-dimensional arrays with equal dimension for G, X1 and X2, to record consumption, value, etc at each element of the possible state-space. However, that matrix could have a lot of empty values.
In the example below, also has a X3 (military category).
% random number
rng(123);
% Max age means number of
MAX_YRS_POST16 = 3;
% store all
cl_EV = cell(MAX_YRS_POST16,1);
% Loop 1, solve BACKWARD
for it_yrs_post16=MAX_YRS_POST16:-1:1
% Store some results, the matrix below includes all possible
% state-space elements
mn_ev_at_gx123 = NaN(it_yrs_post16, it_yrs_post16, it_yrs_post16, it_yrs_post16);
% Loops 2, possibles Years attained so far as well as experiences
for G=0:1:(it_yrs_post16-1)
for X1=0:1:(it_yrs_post16-1-G)
for X2=0:1:(it_yrs_post16-1-G-X1)
for X3=0:1:(it_yrs_post16-1-G-X1-X2)
% Double checkAre these combinations feasible?
if (G+X1+X2+X3 <= it_yrs_post16)
% just plug in a random number
mn_ev_at_gx123(G+1, X1+1, X2+1, X3+1) = rand();
end
end
end
end
end
% store matrixes
cl_EV{it_yrs_post16} = mn_ev_at_gx123;
end
% Display Results
celldisp(cl_EV);
cl_EV{1} =
0.6344
cl_EV{2} =
(:,:,1,1) =
0.7380 0.5316
0.5318 NaN
(:,:,2,1) =
0.1755 NaN
NaN NaN
(:,:,1,2) =
0.1825 NaN
NaN NaN
(:,:,2,2) =
NaN NaN
NaN NaN
cl_EV{3} =
(:,:,1,1) =
0.6965 0.9808 0.3921
0.3432 0.0597 NaN
0.3980 NaN NaN
(:,:,2,1) =
0.5513 0.4809 NaN
0.4386 NaN NaN
NaN NaN NaN
(:,:,3,1) =
0.4231 NaN NaN
NaN NaN NaN
NaN NaN NaN
(:,:,1,2) =
0.2861 0.6848 NaN
0.7290 NaN NaN
NaN NaN NaN
(:,:,2,2) =
0.7195 NaN NaN
NaN NaN NaN
NaN NaN NaN
(:,:,3,2) =
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
(:,:,1,3) =
0.2269 NaN NaN
NaN NaN NaN
NaN NaN NaN
(:,:,2,3) =
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
(:,:,3,3) =
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
1.2.3.3 Generate a Two Dimensional Matrix Based on ND Array for Only non-NaN Cell Values
We can generate a 2-dimensional matrix, what we can consider as a Table, with the information stored in the structures earlier. In this example, we can drop the NaN values. This matrix will be much larger in size due to explicitly storing X1, X2, X3 and G values then the ND array when most values are not NaN. But this output matrix can be much more easily interpretable and readable. When there are many many NaNs in the ND array, this matrix could be much smaller in size.
First, convert each element of the cell array above to a 2D matrix (with the same number of columns), then stack resulting matrixes together to form one big table.
% Create a 2D Array
for it_yrs_post16=MAX_YRS_POST16:-1:1
% Get matrix at cell element
mn_ev_at_gx123 = cl_EV{it_yrs_post16};
% flaten multi-dimensional matrix
ar_ev_at_gx123_flat = mn_ev_at_gx123(:);
% find nan values
ar_id_isnan = isnan(ar_ev_at_gx123_flat);
% obtain dimension-specific index for nan positions
[id_G, id_X1, id_X2, id_X3] = ind2sub(size(mn_ev_at_gx123), find(~ar_id_isnan));
% generate 2-dimensional matrix (table)
mt_ev_at_gx123 = [it_yrs_post16 + zeros(size(id_G)), ...
(id_G-1), (id_X1-1), (id_X2-1), (id_X3-1), ...
ar_ev_at_gx123_flat(~ar_id_isnan)];
% stack results
if (it_yrs_post16 == MAX_YRS_POST16)
mt_ev_at_gx123_all = mt_ev_at_gx123;
else
mt_ev_at_gx123_all = [mt_ev_at_gx123_all; mt_ev_at_gx123];
end
end
% Sort
mt_ev_at_gx123_all = sortrows(mt_ev_at_gx123_all, [1,2,3,4]);
% Create Table
tb_ev_at_gx123_all = array2table(mt_ev_at_gx123_all);
cl_col_names_a = {'YRS_POST16', 'G', 'X1', 'X2', 'X3', 'EV'};
tb_ev_at_gx123_all.Properties.VariableNames = cl_col_names_a;
disp(tb_ev_at_gx123_all);
YRS_POST16 G X1 X2 X3 EV
__________ _ __ __ __ ________
1 0 0 0 0 0.6344
2 0 0 0 0 0.738
2 0 0 0 1 0.18249
2 0 0 1 0 0.17545
2 0 1 0 0 0.53155
2 1 0 0 0 0.53183
3 0 0 0 0 0.69647
3 0 0 0 1 0.28614
3 0 0 0 2 0.22685
3 0 0 1 0 0.55131
3 0 0 1 1 0.71947
3 0 0 2 0 0.42311
3 0 1 0 0 0.98076
3 0 1 0 1 0.68483
3 0 1 1 0 0.48093
3 0 2 0 0 0.39212
3 1 0 0 0 0.34318
3 1 0 0 1 0.72905
3 1 0 1 0 0.43857
3 1 1 0 0 0.059678
3 2 0 0 0 0.39804
1.2.3.4 Mesh Three Vectors Together then Generate A Flat Table
There are three parameters, quadratic of preference, height preference, and reference points preference. Mesh three vectors together with ndgrid. Then generate a flat table with the index of the parameters as well as the values of the parameters.
% Generate Arrays
[it_quadc, it_linh, it_refh] = deal(2, 2, 2);
ar_fl_quadc = linspace(-0.01, -0.001, it_quadc);
ar_fl_linh = linspace(0.01, 0.05, it_linh);
ar_fl_refh = linspace(-0.01, -0.05, it_refh);
% ndgrid mesh together
[mn_fl_quadc, ~] = ndgrid(ar_fl_quadc, ar_fl_linh, ar_fl_refh);
% combine
[ar_it_quadc_idx, ar_it_linh_idx, ar_it_refh_idx] = ind2sub(size(mn_fl_quadc), find(mn_fl_quadc));
% Index and values
mt_paramsmesh_long = [ar_it_quadc_idx, ar_fl_quadc(ar_it_quadc_idx)', ...
ar_it_linh_idx, ar_fl_linh(ar_it_linh_idx)', ...
ar_it_refh_idx, ar_fl_refh(ar_it_refh_idx)'];
% Sort by a and z
mt_paramsmesh_long = sortrows(mt_paramsmesh_long, [1,3, 5]);
Generate a table with Column names:
% Create Table
tb_paramsmesh_long = array2table(mt_paramsmesh_long);
cl_col_names_a = {'quadc_idx', 'quadc_val', 'linh_idx', 'linh_val', 'refh_idx', 'rehfh_val'};
tb_paramsmesh_long.Properties.VariableNames = cl_col_names_a;
disp(tb_paramsmesh_long);
quadc_idx quadc_val linh_idx linh_val refh_idx rehfh_val
_________ _________ ________ ________ ________ _________
1 -0.01 1 0.01 1 -0.01
1 -0.01 1 0.01 2 -0.05
1 -0.01 2 0.05 1 -0.01
1 -0.01 2 0.05 2 -0.05
2 -0.001 1 0.01 1 -0.01
2 -0.001 1 0.01 2 -0.05
2 -0.001 2 0.05 1 -0.01
2 -0.001 2 0.05 2 -0.05
1.3 Cells
1.3.1 Matlab Cell Array Basic Operations
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.3.1.1 String Combine with string cell
ls_st_param_key = {'fl_crra', 'fl_beta', ...
'fl_w', 'fl_r_save', ...
'fl_a_max', 'it_z_n', 'it_a_n'};
cl_st_param_keys = {'fl_wad', 'fl_betart', 'it_z_nfg'};
st_param = 'asdjfl';
disp([{st_param}, ls_st_param_key, cl_st_param_keys]);
Columns 1 through 10
{'asdjfl'} {'fl_crra'} {'fl_beta'} {'fl_w'} {'fl_r_save'} {'fl_a_max'} {'it_z_n'} {'it_a_n'} {'fl_wad'} {'fl_betart'}
Column 11
{'it_z_nfg'}
1.3.2 Matlab List Comprehension with Cells
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.3.2.1 Concatenate Numeric Values as String with Trimming
There is a list of numbers, combine (paste) to single string with some connector, trim each element to eliminate spaces.
rng(123,'philox')
ar_rand = rand([5,1]);
st_fl_rand = string(num2str(ar_rand));
st_untrimmmed = strjoin(st_fl_rand, "#");
cl_st_trimmmed = cellfun(@(x) strtrim(x), cellstr(st_fl_rand), 'UniformOutput', false);
st_trimmmed = strjoin(string(cl_st_trimmmed), "#");
disp(['st_untrimmmed:' st_untrimmmed]);
"st_untrimmmed:" " 0.53162## 0.60704## 0.31843#0.0016474## 0.65784"
disp(['st_trimmmed:' st_trimmmed]);
"st_trimmmed:" "0.53162#0.60704#0.31843#0.0016474#0.65784"
1.3.2.2 Find Index of Elements of String Cells in a larger String Cells
the function below returns the position of cl_st_param_keys in ls_st_param_key should only include in cl_st_param_keys strings that also exist in ls_st_param_key.
ls_st_param_key = {'fl_crra', 'fl_beta', ...
'fl_w', 'fl_r_save', ...
'fl_a_max', 'it_z_n', 'it_a_n'};
cl_st_param_keys = {'fl_w', 'fl_beta', 'it_z_n'};
cell2mat(cellfun(@(m) find(strcmp(ls_st_param_key, m)), ...
cl_st_param_keys, 'UniformOutput', false))
ans = 1x3
3 2 6
1.3.2.3 Given Container of Arrays, Find Total Length of All Arrays for Selected Keys
cl_st_param_keys = {'fl_crra', 'fl_beta'};
param_tstar_map = containers.Map('KeyType','char', 'ValueType','any');
it_simu_vec_len = 5;
param_tstar_map('fl_crra') = linspace(1, 2, 5);
param_tstar_map('fl_beta') = linspace(0.94, 0.98, 10);
param_tstar_map('w') = linspace(1.1, 1.4, it_simu_vec_len);
param_tstar_map('r') = linspace(0.01, 0.04, it_simu_vec_len);
ar_it_array_len = cell2mat(cellfun(@(m) length(param_tstar_map(m)), ...
cl_st_param_keys, 'UniformOutput', false));
it_total_length = sum(ar_it_array_len);
disp(['ar_it_array_len: ' num2str(ar_it_array_len)])
ar_it_array_len: 5 10
disp(['it_total_length: ' num2str(it_total_length)])
it_total_length: 15
1.3.2.4 Given Container of Arrays, Find Min and Max of Each and Draw Random N sets
cl_st_param_keys = {'fl_crra', 'fl_beta'};
param_tstar_map = containers.Map('KeyType','char', 'ValueType','any');
it_simu_vec_len = 5;
param_tstar_map('fl_crra') = linspace(1, 2, 5);
param_tstar_map('fl_beta') = linspace(0.94, 0.98, 10);
param_tstar_map('w') = linspace(1.1, 1.4, it_simu_vec_len);
param_tstar_map('r') = linspace(0.01, 0.04, it_simu_vec_len);
rng(123);
it_simu_length = 20;
mt_param_rand = cell2mat(cellfun(@(m) ...
rand([it_simu_length,1]).*(max(param_tstar_map(m)) - min(param_tstar_map(m))) ...
+ min(param_tstar_map(m)), ...
cl_st_param_keys, 'UniformOutput', false));
tb_rand_draws = array2table(mt_param_rand, 'VariableNames', cl_st_param_keys);
disp(tb_rand_draws);
fl_crra fl_beta
_______ _______
1.5316 0.97337
1.607 0.97305
1.3184 0.94644
1.0016 0.97349
1.6578 0.94983
1.7505 0.97152
1.7407 0.94277
1.7108 0.94781
1.3542 0.97625
1.1479 0.95709
1.8834 0.94962
1.1274 0.96042
1.2132 0.96637
1.0676 0.94936
1.4318 0.96911
1.3791 0.97365
1.9399 0.94242
1.6369 0.96946
1.9791 0.95752
1.5709 0.96145
1.3.3 All Possible Combinations of Multiple Arrays
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.3.3.1 Given Several Arrays of Possibly different Length in Container, all Possible combinations
param_tstar_map = containers.Map('KeyType','char', 'ValueType','any');
param_tstar_map('a') = linspace(1, 5, 5);
param_tstar_map('b') = linspace(0.87, 0.97, 6);
param_tstar_map('c') = linspace(0, 0.5, 10);
cl_st_param_keys = {'a','c'};
cl_ar_param_subset_values = values(param_tstar_map, {'a','c'});
cl_mt_all = cl_ar_param_subset_values;
[cl_mt_all{:}] = ndgrid(cl_ar_param_subset_values{:});
mt_param_vals_combi = cell2mat(cellfun(@(m) m(:), cl_mt_all, 'uni', 0));
tb_all_combi = array2table(mt_param_vals_combi, 'VariableNames', cl_st_param_keys);
disp(tb_all_combi);
a c
_ ________
1 0
2 0
3 0
4 0
5 0
1 0.055556
2 0.055556
3 0.055556
4 0.055556
5 0.055556
1 0.11111
2 0.11111
3 0.11111
4 0.11111
5 0.11111
1 0.16667
2 0.16667
3 0.16667
4 0.16667
5 0.16667
1 0.22222
2 0.22222
3 0.22222
4 0.22222
5 0.22222
1 0.27778
2 0.27778
3 0.27778
4 0.27778
5 0.27778
1 0.33333
2 0.33333
3 0.33333
4 0.33333
5 0.33333
1 0.38889
2 0.38889
3 0.38889
4 0.38889
5 0.38889
1 0.44444
2 0.44444
3 0.44444
4 0.44444
5 0.44444
1 0.5
2 0.5
3 0.5
4 0.5
5 0.5
1.3.4 Nested Cells
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.3.4.1 Nested Cells and access
cl_st_param_keys = {'fl_crra', 'fl_beta'};
it_simu_vec_len = 3;
clns_parm_tstar = cell([4,1]);
clns_parm_tstar{1} = {'fl_crra', 'CRRA', linspace(1, 2, it_simu_vec_len)};
clns_parm_tstar{2} = {'fl_beta', 'Discount', linspace(0.94, 0.98, it_simu_vec_len)};
clns_parm_tstar{3} = {'w', 'Wage', linspace(1.1, 1.4, it_simu_vec_len)};
clns_parm_tstar{4} = {'r', 'Save Interest', linspace(0.01, 0.04, it_simu_vec_len)};
disp(clns_parm_tstar(1));
{1x3 cell}
disp(clns_parm_tstar{1}{1})
fl_crra
disp(clns_parm_tstar{1}{2});
CRRA
disp(clns_parm_tstar{1}{3});
1.0000 1.5000 2.0000
1.4 Characters and Strings
1.4.1 Basic String Operations, Display, Search, Join and Split
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.4.1.1 Date String
Generate a string based on date and time as file suffix.
st_file_suffix = ['_d' datestr(now,'yymmdd_tHHMMSS')];
disp(st_file_suffix);
_d210701_t094001
1.4.1.2 Combine String, Numeric values etc, Single and Double Quotes
Convert a string array into a single string, note the double quotes, and the auto space between:
st_a = "another string";
ar_st = ["abc", num2str(2), "opq", st_a];
disp(strjoin(ar_st));
abc 2 opq another string
If we do not want to have spaces between words, the second parameter for strjoin allows for string connectors:
st_a = "another string";
ar_st = ["abc", num2str(2), "opq", st_a];
disp(strjoin(ar_st, ""));
abc2opqanother string
With single quotes, the str element is not an array, so does not need strjoin, but not need to have spaces:
st_a = 'another string';
str = ['abc ', num2str(2), ' opq ', st_a];
disp((str));
abc 2 opq another string
1.4.1.3 Construct String Print Statement with String and Numeric Elements
In the example below, we have a number of strings we want to put inside a string array, then join with strjoin, but two of the strings need to be constructed as strings first. Note below that double quoates are own strings, single quotes in brackets constructing additional strings.
st_a = "another string";
ar_st = ["abc", "efg"];
ar_fl_vals = rand([1,3]);
st_print = strjoin(...
["Completed SNW_DS_MAIN:", ...
['SNW_MP_PARAM=' num2str(123)], ...
['SNW_MP_CONTROL=' num2str(678)], ...
['STR_VAR1=' char('string')], ...
['STR_VAR2=' char(strjoin(ar_st, "-"))], ...
['STR_VAR3:;' char(strjoin(ar_st, ";"))], ...
['ar_st:;' char(strjoin(strcat( ...
num2str((1:length(ar_st))', '%0.3d'), '=', ar_st' ...
), ";"))], ...
['ar_fl_vals:;' strjoin(string(strcat( ...
num2str((1:length(ar_fl_vals))', '%0.3d'), '=', num2str(ar_fl_vals', '%3.2f'))), ";")], ...
], ";");
% Ways to print
st_out = st_print;
ar_ch_out = char(strsplit(st_print,";")');
ar_st_out = strsplit(st_print,";")';
% Print
disp(st_out);
Completed SNW_DS_MAIN:;SNW_MP_PARAM=123;SNW_MP_CONTROL=678;STR_VAR1=string;STR_VAR2=abc-efg;STR_VAR3:;abc;efg;ar_st:;001=abc;002=efg;ar_fl_vals:;;001=0.87;002=0.25;003=0.48
disp(ar_ch_out);
Completed SNW_DS_MAIN:
SNW_MP_PARAM=123
SNW_MP_CONTROL=678
STR_VAR1=string
STR_VAR2=abc-efg
STR_VAR3:
abc
efg
ar_st:
001=abc
002=efg
ar_fl_vals:
001=0.87
002=0.25
003=0.48
disp(ar_st_out);
"Completed SNW_DS_MAIN:"
"SNW_MP_PARAM=123"
"SNW_MP_CONTROL=678"
"STR_VAR1=string"
"STR_VAR2=abc-efg"
"STR_VAR3:"
"abc"
"efg"
"ar_st:"
"001=abc"
"002=efg"
"ar_fl_vals:"
"001=0.87"
"002=0.25"
"003=0.48"
1.4.1.4 Paste Join Strings Together with Separator
Join strings together with separator, this is similar to the paste0 function in R.
ar_st = ["abc", "efg", "opq"];
disp(strjoin(ar_st, '-'));
abc-efg-opq
1.4.1.5 Combine Char with Numeric Value
Compose a string with words and numerical values
st_title = strcat("Figure Title ", ...
"(", ...
"threedeci=%.3f,", ...
"twodeci=%.2f,", ...
"int=%.0f", ...
")");
ar_params = 123.4567 + zeros(1,3);
st_combo = compose(st_title, ar_params);
disp(st_combo);
Figure Title (threedeci=123.457,twodeci=123.46,int=123)
1.4.1.6 Search if String Contains Substring
Does string contain substring?
st_long1 = 'simu_dense';
st_long2 = 'simu_denser';
st_long3 = 'simuverydense';
st_long4 = 'simu_medium';
st_long5 = 'simuverysmall';
disp([contains(st_long1, 'dense'), contains(st_long2, 'dense'), contains(st_long3, 'dense'), ...
contains(st_long4, 'dense'), contains(st_long5, 'dense')]);
1 1 1 0 0
1.4.1.7 Find Elements of an Array that Matches Any Elements of Another Array
There is an array of strings, check if each element equals values specified in another string, using the match function.
% String array from strings
ar_st_long = string({st_long1, st_long2, st_long3, st_long4, st_long5});
% If matches simu_dense
disp(matches(ar_st_long, 'simu_dense'));
1 0 0 0 0
% If matches simu_dense or simu_denser
disp(matches(ar_st_long, ["simu_dense", "simu_denser"]));
1 1 0 0 0
1.4.1.8 Change File Name MLX to M
st_file_name_mlx = 'continuous_differentiable.mlx';
at_st_split_file_name = split(st_file_name_mlx, ".");
st_file_name_m = strcat(at_st_split_file_name{1}, '_m.m');
disp(st_file_name_m);
continuous_differentiable_m.m
1.4.2 String Array Manipulations, Join, Find, Replace and the Alphabet
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.4.2.1 Generate a String Array from Strings
Empty String Array and fill with values.
ar_st_titles = strings([3,1]);
ar_st_titles(1) = 'Title1';
ar_st_titles(2) = 'Title2';
ar_st_titles(3) = 'Title3';
disp(ar_st_titles);
"Title1"
"Title2"
"Title3"
Three title lines, with double quotes:
ar_st_titles = ["Title1","Title2","Title3"]';
disp(ar_st_titles);
"Title1"
"Title2"
"Title3"
Three words, joined together, now single quotes, this creates one string, rather than a string array:
st_titles = ['Title1','Title2','Title3'];
disp(st_titles);
Title1Title2Title3
Given some previously defined chars or strings with single or double quotes, not sure which. To safely generate a string array, wrap in brackets and then conver with string function. This generates a string array whether the original inputs were single or double quoted:
st_a = 'a';
st_b = 'b';
st_c = 'c';
st_a_dq = "a";
st_b_dq = "b";
st_c_dq = "c";
ar_st_singlequotes = string({st_a, st_b, st_c});
ar_st_doublequotes = string({st_a_dq, st_b_dq, st_c_dq});
disp(["st_singlequotes" ar_st_singlequotes]);
"st_singlequotes" "a" "b" "c"
disp(["ar_st_doublequotes" ar_st_doublequotes]);
"ar_st_doublequotes" "a" "b" "c"
Convert the string array to a cell string array
disp(cellstr(ar_st_doublequotes));
{'a'} {'b'} {'c'}
1.4.2.2 String Cell Array
Create a string array:
ar_st_title_one = {'Title One Line'};
ar_st_titles = {'Title1','Title2','Title3'};
disp(ar_st_title_one);
{'Title One Line'}
disp(ar_st_titles);
{'Title1'} {'Title2'} {'Title3'}
Add to a string array:
ar_st_titles{4} = 'Title4';
disp(ar_st_titles);
{'Title1'} {'Title2'} {'Title3'} {'Title4'}
Update one of the strings:
ar_st_title_one{1} = strcat('log(', ar_st_title_one{1},')');
ar_st_titles{1} = strcat('log(', ar_st_titles{1},')');
disp(ar_st_title_one);
{'log(Title One Line)'}
disp(ar_st_titles);
{'log(Title1)'} {'Title2'} {'Title3'} {'Title4'}
1.4.2.3 Joint String Cell Array with Suffix
ar_st_titles = {'Title1','Title2','Title3'};
disp(strcat(ar_st_titles, '_init'));
{'Title1_init'} {'Title2_init'} {'Title3_init'}
1.4.2.4 Duplicate String
it_duplicate_n = 10;
disp(repmat({'String'}, [1, it_duplicate_n]));
Columns 1 through 9
{'String'} {'String'} {'String'} {'String'} {'String'} {'String'} {'String'} {'String'} {'String'}
Column 10
{'String'}
1.4.2.5 String Join to form Single Element
using char() is safe
st_var_name = "abc"
st_var_name = "abc"
st_var_name = [st_var_name ' percentile values']
st_var_name = 1x2 string
"abc" " percentile values"
strjoin(st_var_name)
ans = "abc percentile values"
st_var_name = "abc"
st_var_name = "abc"
st_var_name = [char(st_var_name) ' percentile values']
st_var_name = 'abc percentile values'
st_var_name = 'abc'
st_var_name = 'abc'
st_var_name = [char(st_var_name) ' percentile values']
st_var_name = 'abc percentile values'
1.4.2.6 String Join dash (Paste)
This is similar to R’s paste function:
st_var_name = "abc";
st_var_name = [st_var_name, 'efg', 'mqo'];
disp(strjoin(st_var_name, "_"));
abc_efg_mqo
disp(strjoin(st_var_name, ","));
abc,efg,mqo
1.4.2.7 Numeric Array to String without Space
String replace
ar_it_test_grp = [3, 8, 9];
strrep(num2str(ar_it_test_grp), ' ', '_')
ans = '3_8_9'
1.4.2.8 Substring replace in Cell Array
ar_st_cells = {'shock=0.35','shock=0.40','shock=0.46'};
ar_st_updated_cells = strrep(ar_st_cells, 'shock', '$\epsilon$');
disp(ar_st_updated_cells);
{'$\epsilon$=0.35'} {'$\epsilon$=0.40'} {'$\epsilon$=0.46'}
1.4.2.9 Find position of String in String Cell
ls_st_param_key = {'fl_crra', 'fl_beta', ...
'fl_w', 'fl_r_save', ...
'fl_a_max', 'it_z_n', 'it_a_n'};
st_param_key = 'fl_a_max';
find(strcmp(ls_st_param_key, st_param_key))
ans = 5
1.4.2.10 Find the positions of String Cells in Full String Cells
Find the positions of fl_w, fl_beta, and it_z_n in ls_st_param_key. Then just find the position of fl_crra. When looking for the position of something that does not exist, generate an find outcome array of length 0.
ls_st_param_key = {'fl_crra', 'fl_beta', ...
'fl_w', 'fl_r_save', ...
'fl_a_max', 'it_z_n', 'it_a_n'};
cl_st_param_keys = {'fl_w', 'fl_beta', 'it_z_n'};
cell2mat(cellfun(@(m) find(strcmp(ls_st_param_key, m)), ...
cl_st_param_keys, 'UniformOutput', false))
ans = 1x3
3 2 6
find(strcmp(ls_st_param_key, 'fl_crra'))
ans = 1
length(find(strcmp(ls_st_param_key, 'fl_crra_not_exist')))
ans = 0
~sum(strcmp(ls_st_param_key, 'fl_crra_not_exist'))
ans =
1
1.4.2.11 Cell to string Paste and Replace dash
cl_st_param_keys = {'fl_crra', 'fl_beta'};
display(strrep(strjoin(cl_st_param_keys, '-'), '_', '\_'));
fl\_crra-fl\_beta
1.4.2.12 Generate Alphebetical String Array from A to Z
Generate a single string that is A to Z, then generate this as a string array.
% a to z single string
st_a2z = 'a':'z';
% a to z array of letters
ar_st_a2z = string(('A':'Z')')';
% Display
disp(st_a2z);
abcdefghijklmnopqrstuvwxyz
disp(ar_st_a2z);
Columns 1 through 18
"A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R"
Columns 19 through 26
"S" "T" "U" "V" "W" "X" "Y" "Z"
1.4.3 Convert and Concatenate Strings Arrays with Numbers and Number Arrays with Strings
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.4.3.1 Generate a String from Numeric Array and Print on Screen with Counter
Want to quickly print on screen an array of number with the array name and a counter printed before each value.
% An array of numbers to print
rng(123);
ar_fl_values = rand(5,1);
% A string array of counters with leading zeros for even display
ar_st_counter_leading0 = num2str((1:length(ar_fl))', '%0.3d');
% A float array of value formatted
ar_fl_values_formated = num2str(ar_fl', '%3.2f');
ar_ch_values_display = strcat('fl_val, c', ar_st_counter_leading0, '=', ar_fl_values_formated);
% print
disp(ar_ch_values_display);
fl_val, c001=0.78
fl_val, c002=0.29
fl_val, c003=0.31
fl_val, c004=0.67
fl_val, c005=0.11
fl_val, c006=0.66
fl_val, c007=0.89
fl_val, c008=0.70
fl_val, c009=0.44
fl_val, c010=0.44
1.4.3.2 Combine A String Array with a Numeric Array using Compose
String array and numeric array, combine together using the compose function, and test different formatting functions. Formating with leading empty spaces, leading zeros, and convert to integer or not.
st_titles = ["%.3f", "%.1f", "%.0f";...
"%6.3f", "%6.1f", "%6.0f";...
"%06.3f", "%06.1f", "%06.0f"];
ar_params = 123.4567890 + zeros(3,3);
st_combo = compose(st_titles, ar_params);
disp(st_combo);
"123.457" "123.5" "123"
"123.457" " 123.5" " 123"
"123.457" "0123.5" "000123"
A string array and a numeric array combined
ls_st_param_esti = {'ar_mu_pos_1', 'ar_COEF_U_gamma'};
ar_params = [1213,456];
st_combo = strcat(ls_st_param_esti', '=', num2str(ar_params'));
disp(st_combo);
{'ar_mu_pos_1=1213' }
{'ar_COEF_U_gamma= 456'}
1.4.3.3 Numeric Array to String Array with Decimal Formatting
There is a numeric array, format with a certain number of decimal points, and convert to string array.
% Inputs
rng(123);
ar_params = [1.23324, 493.1232, 4994.1111, 123];
st_rounding = '.3f';
% Rounding and to string array
ar_st_params = compose(strcat("%", st_rounding), ar_params);
% Display:
disp(ar_st_params);
"1.233" "493.123" "4994.111" "123.000"
1.4.3.4 Title from an Array of Values
There is a vector of parameter values and a vector of names for these parameter values, I want to include these in the title of a figure with the same decimal formating.
% Inputs
rng(123);
ar_params = rand(1,3);
ar_st_parms_names = ["param1", "param2", "param3"];
st_rounding = '.2f';
st_title_main = "this is the figure title";
% Rounding and combining
ar_st_params = strcat(ar_st_parms_names, compose(strcat("=%", st_rounding), ar_params));
% Generate a Single String that is comma separated:
st_param_pasted = strjoin(ar_st_params, ', ');
% Generate title with parameters
st_title_wth_params = strcat(st_title_main, ' (', st_param_pasted, ')');
% Display:
disp(st_title_wth_params);
this is the figure title (param1=0.70, param2=0.29, param3=0.23)
1.4.3.5 Combine String with Numeric Array
Example 1:
ar_fl_abc1 = [0.4 0.1 0.25 0.3 0.4];
disp([num2str(ar_fl_abc1', 'zw=%3.2f;'), num2str(ar_fl_abc1', 'zr=%3.2f')]);
zw=0.40;zr=0.40
zw=0.10;zr=0.10
zw=0.25;zr=0.25
zw=0.30;zr=0.30
zw=0.40;zr=0.40
Example 2:
close all;
rng(123);
ar_z_r_borr_mesh_wage = rand([1,5]);
ar_z_wage_mesh_r_borr = rand([1,5]);
ar_it_rows = round(rand([1,5])*10);
cl_st_full_rowscols = cellstr([num2str(ar_z_r_borr_mesh_wage', 'zr=%3.2f;'), ...
num2str(ar_z_wage_mesh_r_borr', 'zw=%3.2f')]);
cl_col_names = strcat('zi=', num2str(ar_it_rows([1,3,5])'), ':', cl_st_full_rowscols([1,3,5]));
disp(ar_z_r_borr_mesh_wage);
0.6965 0.2861 0.2269 0.5513 0.7195
disp(ar_z_wage_mesh_r_borr);
0.4231 0.9808 0.6848 0.4809 0.3921
disp(cl_st_full_rowscols);
{'zr=0.70;zw=0.42'}
{'zr=0.29;zw=0.98'}
{'zr=0.23;zw=0.68'}
{'zr=0.55;zw=0.48'}
{'zr=0.72;zw=0.39'}
disp(cl_col_names);
{'zi=3:zr=0.70;zw=0.42'}
{'zi=4:zr=0.23;zw=0.68'}
{'zi=4:zr=0.72;zw=0.39'}
1.4.3.6 Combine Number with String Cell Array
We have a string cell array we created from the previous section, now append numbers to it
% Append Common Numbers
cl_col_names_append = strcat(cl_col_names, '-String-Cell-With-Numeric-', num2str(123));
disp(cl_col_names_append);
{'zi=3:zr=0.70;zw=0.42-String-Cell-With-Numeric-123'}
{'zi=4:zr=0.23;zw=0.68-String-Cell-With-Numeric-123'}
{'zi=4:zr=0.72;zw=0.39-String-Cell-With-Numeric-123'}
1.4.3.7 Combine Numeric Array with String Cell Array
Append an array of numeric values
% Append Common Numbers
cl_col_names_append = strcat(cl_col_names, '-String-Cell-With-Numeric-Array-', ...
num2str(transpose(1:length(cl_col_names))));
disp(cl_col_names_append);
{'zi=3:zr=0.70;zw=0.42-String-Cell-With-Numeric-Array-1'}
{'zi=4:zr=0.23;zw=0.68-String-Cell-With-Numeric-Array-2'}
{'zi=4:zr=0.72;zw=0.39-String-Cell-With-Numeric-Array-3'}
1.4.3.8 Convert Numeric Array to String, Apeend Prefix to all elements.
ar_fl_abc1 = [0.4 0.1 0.25 0.3 0.4];
ar_st_wth_prefix = strcat('row=', string(ar_fl_abc1));
disp(ar_st_wth_prefix);
"row=0.4" "row=0.1" "row=0.25" "row=0.3" "row=0.4"
% Does Array Exist in Longer Array as Subset
ar_abc1 = [0.4 0.1 0.25 0.3 0.4];
ar_abc2 = [0.4 0.1 0.2 0.3 0.4];
ar_efg = [0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4];
st_abc1 = strjoin(string(num2str(ar_abc1)));
st_abc2 = strjoin(string(num2str(ar_abc2)));
st_efg = strjoin(string(num2str(ar_efg)));
contains(st_efg, st_abc1)
ans =
0
contains(st_efg, st_abc2)
ans =
1
% Display Convert to String
fprintf('Display string [%s]', num2str([1,2,3]));
Display string [1 2 3]
fprintf('Display string [%s]', num2str(1.1));
Display string [1.1]
fprintf('Display string [%s]', 'abc');
Display string [abc]
1.5 Map Containers
1.5.1 Container Map Basics
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.5.1.1 Generate a Container map with any Type of data
Create a container map with float, int, string, and matrix
close all;
clear all;
% Create A Map with String Keys and any values
param_map = containers.Map('KeyType','char', 'ValueType','any');
param_map('share_unbanked_j') = 12;
param_map('equi_r_j') = 2;
param_map('equi_w_j') = 'abc';
param_map('equi_P_j') = zeros(2,3);
disp(param_map.keys);
{'equi_P_j'} {'equi_r_j'} {'equi_w_j'} {'share_unbanked_j'}
disp(param_map.values);
{2x3 double} {[2]} {'abc'} {[12]}
1.5.1.2 Access Multiple Values of a container map
Values been accessed need to be of the same type
% Parameter Dealing from Map
params_group = values(param_map, {'share_unbanked_j', 'equi_r_j'});
[equi_P_j, equi_r_j] = params_group{:};
disp(['equi_P_j:' num2str(equi_P_j) ', equi_r_j:' num2str(equi_r_j)]);
equi_P_j:12, equi_r_j:2
% Access Scalar Elements of Map and Convert the Array
disp(cell2mat(values(param_map, {'share_unbanked_j', 'equi_r_j'})));
12 2
Create a container map of color values and generate a array of color choices:
% Container map with three colors
mp_colors = containers.Map('KeyType', 'char', 'ValueType', 'any');
mp_colors('blue') = [57 106 177]./255;
mp_colors('red') = [204 37 41]./255;
mp_colors('black') = [83 81 84]./255;
% An selection array
ar_st_colors_pick = {'blue', 'blue', 'red', 'black', 'blue'};
ar_colors = values(mp_colors, ar_st_colors_pick);
% Print selected colors
celldisp(ar_colors);
ar_colors{1} =
0.2235 0.4157 0.6941
ar_colors{2} =
0.2235 0.4157 0.6941
ar_colors{3} =
0.8000 0.1451 0.1608
ar_colors{4} =
0.3255 0.3176 0.3294
ar_colors{5} =
0.2235 0.4157 0.6941
1.5.1.3 Container Integer Keys
Given some matrix, I want to store matrix column names as well as labels for what each row and column correspond to. Achieve this using a cell array of container maps. Cell dimensions correspond to the first, second, etc dimensions, any dimension specific information can be stored in this fashion.
Can access information asssociated with the label value of the row values:
% Define Matrix Row and Column and additional dimension information
cl_mp_datasetdesc = {};
cl_mp_datasetdesc{1} = containers.Map({'dim', 'name', 'labval'}, {1, 'kids', [0,1,2,3]});
cl_mp_datasetdesc{2} = containers.Map({'dim', 'name', 'labval'}, {2, 'age', [18,19,20]});
% get variable labels for the first dimension (rows)
disp([...
string(['dim 1 var name:' cl_mp_datasetdesc{1}('name') ]), ...
string(['dim 2 var name:' cl_mp_datasetdesc{2}('name') ])...
]);
"dim 1 var name:kids" "dim 2 var name:age"
1.5.1.4 Is Key In Container
param_map_a = containers.Map('KeyType','char', 'ValueType','any');
param_map_a('fl_b_bd') = -3;
param_map_a('fl_w_max') = 50;
param_map_a('fl_kp_min') = 0;
param_map_a('it_w_i') = 100;
disp([...
string(['has it_w_i as key? ' num2str(isKey(param_map_a, 'it_w_i'))]), ...
string(['has it_w_i1 as key? ' num2str(isKey(param_map_a, 'it_w_i1'))]) ...
]);
"has it_w_i as key? 1" "has it_w_i1 as key? 0"
1.5.1.5 Container Key Loop
Generate new container key within loop dynamically
param_map_a = containers.Map('KeyType', 'char', 'ValueType','any');
rng('default');
rng(123);
for st_cur = ["abc", "efg", "qqq"]
if (strcmp(st_cur, "abc"))
data = rand([1,1]);
elseif (strcmp(st_cur, "efg"))
data = 123.123;
elseif (strcmp(st_cur, "qqq"))
data = -123;
end
% common function
fl_sh_0p1pc_j = data*2 + 1;
fl_sh_5pc_j = data/2 - 1;
% generate map keys
st_key_sh_0p1pc_j = strjoin([st_cur, 'sh_0p1pc_j'], "_");
st_key_sh_5pc_j = strjoin([st_cur, 'sh_5pc_j'], "_");
% store
param_map_a(st_key_sh_0p1pc_j) = fl_sh_0p1pc_j;
param_map_a(st_key_sh_5pc_j) = fl_sh_5pc_j;
end
disp([...
string(['param_map_a.keys:' param_map_a.keys]), ...
string(['param_map_a.values:' string(param_map_a.values)]) ...
]);
Columns 1 through 7
"param_map_a.keys:" "abc_sh_0p1pc_j" "abc_sh_5pc_j" "efg_sh_0p1pc_j" "efg_sh_5pc_j" "qqq_sh_0p1pc_j" "qqq_sh_5pc_j"
Columns 8 through 14
"param_map_a.values:" "2.3929" "-0.65177" "247.246" "60.5615" "-245" "-62.5"
1.5.2 Container Map Display Swtich Key and Values and Subseting
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.5.2.1 Print Keys and Values
Define container:
% Define Container
param_map = containers.Map('KeyType','char', 'ValueType','any');
param_map('share_unbanked_j') = 12;
param_map('equi_r_j') = 2;
param_map('equi_w_j') = 'abc';
param_map('equi_P_j') = 1.2;
Print the key and values of the container:
param_map_keys = keys(param_map);
param_map_vals = values(param_map);
for i = 1:length(param_map)
st_key = param_map_keys{i};
ob_val = param_map_vals{i};
st_display = strjoin(['pos =' num2str(i) '; key =' string(st_key) '; val =' string(ob_val)]);
disp(st_display);
end
pos = 1 ; key = equi_P_j ; val = 1.2
pos = 2 ; key = equi_r_j ; val = 2
pos = 3 ; key = equi_w_j ; val = abc
pos = 4 ; key = share_unbanked_j ; val = 12
1.5.2.2 Given Map Switch Keys and Values
Given the container map below, switch so that keys become values and values become keys.
First, this is the map that uses strings as keys and index as values:
mp_param_idx = containers.Map('KeyType','char', 'ValueType','any');
mp_param_idx('parm_sk_mean') = 1;
mp_param_idx('parm_sk_sd') = 2;
mp_param_idx('NPquad') = 3;
mp_param_idx('gamma') = 4;
mp_param_idx('HAquad') = 5;
mp_param_idx('theta') = 6;
Second, get the keys and the values, convert the values to string:
param_map_paramNames = keys(mp_param_idx);
param_map_paramIndex_int = values(mp_param_idx);
% convert cell of int to cell of string
param_map_paramIndex_str = cellfun(@(idx) num2str(idx(:)), param_map_paramIndex, 'uni', 0);
Third, generate new Map:
mp_idx_params = containers.Map(param_map_paramIndex_str, param_map_paramNames);
param_map_keys = keys(mp_idx_params);
param_map_vals = values(mp_idx_params);
for i = 1:length(mp_idx_params)
st_key = param_map_keys{i};
ob_val = param_map_vals{i};
st_display = strjoin(['pos =' num2str(i) '; key =' string(st_key) '; val =' string(ob_val)]);
disp(st_display);
end
pos = 1 ; key = 1 ; val = parm_sk_mean
pos = 2 ; key = 2 ; val = parm_sk_sd
pos = 3 ; key = 3 ; val = NPquad
pos = 4 ; key = 4 ; val = gamma
pos = 5 ; key = 5 ; val = HAquad
pos = 6 ; key = 6 ; val = theta
Overall, code together shorter:
% Single call to convert
mp_idx_params_oneline = containers.Map(...
cellfun(@(idx) num2str(idx(:)), values(mp_param_idx), 'uni', 0), ...
keys(mp_param_idx));
% Check equality
disp(['mp_idx_params_oneline==mp_idx_params:' num2str(mp_idx_params_oneline==mp_idx_params) ])
mp_idx_params_oneline==mp_idx_params:0
1.5.2.3 Select of Subset of Key/Values from a Container Map
There is a larger container map, I want to create a new container map, that keeps a subset of the keys/values of the full container map.
% Original Container map
param_map = containers.Map('KeyType','char', 'ValueType','any');
param_map('equi_r_j') = 0.05;
param_map('equi_w_j') = 1.05;
param_map('equi_P_j') = 1;
% To select a subset of keys
ls_st_keys_select = {'equi_w_j', 'equi_P_j'};
% Select
param_map_subset = containers.Map(ls_st_keys_select, values(param_map, ls_st_keys_select));
% display
disp(param_map_subset.keys);
{'equi_P_j'} {'equi_w_j'}
disp(param_map_subset.values);
{[1]} {[1.0500]}
1.5.3 Container Map Example Overriding
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.5.3.1 Update Container Map
There is one map with values, Container Map A. There is another container Map, Container Map B. Container Maps A and B share keys. For keys that exist in B and A, B Key value supercede values for the same keys in A. For new keys in B, they superced keys in A.
param_map_a = containers.Map('KeyType','char', 'ValueType','any');
param_map_a('fl_b_bd') = -3;
param_map_a('fl_w_max') = 50;
param_map_a('fl_kp_min') = 0;
param_map_a('it_w_i') = 100;
param_map_b = containers.Map('KeyType','char', 'ValueType','any');
param_map_b('fl_w_max') = 77;
param_map_b('fl_kp_min') = -231;
param_map_b('it_z_n') = 5;
param_map_b('fl_z_mu') = 0;
param_map_c = [param_map_a; param_map_b];
param_map_c.keys
ans =
{'fl_b_bd'} {'fl_kp_min'} {'fl_w_max'} {'fl_z_mu'} {'it_w_i'} {'it_z_n'}
param_map_c.values
ans =
{[-3]} {[-231]} {[77]} {[0]} {[100]} {[5]}
1.6 Map Structure Array
1.6.1 Maplab Nested Container Map with Struct
Go back to fan’s MEconTools Package, Matlab Code Examples Repository (bookdown site), or Math for Econ with Matlab Repository (bookdown site).
1.6.1.1 A Struct of Model Parameters with Different Information
There is a list of model parameters, there are various information we store for each parameter. Store each type of information in a different container map, and then combine them together in a struct. This is more flexible than generating a table, and can be called with a single line. This is effectively a nested container, imagine if we define for each parameter a map with keys indicating different types of information. Rather than doing that, the keys are elements of the struct, each key/value is in a different container.
% index for different parameters
mp_param_idx = containers.Map('KeyType','char', 'ValueType','any');
mp_param_idx('NPquad') = 3;
mp_param_idx('gamma') = 4;
mp_param_idx('HAquad') = 5;
mp_param_idx('theta') = 6;
mp_param_idx('lambda') = 7;
mp_param_idx('msrErrProtSD') = 8;
mp_param_idx('logProt') = 9;
mp_param_idx('freePriceFrac') = 10;
mp_param_idx('h_exoshk_sd') = 11;
mp_param_idx('h_endoshk_sd') = 12;
% Invert key and index
mp_idx_params = containers.Map(...
cellfun(@(idx) num2str(idx(:)), values(mp_param_idx), 'uni', 0), ...
keys(mp_param_idx));
% Exponentiation Positivity Restrictions
mp_param_explog = containers.Map('KeyType','char', 'ValueType','any');
mp_param_explog('NPquad') = -1;
mp_param_explog('gamma') = 1;
mp_param_explog('lambda') = -1;
mp_param_explog('msrErrProtSD') = 1;
mp_param_explog('freePriceFrac') = 1;
mp_param_explog('h_exoshk_sd') = 1;
mp_param_explog('h_endoshk_sd') = 1;
% Create Struct
param_struct.paramindex = mp_param_idx;
param_struct.paramstring = mp_idx_params;
param_struct.explog = mp_param_explog;
Given the struct contructed, can get the index for a particular parameter, or the explog value in a single line call:
% Get values in single line
disp(['NPquad index=' num2str(param_struct.index('NPquad')) ...
', explog=' num2str(param_struct.explog('NPquad'))]);
NPquad index=3, explog=-1
Furthermore, since we have both mp_param_idx and mp_idx_params, suppose we only know the current index, we can use to index to find the string, and use the string to find the expolog value:
% Get the explog value for a particular index
st_param = param_struct.paramstring('11');
it_explog = param_struct.explog(st_param);
% Single line call
disp(['The explog of parameter index 11 is "' ...
num2str(param_struct.explog(param_struct.paramstring('11'))) ...
'" (param index 11 is "' st_param '")']);
The explog of parameter index 11 is "1" (param index 11 is "h_exoshk_sd")