physics 114: lecture 19 least squares fit to 2d data dale e. gary njit physics department

9
Physics 114: Lecture 19 Least Squares Fit to 2D Data Dale E. Gary NJIT Physics Department

Upload: makena-steadman

Post on 14-Dec-2015

226 views

Category:

Documents


1 download

TRANSCRIPT

Physics 114: Lecture 19 Least Squares Fit to

2D Data

Dale E. Gary

NJIT Physics Department

Apr 19, 2010

Nonlinear Least Squares Fitting We saw that for a function y(x) the chi-square is

which can be used to fit a curve to data points yi. In just the same way, we can easily extend this idea to fitting a

function z(x,y), that is, a surface, to a 2D data set of measurements zi(x,y).

You know that it takes three parameters to fit a Gaussian curve To extend this to a 2D Gaussian is straightforward. It is:

Note that this has 5 parameters, but the most general way to describe a 2D Gaussian actually has 6 parameters, which you will do for homework.

2

2 ( )i

i

y y x

2

2 ( , )i

i

z z x y

2

( ) .x b

cy x ae

2 21 2

1 2( , ) .x b y b

c cz x y ae

Apr 19, 2010

Plotting a 2D Gaussian in MatLAB Let’s introduce some useful MatLAB commands for creating a 2D

Gaussian. One can use a brute force method such as

z = zeros(101,101); a = 2.5; bx = 2.3; by = -1.2; cx = 1.5; cy = 0.8; i = 0; for x = -5:0.1:5 i = i + 1; j = 0; for y = -5:0.1:5 j = j + 1; z(i,j) = a*exp(-((x-bx)/cx)^2 – ((y-by)/cy)^2); end end imagesc(-5:0.1:5,-5:0.1:5,z)

Or, we can plot it as a surface to provide x and y coordinates surf(-5:0.1:5,-5:0.1:5,z)

x

y

2D Gaussian with 5 Parameters

-5 0 5

-5

-4

-3

-2

-1

0

1

2

3

4

5

Apr 19, 2010

Better Way of Creating 2D Functions

That way of using for loops is a very slow, so here is another way of doing it for “round” Gaussians:

x = -5:0.1:5; y = -5:0.1:5; siz = size(x); siz = siz(2); a = 2.5; bx = 2.3; by = -1.2; c = 0.8; dist = zeros(siz,siz); for i=1:siz for j=1:siz dist(i,j) = x(i)^2 + y(j)^2; % Create “distance” array once end end % use the next two statements multiple times for different Gaussians sdist = circshift(dist,round([bx/0.1,by/0.1])); % Shifted “distance” array z = a*exp(-sdist/c); imagesc(x,y,z);

Apr 19, 2010

Best Way of Creating 2D Functions The best way, however, is to use the meshgrid() MatLAB function:

[x, y] = meshgrid(-5:.1:5, -5:.1:5); a = 2.5; bx = 2.3; by = -1.2; cx = 1.5; cy = 0.8; z = a*exp( - (((x-bx)/cx).^2 + ((y-by)/cy).^2) ; surf(x,y,z);

This is completely general, and allows vector calculations which are very fast.

Here is another example, the sinc() function: z = a*sinc(sqrt(((x-bx)/cx).^2 + ((y-by)/cy).^2));

You can see that the meshgrid() function isvery powerful as a shortcut for 2D functioncalculation.

To add noise, just add sig*randn(size(z)),where sig is the standard deviation of the noise.

-5

0

5

-5

0

5

-2

0

2

4

Apr 19, 2010

Searching Parameter Space in 2D Just as we did in the 1D case, searching parameter space is just a

trial and error exercise. % Initial values around which to search a0 = max(max(z)); [ix iy] = find(z == a0); bx0 = x(ix,iy); by0 = y(ix,iy); cx0 = 1; cy0 = 1; astep = 0.05; bstep = 0.05; cstep = 0.05; chisqmin = 1e20; for a = a0-5*astep:astep:a0+5*astep for bx = bx0-5*bstep:bstep:bx0+5*bstep for by = by0-5*bstep:bstep:by0+5*bstep for cx = cx0-5*cstep:cstep:cx0+5*cstep for cy = cy0-5*cstep:cstep:cy0+5*cstep ztest = a*exp(-(((x-bx)/cx).^2 + ((y-by)/cy).^2)); chisq = sum(sum(((ztest-z)/sig).^2)); if (chisq < chisqmin); chisqmin = chisq; params = [a,bx,by,cx,cy]; end end end end end end

params = 2.1465 2.3000 -1.2000 1.2500 0.8000

Apr 19, 2010

The Result Looks Good, but… To calculate the result of the fit, just type

ztest = params(1)*exp(-(((x-params(2))/params(4)).^2 + ((y-params(3))/params(5)).^2));

imagesc(x(1,:),y(:,1),ztest)

This gives a reasonable result, but comparethe fit parameters with the (known) params:

a = 2.1; bx = 2.3; by = -1.2; cx = 1.3; cy = 0.8; params = 2.15 2.3 -1.2 1.25 0.8

The value of cx is especially far off, becauseour search window was limited to 0.75-1.25,so it could not reach 1.3.

Look at the residuals: imagesc(x(1,:),y(:,1),ztest-z)

Can you see a pattern in the noise? To bring out the pattern better, let’s introduce convolution.

-5 -4 -3 -2 -1 0 1 2 3 4 5

-5

-4

-3

-2

-1

0

1

2

3

4

5-5 -4 -3 -2 -1 0 1 2 3 4 5

-5

-4

-3

-2

-1

0

1

2

3

4

5

1D Convolution and Smoothing

Let’s create a noisy sine wave: u = -5:.1:5; w = sin(u*pi)+0.5*randn(size(u)); plot(u,w)

We can now smooth the data by convolvingit with a vector [1,1,1], which does a 3-pointrunning sum.

wsm = conv(w,[1,1,1]); whos wsm

Name Size Bytes Class Attributes wsm 1x103 824 double

Notice wsm is now of length 103. That means we cannot plot(u,wsm), but we can plot(u,wsm(2:102)). Now we see another problem.

Try this: plot(u,w) hold on; plot(u,wsm(2:102)/3,’r’)

Apr 19, 2010

-5 0 5-2

-1

0

1

2

u

sin(

u)

conv( , ) ( * )( ) ( ) ( )w k w k t w k t d

-5 0 5-2

-1.5

-1

-0.5

0

0.5

1

1.5

2

u

w

w

wsm

2D Convolution To do 2D smoothing, we will use a 2D kernel k = ones(3,3), and

use the conv2() function. So to smooth the residuals of our fit, we can use

zsm = conv2(ztest-z,k)/9.; imagesc(x,y,zsm(2:102,2:102))

Now we can see the effect of missing thevalue of cx by 0.05 due to our limitedsearch range.

There are other uses for convolution, suchas edge detection. For example, we can

convolve with a kernel k = [1,1,1,1,1,1]. Or a kernel k = [1,1,1,1,1,1]’. Or even

a kernel k = eye(6). Or k = rot90(eye(6)).

Apr 19, 2010

-5 0 5

-5

0

5-5 0 5

-5

0

5