4

I am building some spring networks in order to build a model for rubber traction tests. I impose a displacement on some of my network's nodes, and I lock some others, then I run a minimization function on the system's energy in order to get the stabilized system.

First, wih the Nelder-Mead method, I had divergence issues, with system's energy growing with iteration number, so I am trying Powell's method. The direction vectors should help my function to 'move' my nodes in the correct direction.

Unfortunately, I still get an error.

Here is my code :

import scipy as sc
import scipy.optimize as opt
import numpy as np
### Scipy.optimize.minimize with Powell's method
# Algorithm' starting point
x0 = np.array([1., 1., 2., 1., 2., 3., 1., 2., 3., 1., 2., 3., 2., 3., 3., 0., 1.,
       0., 2., 1., 0., 3., 2., 1., 4., 3., 2., 4., 3., 4.])

# Setting up the variables we will need
Bounds= opt.Bounds(lb=0, ub=10)
Direc = (np.array([[1, 1, 2, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 1, 2,-1, 0, 1,-2,-1, 0,-2,-1,-2]]))

# Run the optimization function
x_pow = opt.minimize(minimize_energy, x0, method='Powell', tol=1e-6, bounds = Bounds,
                 options={'maxiter': 1e4, 'disp': True, 'direc':Direc}) 

And here is the error I get :

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-23-f0bb1bfcaa17> in <module>
      8 # Run the optimization function
      9 x_pow = opt.minimize(minimize_energy, x0, method='Powell', tol=1e-6, bounds = Bounds,
---> 10                  options={'maxiter': 1e4, 'disp': True, 'direc':Direc}) 
     11 
     12 print('final x')

C:\Bib\envs\statmath3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    598         return _minimize_neldermead(fun, x0, args, callback, **options)
    599     elif meth == 'powell':
--> 600         return _minimize_powell(fun, x0, args, callback, **options)
    601     elif meth == 'cg':
    602         return _minimize_cg(fun, x0, args, jac, callback, **options)

C:\Bib\envs\statmath3\lib\site-packages\scipy\optimize\optimize.py in _minimize_powell(func, x0, args, callback, xtol, ftol, maxiter, maxfev, disp, direc, return_all, **unknown_options)
   2638         delta = 0.0
   2639         for i in ilist:
-> 2640             direc1 = direc[i]
   2641             fx2 = fval
   2642             fval, x, direc1 = _linesearch_powell(func, x, direc1,

IndexError: index 2 is out of bounds for axis 0 with size 2

I don't understand why I get an out of bounds while my direction vectors are the same length as x0, the parameter vector that will be optimized. Thanks for your help!

Lena_Cste
  • 41
  • 3
  • Does Powell expect N direction vectors, where N is the length of x0? I know thats what it uses in the default case, but I'm not certain if it is strictly required. – Tyberius Feb 25 '21 at 19:24

1 Answers1

0

I believe that you need to set the proper bounds. You have 30 parameters, so you need proper bounds for each one of those. You could try something like:

bounds = opt.Bounds(np.full(30, 0.0), np.full(30, 10.0))

serra
  • 59
  • 7