How can I calculate the mean and median of a Gaussian Mixture Model with three components like the following parameters in MATLAB:
Priors[0.4,0.25,0.34]
Centers [0.44;0.74;0.05]
Co-variance [0.03,0.18,0.03]
Thanks
Here is the MATLAB code for calculating mean and median of a Gaussian Mixture Model (GMM):
Mean Calculation for N GMMs:
for i = 1:N
mu = center{i};
p = prior{i};
mean_mix(i) = mu(1)*p(1) + mu(2)*p(2) + mu(3)*p(3);
end
Median Calculation for N GMMs:
median = zeros(N,1);
for i = 1:N
for j = 2:N
if (fix(trapz(x(1:j), gmm_pdfs(1:j,i))*100) == 50);
median(i) = x(j);
end
end
end
Note: gmm_pdfs are the evaluated pdfs against x.
Related
Suppose that I have created a colored noise vector in MATLAB as follows:
Ts = 0.01;
tMax = 10;
t = 0:Ts:tMax;
WhiteNoise_VAR1 = randn(size(t));
c1 = 0.6;
for j=2:numel(t)
E(j) = 1/(2*j+1); % Noise Variance
kessi(j) = sqrt(E(j))*WhiteNoise_VAR1(j) + ...
c1*sqrt(E(j))*WhiteNoise_VAR1(j-1); % Colored Noise Generation
end
what I want to do is calculate the Covariance matrix of the kessi vector defined in the code. In other words, I want to calculate the following formula, which is the colored noise covariance matrix:
E{kessi*transposed(kessi)}
In which E is the expected value operator. How can I do this in MATLAB?
I'm having problems in curve fitting my randomized data for the function
Here is my code
N = 100;
mu = 5; stdev = 2;
x = mu+stdev*randn(N,1);
bin=mu-6*stdev:0.5:mu+6*stdev;
f=hist(x,bin);
plot(bin,f,'bo'); hold on;
x_ = x(1):0.1:x(end);
y_ = (1./sqrt(8.*pi)).*exp(-((x_-mu).^2)./8);
plot(x_,y_,'b-'); hold on;
It seems like I'm having vector size problems since it is giving me the error
Error using plot
Vectors must be the same length.
Note that I simplified y_ since mu and the standard deviation is known.
Plot:
Well first of all some adjustments to your question:
You are not trying to do curve fitting. What you are trying to do (in my opinion) is to overlay a probability density function on an histogram obtained by taking random points from the same distribution (A normal distribution with parameters (mu,sigma)). These two curve should indeed overlay, as they represent the same thing, only one is analytical and the other one is obtained numerically.
As seen in the hist documentation, hist is not recommended and you should use histogram instead
First step: Generating your random data
Knowing the distribution is the Normal distribution, we can use MATLAB's random function to do that :
N = 150;
rng('default') % For reproducibility
mu = 5;
sigma = 2;
r = random('Normal',mu,sigma,N,1);
Second step: Plot the histogram
Because we don't just want a count of the elements in each bin, but a feel of the probability density function, we can use the 'Normalization' 'pdf' arguments
Nbins = 25;
f=histogram(r,Nbins,'Normalization','pdf');
hold on
Here I'd rather specify a number of bins than specifying the bins themselves, because you never know in advance how far from the mean your data is going to be.
Last step: overlay the probability density function over the histogram
The histogram being already consistent with a probability density function, it is sufficient to just overlay the density function:
x_ = linspace(min(r),max(r),100);
y_ = (1./sqrt(2*sigma^2*pi)).*exp(-((x_-mu).^2)./(2*sigma^2));
plot(x_,y_,'b-');
With N = 150
With N = 1500
With N = 150.000 and Nbins = 50
If for some obscure reason you want to use old hist() function
The old hist() function can't handle normalization, so you'll have to do it by hand, by normalizing your density function to fit your histogram:
N = 1500;
% rng('default') % For reproducibility
mu = 5;
sigma = 2;
r = random('Normal',mu,sigma,1,N);
Nbins = 50;
[~,centers]=hist(r,Nbins);
hist(r,Nbins); hold on
% Width of bins
Widths = diff(centers);
x_ = linspace(min(r),max(r),100);
y_ = N*mean(Widths)*(1./sqrt(2*sigma^2*pi)).*exp(-((x_-mu).^2)./(2*sigma^2));
plot(x_,y_,'r-');
I have a function that performs the HodgesLehmann robust mean over a vector x[m,n]. n is the batch index of data, m is the number of samples.
function HLe = HodgesLehmann(x)
% Obtain dimensions
[m,n] = size(x);
% Create xi and xj values with the i <= j restriction enforced
q = logical(triu(ones(m,m),0));
i = uint32((1:m)'*ones(1,m));
xi = x(i(q),:);
j = uint32(ones(m,1)*(1:m));
xj = x(j(q),:);
% Calculate pairwise means (Walsh averages)
W = (xi+xj)./2;
% Calculate ordinary median of Walsh averages
HLe = median(W);
I am looking for a way to accelerate this function, it does not scale well for large dimensions of x. Any way of accelerating this is also welcome.
Many thanks.
Inspired by this solution, here's a possible (not tested for performance) improvement -
%// Calculate pairwise means (Walsh averages)
[I,J] = find(bsxfun(#le,[1:m]',[1:m])); %//'
W = (x(J,:) + x(I,:))./2;
%// Calculate ordinary median of Walsh averages
HLe = median(W);
Given a system of the form y' = A*y(t) with solution y(t) = e^(tA)*y(0), where e^A is the matrix exponential (i.e. sum from n=0 to infinity of A^n/n!), how would I use matlab to compute the solution given the values of matrix A and the initial values for y?
That is, given A = [-2.1, 1.6; -3.1, 2.6], y(0) = [1;2], how would I solve for y(t) = [y1; y2] on t = [0:5] in matlab?
I try to use something like
t = 0:5
[y1; y2] = expm(A.*t).*[1;2]
and I'm finding errors in computing the multiplication due to dimensions not agreeing.
Please note that matrix exponential is defined for square matrices. Your attempt to multiply the attenuation coefs with the time vector doesn't give you what you'd want (which should be a 3D matrix that should be exponentiated slice by slice).
One of the simple ways would be this:
A = [-2.1, 1.6; -3.1, 2.6];
t = 0:5;
n = numel(t); %'number of samples'
y = NaN(2, n);
y(:,1) = [1;2];
for k =2:n
y(:,k) = expm(t(k)*A) * y(:,1);
end;
figure();
plot(t, y(1,:), t, y(2,:));
Please note that in MATLAB array are indexed from 1.
Is there a toolbox or available MATLAB function that will allow me to solve the following approximation of stochastic integrals, where z is a Wiener process:
%Lets say n is 100 and dt is 1/252 and k = .1
n = 100;
dt = 1/252;
k = 0.1;
dz = randn(n,1); %get random increments: normal
%dz = 2*(randi(2,n,1)-1.5); % or plus/minus ones : bernoulli
fnt = exp(-k*(n*dt - [0:n-1]*dt))*sqrt(dt)*dz;