tags:

views:

90

answers:

3

I am trying to translate a function in a book into code, using MATLAB and C#.

I am first trying to get the function to work properly in MATLAB.

Here are the instructions:

alt text

The variables are:

xt and m can be ignored.
zMax = Maximum Sensor Range (100)
zkt = Sensor Measurement (49)
zkt* = What sensor measurement should have been (50)
oHit = Std Deviation of my measurement (5)

I have written the first formula, N(zkt;zkt*,oHit) in MATLAB as this:

hitProbabilty = (1/sqrt( 2*pi * (oHit^2) ))...
                * exp(-0.5 * (((zkt- zktStar) ^ 2) / (oHit^2))  );

This gives me the Gaussian curve I expect.

I have an issue with the definite integral below, I do not understand how to turn this into a real number, because I get horrible values out my code, which is this:

func = @(x) hitProbabilty * zkt * x;
normaliser = quad(func, 0, max) ^ -1;  
hitProbabilty = normaliser * hitProbabilty;

Can someone help me with this integral? It is supposed to normalize my curve, but it just goes crazy.... (I am doing this for zkt 0:1:100, with everything else the same, and graphing the probability it should output.)

+4  A: 

You should use the error function ERF (available in basic MATLAB)


EDIT1:

As @Jim Brissom mentioned, the cumulative distribution function (CDF) is related to the error function by:

normcdf(X) = (1 + erf(X/sqrt(2)) / 2 ,   where X~N(0,1)

Note that NORMCDF requires the Statistics Toolbox


EDIT2:

I think there's been a small confusion seeing the comments.. The above only compute the normalizing factor, so if you want to compute the final probability over a certain range of values, you should do this:

zMax = 100;                         %# Maximum Sensor Range
zktStar = 50;                       %# What sensor measurement should have been
oHit = 5;                           %# Std Deviation of my measurement

%# p(0<z<zMax) = p(z<zMax) - p(z<0)
ncdf = diff( normcdf([0 zMax], zktStar, oHit) );
normaliser = 1 ./ ncdf;

zkt = linspace(0,zMax,500);         %# Sensor Measurement, 500 values in [0,zMax]
hitProbabilty = normpdf(zkt, zktStar, oHit) * normaliser;

plot(zkt, hitProbabilty)
xlabel('z^k_t'), ylabel('P_{hit}(z^k_t)'), title('Measurement Probability')

alt text

Amro
Sorry, but which part of my code do I replace with the error function?Do you mean instead of computing normaliser?
James
Should I wait until after I compute all hitProbabilities, then do the ERF on that array? Then do I multiple the original array by the output of ERF?
James
n = 1 ./ (normcdf((zMax-zktStar)/oHit) - 0.5);Always gives me the value 2, for all values, 0-100? erf() always gives me back 2?
James
not really, try: `plot( 1 ./ (normcdf(([0:zMax]-zktStar)/oHit) - 0.5) )` and you will see a curve (`Inf` in the middle because we're dividing by zero!)
Amro
It gives me a very odd graph, like an upside L, but mirrored horizontally and vertically as well.
James
isnt zMax a constant in your equations? besides it doesnt make any sense if zMax is less than the mean zktStar, therefor you should only plot from 50 to 100, ie `[zktStar:zMax]`
Amro
Brilliant, this looks much more like what I'm after, I'm not sure about the actual values... I will have to see when I move on to the next equations if they match up. But thank you very much for your help. This was very puzzling for me!
James
@James: I made a correction to the normalizer formula, please see the edits.. I would still double check everything above, just to be on the safe side :)
Amro
+2  A: 

The N in your code is just the well-known gaussian or normal distribution. I am mentioning this because since you re-implemented it in Matlab, it seems you missed that, seeing as how it is obviously already implemented in Matlab.

Integrating the normal distribution will yield a cumulative distribution function, available in Matlab for the normal distribution via normcdf. The ncdf can be written in terms of erf, which is probably what Amro was talking about.

Using normcdf avoids integrating manually.

Jim Brissom
I see, so over my loop of 100 values, I should use on the array, this gives me another array.. The articles multiplies the normal with the value, should I do this, or does the function do this for me?-- Do you also mean I can re-write my Gaussian function too? How would I go about doing this? I'm not really maths orientated, only being forced into it out of necessity, forgive my ignorance.
James
You do not need to implement the normal distribution, in Matlab at least. You will have to do this in C#, though (unless you use a library, but this is a different matter). As for normalization: a cumulative distribution function f(x) expresses the probability that a random variable lies in the interval (-inf, x], which is basically the same as saying that the random variable is smaller or equal to x. normalcdf already includes the integration part, but not the power-to-minus-one part. This part probably refers to the percent point function, which is just the inverse of a cdf.
Jim Brissom
I think I understand, so I can replace my code with:measurements = 0:1:100;actualDistance = 50;oHit = 50;hitProbabilities = normpdf(measurements, actualDistance, oHit );normalisedProbabilities = edf(hitProbabilities);plot(measurements, normalisedProbabilities, measurements, normalisedProbabilities);
James
Thanks for pointing out that the Gaussian function in instructions is a standard Gaussian function, so I don't have to re-write it in MATLAB and C#!
James
A: 

In case you still need the result for the integral.

From Mathematica. The Calc is

hitProbabilty[zkt_] := (1/Sqrt[2*Pi*oHit^2])*Exp[-0.5*(((zkt - zktStar)^2)/(oHit^2))];
Integrate[hitProbabilty[zkt], {zkt, 0, zMax}]; 

The result is (just for copy/paste)

((1.2533141373155001*oHit*zktStar*Erf[(0.7071067811865476*Sqrt[zktStar^2])/oHit])/
Sqrt[zktStar^2] + 
(1.2533141373155001*oHit*(zMax-zktStar)*Erf[(0.7071067811865476*Sqrt[(zMax-zktStar)^2])/oHit])/
   Sqrt[(zMax-zktStar)^2])/(2*oHit*Sqrt[2*Pi])

Where Erf[] is the error function

HTH!

belisarius