Array as a function parameter instead separate variables in Matlab - matlab

I need pass to a function (jacobian() in my case) a symbolic variable array is being creating dynamically. Say,
jacobian(handles{2}(t,y,paramlist),y)
where paramlist=[var1, var2, var3, ..., varN] has an arbitry size. All variables here are symbolic and have various names. MATLAB throw an error:
Not enough input arguments.
Knowing number of parameters in the function definition one can pass all parameters separately. Say, for n=3:
jacobian(handles{2}(t,y,paramlist(1),paramlist(2),paramlist(3)),y)
But what about the common case? It's a bad style of programming to write the function call for each fixed number of parameters. Is there a way to pass an array so as it would be treated as distinct variables?

You can convert paramlist to a cell array (using num2cell) and then use {:} indexing to create a comma separated list which you can then use this for indexing into handles{2}. This will make it such that each value of paramlist is passed as a separate subscript.
plistcell = num2cell(paramlist);
jacobian(handles{2}(t, y, plistcell{:}), y)

Related

How to choose pass value to one parameter to a MATLAB function with multiple inputs?

function [c,tc]=v_melcepst(s,fs,w,nc,p,n,inc,fl,fh)
This function has multiple input parameters, but I only want to specify the value for the nc parameter.
In Python, I can easily just do something like v_melcepst(nc=13), but I cannot find the equivalent for MATLAB.
Is this not possible in MATLAB? Do I have to pass default values?
This is indeed not possible in MATLAB. The arguments are sequential, identified by their location in the argument list.
If you wrote the v_melcepst function yourself, you can rewrite it to accept "name/value pairs", the standard way in MATLAB to do named arguments. In this system, groups of two arguments together work as a single named argument. You would call the function as
[c,tc] = v_melcepst('nc',nc);
You can implement this using the old inputParser class (introduced in R2007a), or with the new function arguments block (new in R2019b).
Check the documentation on varargin and nargin.
Basically, do something like
function out = my_func(a,varargin)
if nargin == 1
b = 2; % Your default value
elseif nargin == 2
b = varargin{1};
end
Note that the above does mean you have to have a fixed order of input arguments. Any arguments explicitly named in the function declaration, a in this case, always have to be present, and anything within the varargin has to be in the set order, e.g. you can add a c = varargin{2}, then you cannot set c without setting b.
If you want to be able to give Python-like input argument, i.e. regardless of the order, you need name-value pairs. This is done via inputParser, as suggested in Cris Luengo's answer

How to convert EditField value to cell array?

I want to take a cell array from the user containing the number of zeros and poles of each transfer function in a system identification app that I am designing in MATLAB's app designer.
User enters something like this:
{[2,1], [1,0]; [1,0], [2,1]}
EditField or TextArea treats this input as a char array or string, But I want to re-convert it to a cell array of numbers, not strings. How is that possible?
You can use eval to evaluate the string to get the resulting numbers. This works if it has numbers, variables and functions accessible from the workspace where you are running eval. See documentation for eval at https://www.mathworks.com/help/matlab/ref/eval.html. If there is a variable in the expression for example as, {[2,1], [1,0]; [1,0], a} with a defined in the base workspace then you need to use evalin. evalin lets you specify the workspace where the expression needs to be evaluated.
Finally if it is not a cell array and contains only an array of numbers then str2num also can do the job of converting the string to numbers.

How to rename table variables in Matlab?

I would like to create a table from a matrix of spectra data, using a specific list of variables (column, which here correspond to 1000 spectral wavelenght values) instead of putting the name manually.
To do so, i use the array2table function, and matlab documentation shows that names for rows and label of variables must be put as cell arrays, (and not matrix). So I need to first convert my x-axis (spectral wavelenght) to a cell array. I use the following:
C = num2cell(xaxis); % to convert into a cell array (each cell contain 1 value)
isvarname C % to check that the variable is valid as a cell array
T = array2table(R,'RowNames', concentration,'VariableNames',C);
Here: R is the matrix, concentration is a Cell array 1x500, xaxis is the wavelenght of spectral data 1x1000 (which is ranged from 600 to 1800, approx. there is no null value).
Unfortunately, I got the following error:
"Error using array2table (line 62)
The VariableNames property must be a cell array, with each element containing one nonempty string."
which means I can input properly the columns (variable) names (while row names, however, works fine).
Note: i tried the
T.Properties.VariableNames = c but it is not working either.
I checked the other post on table name value but its not helping,
Any thought about this?
Thank you very much.
Maybe you mistyped your question's code, but it seems that you are using the array xaxis instead of C. Anyway, I suggest you try casting the cells content to strings this way
T = array2table(R,'RowNames', concentration,'VariableNames',cellfun(#(x)num2str(x),num2cell(xaxis),'uniformoutput',false));
Edit
Looking through the table docs it says that
Variable names, specified as the comma-separated pair consisting of 'VariableNames' and a cell array of character vectors that are nonempty and distinct. The number of character vectors must equal the number of variables. The variable names that you assign must be valid MATLABĀ® variable names. You can determine valid variable names using the function isvarname.
Furthermore, the isvarname function says that
A valid variable name begins with a letter and contains not more than namelengthmax characters. Valid variable names can include letters, digits, and underscores. MATLAB keywords are not valid variable names. To determine if the input is a MATLAB keyword, use the iskeyword function.
This means that you cannot use the xaxis values as variable names by themselves, you need to, at least, prepend a character and remove the decimal dot. You can do so with the following
T = array2table(R,'RowNames', concentration,...
'VariableNames',cellfun(#(x)['wavel_',regexprep(num2str(x),'.','_')],num2cell(xaxis),'uniformoutput',false));
This code will prepend 'wavel_' to the numerical string value. It will also replace the dots with underscores using the regexprep function. However, it seems like this is really unnecessary because the column names are not really informative. The array2table function's doc says that if you don't supply the 'variableNames' option it will do the following:
If valid MATLAB identifiers are not available for use as variable names, MATLAB uses a cell array of N character vectors of the form {'Var1' ... 'VarN'} where N is the number of variables.
Maybe using the default variable names is good enough.

How can I get Matlab to use the variable value instead of name

In my code, I have a line that looks like this:
f=#(test) bf{i}(5);
where bf is a cell array with functions from str2func() stored in it, i is a variable storing an integer, and the 5 is the argument to pass to the function. How can I get matlab to evaluate the line using the current value of i? Right now when I display f it outputs:
#(test)bf{i}(5)
Lets say i=1, I want it to output:
#(test)bf{1}(5)
Although technically the bf{1} should also be replaced with whatever function is stored in bf{1}. How can I force matlab to evaluate the variables in this statement?
When you create a function handle, the workspace variables are copied and the expression is evaluated when you call the function handle (Typically not a problem in memory consumption, matlab stores only changes).
Now the problem is, to tell Matlab when to evaluate what part of the expression.
If you are aiming for a better performance, pre-evaluate all constant parts of the function. Let's say your function is #(x)(g(3).*f(x)), in this case matlab would evaluate g(3) on every call.
Instead use:
f=#(x)(x.^2)
g_3=g(3)
h=#(x)(g_3.*f(x))
Now having the constant parts evaluated, you want to see the constants instead of the variabe name. I know two ways to achieve this.
You can use the symbolic toolbox, basically converting the function handle to a symbolic function, then to a function handle again. This not only displays the constants, but also substitutes f. This is not possible for all functions.
>> matlabFunction(h(sym('x')))
ans =
#(x)x.^2.*4.2e1
Another possibility is to use eval:
h=eval(['#(x)',sprintf('%e',g_3),'.*f(x)'])
Pre-evaluating constant parts of the expressions as I did in the first step is typically recommendable, but both solutions to get the constant visible in your function handle aren't really recommendable. The first solution using matlabFunction only applies to some functions, while the second comes with all the disadvantages of eval.

What is the syntax for declaring a global 2-dimensional array in MATLAB?

What is the syntax for declaring a global 2-dimensional array in MATLAB?
I want the array to be blank, or uninitialized. That is, I want to be able to initialize it to some value later on using a for-loop. All the examples I have come across so far consist of initializing the array when it is declared. I find this rather tedious because my array might have to be a large one.
Thanks.
Declare a variable as global first before using it:
global my_glob_var;
MATLAB doesn't really support the concept of 'uninitialised' variables, but you can create an array of NaNs (not a number) to indicate that each value hasn't been assigned yet. The arguments to the nan function indicate the size of the NaN array you wish to create:
my_glob_var = nan(200, 200)
There are other similar functions in case you wish to initialise arrays of zeros, ones, Inf etc.
Then inside the functions you want to use it in, declare it as global again:
function my_function
global my_glob_var % allows this function to use the global variable
my_glob_var % outputs the variable to command
As an aside, you note that you will "initialise it to some value later using a for-loop". Depending on how you are initialising the array, there may be a vectorised way to achieve this (i.e. without using a for-loop). Vectorised operations are usually much quicker in MATLAB.