How to specify index variable name of for loop programmatically?

29 views (last 30 days)
For evaluating the behavior of a function with multiple numerical inputs, I want to write a script which fixes all but one of the input values and iterates through the remaining one using a for loop.
When changing the input variable to be varied, I have to change the index variable of the for loop manually, as well as the range (which could be somewhere else in the script). To have all manually altered values at the same place, I used an eval statement, which is generally frowned upon. Another alternative would be to save all input variables in a struct and then access them, but that would complicate the code unneccessarily.
Minimal example:
% Initialize base values at the beginning
a = 1;
b = 2;
c = 3;
% Specify which of the values should be iterated -
% this is the only block that should be changed manually between each run
iter_var_name = 'a'
iter_var_values = [1:4];
% Further initializations and calculations happen here, creating some distance between the initialization
% and the for loop
% Now the for loop - I would like to not have to remember writing
% something here additionally when I change which variable is varied
all_costs = zeros(1,length(iter_var_values))
for k = 1:length(iter_var_values)
eval([iter_var_name, '= iter_var_values(k);'])
all_costs(k) = myfun(a,b,c)
end
function cost = myfun(a,b,c)
cost = a + b/c;
end
My question is - Is there a cleaner way to rethink this problem? Thank you in advance for your help.

Accepted Answer

Stephen23
Stephen23 on 15 Jun 2021
Edited: Stephen23 on 15 Jun 2021
"Is there a cleaner way to rethink this problem?"
Of course.
Using MATLAB effectively means using arrays and indexing. Note that your title already hints that indexing is the solution to your question, and that MATLAB inputs are entirely positional, which corresponds very nicely with indexing.
% Initialize base values at the beginning
C = {1,2,3}; % or C = {a,b,c};
% Specify which of the values should be iterated -
% this is the only block that changes manually between each run
iter_var_index = 1; % you could generate this from STRCMP or similar.
iter_var_values = 1:4; % removed superfluous square brackets.
% Now the for loop - no need to change anything here!
all_costs = zeros(1,length(iter_var_values));
for k = 1:length(iter_var_values)
C{iter_var_index} = iter_var_values(k); % basic indexing.
all_costs(k) = myfun(C{:}); % comma-separated list.
end
% Checking:
all_costs
all_costs = 1×4
1.6667 2.6667 3.6667 4.6667
function cost = myfun(a,b,c)
cost = a + b/c;
end
Result: simpler, neater, faster, much more efficient code which is easier to debug. See also:
Don't get stuck trying to force a square peg into a round hole, or paint yourself into a corner with poor data design:
  1 Comment
Fabia Bayer
Fabia Bayer on 15 Jun 2021
Thank you very much! This is exactly what I was trying to achieve, you helped me tie together the right concepts.

Sign in to comment.

More Answers (1)

Sulaymon Eshkabilov
Sulaymon Eshkabilov on 15 Jun 2021
Note that dynamically changing the variable names is not recommended practice.
There are some points to be fixed in your code:
...
iter_var_values1 = 1:4;
iter_var_values2 = 2:5;
iter_var_values3 = 3:6;
...
cost = zeros(1,length(iter_var_values)) % Memory allocation
for k = 1:length(iter_var_values)
var1 = iter_var_values1(k);
var2 = iter_var_values2(k);
var3 = iter_var_values3(k);
cost(k) = myfun(var1,var2,var3)
end
function cost = myfun(a,b,c)
cost = a + b/c;
end

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!