# What is the recommended way to pass long list of parameters between main workspace and function?

47 visualizzazioni (ultimi 30 giorni)

Mostra commenti meno recenti

In my work I encountered a problem with passing variables betwen main script and function. Of course I can do it manually:

a1=1;a2=2;a3=3;a4=4;a5=5; %The list is much longer in my project, here just example

sum=calcvalues(a1,a2,a3,a4,a5);

function sum=calcvalues(a1,a2,a3,a4,a5)

sum=0;

b=[1,2,3];

for i=1:3

sum_tmp=sum_support(a1,a2,a3,a4,a5,b(i));

sum=sum+sum_tmp;

end

end

function sum_support = sum_support(a1,a2,a3,a4,a5,b)

sum_support=a1*a2+a3^b+a4*a5;

end

But I have to retype all values every time, and after any modification in list of function inputs there is no option to sync with other executions. Additionally, the list is very long, and take space in every function, making the code less readable. My intention was to override this with

function sum=calcvalues(varargin)

But this doesn't preserve file names. The output is just a 1x5 cell with anonymouse numbers. So far I managed to use eval to assign names dyanmicaly but this does not looks like a good practise. What is the recommended way to restore/preserve the names?

EDIT to clarify:

Here is the closest solution to what I expected. However this requires to use save command to unpack the structure. Is it possible to do this in more elegant way?

a1=1;a2=2;a3=3;a4=4;a5=5; %The list is much longer in my project, here just example

value_holder=struct('a1',a1,'a2',a2,'a3',a3,'a4',a4,'a5',a5);

sum=calcvalues(value_holder)

function sum=calcvalues(value_holder)

sum=0;

b=[1,2,3];

for i=1:3

sum_tmp=sum_support(value_holder,b(i));

sum=sum+sum_tmp;

end

end

function sum_support = sum_support(value_holder,b)

save('temp.mat','-struct','value_holder')

load('temp.mat')

sum_support=a1*a2+a3^b+a4*a5;

end

##### 7 Commenti

### Risposta accettata

dpb
il 24 Mag 2022

If the variables are such as your example of a sequence of number variables with same root name, that implies they're related/same thing, just different instances. In that case I'd use an array and indexing -- "A" instead.

Alternatively, if they are actually different variables, take those that are related and create a structure to pass for succinctness and then reference the component variables in the struct.

Alternatively, if there are a lot of disparate variables, consider putting them into a table and pass the table.

Would need a lot more information about the actual variables and their use to have specifics, but design the data structure around the problem and then implement it, don't just create variables willy-nilly with no overall structure.

##### 10 Commenti

Matt J
il 24 Mag 2022

Modificato: Matt J
il 24 Mag 2022

Alright, I'm mentioning this against my better judgement, but you can unpack the variables in the implicit manner that you want by doing,

eval(structvars(s)')

This might be a compromise in performance between load/save and my suggestion. However, eval() has at least the same programming hazards as load(), so take great heed of the discussion here,

### Più risposte (3)

Steven Lord
il 24 Mag 2022

If all your variables are related and so should remain together, I would pack them into a struct array.

s = struct('a1',1,'a2',2)

s.a3 = 3;

s.a4 = 4;

s.a5 = 5

Now you can pass s into and out of your function and use the values in its fields in your function. Functions that need some but not all of the fields in the struct can ignore the ones they don't need, and you can add fields to the struct without affecting existing code.

##### 3 Commenti

Steven Lord
il 24 Mag 2022

Unpack just the variables that ODE function needs at the top of the ODE function. Or if a variable only appears once in the ODE function, you can index into the struct rather than creating an additional variable.

s = struct('a1',1,'a2',2,'a3',3,'a4',4, 'a5', 5);

function sum=calcvalues(s)

sum=0;

b=[1,2,3];

for i=1:3

sum_tmp=sum_support(s,b(i));

sum=sum+sum_tmp;

end

end

function sum_support = sum_support(s,b)

% The next few lines were added

a1 = s.a1;

a2 = s.a2;

a3 = s.a3;

a4 = s.a4;

% a5 = s.a5; % Instead of doing this you can use s.a5

sum_support=a1*a2+a3^b+a4*s.a5; % like I did here

end

dpb
il 25 Mag 2022

Modificato: dpb
il 25 Mag 2022

For something that looks likes OP's example of a bunch of constants to retrieve, I think I'd do as you suggest and retrieve in the individual ODE functions the ones needed for the function --

s=struct('coeff',[1:5]); % put all the coefficients in array instead of many (unuseful anyway) names

Then in each ODE function can write something like

IDX=[1,3,4]; % the needed coefficients for this ODE

S=sum_support(s,IDX); % call the function with needed index array

function sum_support = sum_support(s,b)

sum_support=sum(s.coeff(b))

end

At command line to show syntax works as expected...

>> s = struct('coeff',[1:5]);

>> IDX=[1 3];

>> sum(s.coeff(IDX))

ans =

4.00

>>

One could make things more simple for using for the ODE functions by creating either a struct array of an element of the coefficients for the given ODE and even have a name to ensure use right array element or if it's not too complicated, use a 2D array where each row contains the coefficents for the given ODE so the very long 1D string is given some structure associated with its use.

The disadvantage is that they are then position dependent so Steven's solution is better in that regards.

Matt J
il 24 Mag 2022

Modificato: Matt J
il 24 Mag 2022

In the case of your posted example, the appropriate re-implementation would be,

a=1:5;

result=calcvalues(a);

function accum=calcvalues(a)

accum=0;

b=[1,2,3];

for i=1:3

accum=accum+sum_support(a,b(i));

end

end

function sum_support = sum_support(a,b)

sum_support=a(1)*a(2)+a(3)^b+a(4)*a(5);

end

##### 6 Commenti

Matt J
il 24 Mag 2022

Modificato: Matt J
il 24 Mag 2022

I said "if" they are, not that I know that for a fact. If they aren't the same length, you can still possibly use a cell array.

The point though is that you should go through your variables to see which ones are similar in size and type, and which can be grouped into arrays.

Catalytic
il 24 Mag 2022

Modificato: Catalytic
il 24 Mag 2022

Do not use load/save to introduce undeclared variables in your workspace. This can have unexpected effects as described in this doc page -

which also mentions recommended alternatives.

##### 5 Commenti

Catalytic
il 24 Mag 2022

### Vedere anche

### Categorie

### Community Treasure Hunt

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

Start Hunting!