MATLAB Global Variable and Scripts - matlab

I have an m-file ParamStruct.m. Below are the contents of that file:
global Params
total_params = [];
Params.one = 1;
Params.two = 2;
Params.three = 3;
total_params = [total_params;Params];
Params.one = 4;
Params.two = 5;
Params.three = 6;
total_params = [total_params;Params];
for ii = length(total_params)
Add_Param_Vals
end
Then I have another m-file which I use as a script called Add_Param_Values. The contents of that file are as follows:
global Params
disp("adding values: ")
Params.one + Params.two
The purpose of the two m-files is to 1.) define two Params structs in ParamStruct.m, then call Add_Param_Values from ParamStruct so that for each call, I can utilize the current Params struct as indexed by the for loop in ParamStruct. For example, when I run ParamStruct at the output I would like to see the following:
adding values:
ans =
3
adding values:
ans =
9
But instead I am seeing
adding values:
ans =
9
So it seems like it is only utilizing the last element in the total_params variable and I dont know how to correct that. I do not want to modify anything in the Add_Param_Vals m-file as I am not the owner of it. Any ideas??

Sorry for the post. I was able to figure it out. Here is what I ended up doing:
global Params
total_params = [];
Params.one = 1;
Params.two = 2;
Params.three = 3;
total_params = [total_params;Params];
Params.one = 4;
Params.two = 5;
Params.three = 6;
total_params = [total_params;Params];
for ii = 1:length(total_params)
Params = total_params(ii);
Add_Param_Vals
end

Related

How to loop through the columns of a Matlab table by using the headings?

I am trying to make a for-loop for the Matlab code below. I have named each column with JAN90, FEB90, etc. all the way up to AUG19, which can be found in a matrix named "data". At this point I need to change the month and year manually to obtain the result I want. Is there a way to iterate over the columns by the column name? Would it be easier to name the columns Var1, Var2 etc.?
clear;
clc;
data = readtable('Data.xlsx','ReadVariableNames',false);
data(1,:) = [];
data.Var2 = str2double(data.Var2);
data.Var3 = str2double(data.Var3);
data.Var4 = str2double(data.Var4);
data.Var5 = str2double(data.Var5);
data.Var6 = str2double(data.Var6);
data.Var7 = str2double(data.Var7);
data.Var8 = str2double(data.Var8);
data.Var9 = str2double(data.Var9);
data.Var10 = str2double(data.Var10);
data.Var11 = str2double(data.Var11);
data.Var12 = str2double(data.Var12);
data.Var13 = str2double(data.Var13);
data(:,1) = [];
data = table2array(data);
data = array2table(data.');
data = table2cell(data)
data = cell2table(data, 'VariableNames',{'JAN90','FEB90','MAR90','APR90','MAY90','JUN90','JUL90','AUG90'...
,'SEP90','OCT90','NOV90','DEC90','JAN91','FEB91','MAR91','APR91','MAY91','JUN91','JUL91','AUG91'...
,'SEP91','OCT91','NOV91','DEC91','JAN92','FEB92','MAR92','APR92','MAY92','JUN92','JUL92','AUG92'...
,'SEP92','OCT92','NOV92','DEC92','JAN93','FEB93','MAR93','APR93','MAY93','JUN93','JUL93','AUG93'...
,'SEP93','OCT93','NOV93','DEC93','JAN94','FEB94','MAR94','APR94','MAY94','JUN94','JUL94','AUG94'...
,'SEP94','OCT94','NOV94','DEC94','JAN95','FEB95','MAR95','APR95','MAY95','JUN95','JUL95','AUG95'...
,'SEP95','OCT95','NOV95','DEC95','JAN96','FEB96','MAR96','APR96','MAY96','JUN96','JUL96','AUG96'...
,'SEP96','OCT96','NOV96','DEC96','JAN97','FEB97','MAR97','APR97','MAY97','JUN97','JUL97','AUG97'...
,'SEP97','OCT97','NOV97','DEC97','JAN98','FEB98','MAR98','APR98','MAY98','JUN98','JUL98','AUG98'...
,'SEP98','OCT98','NOV98','DEC98','JAN99','FEB99','MAR99','APR99','MAY99','JUN99','JUL99','AUG99'...
,'SEP99','OCT99','NOV99','DEC99','JAN00','FEB00','MAR00','APR00','MAY00','JUN00','JUL00','AUG00'...
,'SEP00','OCT00','NOV00','DEC00','JAN01','FEB01','MAR01','APR01','MAY01','JUN01','JUL01','AUG01'...
,'SEP01','OCT01','NOV01','DEC01','JAN02','FEB02','MAR02','APR02','MAY02','JUN02','JUL02','AUG02'...
,'SEP02','OCT02','NOV02','DEC02','JAN03','FEB03','MAR03','APR03','MAY03','JUN03','JUL03','AUG03'...
,'SEP03','OCT03','NOV03','DEC03','JAN04','FEB04','MAR04','APR04','MAY04','JUN04','JUL04','AUG04'...
,'SEP04','OCT04','NOV04','DEC04','JAN05','FEB05','MAR05','APR05','MAY05','JUN05','JUL05','AUG05'...
,'SEP05','OCT05','NOV05','DEC05','JAN06','FEB06','MAR06','APR06','MAY06','JUN06','JUL06','AUG06'...
,'SEP06','OCT06','NOV06','DEC06','JAN07','FEB07','MAR07','APR07','MAY07','JUN07','JUL07','AUG07'...
,'SEP07','OCT07','NOV07','DEC07','JAN08','FEB08','MAR08','APR08','MAY08','JUN08','JUL08','AUG08'...
,'SEP08','OCT08','NOV08','DEC08','JAN09','FEB09','MAR09','APR09','MAY09','JUN09','JUL09','AUG09'...
,'SEP09','OCT09','NOV09','DEC09','JAN10','FEB10','MAR10','APR10','MAY10','JUN10','JUL10','AUG10'...
,'SEP10','OCT10','NOV10','DEC10','JAN11','FEB11','MAR11','APR11','MAY11','JUN11','JUL11','AUG11'...
,'SEP11','OCT11','NOV11','DEC11','JAN12','FEB12','MAR12','APR12','MAY12','JUN12','JUL12','AUG12'...
,'SEP12','OCT12','NOV12','DEC12','JAN13','FEB13','MAR13','APR13','MAY13','JUN13','JUL13','AUG13'...
,'SEP13','OCT13','NOV13','DEC13','JAN14','FEB14','MAR14','APR14','MAY14','JUN14','JUL14','AUG14'...
,'SEP14','OCT14','NOV14','DEC14','JAN15','FEB15','MAR15','APR15','MAY15','JUN15','JUL15','AUG15'...
,'SEP15','OCT15','NOV15','DEC15','JAN16','FEB16','MAR16','APR16','MAY16','JUN16','JUL16','AUG16'...
,'SEP16','OCT16','NOV16','DEC16','JAN17','FEB17','MAR17','APR17','MAY17','JUN17','JUL17','AUG17'...
,'SEP17','OCT17','NOV17','DEC17','JAN18','FEB18','MAR18','APR18','MAY18','JUN18','JUL18','AUG18'...
,'SEP18','OCT18','NOV18','DEC18','JAN19','FEB19','MAR19','APR19','MAY19','JUN19','JUL19','AUG19'});
m = [1 2 3 6 12 24 36 60 84 120 240 360]';
for i=1:100
t = i;
data.X_1 = (1-exp(-m./t))./(m./t);
data.X_2 = ((1-exp(-m./t))./(m./t))-exp(-m./t);
model_1 = fitlm(data, 'FEB95 ~ X_1 + X_2');
RSS(100,:) = zeros ;
res = model_1.Residuals.Raw;
res(any(isnan(res), 2), :) = [];
RSS(i) = sum(res.^2);
end
RSS(:,2) = [1:1:100];
min = min(RSS(:,1));
t = find(RSS(:,1) == min)
data.X_1 = (1-exp(-m./t))./(m./t);
data.X_2 = ((1-exp(-m./t))./(m./t))-exp(-m./t);
model_1 = fitlm(data, 'FEB95 ~ X_1 + X_2')
res = model_1.Residuals.Raw;
res(any(isnan(res), 2), :) = [];
RSS = sum(res.^2)
intercept = model_1.Coefficients.Estimate(1,1);
beta_1 = model_1.Coefficients.Estimate(2,1);
beta_2 = model_1.Coefficients.Estimate(3,1);
Yhat = intercept + beta_1.*data.X_1 + beta_2.*data.X_2;
plot(m, Yhat)
hold on
scatter(m, data.FEB95)
I.e "FEB95" should be dynamic? Any suggestions?
Her is how I would approach your problem. First realize that VarNames=data.Properties.VariableNames will get a list of all column names in the table. You could then loop over this list. For example
for v=VarNames
current_column = v{1};
% ....
% Define the model spec for the current column
model_spec = [current_column ' ~ X_1 + X_2'];
% and create the model
model_1 = fitlm(data, model_spec);
% ... Continue computation ... and collect results in a table or array
end

Fill structure more efficient

How can a structure i.e. 'settings' be filled more easily than with this code:
settings(1).exposure = 1;
settings(1).rebalancing = 0;
settings(2).exposure = 0;
settings(2).rebalancing = 0;
settings(3).exposure = 1;
settings(3).rebalancing = 1;
settings(4).exposure = 0;
settings(4).rebalancing = 1;
settings(5).exposure = 'benchmark';
settings(5).rebalancing = 0;
settings(6).exposure = 'benchmark';
settings(6).rebalancing = 1;
You can compress it using the struct function:
>> s = struct('exposure',{1,0,1,0,'benchmark','benchmark'},'rebalancing',{0,0,1,1,0,1});
>> s(6)
ans =
exposure: 'benchmark'
rebalancing: 1
The array literals can be replaced by any variable that contains your data, as long as all arrays are conforming in size.
you can create an array / matrix with [ 1 2 3 4 5 6]
then in a for loop, for each number ask an input
i=1:6;
for i:6;
settings(i).exposure=input(...);
settings(i).rebalancing=input(...);
end
I think you should be able with this. (its been sometime since I last used a computer with MatLab so I can't confirm)

How can I display different types of output in a matix in matlab?

please consider that I have different types of output in each iteration , how I can show all of them in a matrix?or in a table ? I need to have label for each column and to be accessible when I need it for calling or comparing or etc ...
for example outputs of iterations:
myfilename =
file35.txt
a_Count =
3
PPS_Count =
16
PPP_Count =
8
emo =
'trust'
x =
1
for example outputs of iteration 2:
myfilename =
file36.txt
a_Count =
5
PPS_Count =
10
PPP_Count =
8
emo =
'anger'
x =
0
for example outputs of iteration 3:
myfilename =
file37.txt
a_Count =
6
PPS_Count =
32
PPP_Count =
8
emo =
'trust'
x =
0
thanks in advance.
Here is a tutorial on creating a struct array and documentation for struct.
In your case what I would do is first create the empty struct and then loop through the files:
data_struct = struct('a_Count',{},'PPS_Count',{},'PPP_Count',{},'emo',{},'x',{});
numfiles = 1; % just for testing purposes
for findex = 1:numfiles
% Code to read in file data goes here. Replace from here to next comment.
new_a_Count = 3;
new_PPS_Count = 16;
new_PPP_Count = 8;
new_emo = 'trust';
new_x = 1;
% Replace down to here populating variables:
% new_a_Count, new_PPS_Count, new_PPP_Count, new_emo, new_x
data_struct(findex).a_Count = new_a_Count;
data_struct(findex).PPS_Count = new_PPS_Count;
data_struct(findex).PPP_Count = new_PPP_Count;
data_struct(findex).emo = new_emo;
data_struct(findex).x = new_x;
end;
% display all values in data_struct(1):
disp("data_struct(1) = ");
disp(data_struct(1));
disp("\n");
% display just the first field "a_Count"
disp("data_struct(1).a_Count = ");
disp(data_struct(1).a_Count);
Note that you can call those new variables anything, including the same names as the struct fields. Here's the output you should get when you run this:
data_struct (1) =
{
PPP_Count = 8
PPS_Count = 16
a_Count = 3
emo = trust
x = 1
}
data_struct(1).a_Count =
3

In Matlab, how can I sort the order of a nested structure?

I am trying to sort the order of a nested structure in descending order by a specified parameter. Please refer to the following nested structure:
struct(1).otherStruct(1).name = 'A';
struct(1).otherStruct(1).classAve = 21;
struct(1).otherStruct(2).name = 'B';
struct(1).otherStruct(2).classAve = 21;
struct(1).otherStruct(3).name = 'C';
struct(1).otherStruct(3).classAve = 21;
struct(2).otherStruct(1).name = 'D';
struct(2).otherStruct(1).classAve = 13;
struct(2).otherStruct(2).name = 'E';
struct(2).otherStruct(2).classAve = 13;
struct(2).otherStruct(3).name = 'F';
struct(2).otherStruct(3).classAve = 13;
struct(3).otherStruct(1).name = 'G';
struct(3).otherStruct(1).classAve = 24;
struct(3).otherStruct(2).name = 'H';
struct(3).otherStruct(2).classAve = 24;
struct(3).otherStruct(3).name = 'I';
struct(3).otherStruct(3).classAve = 24;
My goal is to sort the structure above by the highest classAve to the lowest. I would like to sort by the parent structure "struct". As an illustration of what I would like the output to be, please refer to the code below. Notice that the nested structure is now in descending order by classAve but reassigned within the parent structure.
struct(1).otherStruct(1).name = 'G';
struct(1).otherStruct(1).classAve = 24;
struct(1).otherStruct(2).name = 'H';
struct(1).otherStruct(2).classAve = 24;
struct(1).otherStruct(3).name = 'I';
struct(1).otherStruct(3).classAve = 24;
struct(2).otherStruct(1).name = 'A';
struct(2).otherStruct(1).classAve = 21;
struct(2).otherStruct(2).name = 'B';
struct(2).otherStruct(2).classAve = 21;
struct(2).otherStruct(3).name = 'C';
struct(2).otherStruct(3).classAve = 21;
struct(3).otherStruct(1).name = 'D';
struct(3).otherStruct(1).classAve = 13;
struct(3).otherStruct(2).name = 'E';
struct(3).otherStruct(2).classAve = 13;
struct(3).otherStruct(3).name = 'F';
struct(3).otherStruct(3).classAve = 13;
If anyone has suggestions on an easy way to accomplish this, any help would be greatly appreciated. Thank you!
Firstly I'd suggest using another variable name (eg structA) instead of struct since that's a function to create structs.
Then to solve your problem (assuming each otherStruct child has the same classAve):
classAve = arrayfun(#(ii) structA(ii).otherStruct(1).classAve,1:numel(structA));
[~, sort_idx] = sort(classAve,'descend');
structAsorted = structA(sort_idx);
The first line is the largest hurdle to jump; it extracts the indices of the first otherStruct in each array element of the big struct. The following two lines are trivial for sorting stuff.

For loop running over different variables

Good day,
I would like to do the following in Matlab:
var1 = 10;
var2 = 15;
var3 = 20;
j = 1;
for i = [var1,var2,var3]
a(j) = i + 10;
j = j + 1;
end
clear j;
With result:
a(1) = var1 + 10 = 20
a(2) = var1 + 10 = 25
a(3) = var1 + 10 = 30
Any ideas?
Engaging heavy use of crystal ball. It appears that you'd like to dynamically generate the names var1, var2, etc. Don't. There is just about never an advantage to naming variables this way. Use cell arrays instead:
var{1} = 10;
var{2} = 15;
var{3} = 20;
so that you can just use:
for i = 1:length(var)
a(j) = var{i} + 10;
...
Note the curly brace.
If your variables are all the same size, it's even better to use array slices. var(:, i) or var(:,:,:,i), for example
There was a similar question with a successful answer: foreach loop with strings in Matlab
maybe use the cell array syntax with {}:
for i = {var1,var2,var3}
a(j) = i + 10;
j = j + 1;
end
Both #FloHin and #Peter have mentioned using cells, which is a great method to help you when you have a limited number of non-scalar variables. In case you are dealing with unknown number of such variables that follow a certain format, you can use eval function to get the value of the current variable on-demand:
var1 = 10;
var2 = 15;
var3 = 20;
var4 = 30;
# ...
# more variables following the varN = x pattern
all_variables = who('var*');
num = numel(all_variables);
a = zeros(num, 1);
for i = 1:num
a(i) = eval(all_variables{i}) + 10;
end