Matlab Function - ask for user input for given argument - matlab

I have a Matlab function that has numerous name-value parameter inputs. For some of the parameter names, there are a lot of possible values (which are not always obvious) that the user can choose from. What I would like to do is, IF the user calls the name, but does NOT give a value, THEN Matlab would display possible entries AND THEN take the user's input.
For example I have a function such as:
function getSomeData( varargin )
p=inputParser;
defaultData='abc';
addParameter(p, 'Data', defaultData);
parse(p,varargin{:});
end
If the user were to call the function in the command window such as:
>> getSomeData('Data')
in which the user did not give a value for 'Data', the window would display and prompt
>> getSomeData('Data')
No value for 'Data' Given
Possible Values of 'Data' are:
'abc'
'def'
'other'
Please input your 'Data':
in which I could use the result=input(prompt) function.
Any help or advice is very much appreciated! Cheers

May I ask you to specify the complexity of your input stuff. Either you come from java and think that you need to create an I/O object to be able to read inputs, or else your problem is more complex that the description gives the impression of.
Otherwise, I would give you the design of a less complicated way forward here. One way to do this is to use the nargin property, which finds the number of inputs to the function. Together with nargin, use an if statement (or switch-case?).
if nargin==0
% print alternative inputs with disp or fprintf.
% This alternative can also be replaced with comments (single block with
% no empty rows) right below the function. This will then be seen with
% the `help funName` command
elseif nargin==1
% Print description + permitted values. This can be done from a
% switch-case statement (if you want the switch-case statement
% can be placed in an external function).
elseif ~mod(nargin,2)
%parse input pairs and do the calculations.
else
error('wrong number of input arguments');
% or
% fprintf('wrong number of input arguments\n');
% set outputs to '', {}, [], ...
% return;
end
I hope this helps even though it is not exactly the solution proposed by you. This is however a simple solution with the advantage that you do not mix up the information parts and execution parts. My guess is that this is a convenient way to work with I/O without implementing a complicated parser.
These problems are otherwise normally solved by a complicated parser with a lot of different commands (compare with the terminal (unix based) of cmd prompt (windows)).

Related

Matlab "auto-squeeze" plot

Matlab plot requires the data to be of the same dimension. Meaning, you cannot plot a 1x10 vector with a 1x1x10 vector. This is sometimes necessary. For those purposes, you can use the squeeze function to get rid of the singleton dimensions.
However, this is kind of a hassle. For the plot function specifically, it would be useful to have the argument always squeezed. How would one go about creating a new function, lets call it splot which squeezes every input and passes it onto plot. Here is an attempt (that doesn't work)
function splot(varargin)
for i=1:length(varargin)
varargin{i}=squeeze(varargin{i});
end
plot(varargin)
end
plot(varargin) part fails, because that is simply not how matlab syntax works. But is there any way to achieve what I want? I guess I could write a long if elseif chain where I manually write the case with every possible number of input arguments like:
if length(varargin)==2
plot(varargin{1},varargin{2})
if length(varargin)==3
plot(varargin{1},varargin{2},varargin{3})
But this is going to be very annoying. Any better ideas.
This question is similar to Is there any mechanism to auto squeeze in Matlab / Octave , however, not similar enough, because the other question is for squeezing every vector, which is a bad idea. Here I am asking a way to squeeze only the inputs to the plot function and requiring syntax help.
From the docs there are several ways to call plot. Generally
Just numeric arrays, these can be on their own, or one or more pairs
plot(Y), plot(X,Y) or plot(X1,Y1,...,Xn,Yn)
Numeric arrays as before, with a char array giving the line spec
plot(X,Y,LineSpec) or plot(Y,LineSpec)
Either of the previous two, plus name-value pair options
plot(___,Name,Value)
In any of these cases, you want to squeeze the first N inputs which are numeric, since either of the optional additions have the first non-plottable input as a char.
We can achieve that with the following code, see the comments for details:
function h = splot( varargin )
% Check if there are any optional inputs, which will either be
% LineSpec (which is a char) or name-value pairs (which the
% first of will be a char)
bNumericArg = cellfun( #isnumeric, varargin );
% By default, assume all inputs are arrays to plot
lastArrayArg = numel(varargin);
if ~all(bNumericArg)
% In this case, there are some optional inputs, get last array index
lastArrayArg = find( ~bNumericArg, 1 ) - 1;
end
% Squeeze the arrays
for ii = 1:lastArrayArg
varargin{ii} = squeeze(varargin{ii});
end
% Plot with all inputs, optional output
if nargout > 0
h = plot( varargin{:} );
else
plot( varargin{:} );
end
end
There are two possible cases I've not handled here which the plot function can handle,
Having the first input as the target axes i.e. plot(ax,___), could be achieved by altering the loop slightly to start from 1 or 2 depending if the first input is an axes object
Having pairs of arrays each with their own line spec argument i.e. plot(X1,Y1,LineSpec1,...,Xn,Yn,LineSpecn). The later pairs will be ignored. This would be trickier to handle since you'd likely have to parse all inputs and check whether a char is just a line spec or if you're messing with name-value pairs. Maybe a heuristic to do with "two arrays then a char, repeated". I've never used this syntax so omitting the over-complication for now.

Running MATLAB function without defining all parameters

I have a Matlab function
PlotSubbands(imfx(:,1),wx,3,3,j,j,1);ylabel('Subband');
from TQWT toolbox. eeweb.poly.edu/iselesni/TQWT. When I execute, the function plots 'j' number of plots. (I have not included full code). The function plots the input signal, which is in this case imfx(:,1) for every subplot. And this what I don't want. I tried removing it from the parameters but I got error, 'not enough input arguments'. This is because in the function the first input signal parameters is defined and used. I cannot remove it from there. Appreciate your inputs on the same. Thank you.
The function PlotSubbands include following lines
if isreal(x)
plot((0:N-1)/fs,x/(2*max(abs(x))),'b')
else
plot((0:N-1)/fs, real(x)/(2*max(abs(x))), 'black')
The repeated plotting of input signal is done from these two line. Commenting these lines can solve the problem (If array x does not include imaginary part, then better to comment these lines). However, the to determine the real array, isreal(x) is needed further in the function. So, I defined the value of x here and it solved the repeated plotting issue.

How to get all outputs (MatLab)?

Suppose I have a function that gives out unknown number of output arguments (it depends on input,thus change through the loops). How to get all of them?
nargout doesn't help as the function uses varargout (the result is -1)
And of course I can't rewrite the function, otherwise the question wouldn't arise :- )
Well, thanks to all partisipated in discussion. Summing up, it seems the problem has no general solution, because MatLab itself estimates the number of desired outputs before the function call to use inside it. Three cases can be pointed out though:
1) The funcrion doesn't have varargout in definition, thus nOut=nargout(#fcn) returns positive number.
Then nOut is an actual number of outputs and we can use a cell array and a column list trick.
X=cell(1,nOut);
[X{:}]=fcn(inputs);
2) The funcrion has varargout in definition, thus nOut=nargout(#fcn) returns negative number. However some correlation with inputs can be found (like length(varargin)=length(varargout)).
Then we can calculate the resulting nOut from inputs and perform the above column list trick.
3) You know the fcn developer.
Ask him fot assistance. For example to make the function's output to be a cell array.
One of ways I usually use in this case is to store all outputs in a cell array inside the function. Getting the cell array outside the function's body, you might investigate its length and other properties.
Here is how you could deal with the problem in general. I didn't mention this solution earlier because... it is horrible.
Suppose a function can have 1 or 2 output arguments:
try
[a, b] = f(x)
catch
a = f(x)
end
Of course it is possible to do this for any number of output arguments, but you really don't want to.

Why is this error happening: Index exceeds matrix dimensions

I am running a GUI system in MATLAB and I am a beginner with working with GUI's.
The code is extensively long and so I am going to just put in what and where I have things and see if it is enough information for help to be given, thanks.
in my first GUi I have this in the opening function:
HW12_result_bhanford(handles.scan_age, handles.check_athlete, handles.radio_male, handles.radio_female)
this is supposed to be transferring these four variables over to my third GUI named
HW12_result_bhanford
In my second GUI I have this written in the opening function:
age = varargin{1}
athlete = varargin{2}
male = varargin{3}
female = varargin{4}
I then use these four variables(age, athlete, male, female) later in the second GUI and I
assume them to be the equivalent value of the corresponding variable passed from the first
GUI.
When I run everything the error that comes back is Index exceeds matrix dimensions.
if anyone could help me, that would be awesome. If you cannot help without the entire code I understand.
You use varargin if your argument list is variable, and varargin has to be in your function definition.
function HW12_result_bhanford(varargin)
In this case function receive a cell array as an input, so you can get individual arguments with varargin{1} etc.
If you put your arguments together as a structure, you can pass this structure as an argument along.
function HW12_result_bhanford(handles)
But if the function definition has individual arguments, for example,
function HW12_result_bhanford(age, athlete, male, female)
you cannot use varargin, just process the arguments as is.
Read more on how to use VARARGIN.

When using a multiple-output matlab function, do i need to callback all variables?

When using a multiple-output matlab function, do i need to callback all variables? or can I just take the first two variables? (if so..is it not recommended?)
lets say in function.m
[a, b, c] = function( )
in main.m
[var1, var2] = function;
When calling (almost) any function in matlab you can request fewer outputs than it specifies. So, yes the example you give should work perfectly fine.
There are some clever things you can do with this, such as using nargout within a function to see how many output arguments have been requested and only calculating the values that have been requested as an optimisation trick.
It depends on the definition of the function, and exactly which of the outputs you want to get.
Not all the function allow to do it, you can find all the options for each function in the beginning of the help documentation on the specific function.
If you want only the 2nd, or 3rd outputs, and you want also to save the computation-time of the results that does not interesting, you can use ~ option, like this (for versions 2009b and later):
[~, var1, var2]=function
Many functions allow for options to passed that change how the function behaves. I used/wrote various numerical solving functions a bit and one that nice amount of option, for instance is the LSMR function(s).
Otherwise, if you can manipulate the original either introduce an input(s) to do so before or at the end with an inline subroutine to generate the outputs you want.
Or if you can't it will return as either a cell array or a vector and you can pass an anonymous function to generate the desired outputs that way.
Really, can be done many ways. Very contextual.