Search code examples
pythonscipymathematical-optimization

scipy minimize slsqp, leads to OverflowError: Python int too large to convert to C long


This program:

from __future__ import division
import numpy as np
from scipy.optimize import minimize
from collections import deque

def buy_captial():
    """ buys the profit maximizing amount of captial """
    offers = {'W': [{'quantity':50, 'price': 1}],
              'K': [{'quantity':200, 'price': 0.5}]}
    key_order = ('W', 'K')
    exponents = {'W': 0.6, 'K': 0.4}

    prices = {}
    quantities = {}
    for key in key_order:
        if key in offers:
            prices[key] = deque([offers[key][i]['price'] for i in range(len(offers[key]))])
            quantities[key] = deque([offers[key][i]['quantity'] for i in range(len(offers[key]))])

    print quantities
    budget = [{'type': 'ineq', 'fun': lambda x:
                                        200
                                        - sum([x[i] * prices[key_order[i]][0] for i in rng])}]
    rng = range(len(key_order))
    x0 = np.zeros(len(key_order))
    bounds =  ((0, 50), (0, 200))

    def objective(x):
        return \
            - 5  * np.prod([(x[i]) ** exponents[key_order[i]] for i in rng]) \
            + sum([x[i] * prices[key_order[i]][0] for i in rng])


    res = minimize(objective, x0=x0, method='SLSQP', constraints=budget, bounds=bounds)
    print 'buy', res,

buy_captial()

leads to this error:

python test_buy_captial.py 
{'K': deque([200]), 'W': deque([50])}
Traceback (most recent call last):
  File "test_buy_captial.py", line 37, in <module>
    buy_captial()
  File "test_buy_captial.py", line 34, in buy_captial
    res = minimize(objective, x0=x0, method='SLSQP', constraints=budget, bounds=bounds)
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/_minimize.py", line 358, in minimize
    constraints, **options)
  File "/usr/local/lib/python2.7/dist-packages/scipy/optimize/slsqp.py", line 333, in _minimize_slsqp
    xl[infbnd[:, 0]] = -1.0E12
OverflowError: Python int too large to convert to C long

Solution

  • The problem is that the bounds are specified, as integers. The Fortran backbone can't convert that. The solution is to specify the bounds as float. Either by the 'float()' argument or better for speed as pointed out by @pv. by bounds = array([[0, 50], [0, 200]], dtype=float)