Simplification of creating new variables in a loop from preset array names

2 visualizzazioni (ultimi 30 giorni)
I am woking on sensetivity analysis in Matlab and have to calculate sensetivity for every input parameter I have. Currently there is 10+ parameters inside so hardcoding all parameters by hand becomes waste of time. Thought, all calculations are exactly the same and I just need to provide different names to every variable.
Is there any solution to give the names within the for loop so it will automatially assign new name while itteration.
Here is a current view of the code:
%-------------------------------------------------------------------------
% Evaluate the first-order sensitivity r_Percentage_Internal_Wall
% sort according to Percentage_Internal_Wall values:
[r_Percentage_Internal_Wall_sort,I_r_Percentage_Internal_Wall] = sort(r_Percentage_Internal_Wall);
% evaluate the mean values of blocks of 100 samples:
r_Percentage_Internal_Wall_blocks = mean(reshape(r_Percentage_Internal_Wall_sort,n_MCS/100,100),1);
r_grey_energy_gwp_blocks_r_Percentage_Internal_Wall = mean(reshape(r_grey_energy_gwp(I_r_Percentage_Internal_Wall),n_MCS/100,100),1);
% these are the means of blocks of 100 samples of r_grey_energy_gwp sorted according to r_Const_Thickness values
% Estimate the first-order sensitivity values:
% Form is: VarY_X1=var(Y_blocks_X1); % the variance of E[Y|X1]
Var_r_grey_energy_gwp_r_Percentage_Internal_Wall = var(r_grey_energy_gwp_blocks_r_Percentage_Internal_Wall);
% First-order sensitivity indexes:
S_r_Percentage_Internal_Wall = Var_r_grey_energy_gwp_r_Percentage_Internal_Wall/r_grey_energy_gwp_var %#ok<NOPTS>
%-------------------------------------------------------------------------
% Evaluate the first-order sensitivity r_Reinforcement
% sort according to Reinforcement values:
[r_Reinforcement_sort,I_r_Reinforcement] = sort(r_Reinforcement);
% evaluate the mean values of blocks of 100 samples:
r_Reinforcement_blocks = mean(reshape(r_Reinforcement_sort,n_MCS/100,100),1);
r_grey_energy_gwp_blocks_r_Reinforcement = mean(reshape(r_grey_energy_gwp(I_r_Reinforcement),n_MCS/100,100),1);
% these are the means of blocks of 100 samples of r_grey_energy_gwp sorted according to r_Const_Thickness values
% Estimate the first-order sensitivity values:
% Form is: VarY_X1=var(Y_blocks_X1); % the variance of E[Y|X1]
Var_r_grey_energy_gwp_r_Reinforcement = var(r_grey_energy_gwp_blocks_r_Reinforcement);
% First-order sensitivity indexes:
S_r_Reinforcement = Var_r_grey_energy_gwp_r_Reinforcement/r_grey_energy_gwp_var %#ok<NOPTS>
I would like to do it in a for loop in such a way, that it automatically creates new variables and puts the name from array = ["Reinforcement","Percentage_Internal_Wall", ... ] and doing all the calculations presented above.
As well I have python code which was doing quite the same. Here it is:
for indi in indicators:
result_df['grey_energy_'+ indi] = interim_df['grey_energy_insul_' + indi] + interim_df['grey_energy_const_'+indi] + \
interim_df['grey_energy_window_' + indi] + interim_df['grey_energy_internal_' + indi]
result_df['grey_energy_D_'+ indi] = interim_df['grey_energy_insul_D_' + indi] + interim_df['grey_energy_const_D_'+indi] + \
interim_df['grey_energy_window_D_' + indi] + interim_df['grey_energy_internal_D_' + indi]
The structure I would like to have:
Indicators = {'r_Length' 'r_Height' and etc.}
for i = 1: indicators
% Evaluate the first-order sensitivity r_Reinforcement
% sort according to Reinforcement values:
[(Indicators{i})_sort,I_(Indicators{i})] = sort((Indicators{i}));
% evaluate the mean values of blocks of 100 samples:
(Indicators{i})_blocks = mean(reshape((Indicators{i})_sort,n_MCS/100,100),1);
r_grey_energy_gwp_blocks_(Indicators{i}) = mean(reshape(r_grey_energy_gwp(I_(Indicators{i})),n_MCS/100,100),1);
% these are the means of blocks of 100 samples of r_grey_energy_gwp sorted according to r_Const_Thickness values
% Estimate the first-order sensitivity values:
% Form is: VarY_X1=var(Y_blocks_X1); % the variance of E[Y|X1]
Var_r_grey_energy_gwp_(Indicators{i}) = var(r_grey_energy_gwp_blocks_(Indicators{i}));
% First-order sensitivity indexes:
S_(Indicators{i}) = Var_r_grey_energy_gwp_(Indicators{i})/r_grey_energy_gwp_var %#ok<NOPTS>
end

Risposta accettata

Guillaume
Guillaume il 20 Mag 2019
Modificato: Guillaume il 20 Mag 2019
Embedding metadata in variable names is a sure way of creating complex and buggy code. See Tutorial: why variables should not be named dynamically.
I don't know much about Python, but it looks like your Python code only use two variables Result_df and interim_df. That's what you should do in matlab as well. The two variables appear to be dictionaries. The equivalent in matlab is containers.Map.
%asuming you have an interim_df containers.Map already filled
%and indicator a row string vector
result_df = containers.Map;
for indi = indicators
result_df("grey_energy_" + indi) = interim_df("grey_energy_insul_" + indi) + ...
%etc
end
However, you may want to rethink the storage altogether and store everything in a single table which would avoid all this variable name manipulation.
  5 Commenti
Stephen23
Stephen23 il 21 Mag 2019
Modificato: Stephen23 il 21 Mag 2019
"Or it is better to separate the samples by name and do the sorting in different tables and then compute it there?"
If I was given as task like this I would use a non-scalar structure to store the data, with fields for the data, names, etc. It is trivial to loop over a non-scalar structure and apply whatever operations you want to the fields of each structure element.
Something like this (pseudocode):
S(1).name = 'r_Length';
S(1).data = [...]
S(2).name = 'r_Height';
S(2).data = [...]
...
names = {S.name}
for k = 1:numel(S)
tmp = mean(S(k).data)
val = somefunction(tmp)
... sorting, whatever else you want to do
S(k).out = ...
end
Note that this code uses simple and very efficicent indexing.
Tables also support applying functions to groups of rows, you can probably do something equivalent with tables:
"Is there any solution to give the names within the for loop so it will automatially assign new name while itteration."
It is certainly possible, but you would be forcing yourself into writing very inefficicent, complex, buggy code that would be hard to debug. You can easily avoid this using a structure array, or a cell array, or a table, etc.
Konstantin Tkachuk
Konstantin Tkachuk il 21 Mag 2019
Thank you a lot for the help!
Definitely restructure my code in this way now!
Seems way cleaner and more efficient.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Matrices and Arrays in Help Center e File Exchange

Prodotti


Release

R2017b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by