Define multiple variables at the same time in MATLAB? - matlab

I don't know if MATLAB can do this, and I want it purely for aesthetics in my code, but can MATLAB create two variables at the same time?
Example
x = cell(4,8);
y = cell(4,8);
Is there a way to write the code something similar to:
x&y = cell(4,8);

Use comma-separated lists to get multiple variables in the left hand side of an expression.
You can use deal() to put multiple assignments one line.
[x,y] = deal(cell(4,8), cell(4,8));
Call it with a single input and all the outputs get the same value.
[x,y] = deal( cell(4,8) );
>> [a,b,c] = deal( 42 )
a =
42
b =
42
c =
42

It depends on the function that you use to generate the data. You can create your own function in MATLAB that has more than one output:
[a, b, c] = foo();
Many builtin function also have this option. But this must be supported directly by the returning function.

Related

Summation of N function handles in MATLAB

I have N functions in MATLAB and I can define them using strcat, num2str and eval in a for loop. So without defining by hand I am able to define N functions. Let N=4 and let them be given as follows:
f1=#(x) a1*x+1;
f2=#(x) a2*x+1;
f3=#(x) a3*x+1;
f4=#(x) a4*x+1;
Now I add these four functions and I can do this by hand as follows:
f=#(x)(f1(x)+f2(x)+f3(x)+f4(x));
Here I can do it by hand because I know that N=4. However, in general I never know how many functions I will have. For all cases I cannot write a new function.
Is there any way to do this automatically? I mean if I give N=6 I am expecting to see MATLAB giving me this:
f=#(x)(f1(x)+f2(x)+f3(x)+f4(x)+f5(x)+f6(x));
Whenever I give N=2 then I must have the function f, defined as follows:
f=#(x)(f1(x)+f2(x));
How can we do this?
First of all, you should read this answer that gives a series of reasons to avoid the use of eval. There are very few occasions where eval is necessary, in all other cases it just complicates things. In this case, you use to dynamically generate variable names, which is considered a very bad practice. As detailed in the linked answer and in further writings linked in that answer, dynamic variable names make the code harder to read, harder to maintain, and slower to execute in MATLAB.
So, instead of defining functions f1, f2, f3, ... fN, what you do is define functions f{1}, f{2}, f{3}, ... f{N}. That is, f is a cell array where each element is an anonymous function (or any other function handle).
For example, instead of
f1=#(x) a1*x+1;
f2=#(x) a2*x+1;
f3=#(x) a3*x+1;
f4=#(x) a4*x+1;
you do
N = 4;
a = [4.5, 3.4, 7.1, 2.1];
f = cell(N,1);
for ii=1:N
f{ii} = #(x) a(ii) * x + 1;
end
With these changes, we can easily answer the question. We can now write a function that outputs the sum of the functions in f:
function y = sum_of_functions(f,x)
y = 0;
for ii=1:numel(f)
y = y + f{ii}(x);
end
end
You can put this in a file called sum_of_functions.m, or you can put it at the end of your function file or script file, it doesn't matter. Now, in your code, when you want to evaluate y = f1(x) + f2(x) + f3(x)..., what you write is y = sum_of_functions(f,x).

Using MATLAB's chi2gof with non-standard user-specified PDFs

I would like to use MATLAB's chi2gof to perform a chi-square goodness-of-fit test. My problem is that my assumed (i.e., theoretical) distribution is not one of the standard built-in probability distributions in MATLAB. The specific form of my desired distribution is:
p = x^a*exp(-b*x^2)
where a and b are constants. There must be a way to use chi2gof for arbitrary PDFs? I have done an exhaustive Google search, but have come up empty-handed.
You can specify a handle to a function that takes a single argument to chi2gof this way:
a = ...
b = ...
c = ...
F = #(x)a*exp(-b*x-c*x.^2); % Technically this is an anonymous function
[H,P,STATS] = chi2gof(data,'cdf',F)
Or in special cases:
a = ...
b = ...
c = ...
F = #(x,a,b,c)a*exp(-b*x-c*x.^2);
[H,P,STATS] = chi2gof(data,'cdf',{F,a,b,c})
the last line of which is equivalent to
[H,P,STATS] = chi2gof(data,'cdf',#(x)F(x,a,b,c))
If the parameters a, b, and c are estimated (e.g., using some fitting process), then you should specify the number of estimated parameters to chi2gof. In this case:
[H,P, STATS] = chi2gof(data,'cdf',F,'nparams',3)
Please read the documentation to learn about the other options.

Optimization with Matlab

A common way to write the objective function in matlab (including the gradient vector) is the following:
[L,G] = objfun(x)
where L is the value of objective function, G is the gradient vector and x is a vector of coefficients which I want to optimize.
However, when I include another input (i.e [L,G]=objfun(x,M), where M is a matrix) or when I call another function in the function objfun, the code is not running.
How can I include any inputs and call any functions in the objfun by keeping this format of optimization?
Note that I call the optimization as follows:
[x ,fval] = fminunc(#objfun,x,options)
where
options = optimoptions(#fminunc,'Algorithm','quasinewton',...
'Display','iter','Gradobj','on','TolFun',10^-8)
There's an mathworks help article on passing extra parameters to the objective function:
You can use the #(...) operator to generate an anonymous function handle to your function that will only depend on a single parameter.
a = 4; b = 2.1; c = 4;
f = #(x)objfun(x,a,b,c)
From the original page (where your objfun is parameterfun):
Note: The parameters passed in the anonymous function are those that exist at the time the anonymous function is created. Consider the
example
a = 4; b = 2.1; c = 4;
f = #(x)parameterfun(x,a,b,c)
Suppose you subsequently change, a to 3 and run
[x,fval] = fminunc(f,x0)
You get the same answer as before, since parameterfun uses a = 4, the
value when f was created.
To change the parameters that are passed to the function, renew the
anonymous function by reentering it:
a = 3;
f = #(x)parameterfun(x,a,b,c)

Matlab Defining A Function That Has Vector As An Input

I was given a simple exercise by my professor, which is to define a cerrtain function. Here is my function
function [a,b,c] = PHUN([x,y],[z,t,w])
a = x
b = ((y+z)^2)*t
c = z/w + x
However, matlab states that I am using invalid syntax in the first line. So, I figured, perhaps there is a particular way in which vector inputs are supposed to be typed. I have attempt several searches on defining functions with vector inputs (or arguments), but have not been successful. I was wondering if someone could possibly help me.
You can pass vectors as arguments in the same way you pass variables. Then access them in the function body appropriately. Your function could be re-written as follows:
function [a,b,c] = PHUN(X,Y)
a = X(1)
b = ((X(2)+Y(1))^2)*Y(2)
c = Y(1)/Y(3) + X(1)
Or if you want to keep the original variables:
function [a,b,c] = PHUN(X,Y)
Z = num2cell([X,Y]);
[x,y,z,t,w] = Z{:};
a = x
b = ((y+z)^2)*t
c = z/w + x

Merging function handles in MATLAB

I'm currently coding a simulation in MATLAB and need some help in regards to an issue that I've been having.
I'm working on a problem where I have n separate anonymous function handles fi stored in cell array, each of which accepts a 1×1 numeric array xi and returns a 1×1 numeric array yi.
I'm trying to combine each of these anonymous function handles into a single anonymous function handle that accepts a single n×1 numeric array X and returns a single n×1 numeric array Y, where the i-th elements of X and Y are xi and yi = fi (xi), respectively.
As an example, let n = 2 and f_1, f_2 be two function handles that input and output 1×1 arrays and are stored in a cell array named functions:
f_1 = #(x_1) x_1^2
f_2 = #(x_2) x_2^3
functions = {f_1, f_2}
In this example, I basically need to be able to use f_1 and f_2 to construct a function handle F that inputs and outputs a 2×1 numeric array, like so:
F = #(x) [f_1(x(1,1)); f_2(x(2,1))]
The question is how to generalize this for an arbitrary number n of such functions.
It is difficult to define such a function using the inline #()-anonymous
syntax (because of the requirement for the function’s body to be
an expression).
However, it is possible to define a regular function that runs over
the items of a given vector and applies the functions from a given
cell array to those items:
function y = apply_funcs(f, x)
assert(length(f) == length(x));
y = x;
for i = 1 : length(f)
y(i) = feval(f{i}, x(i));
end
end
If it is necessary to pass this function as an argument to another
one, just reference it by taking its #-handle:
F = #apply_funcs
This can be solved using a solution I provided to a similar previous question, although there will be some differences regarding how you format the input arguments. You can achieve what you want using the functions CELLFUN and FEVAL to evaluate your anonymous functions in one line, and the function NUM2CELL to convert your input vector to a cell array to be used by CELLFUN:
f_1 = #(x_1) x_1^2; %# First anonymous function
f_2 = #(x_2) x_2^3; %# Second anonymous function
fcnArray = {f_1; f_2}; %# Cell array of function handles
F = #(x) cellfun(#feval,fcnArray(:),num2cell(x(:)));
Note that I used the name fcnArray for the cell array of function handles, since the name functions is already used for the built-in function FUNCTIONS. The colon operator (:) is used to turn fcnArray and the input argument x into column vectors if they aren't already. This ensures that the output is a column vector.
And here are a few test cases:
>> F([2;2])
ans =
4
8
>> F([1;3])
ans =
1
27
#you can try
f=#(x)[x(1)^2;x(2)^3]
>>f([1,2])
ans =
1
8
>>f([2,3])
ans =
4
27