lordy
lordy

Reputation: 630

2d gaussian function does not produce correct results

I would like to write a function that returns an np.array of size nx x ny that contains a centered gaussian distribution with mean mu and sd sig. The code below works in certain cases but in many not - what's wrong or what else should I write to get what I need?

import matplotlib.pyplot as plt
import numpy as np

def create2dGaussian(mu, sigma, nx, ny):
    x, y = np.meshgrid(np.linspace(-nx / 2.0, +nx / 2.0, nx), np.linspace(-ny / 2.0, +ny / 2.0, ny))
    d = np.sqrt(x * x + y * y)
    g = np.exp(-((d - mu) ** 2 / (2.0 * sigma ** 2)))

    # just for debugging:
    np.set_printoptions(precision=1, suppress=True)
    print(g.shape)
    print(g)
    plt.imshow(g, cmap='jet', interpolation='nearest')
    plt.colorbar()
    plt.show()

    return g

Here are some test cases with comments:

from create2dGaussian import create2dGaussian

create2dGaussian(1, 10, 25, 25) # seems to work
create2dGaussian(1, 5, 25, 25) # the middle is not quite the peak anymore
create2dGaussian(1, 1, 25, 25) # the above problem more clearly visible
create2dGaussian(1, 1, 5, 5) # here it is extrem as the middle is now only 0.6

create2dGaussian(5, 10, 25, 25) # mean is still 1 and not 5

Upvotes: 2

Views: 346

Answers (2)

Kai Aeberli
Kai Aeberli

Reputation: 1220

Your issue is that when creating your dataset, you are creating values that already have a mean and standard deviation. They are all at distance from each other implied by the nx, ny parameters. When you then apply the gaussian and provide a mean and standard deviation that is not the same as that of your dataset, it will show the actual mean of the dataset which is not in the center, as you specified it without looking at the data.

Take for example this case:

create2dGaussian(1, 1, 5, 5)

you tell it to have a mean of 1, but the center of the distribution is a 0.

import matplotlib.pyplot as plt
import numpy as np

def create2dGaussian(mu, sigma, nx, ny):
    x, y = np.meshgrid(np.linspace(-nx / 2.0, +nx / 2.0, nx), np.linspace(-ny / 2.0, +ny / 2.0, ny))
    d = np.sqrt(x * x + y * y)
    g = mu * np.exp(-((d - mu) ** 2 / (2.0 * sigma ** 2)))

    np.set_printoptions(precision=1, suppress=True)
    print(("x", x))
    print(("y", y))
    print(("d", d))
    plt.imshow(g, cmap='jet', interpolation='nearest')
    plt.colorbar()
    plt.show()

    return g

#create2dGaussian(1, 10, 25, 25) # seems to work
#create2dGaussian(1, 5, 25, 25) # the middle is not quite the peak anymore
#create2dGaussian(1, 5, 25, 25) # the above problem more clearly visible
create2dGaussian(1, 1, 5, 5) # here it is extrem as the middle is now only 0.6

#create2dGaussian(5.0, 10.0, 25.0, 25.0) # mean is still 1 and not 5

Output:

('x', array([
       [-2.5, -1.2,  0. ,  1.2,  2.5],
       [-2.5, -1.2,  0. ,  1.2,  2.5],
       [-2.5, -1.2,  0. ,  1.2,  2.5],
       [-2.5, -1.2,  0. ,  1.2,  2.5],
       [-2.5, -1.2,  0. ,  1.2,  2.5]]))
('y', array([
       [-2.5, -2.5, -2.5, -2.5, -2.5],
       [-1.2, -1.2, -1.2, -1.2, -1.2],
       [ 0. ,  0. ,  0. ,  0. ,  0. ],
       [ 1.2,  1.2,  1.2,  1.2,  1.2],
       [ 2.5,  2.5,  2.5,  2.5,  2.5]]))
('d', array([
       [3.5, 2.8, 2.5, 2.8, 3.5],
       [2.8, 1.8, 1.2, 1.8, 2.8],
       [2.5, 1.2, 0. , 1.2, 2.5],
       [2.8, 1.8, 1.2, 1.8, 2.8],
       [3.5, 2.8, 2.5, 2.8, 3.5]]))
('g', array([
       [0. , 0.2, 0.3, 0.2, 0. ],
       [0.2, 0.7, 1. , 0.7, 0.2],
       [0.3, 1. , 0.6, 1. , 0.3],
       [0.2, 0.7, 1. , 0.7, 0.2],
       [0. , 0.2, 0.3, 0.2, 0. ]]))

2-D Gaussian

Upvotes: 1

esandier
esandier

Reputation: 165

There is a confusion with the mean in what you propose. In the 1D case, saying it is centered is exactly saying its mean is 0. For a 2D gaussian there are so to speak two means, defined as the expectation of x and of y. Again saying it is centered is exactly saying they are both 0.

To summarize, your density is not the density of a centered 2D gaussian, which should be

exp(-((x**2 +y**2) / (2.0 * sigma ** 2)))

If the gaussian is centered at (xm, ym) then the density is

exp(-(((x-xm)**2 +(y-ym)**2) / (2.0 * sigma ** 2)))

But there is no such thing as a centered gaussian with mean mu.

Upvotes: 2

Related Questions