def resid(c): F.c = c # update basis coefficients f = F(x) # interpolate at basis nodes x return f ** -2 + f ** -5 - 2 * x # ### Compute function inverse # In[4]: c0 = np.zeros(n) # set initial guess for coeffs c0[0] = 0.2 problem = NLP(resid) F.c = problem.broyden(c0) # compute coeff by Broyden's method # ### Plot setup # In[5]: n = 1000 x = np.linspace(a, b, n) r = resid(F.c) # ### Plot function inverse # In[6]:
def f(x): fval = x - np.sqrt(x) fjac = 1-0.5 / np.sqrt(x) return fval, fjac problem_as_zero = NLP(f, xinit) ''' Compute fixed-point using Newton method ''' t0 = tic() x1 = problem_as_zero.newton() t1 = 100 * toc(t0) n1 = problem_as_zero.fnorm ''' Compute fixed-point using Broyden method ''' t0 = tic() x2 = problem_as_zero.broyden() t2 = 100 * toc(t0) n2 = problem_as_zero.fnorm ''' Compute fixed-point using function iteration ''' t0 = tic() x3 = problem_as_fixpoint.fixpoint() t3 = 100 * toc(t0) n3 = np.linalg.norm(problem_as_fixpoint.fx - x3) print('Hundredths of seconds required to compute fixed-point of g(x)=sqrt(x)') print('using Newton, Broyden, and function iteration methods, starting at') print('x = %4.2f\n' % xinit) print('Method Time Norm of f x\n', '-' * 40) ff = '%9s %8.2f %8.0e %5.2f'
pcrit[0] = f.zero(0.0) # Next, for each possible price shock, we compute next period log-price by adding the shock to current log-prices (the nodes of the Value object). Then, we use each next-period price to compute the expected value of an option with one-period to maturity (save the values in ```v```). We update the value function to reflect the new time-to-maturity and use ```broyden``` to solve for the critical value. We repeat this procedure until we reach the $T=300$ horizon. # In[8]: for t in range(T): v = np.zeros((1, n)) for k in range(m): pnext = Value.nodes + e[k] v += w[k] * np.maximum(K - np.exp(pnext), delta * Value(pnext)) Value[:] = v pcrit[t + 1] = f.broyden(pcrit[t]) # ### Print Critical Exercise Price 300 Periods to Expiration # In[9]: print('Critical Price = %5.2f' % np.exp(pcrit[-1])) # ### Plot Critical Exercise Prices # In[10]:
eta = 1.6 e = -1 / eta s = q.sum() fval = s**e + e * s**(e - 1) * q - c * q fjac = e*s**(e-1) * np.ones([2,2]) + e * s ** (e-1) * np.identity(2) +\ (e-1)*e*s **(e-2)* np.outer(q, [1,1]) - np.diag(c) return fval, fjac market = NLP(cournot) x = market.newton([0.2, 0.2]) print('q1 = ', x[0], '\nq2 = ', x[1]) ''' Example page 39 ''' # continuation of example page 35 example(39) x = market.broyden([0.2, 0.2]) print('q1 = ', x[0], '\nq2 = ', x[1]) ''' Example page 43 ''' # numbers don't match those of Table 3.1, but CompEcon2014' broyden gives same answer as this code example(43) opts = {'maxit': 30, 'all_x': True, 'print': True} g = NLP(lambda x: sqrt(x), 0.5) f = NLP(lambda x: (x - sqrt(x), 1 - 0.5 / sqrt(x)), 0.5) x_fp = g.fixpoint(**opts) x_br = f.broyden(**opts) x_nw = f.newton(**opts) ''' Example page 51 ''' example(51) f = MCP(lambda x: (1.01 - (1 - x)**2, 2 * (1 - x)), 0, np.inf)
# In[7]: pcrit[0] = f.zero(0.0) # Next, for each possible price shock, we compute next period log-price by adding the shock to current log-prices (the nodes of the Value object). Then, we use each next-period price to compute the expected value of an option with one-period to maturity (save the values in ```v```). We update the value function to reflect the new time-to-maturity and use ```broyden``` to solve for the critical value. We repeat this procedure until we reach the $T=300$ horizon. # In[8]: for t in range(T): v = np.zeros((1, n)) for k in range(m): pnext = Value.nodes + e[k] v += w[k] * np.maximum(K - np.exp(pnext), delta * Value(pnext)) Value[:] = v pcrit[t + 1] = f.broyden(pcrit[t]) # ### Print Critical Exercise Price 300 Periods to Expiration # In[9]: print('Critical Price = %5.2f' % np.exp(pcrit[-1])) # ### Plot Critical Exercise Prices # In[10]: fig1 = demo.figure('American Put Option Optimal Exercise Boundary', 'Periods Remaining Until Expiration', 'Exercise Price') plt.plot(np.exp(pcrit))
def f(x): fval = x - np.sqrt(x) fjac = 1 - 0.5 / np.sqrt(x) return fval, fjac problem_as_zero = NLP(f, xinit) ''' Compute fixed-point using Newton method ''' t0 = tic() x1 = problem_as_zero.newton() t1 = 100 * toc(t0) n1 = problem_as_zero.fnorm ''' Compute fixed-point using Broyden method ''' t0 = tic() x2 = problem_as_zero.broyden() t2 = 100 * toc(t0) n2 = problem_as_zero.fnorm ''' Compute fixed-point using function iteration ''' t0 = tic() x3 = problem_as_fixpoint.fixpoint() t3 = 100 * toc(t0) n3 = np.linalg.norm(problem_as_fixpoint.fx - x3) print('Hundredths of seconds required to compute fixed-point of g(x)=sqrt(x)') print('using Newton, Broyden, and function iteration methods, starting at') print('x = %4.2f\n' % xinit) print('Method Time Norm of f x\n', '-' * 40) ff = '%9s %8.2f %8.0e %5.2f' print(ff % ('Newton', t1, n1, x1)) print(ff % ('Broyden', t2, n2, x2))
T, n = 1, 15 tnodes = BasisChebyshev(n - 1, 0, T).nodes F = BasisChebyshev(n, 0, T, y=np.ones((2, n))) def resid(c, tnodes, T, n, F, r, k, eta, s0): F.c = np.reshape(c[:], (2, n)) (p, s), d = F(tnodes, [[0, 1]]) d[0] -= (r * p + k) d[1] += p ** -eta (p_0, p_T), (s_0, s_T) = F([0, T]) return np.r_[d.flatten(), s_0 - s0, s_T] storage = NLP(resid, F.c.flatten(), tnodes, T, n, F, r, k, eta, s0) c = storage.broyden(print=True) F.c = np.reshape(c, (2, n)) nplot = 501 t = np.linspace(0, T, nplot) (p, s), (dp, ds) = F(t, [[0, 1]]) res_p = dp - r * p - k res_s = ds + p ** -eta plt.figure() plt.subplot(2, 1, 1) plt.plot(t, res_p) plt.title('Residuals') plt.ylabel('d(price) residual') plt.subplot(2, 1, 2) plt.plot(t, res_s)
# ### Solve the problem # #### * Using Newton's method # In[3]: A.newton(x0) err_newton = err(A.x_sequence) # #### * Using Broyden's method # In[4]: A.broyden(x0) err_broyden = err(A.x_sequence) # #### * Using function iteration # # This method finds a zero of $f(x)$ by looking for a fixpoint of $g(x) = x-f(x)$. # In[5]: A.funcit(x0) err_funcit = err(A.x_sequence) # ### Plot results
fval = np.exp(-x) - 1 fjac = -np.exp(-x) return fval, fjac problem = NLP(f, all_x=True) ''' Randomly generate starting point ''' problem.x0 = 10 * np.random.randn(1) ''' Compute root using Newton method ''' t0 = tic() x1 = problem.newton() t1 = 100 * toc(t0) n1, x_newton = problem.fnorm, problem.x_sequence ''' Compute root using Broyden method ''' t0 = tic() x2 = problem.broyden() t2 = 100 * toc(t0) n2, x_broyden = problem.fnorm, problem.x_sequence ''' Print results ''' print('Hundredths of seconds required to compute root of exp(-x)-1,') print('via Newton and Broyden methods, starting at x = %4.2f.' % problem.x0) print('\nMethod Time Norm of f Final x') print('Newton %8.2f %8.0e %5.2f' % (t1, n1, x1)) print('Broyden %8.2f %8.0e %5.2f' % (t2, n2, x2)) ''' View current options for solver ''' print(problem.opts) ''' Describe the options ''' print(problem.opts.__doc__) ''' Plot the convergence ''' b = -abs(problem.x0) a = -b
problem = NLP(f, all_x=True) ''' Randomly generate starting point ''' problem.x0 = 10 * np.random.randn(1) ''' Compute root using Newton method ''' t0 = tic() x1 = problem.newton() t1 = 100 * toc(t0) n1, x_newton = problem.fnorm, problem.x_sequence ''' Compute root using Broyden method ''' t0 = tic() x2 = problem.broyden() t2 = 100 * toc(t0) n2, x_broyden = problem.fnorm, problem.x_sequence ''' Print results ''' print('Hundredths of seconds required to compute root of exp(-x)-1,') print('via Newton and Broyden methods, starting at x = %4.2f.' % problem.x0) print('\nMethod Time Norm of f Final x') print('Newton %8.2f %8.0e %5.2f' % (t1, n1, x1)) print('Broyden %8.2f %8.0e %5.2f' % (t2, n2, x2)) ''' View current options for solver ''' print(problem.opts) ''' Describe the options '''
# ### Approximation structure # In[3]: n, a, b = 21, 0.5, 2.5 Q = BasisChebyshev(n, a, b) c0 = np.zeros(n) c0[0] = 2 p = Q.nodes # ### Solve for effective supply function # In[4]: monopoly = NLP(resid) Q.c = monopoly.broyden(c0) # ### Setup plot # In[5]: nplot = 1000 p = np.linspace(a, b, nplot) rplot = resid(Q.c) # ### Plot effective supply # In[6]: demo.figure("Monopolist's Effective Supply Curve", 'Quantity', 'Price') plt.plot(Q(p), p)
S.c = c # update interpolation coefficients q = S(p) # compute quantity supplied at price nodes return p - q * (p ** (eta+1) / eta) - alpha * np.sqrt(q) - q ** 2 # Notice that `resid` only takes one argument. The other parameters (`Q`, `p`, `eta`, `alpha`) should be declared as such in the main script, were Python's scoping rules will find them. # ### Solve for effective supply function # # Class `NLP` defines nonlinear problems. It can be used to solve `resid` by Broyden's method. # In[7]: cournot = NLP(resid) S.c = cournot.broyden(S.c, tol=1e-12) # ### Plot demand and effective supply for m=5 firms # In[8]: prices = np.linspace(a, b, 501) fig1 = demo.figure('Cournot Effective Firm Supply Function', 'Quantity', 'Price', [0, 4], [0.5, 2]) plt.plot(5 * S(prices), prices, D(prices), prices) plt.legend(('Supply','Demand')) # ### Plot residual
T, n = 1, 15 tnodes = BasisChebyshev(n - 1, 0, T).nodes F = BasisChebyshev(n, 0, T, y=np.ones((2, n))) def resid(c, tnodes, T, n, F, r, k, eta, s0): F.c = np.reshape(c[:], (2, n)) (p, s), d = F(tnodes, [[0, 1]]) d[0] -= (r * p + k) d[1] += p**-eta (p_0, p_T), (s_0, s_T) = F([0, T]) return np.r_[d.flatten(), s_0 - s0, s_T] storage = NLP(resid, F.c.flatten(), tnodes, T, n, F, r, k, eta, s0) c = storage.broyden(print=True) F.c = np.reshape(c, (2, n)) nplot = 501 t = np.linspace(0, T, nplot) (p, s), (dp, ds) = F(t, [[0, 1]]) res_p = dp - r * p - k res_s = ds + p**-eta plt.figure() plt.subplot(2, 1, 1) plt.plot(t, res_p) plt.title('Residuals') plt.ylabel('d(price) residual') plt.subplot(2, 1, 2) plt.plot(t, res_s)
n, a, b = 21, 0.5, 2.5 Q = BasisChebyshev(n, a, b) c0 = np.zeros(n) c0[0] = 2 p = Q.nodes # ### Solve for effective supply function # In[4]: monopoly = NLP(resid) Q.c = monopoly.broyden(c0) # ### Setup plot # In[5]: nplot = 1000 p = np.linspace(a, b, nplot) rplot = resid(Q.c) # ### Plot effective supply # In[6]:
return np.array(fval), np.array(fjac) problem_as_zero = NLP(f, maxit=1500) '''% Randomly generate starting point''' xinit = np.random.randn(2) ''' Compute fixed-point using Newton method ''' t0 = tic() z1 = problem_as_zero.newton(xinit) t1 = 100 * toc(t0) n1 = problem_as_zero.fnorm ''' Compute fixed-point using Broyden method ''' t0 = tic() z2 = problem_as_zero.broyden(xinit) t2 = 100 * toc(t0) n2 = problem_as_zero.fnorm ''' Compute fixed-point using function iteration ''' t0 = tic() z3 = problem_as_fixpoint.fixpoint(xinit) t3 = 100 * toc(t0) n3 = np.linalg.norm(problem_as_fixpoint.fx - z3) ''' Print table header ''' print('Hundredths of seconds required to compute fixed-point of g(x1,x2)=[x1^2+x2^3;x1*x2-0.5]') print('using Newton, Broyden, and function iteration methods, starting at') print('x1 = {:4.2f} x2 = {:4.2f}\n\n'.format(*xinit)) print('Method Time Norm of f x1 x2\n', '-' * 45) print('Newton {:8.2f} {:8.0e} {:5.2f} {:5.2f}'.format(t1, n1, *z1))
x0 = 2.0 # ### Solve the problem # #### * Using Newton's method # In[3]: A.newton(x0) err_newton = err(A.x_sequence) # #### * Using Broyden's method # In[4]: A.broyden(x0) err_broyden = err(A.x_sequence) # #### * Using function iteration # # This method finds a zero of $f(x)$ by looking for a fixpoint of $g(x) = x-f(x)$. # In[5]: A.funcit(x0) err_funcit = err(A.x_sequence) # ### Plot results # In[6]: