Different functions with different variables as input

조회 수: 31 (최근 30일)
Oliver Old
Oliver Old 2020년 4월 29일
댓글: Oliver Old 2020년 4월 29일
Hello Matlab Community,
I have a problem, when different functions have different input variables. Then functions I call want of course all input variables. But I don't want to code for every function a single code. Do you have any idea, how I can "bundle" or something similar the input variables to loop them through the whole code with all called functions?
function [R, H, J] = RS(@func,@func2,x,y,eta, S)
[H] = F1(func, x ,y, eta, S); % called function 1
[J] = F2(func2,x,y,eta, S); % called function 2
H_inv = inv(H);
R = (H_inv*J*H_inv);
R = sqrt(diag(R));
end
in the example, the input variables "x,y,eta, S" are only for the RS function needed, but every func and func2 I want to run, have different number of input variables and different input variables. I've tried this
f = @(theta,eps,L,K,B,LK,FK,D)func(theta,eps,L,K,B,LK,FK,D);
f2 = @(theta,eps,L,K,B,LK,FK,D,ti,gi)func2(theta,eps,L,K,B,LK,FK,D,ti,gi);
function [R, H, J] = RS(f,f2,x,y,eta, S)
[H] = F1(f, x ,y, eta, S); % called function 1
[J] = F2(f2,x,y,eta, S); % called function 2
H_inv = inv(H);
R = (H_inv*J*H_inv);
R = sqrt(diag(R));
end
but, that doesn't work. Thanks in advance.

채택된 답변

Jeff Miller
Jeff Miller 2020년 4월 29일
I think you can do this by bundling up the arguments for each function in a cell array. It would look something like this (untested):
function [R, H, J] = RS(@func,@func2,args,arg2)
[H] = F1(func, args{:}); % called function 1
[J] = F2(func2, args2{:}); % called function 2
H_inv = inv(H);
R = (H_inv*J*H_inv);
R = sqrt(diag(R));
end
The call to this function would look something like:
[R, H, J] = RS(@func,@func2,{theta,eps,L,K,B,LK,FK,D},{theta,eps,L,K,B,LK,FK,D,ti,gi})

추가 답변 (2개)

Steven Lord
Steven Lord 2020년 4월 29일
A cell array is one option, but there are at least three potential drawbacks I see with that approach.
The first drawback is that once you package your variables into a cell, you lose the ability to give them a name that identifies who they are and what they are for. If you've given your function good help text that explains the purpose of each input that can mitigate this drawback ... assuming your users read your help text, which is not always a valid assumption.
A second drawback is that either all your functions need to accept all the elements of your cell array or you need to create individual cells for each function.
A third drawback is that this approach encourages designing functions to accept many positional input arguments. Forgetting one of those input arguments changes the meaning of any following inputs and can lead to sometimes cryptic error messages. We see this on Answers occasionally, when someone calls fmincon and forgets one of the nine input arguments preceeding the options structure.
An approach that can avoid these drawbacks is to pack your variables not into a cell array but into a struct or a table.
  1. struct fields and table variables have names that can be used to identify their purpose.
  2. If you pass a struct or table into a function, the function can access any or all of the fields or variables of those inputs and ignore those they neither need nor want. This also means the struct or table is extensible. If a new function needs a new piece of data, put it in a new field or variable and existing functions will happily ignore it and continue working as they did before.
  3. Passing in one variable, a struct or table, makes it easy to remember the order in which you need to specify the inputs to your function. The order of fields or variables doesn't matter in most circumstances to MATLAB.
  댓글 수: 1
Oliver Old
Oliver Old 2020년 4월 29일
ok, thank you for your useful objection! I will implement a struct array, your hints seems traceable to me.

댓글을 달려면 로그인하십시오.


Ameer Hamza
Ameer Hamza 2020년 4월 29일
Example:
f1 = @(a,b,c,d) a+b+c+d;
f2 = @(a,b,c,d) a-b+c-d;
a = 1; b = 2; c = 3; d = 4;
y = RS(f1, f2, a, b, c, d)
function y = RS(f1, f2, a, varargin) % varargin will replace b, c, and d
y1 = f1(a, varargin{:});
y2 = f2(a, varargin{:});
y = y1 + y2;
end
  댓글 수: 2
Oliver Old
Oliver Old 2020년 4월 29일
편집: Oliver Old 2020년 4월 29일
Thank you Ameer Hamza. Actually, I am not so familiar with varargin. I will check this way, as I think this is a very smart approach for my application. One difference from my code to your recommendation are the missing called function within RS. In your proposal, there are just the function values of f and f1 considered. But I think it will nevertheless work with the varargin approach. I have to try! Thanks!!!
Ameer Hamza
Ameer Hamza 2020년 4월 29일
Yes, my code was just an example. For the function in your question, varargin will work like this
function [R, H, J] = RS(@func,@func2, varargin)
[H] = F1(func, varargin{:}); % called function 1
[J] = F2(func2, varargin{:}); % called function 2
H_inv = inv(H);
R = (H_inv*J*H_inv);
R = sqrt(diag(R));
end
and you can call the function RS same as before
[R, H, J] = RS(@func, @func2, x ,y, eta, S)
or whatever the argument list is. Extra arguments are automatically packed inside varargin

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Variables에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by