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

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.

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).

matlab GPU computation

I am learning matlab GPU functions. My function myfun takes 2 input parameters delta, p. Eventually, I will apply myfun to many combinations of delta,p. For each combination of delta,p, 'myfun' will how many V's satisfies the condition delta*V-p>0, where V = [0:0.001:1]. Ideally, I want V to be a global variable. But it seems that matlab GPU has some restrictions on global variable. So I use another way to do this thing. The code is as the following:
function result = gpueg2()
dd = 0.1;
DELTA = [dd:dd:1];
dp = 0.001;
P = [0:dp:1];
[p,delta]=meshgrid(P,DELTA);
p = gpuArray(p(:));
delta = gpuArray(delta(:));
V = [0:0.001:1];
function [O] = myfun(delta,p)
O = sum((delta*V-p)>0);
end
result = arrayfun(#myfun,delta,p);
end
However, it through an error message
Function passed as first input argument contains unsupported or unknown function 'sum'.
But I believe sum is applicable in GPU.
Any advice and suggestions are highly appreciated.
The problem with sum is not with the GPU, it's with using arrayfun on a GPU. The list of functions that arrayfun on a GPU accepts is given here: https://www.mathworks.com/help/distcomp/run-element-wise-matlab-code-on-a-gpu.html. sum is not on the list on that page of documentation.
Your vectors are not so big (though I accept this may be a toy example of your real problem). I suggest the following alternative implementation:
function result = gpueg2()
dd = 0.1;
DELTA = dd:dd:1;
dp = 0.001;
P = 0:dp:1;
V = 0:0.001:1;
[p,delta,v] = meshgrid(P,DELTA,V);
p = gpuArray(p);
delta = gpuArray(delta);
v = gpuArray(v);
result = sum(delta.*v-p>0, 3);
end
Note the following differences:
I make 3D arrays of p,delta,v, rather than 2D. These three are only 24MB in total.
I do the calculation delta.*v-p>0 on the whole 3D array: this will be well split on the GPU.
I do the sum on the 3rd index, i.e. over V.
I have checked that your routine on the CPU and mine on the GPU give the same results.

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)

Define multiple variables at the same time in 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.

How do I make a function from a symbolic expression in MATLAB?

How can I make a function from a symbolic expression? For example, I have the following:
syms beta
n1,n2,m,aa= Constants
u = sqrt(n2-beta^2);
w = sqrt(beta^2-n1);
a = tan(u)/w+tanh(w)/u;
b = tanh(u)/w;
f = (a+b)*cos(aa*u+m*pi)+a-b*sin(aa*u+m*pi); %# The main expression
If I want to use f in a special program to find its zeroes, how can I convert f to a function? Or, what should I do to find the zeroes of f and such nested expressions?
You have a couple of options...
Option #1: Automatically generate a function
If you have version 4.9 (R2007b+) or later of the Symbolic Toolbox you can convert a symbolic expression to an anonymous function or a function M-file using the matlabFunction function. An example from the documentation:
>> syms x y
>> r = sqrt(x^2 + y^2);
>> ht = matlabFunction(sin(r)/r)
ht =
#(x,y)sin(sqrt(x.^2+y.^2)).*1./sqrt(x.^2+y.^2)
Option #2: Generate a function by hand
Since you've already written a set of symbolic equations, you can simply cut and paste part of that code into a function. Here's what your above example would look like:
function output = f(beta,n1,n2,m,aa)
u = sqrt(n2-beta.^2);
w = sqrt(beta.^2-n1);
a = tan(u)./w+tanh(w)./u;
b = tanh(u)./w;
output = (a+b).*cos(aa.*u+m.*pi)+(a-b).*sin(aa.*u+m.*pi);
end
When calling this function f you have to input the values of beta and the 4 constants and it will return the result of evaluating your main expression.
NOTE: Since you also mentioned wanting to find zeroes of f, you could try using the SOLVE function on your symbolic equation:
zeroValues = solve(f,'beta');
Someone has tagged this question with Matlab so I'll assume that you are concerned with solving the equation with Matlab. If you have a copy of the Matlab Symbolic toolbox you should be able to solve it directly as a previous respondent has suggested.
If not, then I suggest you write a Matlab m-file to evaluate your function f(). The pseudo-code you're already written will translate almost directly into lines of Matlab. As I read it your function f() is a function only of the variable beta since you indicate that n1,n2,m and a are all constants. I suggest that you plot the values of f(beta) for a range of values. The graph will indicate where the 0s of the function are and you can easily code up a bisection or similar algorithm to give you their values to your desired degree of accuracy.
If you broad intention is to have numeric values of certain symbolic expressions you have, for example, you have a larger program that generates symbolic expressions and you want to use these expression for numeric purposes, you can simply evaluate them using 'eval'. If their parameters have numeric values in the workspace, just use eval on your expression. For example,
syms beta
%n1,n2,m,aa= Constants
% values to exemplify
n1 = 1; n2 = 3; m = 1; aa = 5;
u = sqrt(n2-beta^2);
w = sqrt(beta^2-n1);
a = tan(u)/w+tanh(w)/u;
b = tanh(u)/w;
f = (a+b)*cos(aa*u+m*pi)+a-b*sin(aa*u+m*pi); %# The main expression
If beta has a value
beta = 1.5;
eval(beta)
This will calculate the value of f for a particular beta. Using it as a function. This solution will suit you in the scenario of using automatically generated symbolic expressions and will be interesting for fast testing with them. If you are writing a program to find zeros, it will be enough using eval(f) when you have to evaluate the function. When using a Matlab function to find zeros using anonymous function will be better, but you can also wrap the eval(f) inside a m-file.
If you're interested with just the answer for this specific equation, Try Wolfram Alpha, which will give you answers like:
alt text http://www4c.wolframalpha.com/Calculate/MSP/MSP642199013hbefb463a9000051gi6f4heeebfa7f?MSPStoreType=image/gif&s=15
If you want to solve this type of equation programatically, you probably need to use some software packages for symbolic algebra, like SymPy for python.
quoting the official documentation:
>>> from sympy import I, solve
>>> from sympy.abc import x, y
Solve a polynomial equation:
>>> solve(x**4-1, x)
[1, -1, -I, I]
Solve a linear system:
>>> solve((x+5*y-2, -3*x+6*y-15), x, y)
{x: -3, y: 1}