Python Forum

Full Version: Multi-gaussian function
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hey! I need help developing a code for a multi-gaussian function. The point would be to create a function that uses the number of gaussian requested by the user to make the final fitting function. All parameters are passed as *params and number of gaussians is deduced from the number of items in *params (1 + n*3). However, I am very new to coding and was left with a base to work with, only I am confused of what to do next.

This is the code so far:
def multi_gaussian(x, *params):
    y0 = params[0]
    n_gauss = ...
    y = np.ones_like()
    for i in range(n_gauss):
        parameters = ...
        y += gaussian(x, parameters)
    return y


I understand that n_gauss should be extracted from the length of *params, but I am unsure of how the parameters should be defined: in the file that I use the function in, or in this same code, such as here

 def two_gaussian(x, *param):
    y0, A1, w1, xc1, A2, w2, xc2 = param
    y = y0 + (A1/(w1*np.sqrt(np.pi/2)))*np.exp(-2*np.power((x-xc1)/w1, 2.))
    + (A2/(w2*np.sqrt(np.pi/2)))*np.exp(-2*np.power((x-xc2)/w2, 2.))
    return y
y should be a constant background function, but I am unsure of how extracting parameters works. Any kind of help is appreciated!
Within multi_gaussian the params variable will be interpreted as a tuple of size 3 * n + 1. So, the answer to your question would be something like the following:

def multi_gaussian(x, *params):
    y0 = params[0]
    n_gauss = (len(params) - 1) // 3    
    y = y0 * np.ones_like(x)  # ??? 
    for i in range(n_gauss):
        parameters = params[1+3*i:1+3*i + 3]
        y += gaussian(x, *parameters)
    return y
However, you probably need to check if len(params) is correct (e.g. len(params) - 1 is divisible by 3).
Hey, thank you for the help! Now that I'm trying to run the code, there seems to be an error in the function I've defined as gaussian

def gaussian(x, *param):
    y0, A1, w1, xc1 = param
    y = y0 + (A1/(w1*np.sqrt(np.pi/2)))*np.exp(-2*np.power((x-xc1)/w1, 2.))
    return y
It returns an error at the y0, A1, w1, xc1 = param line:

ValueError: not enough values to unpack (expected 4, got 3)
But to my understanding each value has been used in a function, and in higher gaussian fittings (two etc.) this seems to work perfectly fine.
The "parameters" variable is expected to have len = 4 (i.e. the first element is always y0);
So, you need to change the line of code where the "parameters" variable is defined:

parameters = [y0] + params[1 + 3 * i:1 + 3 * i + 3]
Changed the code, now there's another error:

parameters = [y0] +  params[1 + 3 * i:1 + 3 * i + 3]

TypeError: can only concatenate list (not "tuple") to list
(Jul-21-2020, 07:32 AM)Laplace12 Wrote: [ -> ]Changed the code, now there's another error:
Not an error actually, I just forgot that params is a tuple, try instead parameters = (y0, ) + params[1 + 3 * i:1 + 3 * i + 3]