lmfit / lmfit-py

Non-Linear Least Squares Minimization, with flexible Parameter settings, based on scipy.optimize, and with many additional classes and methods for curve fitting.
https://lmfit.github.io/lmfit-py/
Other
1.05k stars 273 forks source link

RuntimeError: maximum recursion depth exceeded while calling a Python object #196

Closed licode closed 8 years ago

licode commented 9 years ago

I find that the total number of models can't be so large by using the current composite model. For instance, I need to add many gaussians together.

G = GaussianModel(prefix='g0')
    for i in xrange(500):
        G += GaussianModel(prefix='g'+str(i+1))

When the iteration number goes beyond 500, it will show the runtime error

611     @property
    612     def param_names(self):
--> 613         return self.left.param_names | self.right.param_names
    614 
    615     @property

RuntimeError: maximum recursion depth exceeded while calling a Python object

I am working on fluorescence fitting. I have many elements to fit, and each element might have more than 10 K,L lines, and each line is basically a gaussian. So it is easy for the total number to hit a large value. However, the fitting paramters might not be so many, because models have constraints in between.

This may be a minor point, as we didn't see such complicated models quite often. But it looks like that previous lmfit version works fine, because we didn't use binary operator before. I don't know if it is possible to improve this.

newville commented 9 years ago

@licode you could use sys.setrecursionlimit() to increase the recursion limit.

As it happens, I also work with X-ray fluorescence at a synchrotron, and there are lots of other people doing similar work. Perhaps we should be working together, or at least aware of what each other are working on? See https://github.com/xraypy for the X-ray spectroscopy I've been working on, and of course, https://github.com/vasole/pymca.

For example, though there may be 10 K, L lines per element, they are not independent. In fact, you generally want them to not be independent Gaussian peaks. You might them write a model function KEmissionLines() that has only an amplitude parameter, and takes an element symbol/Z -- this would represent the intensity of several peaks for each element. You could have L3EmissionLines(), L2EmisssionLines(), and L1EmissionLines() that are like KEmissionLines(), and you could decide which of these to include (or, say, fix their amplitude to 0) based on the excitation energy.

There are other finer points, but that would drift further off-topic. Lots of people have worked on and/or are working on this problem.

licode commented 9 years ago

Thanks for the suggestion.

What I am doing is to add several gaussians together for one element, but fix the relative amplitude according to branching ratio calculated, so there is only one fitting amplitude from the first primary line. I think that is similar to your idea. I will take a look at xraypy.