Mr.Smalltree
Mr.Smalltree

Reputation: 1

Python Symfit : bound issue in chained minimization

I am tackling an optimization problem, and to do so I chain 3 optimizers. Symfit is imported as sft, and sympy as sy: [EDIT] The code below is a Minimal example of my situation, producing the same error message.

k, a = sft.parameters('k, a') # parameters to be optimized
k.min = 0.01
k.max = 1
a.min, a.max = 0.01, 1
L = sft.Parameter('L', value = 5, fixed = True) #this parameter is known,
 #therefore I don't wan't is to move


#variables
x = sft.Variable('x')
A = sft.Variable('A')
P = sft.Variable('P')

#model
model_dict = {
    sy.Derivative(A, x): k * A - P**a/ L, 
    sy.Derivative(P, x): - k * (P**2)/L 
    }

odemodel = sft.ODEModel(model_dict, initial= {x : 0.,
                                             A : 0,
                                             P : 0
                                             }) 

#some mock data ( inspired of tBuLi symfit doc)
x = np.linspace(0, 20, 40)
mock_data = odemodel(x=x, k=0.1, a = 0.08, L = 5)._asdict()
sigma_data = 0.5
np.random.seed(42)
for var in mock_data:
    mock_data[var] += np.random.normal(0, sigma_data, size=len(x))
fit = sft.Fit(odemodel, x = x,
              A = mock_data[A], P = mock_data[P],
              minimizer = [DifferentialEvolution, LBFGSB, BasinHopping]) #DifferentialEvolution #BasinHopping
fit_result = fit.execute()

The following error message pops :

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-ea4a7a6e9a8e> in <module>
     34               A = mock_data[A], P = mock_data[P],
     35               minimizer = [DifferentialEvolution, LBFGSB, BasinHopping]) #DifferentialEvolution #BasinHopping
---> 36 fit_result = fit.execute()

C:\ProgramData\Anaconda3\lib\site-packages\symfit\core\fit.py in execute(self, **minimize_options)
    577         :return: FitResults instance
    578         """
--> 579         minimizer_ans = self.minimizer.execute(**minimize_options)
    580         minimizer_ans.covariance_matrix = self.covariance_matrix(
    581             dict(zip(self.model.params, minimizer_ans._popt))

C:\ProgramData\Anaconda3\lib\site-packages\symfit\core\minimizers.py in execute(self, **minimizer_kwargs)
    270         for minimizer, kwargs in zip(self.minimizers, bound_arguments.arguments.values()):
    271             minimizer.initial_guesses = next_guess
--> 272             ans = minimizer.execute(**kwargs)
    273             next_guess = list(ans.params.values())
    274             answers.append(ans)

C:\ProgramData\Anaconda3\lib\site-packages\symfit\core\support.py in wrapped_func(*args, **kwargs)
    421                     else:
    422                         bound_args.arguments[param.name] = param.default
--> 423             return func(*bound_args.args, **bound_args.kwargs)
    424         return wrapped_func
    425 

C:\ProgramData\Anaconda3\lib\site-packages\symfit\core\minimizers.py in execute(self, **minimize_options)
    408         if jacobian is None:
    409             jacobian = self.wrapped_jacobian
--> 410         return super(ScipyGradientMinimize, self).execute(jacobian=jacobian, **minimize_options)
    411 
    412     def scipy_constraints(self, constraints):

C:\ProgramData\Anaconda3\lib\site-packages\symfit\core\minimizers.py in execute(self, **minimize_options)
    428     def execute(self, **minimize_options):
    429         return super(ScipyBoundedMinimizer, self).execute(bounds=self.bounds,
--> 430                                                           **minimize_options)
    431 
    432 

C:\ProgramData\Anaconda3\lib\site-packages\symfit\core\support.py in wrapped_func(*args, **kwargs)
    421                     else:
    422                         bound_args.arguments[param.name] = param.default
--> 423             return func(*bound_args.args, **bound_args.kwargs)
    424         return wrapped_func
    425 

C:\ProgramData\Anaconda3\lib\site-packages\symfit\core\minimizers.py in execute(self, bounds, jacobian, hessian, constraints, **minimize_options)
    353             jac=jacobian,
    354             hess=hessian,
--> 355             **minimize_options
    356         )
    357         return self._pack_output(ans)

C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    608     elif meth == 'l-bfgs-b':
    609         return _minimize_lbfgsb(fun, x0, args, jac, bounds,
--> 610                                 callback=callback, **options)
    611     elif meth == 'tnc':
    612         return _minimize_tnc(fun, x0, args, jac, bounds, callback=callback,

C:\ProgramData\Anaconda3\lib\site-packages\scipy\optimize\lbfgsb.py in _minimize_lbfgsb(fun, x0, args, jac, bounds, disp, maxcor, ftol, gtol, eps, maxfun, maxiter, iprint, callback, maxls, **unknown_options)
    275         bounds = [(None, None)] * n
    276     if len(bounds) != n:
--> 277         raise ValueError('length of x0 != length of bounds')
    278     # unbounded variables must use None, not +-inf, for optimizer to work properly
    279     bounds = [(None if l == -np.inf else l, None if u == np.inf else u) for l, u in bounds]

ValueError: length of x0 != length of bounds

As mentioned in this (long) message it is the second minimizer lbfgsb which is causing troubles but I don't know at all how to overcome this. In my full code, when I try to put only one minimizer, the program runs forever and I cannot find out why. This is why one minimizer only seems to be not enough and I want to chain them. I think this is due to the complexity of the problem : two coupled ODE with 7 parameters to optimize, and a initial guess performed with InteractiveGuess ( very great tool by the way).

Thanks by advance for your help !

Upvotes: 0

Views: 201

Answers (0)

Related Questions