<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Trust Region
Step1:  The plot below show the Rosenbrock function in faded black and a blue quadratic approximation to the function about the blue dot.
Step2:  We now add a trust region radius as a red dashed line, and show the optimal point (from the blue model) within that radius as a red dot.  An actual trust region algorithm doesn't necessary find the exact optimum (it uses a more efficient, but approximate method to avoid actually solving an internal optimization problem), but for our purposes we will assume that it does.  You can change the trust region radius with the slider below.  Note that at large radii, the solution is unaffected by the radius and sits at the minimum point of the quadratic. As the trust region radius decreases, the constrained optimum moves and the step direction changes.
<ASSISTANT_TASK:>
Python Code:
ymin = -4.0
ymax = 8.0
xmin = -4.0
xmax = 6.0
x0 = np.array([2.0, 1.0])
def rosenbrock(xvec):
    x = xvec[0]
    y = xvec[1]
    f = (1.0 - x)**2 + 100.0*(y - x**2)**2
    g = np.zeros(2)
    g[0] = -2*(1 - x) + 200*(y - x**2)*-2*x
    g[1] = 200*(y - x**2)
    H = np.zeros((2, 2))
    H[0, 0] = 2.0 + 1200.0*x**2 - 400.0*y
    H[0, 1] = -400.0*x
    H[1, 0] = -400.0*x
    H[1, 1] = 200.0
    return f, g, H
f, g, H = rosenbrock(x0)
def quad(x):
    s = x - x0
    fnew = f + np.dot(g, s) + 0.5*np.dot(s, np.dot(H, s))
    gnew = g + np.dot(H, s)
    return fnew, gnew
n = 200
x = np.linspace(xmin, xmax, n)
y = np.linspace(ymin, ymax, n)
[X, Y] = np.meshgrid(x, y, indexing='ij')
Z = np.zeros((n, n))
Zquad = np.zeros((n, n))
for i in range(n):
    for j in range(n):
        xvec = np.array([X[i, j], Y[i, j]])
        Z[i, j], _, _ = rosenbrock(xvec)
        Zquad[i, j], _ = quad(xvec)
Explanation: Trust Region
End of explanation
 # plot rosenbrock
plt.figure()
levels = [1., 10.0, 100.0, 1000.0, 1e4]
plt.contour(X, Y, Z, levels, colors='k', alpha=0.3)
plt.xlabel('x')
plt.ylabel('y')
# plot quadratic model
levels = [1., 10.0, 100.0, 1000.0, 1e4]
plt.contour(X, Y, Zquad, levels, colors='b')
plt.plot(x0[0], x0[1], 'bo')
plt.show()
Explanation: The plot below show the Rosenbrock function in faded black and a blue quadratic approximation to the function about the blue dot.
End of explanation
@interact(R=(0.0,5.0,0.1))
def radius(R=3.5):
    
    # redefine constraint
    def con(x):
        return [R - np.linalg.norm(x - x0)]
    
    # solve optimization problem
    constraints = {'type': 'ineq', 'fun': con}
#     options={'disp': True, 'iprint': 2, 'maxiter': 1000}
    res = minimize(quad, x0, method='SLSQP', jac=True, constraints=constraints)  #, options=options)
    
    
    # plot rosenbrock
    plt.figure()
    levels = [1., 10.0, 100.0, 1000.0, 1e4]
    plt.contour(X, Y, Z, levels, colors='k', alpha=0.3)
    plt.xlabel('x')
    plt.ylabel('y')
    # plot quadratic model
    levels = [1., 10.0, 100.0, 1000.0, 1e4]
    plt.contour(X, Y, Zquad, levels, colors='b')
    plt.plot(x0[0], x0[1], 'bo')
    # plot circle boundary
    theta = np.linspace(-np.pi, np.pi, 300)
    xt = x0[0] + R*np.cos(theta)
    yt = x0[1] + R*np.sin(theta)
    plt.plot(xt, yt, 'r--')
    # plot optimal point within boundary (using model)
    xopt = res.x
    plt.plot([x0[0], xopt[0]], [x0[1], xopt[1]], 'r')
    plt.plot(xopt[0], xopt[1], 'ro')
#     plt.axis('equal')
    plt.xlim([-4, 8])
    plt.ylim([-4, 6])
    plt.show()
Explanation: We now add a trust region radius as a red dashed line, and show the optimal point (from the blue model) within that radius as a red dot.  An actual trust region algorithm doesn't necessary find the exact optimum (it uses a more efficient, but approximate method to avoid actually solving an internal optimization problem), but for our purposes we will assume that it does.  You can change the trust region radius with the slider below.  Note that at large radii, the solution is unaffected by the radius and sits at the minimum point of the quadratic. As the trust region radius decreases, the constrained optimum moves and the step direction changes.
End of explanation
<END_TASK>