# how to write lot of inputs in a function

50 views (last 30 days)
tomer polsky on 10 Jan 2018
Commented: Adam on 12 Jan 2018
hello i have this call for function in my main program :
[A_a,A_b,B_a,B_b,C_a,C_b]=basic_matrix_numeric(C1,C,R,R2,R_C1,R_C,R1,L1,L2,V_diode,U);
how ever as you can see there are a lot inputs , i tried to make it look better for exmaple write all the inputs in a cell like this:
values ={C1,C,R,R2,R_C1,R_C,R1,L1,L2,V_diode,U}
[A_a,A_b,B_a,B_b,C_a,C_b]=basic_matrix_numeric(values);
but as you can see i get an eror any other ideas ?
Usually if you need that many inputs for a function it is a strong suggestion that you should split it into multiple functions instead, each taking a more specific set of inputs.

Stephen23 on 10 Jan 2018
Edited: Stephen23 on 10 Jan 2018
"how to write lot of inputs in a function"
Put all of the data into one structure, and then pass that. Inside the function access the data directly from the structure. You can do the same with the output. This is usually the easiest way of passing lots of names arguments, rather than trying to rely on the fiddly positional input arguments of a function.
Or, if you really really want to keep all of those input arguments, simply use a comma-separated list:
values = {C1,C,R,R2,R_C1,R_C,R1,L1,L2,V_diode,U};
[A_a,A_b,B_a,B_b,C_a,C_b] = basic_matrix_numeric(values{:});
Stephen23 on 11 Jan 2018
@tomer polsky: MATLAB does not magically convert the fields of the structure into separate input arguments, so you need to rewrite the function to:
• accept one input argument (a structure).
• use the fields of that structure inside the function.

Simon Parten on 11 Jan 2018
Edited: Simon Parten on 11 Jan 2018
Interestingly, I'd probably disagree with Stephen's answer here. If the function has to know about the structure of the data it's being passed, you have a leaky abstraction. At some point in the future, this is going to be rather difficult to explain to anyone else / test / make robust / debug / remember what the hell was going on.
How much this matters, depends how long lived your code is going to be, and how many other people you expect to use it ...
My personal suggestion is to pass meaningful name / value pair arguments, as a varargin, then parse and validate them using The InputParser, and set a series of sane defaults for those you don't need. This is also 'self documenting' for when you forget how it all works in the future...
function blahblah = Blaher(varargin)
p = inputParser;
p.FunctionName = 'Blaher';
p.CaseSensitive = true;
p.StructExpand = true;
addParameter(p, 'sayBlah', 'Blah' , @(x) validateattributes(x,{'char'},{'nonempty'}) );
addParameter(p, 'sayBob', 'bob' , @(x) validateattributes(x,{'char'},{'nonempty'}) );
addParameter(p, 'sayHi', 'hi' , @(x) isa(x,{'char'},{'nonempty'}) ;
addParameter(p, 'SaySo', true , @(x) validateattributes(x,{'logical'},{'nonempty'}));
p.parse(varargin{:});
this.sayBlah = p.Results.sayBlah;
this.sayBob = p.Results.sayBob;
this.sayHi = p.Results.sayHi;
this.SaySo = p.Results.SaySo;
% now say blah as appropriate.
end
I tend to avoid varargin as I have never liked it, but I have used it with 'name', 'value' pairs on some occasions, when validating a class constructor that is some parameter-holding class with defined defaults that for many properties do not need to be changed.
Where the problem is just the number of inputs rather than that some or all of them are wanted to be optional, I just name them all as individual arguments usually. I use parameter classes though so my function that is doing something won't generally take a vast number of arguments, but the construction of my parameter class may. It's just moving where the arguments are defined really.
Still, if you simply have a problem with feeling you have too many inputs to name individually then it is a strong indication that you simply have too many inputs and need to design the code differently.
I almost never use structs though, ghastly christmas tree structures that you can hang anything off and easily accidentally create new fields with typos instead of getting error messages as a class would give you.