Matrix as a 2D probability distribution: get the central moments - matlab

I have got a matrix which gives me a 2-dimensional discrete distribution (N²->R) in Matlab.
Are there built-in functions in Matlab (R2011b, with the statistic toolbox) giving the central moments and the mean? If they exist for functions of (R²->R) it is fine too. Otherwise I will have to build them myself, but I don't want to reinvent the wheel.
Thank you

A quick look and I couldn't turn up any functions, though this isn't a fact by any means.
However, working it out from scratch, and assuming you mean a matrix such as:
% x=1 x=2 x=3
P = [ 0.1 0.2 0.1 % y = 1
0.1 0.1 0.2 % y = 2
0.0 0.0 0.2 ] % y = 3
And you mean that this describes the joint discrete distribution (joint probability mass function). That is, the entry at (X,Y) contains the probability of (X,Y) occurring.
I'm also assuming by your use of N in mathematical notation means the natural numbers. If so, then you can use the following code.
Mean:
meanX = sum(P,1) * (1:size(P,2))';
meanY = sum(P,2)' * (1:size(P,1))';
For the central moment K,L (K correspnding to X and L corresponding to Y):
[X,Y] = meshgrid(1:size(P,2),1:size(P,1));
integrandXY_KL = (X - meanX).^K .* (Y-meanY).^L .* P;
momentXY_KL = sum(integrandXY_KL(:));
And you can generalize it further if the values of X are arbitrary (and not just natural numbers) as follows. If Xvals = [ 1 2 4 ] and Yvals = [ 4 5 6 ]. All of the above still works, you just replace all occurences of 1:size(P,2) with Xvals and all occurences of 1:size(P,1) with Yvals.

Related

How can I code a contour integral representation of cosine?

I am pretty new to MATLAB computation and would appreciate any help on this. Firstly, I am trying to integrate a cosine function using the McLaurin expansion [cos(z) = 1 − (z^2)/2 + (z^4)/4 + ....] and lets say plotted over one cycle from 0 to 2π. This first integral (as seen in Figure 1) would serve as a "reference" or "contour" for what I want to do next.
Figure 1 - "The first integral representation"
Now, my next problem comes from writing in MATLAB cos(z) in
terms of an integral in the complex plane.
Figure 2 - "showing cos(z) as an integral in the complex plane"
Where I could choose an equi-sampled set of points 'sn' along the contour, from 'sL' to 'sU'
and separated by '∆s'. This is Euler’s method.
I am trying to write a code to numerically approximate the integral
along a suitable contour and plot the approximation against the
exact value of cos(z). I would like to do this twice - once for
z ∈ [0, 6π] and once for complex valued z in the range
z ∈ [0 + i, 6π + ]. Then to plot both the real and imaginary part of the
computed cos(z)
I am aware of the steps I am looking to implement which I'll bullet-point here.
Choose γ, SL, SU , N.
Step through z from z lower to z upper (use a different
number of steps (other than N) for this).
For each value of z compute cos z by stepping along the contour in
N discrete steps from SL to SU .
For each value of sn along the contour compute the integrand e^(sn-(z^2/4sn))/sqrt(sn) and add it to the rolling sum [I have attached figure 3 showing an image formula of the integrand if its not clear!] Figure 3 - "The exponential integrand I am looking to compute"
Now I will show what I have attempted in MATLAB!
% "Contour Integral Representation of Cosine"
% making 'z' a possible number such as pi
N = 10000000; % example number - meaning sample of steps
z_lower = 0;
z_upper = 6*pi;
%==========================%
z1 = linspace(z_lower,z_upper,N);
y = 1;
Sl = y - 10*1i;
sum = 0.0;
%==========================%
for z = linspace(z_lower,z_upper,N)
for Sn = linspace(Sl,Su,N)
sum = sum + ((exp(Sn) - (z.^2/4*Sn))/sqrt(Sn))*ds;
end
end
sum = sum*(sqrt(pi)/2*pi*1i);
plot(Sn,sum)
Edit1: Hiya, this figure will show what I am expecting - the numerical method to be not exactly the same as the "symbolic" integration lets say. In figure 4, the black cosine wave is the same as in figure 1 and the blue is the numerical integration method.Figure 4 - "End Result of what I expect to plot

Using tf() function in MATLAB

I'm trying to input this transfer function in matlab, but I can't figure out how because it has both positive and negative exponents.
If I do H = tf([1],[1 1 1 1],0.1,'variable','z^-1') I almost get it, but I can't figure out how to add the positive z to the bottom. I'm trying to use this H to plot the poles and zeros with pzmap(H).
To avoid negative exponents, we can multiply both the denominator and the numerator by z^3:
H = tf([1 0 0 0 0],[1 1 1 1 1],0.1,'variable','z')
Or divide its by z
H = tf([1],[1 1 1 1 1],0.1,'variable','z^-1')
You can create
z = tf('z', 0.1)
and then create any transfer function you want, e.g.
H = z / (1 + z + z^-1 + z^-2 + z^-3)
However, Matlab automatically adds additional pole-zero pairs at z=0, to make the transfer function H contain only z and no z^-1. Therefore, you will see multiple poles at z=0 instead of only one. Unfortunately I haven't found a solution to stop Matlab from doing that...
What you refer to as a transfer function is actually called DSP representation due to their implementation properties. In that every power of z is a unit delay. Hence, you have to use the filt. In this representation z terms should have nonpositive powers hence if you factor out one z from the denominator and cancel out you get
H = filt(1,[1,1,1,1,1])

Linear regression in MATLAB [duplicate]

This question already has an answer here:
How do I determine the coefficients for a linear regression line in MATLAB? [closed]
(1 answer)
Closed 7 years ago.
How could I make a linear regression with several value equals on x with MATLAB?
Now, an example with minimal data (not the data I use) :
y = [1,2,3,4,5,6,7,8,9,10];
x = [2,2,2,4,4,6,6,6,10,10];
If I use polyfit or \:
x = temp(:,1); y = temp(:,2);
b1 = x\y;
yCalc1 = b1*x;
plot(x,yCalc1,'-r');
Then the linear regression is wrong because (I suppose) he didn't notice that several values have got the same (x).
Here, a graph with my real data. Blue dots: my data. Red line : the linear regression (it's wrong). Don't focus to green dash line:
And here, the "same" graph (done with Excel):
Blue dots: my data. Red line : the linear regression (it's right)
Du you think that if I do a mean for each yvalues with the same x, it's mathematicaly right ?
If you intended to solve simple linear regression with matrix form Y= XB and the operator \, you need to add an additional column of ones in your X for calculating the intercepts.
y0 = [1,2,3,4,5,6,7,8,9,10];
x0 = [2,2,2,4,4,6,6,6,10,10];
X1 = [ones(length(x0),1) x0'];
b = X1\y0';
y = b(1) + x0*b(2)
plot(x0,y0,'o')
hold on
plot(x0,y,'--r')
You can find a good Matlab example here
So, Dan suggests me a function and it's working now.
If you want to do the same thing, just do like that :
use the fitlm function (http://fr.mathworks.com/help/stats/fitlm.html?refresh=true#bunfd6c-2)
Example datas :
y = [1,2,3,4,5,6,7,8,9,10];
x = [2,2,2,4,4,6,6,6,10,10];
tbl = table(x,y)
lm = fitlm(tbl,'linear')
and you will have different values.
A linear regression is an equation as y = ax + b. Here, on result, a correspond to x (bellow equal to 0.15663) and b correspond to (Intercept) (bellow equal to 1.4377).
With other values, Matlab will show you this result :
Linear regression model:
y ~ 1 + x
Estimated Coefficients:
Estimate SE tStat pValue
________ _________ ______ ___________
(Intercept) 1.4377 0.031151 46.151 5.8802e-290
x 0.15663 0.0054355 28.816 1.2346e-145
Number of observations: 1499, Error degrees of freedom: 1497
Root Mean Squared Error: 0.135
R-squared: 0.357, Adjusted R-Squared 0.356
F-statistic vs. constant model: 830, p-value = 1.23e-145
Thank's to Dan again !

Is there an optimized vectorized function of the rectified linear function max(0,x) in MATLAB?

I was trying to get an vector optimized version of the linear rectifier. i.e. y = max(0,x). So what it should compute its element wise max of zero and x_i. I obviously implemented:
function [ y ] = rectSig( x )
%rectSig computes vector-wise rectified linear function
% computes y = [..., max(0,x_i), ...]
n=length(x);
y = zeros(1,n);
for i=1:1:length(x);
y(i) = max(0,x(i));
end
end
however, I know that looping like this in MATLAB is ill advised. So I was wondering if there was a better way to do this or if obviously matlab had its own implementation of a vectorized version of such a function? I always try to avoid loops if I can in matlab if there is a way to vectorize my code. It usually tends to speed things up.
Btw, I obviously tried googling it but didn't really get the result I expected...
The solution is as simple as
y = max(x,0);
This works for x being a column, row vector, matrix, higher dimensional matrix, etc. On the other hand
y = max(zeros(1,length(x)),x);
only works for x being a row vector. It fails when x is a column vector or matrix.
max accepts matrix inputs:
x = -5:5;
comparisonvector = zeros(size(x));
y = max(comparisonvector, x);
Returns:
y =
0 0 0 0 0 0 1 2 3 4 5

conditional generation of random numbers using matlab

I have a function that generates normal random number matrix having normal distribution using normrnd.
values(vvvv)= normrnd(0,0.2);
The output is from round1 is:
ans =
0.0210 0.1445 0.5171 -0.1334 0.0375 -0.0165 Inf -0.3866 -0.0878 -0.3589
The output from round 2 is:
ans =
0.0667 0.0783 0.0903 -0.0261 0.0367 -0.0952 0.1724 -0.2723 Inf Inf
The output from round 3 is:
ans =
0.4047 -0.4517 0.4459 0.0675 0.2000 -0.3328 -0.1180 -0.0556 0.0845 Inf
the function will be repeated 20 times.
It is obvious that the function is completely random. What I seek is to add a condition.
What I need is: if any entry has a value between 0.2 and 0.3. that value will be fixed in the next rounds. Only the remaining entries will be subjected to change using the function rand.
I have found the rng(sd) which seeds the random number generator using the nonnegative integer sd so that rand, randi, and randn produce a predictable sequence of numbers.
How to set custom seed for pseudo-random number generator
but how to make several entries of the matrix only effected!!
Another problem: seems that rng is not available for matlab r2009
How to get something similar without entering in the complication of probability & statistics
You can do this more directly than actually generating all these matrices, and it's pretty easy to do so, by thinking about the distribution of the final output.
The probability of a random variable distributed by N(0, .2) lying between .2 and .3 is p ~= .092.
Call the random variable of the final output of your matrix X, where you do this n (20) times. Then either (a) X lies between .2 and .3 and you stopped early, or (b) you didn't draw a number between .2 and .3 in the first n-1 draws and so you went with whatever you got on the nth draw.
The probability of (b) happening is just b=(1-p)^(n-1): the independent events of drawing outside [.2, .3], which have probability 1-p, happend n-1 times. Therefore the probability of (a) is 1-b.
If (b) happened, you just draw a number from normrnd. If (a) happened, you need the value of a normal variable, conditional on its being between .2 and .3. One way to do this is to find the cdf values for .2 and .3, draw uniformly from the range between there, and then use the inverse cdf to get back the original number.
Code that does this:
mu = 0;
sigma = .2;
upper = .3;
lower = .2;
n = 20;
sz = 15;
cdf_upper = normcdf(upper, mu, sigma);
cdf_lower = normcdf(lower, mu, sigma);
p = cdf_upper - cdf_lower;
b = (1-p) ^ (n - 1);
results = zeros(sz, sz);
mask = rand(sz, sz) > b; % mask value 1 means case (a), 0 means case (b)
num_a = sum(mask(:));
cdf_vals = rand(num_a, 1) * p + cdf_lower;
results(mask) = norminv(cdf_vals, mu, sigma);
results(~mask) = normrnd(mu, sigma, sz^2 - num_a, 1);
If you want to simulate this directly for some reason (which is going to involve a lot of wasted effort, but apparently you don't like "the complications of statistics" -- by the way, this is probability, not statistics), you can generate the first matrix and then replace only the elements that don't fall in your desired range. For example:
mu = 0;
sigma = .2;
n = 10;
m = 10;
num_runs = 20;
lower = .2;
upper = .3;
result = normrnd(mu, sigma, n, m);
for i = 1 : (num_runs - 1)
to_replace = (result < lower) | (result > upper);
result(to_replace) = normrnd(mu, sigma, sum(to_replace(:)), 1);
end
To demonstrate that these are the same, here's a plots of the empirical CDFs of doing this for 1x1 matrices 100,000 times. (That is, I ran both functions 100k times and saved the results, then used cdfplot to plot values on the x axis vs portion of the obtained values that are less than that on the y axis.)
They're identical. (Indeed, a K-S test for identity of distribution gives a p-value of .71.) But the direct way was a bunch faster to run.