1

I'm trying to fit a dynamic n-modal Gaussian function to some test data, but I'm having some difficulty in getting the scipy.optimize.curve_fit method to interpret my arguments properly.

from scipy.optimize import curve_fit
import numpy as np


def gaussian(x_g, mu, sigma, a):
return a * np.exp((-1 * (x_g-mu) ** 2) / (2 * sigma)**2)


def n_modal(x_n, mu_n, sigma_n, a_n):
mu_n = np.array(mu_n)
sigma_n = np.array(sigma_n)
a_n = np.array(a_n)
result = 0
for i in range(mu_n.shape[0]):
    result += gaussian(x_n, mu_n[i], sigma_n[i], a_n[i])
return result


xes = np.linspace(-2*np.pi, 2*np.pi, 1000)
ys = np.sin(2*xes)
mus = np.array([-6, -4, -2, -1, 1, 2, 4, 6]).reshape((1, 8))
sigmas = np.array([1, 1, 1, 1, 1, 1, 1, 1]).reshape((1, 8))
asz = np.array([1, -1, -1, 1, -1, 1, -1, 1]).reshape((1, 8))
params = np.concatenate((mus, sigmas, asz), axis=0)
param_opt, param_cov = curve_fit(n_modal, xes, ys, p0=params)

The terminal just tells me that I'm feeding in the wrong amount of parameters, as expected, because the method probably can't figure out that the function takes a dynamic amount of parameters for mu_n, sigma_n, and a_n.

I know that I can just remake the functions with an explicit amount of variables (see below), but I want something a bit more general. What are my options?

def bimodal(x_bi, mu1, sigma1, a1, mu2, sigma2, a2):
return (gaussian(x_bi, mu1, sigma1, a1) + 
        gaussian(x_bi, mu2, sigma2, a2))

def trimodal(x_tri, mu1, sigma1, a1, mu2, sigma2, a2, mu3, sigma3, a3):
return (gaussian(x_tri, mu1, sigma1, a1) + 
        gaussian(x_tri, mu2, sigma2, a2) + 
        gaussian(x_tri, mu3, sigma3, a3))

def tetramodal(x_tet, mu1, sigma1, a1, mu2, sigma2, a2, mu3, sigma3, a3, mu4, sigma4, a4):
return (gaussian(x_tet, mu1, sigma1, a1) + 
        gaussian(x_tet, mu2, sigma2, a2) + 
        gaussian(x_tet, mu3, sigma3, a3) +
        gaussian(x_tet, mu4, sigma4, a4))
tionichm
  • 163
  • 10
  • 1
    Do I understand correctly that you want a function `n_modal` that takes a variable number of input arguments, so that you can call it like any of the three specialized functions? In that case have a look at https://stackoverflow.com/q/919680/3005167. – MB-F Aug 09 '18 at 11:36

0 Answers0