1

I have a general class of non-linear problem where I have 2 or more vectors of y-data that are coupled in a dependent, but known, way to 2 or more vectors of x-data, and I want to find the parameters. I'm looking for a way to adapt the basic non-linear fit model in python to take both sets of data into account.

In a general case, I might have the pair:

[y1(x1, x2; A, B), y2(x1, x2; A, B)]

As a concrete example, I might have:

y1 = A sin(B x1) + e^(-A x1)

y2 = A x1^2 + B x2 + log[A x2]

(Assume these are not analytically solvable, or might present inefficiencies if solved). I know all the values y1, y2 and x1, x2, and I want to find an estimate for A and B that takes into account the data from both ys. I could just fit one or the other equation and get an estimate for A and B.

For example, imagine if y2 did not depend on B (or did so very weakly). It still gives strong information about the value of A that I want y1 to take into account.

As a secondary question, how would I use this method to put different weights on the two sets of the y-data?

Edit:

One potential approach I can think of would be to stack all the y-data into a single column, and then use the function to process the expected y1,y2, and then end the function with something like return vstack((y1,y2)) so I could compare the two sets? Then I could just have a weighting function that matches the length of this joined function?

Necarion
  • 105
  • 1
  • 6
  • You used lot of text in your question. It would have been much easier to understand you if you would have included a simple example of what you want, in terms of sample input an output – Sheldore Jun 05 '19 at 19:14
  • Can your nonlinear fit method handle vector-valued functions as in your proposed approach? – Davis Herring Jun 05 '19 at 20:10
  • Depending on the level of generalization you need, you could just use `scipy.optimize.leastsq` and write your own residual function including weights. Most of the time that's not a big deal, but can become tricky if you want have e.g. variable amount of equations or data sets. Did you have a look at `lmfit`? I'm not using that, but it might be capable of doing what you want. – mikuszefski Jun 06 '19 at 07:52
  • You may have a look [here](https://stackoverflow.com/a/20341726/803359) – mikuszefski Jun 06 '19 at 07:57

1 Answers1

0

I think you can follow this symfit example here, and adapt it to your problem. So that would be something like:

from symfit import variables, parameters, Fit, sin, exp, log

x_1, x_2, y_1, y_2 = variables('x_1, x_2, y_1, y_2')
A, B = parameters('A, B')

model_dict = {
    y_1: A * sin(B * x_1) + exp(-A * x_1),
    y_2: A * x_1**2 + B * x_2 + log(A * x_2)
}

fit = Fit(model_dict, x_1=x1data, y_1=y1data, x_2=x2data, 
          y_2=y2data, sigma_y_1=y1stdev, sigma_y_2=y2stdev)
fit_result = fit.execute()

This example already includes different weights on the different y_1 and y_2 by providing the standard deviations as extra information.

Disclaimer: I'm the author of symfit.

tBuLi
  • 2,295
  • 2
  • 16
  • 16