Bagnarol
Bagnarol

Reputation: 135

Scipy curve_fit with a parameters matrix of unknown shape

I am trying to use either scipy.curve_fit or scipy.least_squares for a function like

def f(x, C): 
    
  r = 0
  for i in range( len(C) ) :
      for j in range( len(C[i]) ):
          r+= x[0]**j * x[1]**i * C[i][j]          
  return r

where C is a list of lists of length defined run time. One of the parameters of the code is something like [[1., 1.]] or [[1., 1.], [1.]] which defines the shape of C.

I tried following this answer, but there the C would be a NxN matrix, and curve_fit does not work well with matrices as input. I tried to define a function with x, *args as parameters but with no luck for now.

I also tried following this other answer which uses least_squares directly, but also here I get the obstacle that I do not know the size of the rows beforehand.

I feel that a combination of the two answers can work for me but I cannot figure it out. I was thinking to write a function that has as parameters the length of C, a list of the lengths of C[i], and then the elements of C flattened, but I cannot write a working version of the code. If anyone has a clear understanding of how to do that, or had a similar problem, I'd be thankful for any help.

Upvotes: 1

Views: 374

Answers (1)

Bagnarol
Bagnarol

Reputation: 135

Since this question got some recent activity I will answer it, as I solved it few days later. I solved it with a lambda function.

I defined my function as

def f(xy, *args, dimC = 1, dimCi = [2]): 

   x, y = xy # I have to unpack the tuple because a normal list seems to not work

   r = 0

   for i in range( dimC ) :
       for j in range( dimCi[i] ):
           r+= args[i*dimC + j] * x**i * k2**j
        
   return r

Then I just need to flatten the initial guess and I am free to call

C, cov_C = curve_fit(lambda x, *p: f(x, *p, dimC = dimMat, dimCi = dimMati), ( x, y ), z), p0=init_guess)

Upvotes: 0

Related Questions