bcf
bcf

Reputation: 2134

Scipy Minimize Not Working

I'm running the minimization below:

from scipy.optimize import minimize
import numpy as np
import math
import matplotlib.pyplot as plt

### objective function ###
def Rlzd_Vol1(w1, S):
    L = len(S) - 1
    m = len(S[0])

    # Compute log returns, size (L, m)
    LR = np.array([np.diff(np.log(S[:,j])) for j in xrange(m)]).T

    # Compute weighted returns
    w = np.array([w1, 1.0 - w1])
    R = np.array([np.sum(w*LR[i,:]) for i in xrange(L)])  # size L

    # Compute Realized Vol.
    vol = np.std(R) * math.sqrt(260)

    return vol

# stock prices
S = np.exp(np.random.normal(size=(50,2)))

### optimization ###
obj_fun = lambda w1: Rlzd_Vol1(w1, S)
w1_0 = 0.1

res = minimize(obj_fun, w1_0)
print res


### Plot objective function ###
fig_obj = plt.figure()
ax_obj = fig_obj.add_subplot(111)
n = 100
w1 = np.linspace(0.0, 1.0, n)
y_obj = np.zeros(n)
for i in xrange(n):
    y_obj[i] = obj_fun(w1[i])
ax_obj.plot(w1, y_obj)
plt.show()

The objective function shows an obvious minimum (it's quadratic):

objective function

But the minimization output tells me the minimum is at 0.1, the initial point:

minimization output

I cannot figure out what's going wrong. Any thoughts?

Upvotes: 1

Views: 8969

Answers (1)

Andi
Andi

Reputation: 1273

w1 is passed in as a (single entry) vector and not as scalar from the minimize routine. Try what happens if you define w1 = np.array([0.2]) and then calculate w = np.array([w1, 1.0 - w1]). You'll see you get a 2x1 matrix instead of a 2 entry vector.

To make your objective function able to handle w1 being an array you can simply put in an explicit conversion to float w1 = float(w1) as the first line of Rlzd_Vol1. Doing so I obtain the correct minimum.

Note that you might want to use scipy.optimize.minimize_scalar instead especially if you can bracket where you minimum will be.

Upvotes: 3

Related Questions