3

I am trying to use scipy.optimize to solve a minimization problem but getting failures on using an inequality constraint or a bound. Looking for any suggestions regarding proper usage of constraints vs bounds, and if any other algorithm would be suitable in this case.

The problem is:

enter image description here

Here is a reproducible code (res['success'] and res1['success'] are both False- optimization fails):

import pandas as pd
import numpy as np
from scipy.optimize import minimize as scimin

def obj(wc, M, wb, S): return (wc.dot(M.T) - wb).dot(S).dot(wc.dot(M.T) - wb)

n=278 k= 16

c_labels = ['c'+ str(i) for i in range(k)] r_labels_1 = ['r' + str(i) +s for i in range(k) for s in ['a', 'b']] r_labels_2 = ['r' + str(i) for i in range(k, n-k)] r_labels = r_labels_1 + r_labels_2

wb = pd.Series(index=r_labels, data=np.random.triangular(0, 1.0/n, 0.3, n)) wb = wb/wb.sum() cc = pd.Series(index=c_labels, data=4 + 2np.random.random(k)) cb = pd.Series(index=r_labels, data=3 + 10np.random.random(n)) s_pre = np.random.rand(n, n) S = pd.DataFrame(index=r_labels, columns= r_labels, data=s_pre.dot(s_pre.T))

M = pd.DataFrame(data=np.eye(k), index= ['r'+ str(i) +'a' for i in range(k)], columns = c_labels) for i in range(k): M.loc['r' + str(i)+ 'b'] = M.loc['r' + str(i) + 'a'] M = M.loc[r_labels_1].applymap(lambda x: x* np.random.rand()) M = M / M.sum() for i in r_labels_2: M.loc[i] = 0

one_k = pd.DataFrame(index=M.columns, data=np.ones(len(M.columns))) con1 = {'type': 'eq', 'fun': lambda x: x.sum() - 1} con2 = {'type': 'eq', 'fun': lambda x: cc.dot(x) - cb.dot(wb)}

try 1 with inequality constraint

con3 = {'type': 'ineq', 'fun': lambda x: min(x)} consts = [con1, con2, con3] res = scimin(obj, x0=one_k, args=(M, wb, S), constraints=consts, method='SLSQP') assert (res['success'] == True) wc = res['x'] oj = obj(wc, M, wb, S)

try 2 with bounds instead of inequality constraint

bounds = [(0, 1000)] *len(M.columns) consts = [con1, con2] res1 = scimin(obj, x0=one_k, args=(M, wb, S), constraints=consts, bounds= bounds, method='SLSQP') assert (res1['success'] == True) wc1 = res1['x'] oj1 = obj(wc1, M, wb, S)

dayum
  • 131
  • 4

0 Answers0