Why is MATLAB calculation of standard deviation different than a hand calculation? - matlab

Matlab:
>> std( [3 2 2 3] )
ans =
0.5774
Layman's interpretation of standard deviation per Google:
Mean of {3,2,2,3} = 2.5
Deviation from mean for each value = {0.5, 0.5, 0.5, 0.5}
Square of deviation from mean = {0.25, 0.25, 0.25, 0.25}
Mean of the squares = 0.25
Square root of 0.25 = 0.5
Therefore Standard Deviation of {3,2,2,3} = 0.5
What did I muck up? I was foolishly expecting those two numbers to agree.

Matlab std computes the corrected standard deviation. From help std:
std normalizes Y by (N-1), where N is the sample size. This is the
sqrt of an unbiased estimator of the variance of the population from
which X is drawn, as long as X consists of independent, identically
distributed samples.
So you have
Square of deviation from mean = {0.25, 0.25, 0.25, 0.25}
Then you don't compute the actual root mean of the deviations, but sqrt(sum([0.25 0.25 0.25 0.25])/3). Generally, sum(square of deviation)/(N-1) for a vector of length N.
Update: as Leonid Beschastny pointed out, you can get matlab to calculate the uncorrected standard deviation. Again, from help std:
Y = std(X,1) normalizes by N and produces the square root of the second
moment of the sample about its mean. std(X,0) is the same as std(X).

Related

Trying to find the full width at half maximum for a noisy signal

I am currently looking to find the FWHM of a signal.
The peak of the signal is around 1.0 but the lowest value is only around 0.6.
So, in fact, I don't have a half maximum value.
How could I proceed to analyze the curve in a similar fashion?
Here is an image of the curve:
Assuming that min and max of the signal y is 0.6 and 1 respectively you can find FWHM:
idx1 and idx2 each return indexes of two points before and after the desired point at half. We can use these points to interpolate value of x at the half of y.
%height at half
h=(0.6+1)/2;
idx1=find(y>h,1) +[-1 0];
idx2=find(y>h,1,'last') +[0 1];
x1 = interp1(y(idx1),x(idx1),h);
x2 = interp1(y(idx2),x(idx2),h);
w = x2 - x1;

How to calculate normalized euclidean distance on two vectors?

Let's say I have the following two vectors:
x = [(10-1).*rand(7,1) + 1; randi(10,1,1)];
y = [(10-1).*rand(7,1) + 1; randi(10,1,1)];
The first seven elements are continuous values in the range [1,10]. The last element is an integer in the range [1,10].
Now I would like to compute the euclidean distance between x and y. I think the integer element is a problem because all other elements can get very close but the integer element has always spacings of ones. So there is a bias towards the integer element.
How can I calculate something like a normalized euclidean distance on it?
According to Wolfram Alpha, and the following answer from cross validated, the normalized Eucledean distance is defined by:
You can calculate it with MATLAB by using:
0.5*(std(x-y)^2) / (std(x)^2+std(y)^2)
Alternatively, you can use:
0.5*((norm((x-mean(x))-(y-mean(y)))^2)/(norm(x-mean(x))^2+norm(y-mean(y))^2))
I would rather normalise x and y before calculating the distance and then vanilla Euclidean would suffice.
In your example
x_norm = (x -1) / 9; % normalised x
y_norm = (y -1) / 9; % normalised y
dist = norm(x_norm - y_norm); % Euclidean distance between normalised x, y
However, I am not sure about whether having an integer element contributes to some sort of bias but we have already gotten kind of off-topic for stack overflow :)
From Euclidean Distance - raw, normalized and double‐scaled coefficients
SYSTAT, Primer 5, and SPSS provide Normalization options for the data so as to permit an investigator to compute a distance
coefficient which is essentially “scale free”. Systat 10.2’s
normalised Euclidean distance produces its “normalisation” by dividing
each squared discrepancy between attributes or persons by the total
number of squared discrepancies (or sample size).
Frankly, I can see little point in this standardization – as the final
coefficient still remains scale‐sensitive. That is, it is impossible
to know whether the value indicates high or low dissimilarity from the
coefficient value alone

Not getting what 'spatial weights' for HOG are

I am using HOG for sunflower detection. I understand most of what HOG is doing now, but have some things that I do not understand in the final stages. (I am going through the MATLAB code from Mathworks).
Let us assume we are using the Dalal-Triggs implementation. (That is, 8x8 pixels make 1 cell, 2x2 cells make 1 block, blocks are taken at 50% overlap in both directions, and lastly, that we have quantized the histograms into 9 bins, unsigned. (meaning, from 0 to 180 degrees)). Finally, our image here is 64x128 pixels.
Let us say that we are on the first block. This block has 4 cells. I understand that we are going to weight the orientations of each of the orientations by their magnitude. I also understand that we are going to weight them further, by a gaussian centered on the block.
So far so good.
However in the MATLAB implementation, they have an additional step, whereby they create a 'spatial' weight:
If we dive into this function, it looks like this:
Finally, the function 'computeLowerHistBin' looks like this:
function [x1, b1] = computeLowerHistBin(x, binWidth)
% Bin index
width = single(binWidth);
invWidth = 1./width;
bin = floor(x.*invWidth - 0.5);
% Bin center x1
x1 = width * (bin + 0.5);
% add 2 to get to 1-based indexing
b1 = int32(bin + 2);
end
Now, I believe that those 'spatial' weights are being used during the tri-linear interpolation part later on... but what I do not get is just how exactly they are being computed, or the logic behind that code. I am completely lost on this issue.
Note: I understand the need for the tri-linear interpolation, and (I think) how it works. What I do not understand is why we need those 'spatial weights', and what the logic behind their computation here is.
Thanks.
The idea here is that each pixel contributes not only to its own histogram cell, but also to the neighboring cell to some degree. These contributions are weighed differently, depending on how close the pixel is to the edge of the cell. The closer you are to an edge of your cell, the more you contribute to the corresponding neighboring cell, and the less you contribute to your own cell.
This code is pre-computing the spatial weights for the trilinear interpolation. Take a look at the equation here for trilinear interpolation:
HOG Trilinear Interpolation of Histogram Bins
There you see things like (x-x1)/bx, (y-y1)/by, (1 - (x-x1)/bx), etc. In the code, wx1 and wy1 correspond to:
wx1 = (1 - (x-x1)/bx)
wy1 = (1 - (y-y1)/by)
Here, x1 and y1 are centers of the histogram bins for the X and Y directions. It's easier to describe these things in 1D. So in 1D, a value x will fall between 2 bin centers x1 <= x < x2. It doesn't matter exactly bin (1 or 2) it belongs. The important thing is to figure out the fraction of x that belongs to x1, the rest belongs to x2. Using the distance from x to x1 and dividing by the width of the bin gives a percentage distance. 1 minus that is the fraction that belongs to bin 1. So if x == x1, wx1 is 1. And if x == x2, wx1 is zero because x2 - x1 == bx (the width of a bin).
Going back to the code that creates the 4 matrices is just pre-computing all the multiplications of the weights needed for the interpolation of all the pixels in a HOG block. That is why it is a matrix of weights: each element in the matrix if for one of the pixels in the HOG block.
For example, you look at the equation for the wieghts for h(x1, y2, ~) you'll see these 2 weights for x and y (ignoring the z component).
(1 - (x-x1)/bx) * ((y-y1)/by)
Going back to the code, this multiplication is pre-computed for every pixel in the block using:
weights.x1y2 = (1-wy1)' * wx1;
where
(1-wy1) == (y - y1)/by
The same logic applies to the other weight matrices.
As for the code in "computeLowerHistBin", it's just finding the x1 in the trilinear interpolation equation, where x1 <= x < x2 (same for y1). There are probably a bunch of ways to solve this problem given a pixel location x and the width of a bin bx as long as you satisfy x1 <= x < x2.
For example, "|" indicate bin edges. "o" are the bin centers.
-20 0 20 40
|------o-------|-------o-------|-------o-------|
-10 10 30
if x = [2 9 11], the lower bin center x1 is [-10 -10 10].

"Frequency" shift in discrete FFT in MATLAB

(Disclaimer: I thought about posting this on math.statsexchange, but found similar questions there that were moved to SO, so here I am)
The context:
I'm using fft/ifft to determine probability distributions for sums of random variables.
So e.g. I'm having two uniform probability distributions - in the simplest case two uniform distributions on the interval [0,1].
So to get the probability distribution for the sum of two random variables sampled from these two distributions, one can calculate the product of the fourier-transformed of each probabilty density.
Doing the inverse fft on this product, you get back the probability density for the sum.
An example:
function usumdist_example()
x = linspace(-1, 2, 1e5);
dx = diff(x(1:2));
NFFT = 2^nextpow2(numel(x));
% take two uniform distributions on [0,0.5]
intervals = [0, 0.5;
0, 0.5];
figure();
hold all;
for i=1:size(intervals,1)
% construct the prob. dens. function
P_x = x >= intervals(i,1) & x <= intervals(i,2);
plot(x, P_x);
% for each pdf, get the characteristic function fft(pdf,NFFT)
% and form the product of all char. functions in Y
if i==1
Y = fft(P_x,NFFT) / NFFT;
else
Y = Y .* fft(P_x,NFFT) / NFFT;
end
end
y = ifft(Y, NFFT);
x_plot = x(1) + (0:dx:(NFFT-1)*dx);
plot(x_plot, y / max(y), '.');
end
My issue is, the shape of the resulting prob. dens. function is perfect.
However, the x-axis does not fit to the x I create in the beginning, but is shifted.
In the example, the peak is at 1.5, while it should be 0.5.
The shift changes if I e.g. add a third random variable or if I modify the range of x.
But I can't get figure how.
I'm afraid it might have to do with the fact that I'm having negative x values, while fourier transforms usually work in a time/frequency domain, where frequencies < 0 don't make sense.
I'm aware I could find e.g. the peak and shift it to its proper place, but seems nasty and error prone...
Glad about any ideas!
The problem is that your x origin is -1, not 0. You expect the center of the triangular pdf to be at .5, because that's twice the value of the center of the uniform pdf. However, the correct reasoning is: the center of the uniform pdf is 1.25 above your minimum x, and you get the center of the triangle at 2*1.25 = 2.5 above the minimum x (that is, at 1.5).
In other words: although your original x axis is (-1, 2), the convolution (or the FFT) behave as if it were (0, 3). In fact, the FFT knows nothing about your x axis; it only uses the y samples. Since your uniform is zero for the first samples, that zero interval of width 1 is amplified to twice its width when you do the convolution (or the FFT). I suggest drawing the convolution on paper to see this (draw original signal, reflected signal about y axis, displace the latter and see when both begin to overlap). So you need a correction in the x_plot line to compensate for this increased width of the zero interval: use
x_plot = 2*x(1) + (0:dx:(NFFT-1)*dx);
and then plot(x_plot, y / max(y), '.') will give the correct graph:

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

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.