def demslv07(): """Linear complementarity problem methods """ # Generate problem test data n = 8 z = np.random.randn(n, 2) - 1 a = np.min(z, 1) b = np.max(z, 1) q = np.random.randn(n) M = np.random.randn(n, n) M = -np.dot(M.T, M) x0 = np.random.randn(n) # Define the problem by creating an MCP object L = MCP(M, a, b, q, showiters=True) # Solve my applying Newton method to semi-smooth formulation t1 = tic() x1, z1 = L.zero(x0) t1 = toc(t1) # Solve my applying Newton method to minmax formulation t2 = tic() x2, z2 = L.zero(x0, transform='minmax') t2 = toc(t2) # Print results G = lambda x, z: norm(minmax(x, a, b, z)) print('Hundreds of seconds required to solve randomly generated linear \n', 'complementarity problem on R^8 using Newton and Lemke methods') print('\nAlgorithm Time Norm \n{}'.format('-' * 40)) print('Newton semismooth {:6.2f} {:8.0e}'.format(100 * t1, G(x1, z1))) print('Newton minmax {:6.2f} {:8.0e}'.format(100 * t2, G(x2, z2)))
def demslv08(): """Nonlinear complementarity problem methods Solve nonlinear complementarity problem on R^2 using semismooth and minmax methods """ ''' function to be solved''' def f(z): x, y = z fval = np.array([200 * x * (y - x ** 2) + 1 - x, 100 * (x ** 2 - y)]) fjac = np.array([[200 * (y - x ** 2) - 400 * x ** 2 - 1, 200 * x], [200 * x, -100]]) return fval, fjac # Generate problem test data z = 2 * np.random.randn(2, 2) a = 1 + np.min(z, 0) b = 1 + np.max(z, 0) x0 = np.random.randn(2) hdr = 'Hundreds of seconds required to solve nonlinear complementarity \n' \ 'problem on R^2 using minmax and semismooth formulations, with \n' \ 'randomly generated bounds \n\ta = [{:4.2f}, {:4.2f}] \n\tb = [{:4.2f}, {:4.2f}]' print(hdr.format(a[0], a[1], b[0], b[1])) print('\nAlgorithm Time Norm x1 x2\n{}'.format('-' * 56)); # Define the problem P = MCP(f, a, b, maxit=1500) '''Solve my applying Newton method to minmax formulation ''' t1 = tic() x, z = P.zero(x0, transform='minmax') print('Newton minmax {:6.2f} {:8.0e} {:5.2f} {:5.2f}'.format(100*toc(t1), norm(minmax(x, a, b, z)), *x)) '''Solve my applying Newton method to semismooth formulation ''' t2 = tic() x, z = P.zero(x0) print('Newton semismooth {:6.2f} {:8.0e} {:5.2f} {:5.2f}'.format(100*toc(t2), norm(minmax(x, a, b, z)), *x))
def demslv08(): """Nonlinear complementarity problem methods Solve nonlinear complementarity problem on R^2 using semismooth and minmax methods """ ''' function to be solved''' def f(z): x, y = z fval = np.array([200 * x * (y - x**2) + 1 - x, 100 * (x**2 - y)]) fjac = np.array([[200 * (y - x**2) - 400 * x**2 - 1, 200 * x], [200 * x, -100]]) return fval, fjac # Generate problem test data z = 2 * np.random.randn(2, 2) a = 1 + np.min(z, 0) b = 1 + np.max(z, 0) x0 = np.random.randn(2) hdr = 'Hundreds of seconds required to solve nonlinear complementarity \n' \ 'problem on R^2 using minmax and semismooth formulations, with \n' \ 'randomly generated bounds \n\ta = [{:4.2f}, {:4.2f}] \n\tb = [{:4.2f}, {:4.2f}]' print(hdr.format(a[0], a[1], b[0], b[1])) print('\nAlgorithm Time Norm x1 x2\n{}'.format( '-' * 56)) # Define the problem P = MCP(f, a, b, maxit=1500) '''Solve my applying Newton method to minmax formulation ''' t1 = tic() x, z = P.zero(x0, transform='minmax') print('Newton minmax {:6.2f} {:8.0e} {:5.2f} {:5.2f}'.format( 100 * toc(t1), norm(minmax(x, a, b, z)), *x)) '''Solve my applying Newton method to semismooth formulation ''' t2 = tic() x, z = P.zero(x0) print('Newton semismooth {:6.2f} {:8.0e} {:5.2f} {:5.2f}'.format( 100 * toc(t2), norm(minmax(x, a, b, z)), *x))
def demslv07(): """Linear complementarity problem methods """ # Generate problem test data n = 8 z = np.random.randn(n, 2) - 1 a = np.min(z, 1) b = np.max(z, 1) q = np.random.randn(n) M = np.random.randn(n, n) M = - np.dot(M.T, M) x0 = np.random.randn(n) # Define the problem by creating an MCP object L = MCP(M, a, b, q, showiters=True) # Solve my applying Newton method to semi-smooth formulation t1 = tic() x1, z1 = L.zero(x0) t1 = toc(t1) # Solve my applying Newton method to minmax formulation t2 = tic() x2, z2 = L.zero(x0, transform='minmax') t2 = toc(t2) # Print results G = lambda x, z: norm(minmax(x, a, b, z)) print('Hundreds of seconds required to solve randomly generated linear \n', 'complementarity problem on R^8 using Newton and Lemke methods') print('\nAlgorithm Time Norm \n{}'.format('-' * 40)) print('Newton semismooth {:6.2f} {:8.0e}'.format(100 * t1, G(x1, z1))) print('Newton minmax {:6.2f} {:8.0e}'.format(100 * t2, G(x2, z2)))
# ### Set up the problem # The class **MCP** is used to represent mixed-complementarity problems. To create one instance, we define the objective function and the boundaries $a$ and $b$ such that for $a \leq x \leq b$ # In[3]: def billups(x): fval = 1.01 - (1 - x) ** 2 fjac = 2 * (1 - x ) return fval, fjac a = 0 b = np.inf Billups = MCP(billups, a, b) # ### Solve by applying Newton method # * Using minmax formulation # Initial guess is $x=0$ Billups.x0 = 0.0 # In[4]: t1 = tic() x1 = Billups.zero(transform='minmax') t1 = 100*toc(t1) n1 = Billups.fnorm
numB = 2 * egt den = (gamma + k) * egt + 2 * gamma expA = 2 * k * a / (s**2) A = (numA / den)**expA B = numB / den Z = A * exp(-B * r) return Z def ss(x, r, tau): k, a, s = x resid = r + 100 * log(Z(r / 100, tau, k, a, s)) / tau return -(resid**2).sum() def ss2(x, r, tau): tmp = lambda x: ss(x, r, tau) return jacobian(tmp, x)[0] x0 = np.array([0.51, 0.05, 0.12]) hola = MCP(ss2, np.zeros(3), np.ones(3), x0, treasury_r[0], treasury_tau) x = hola.zero(print=True) print(x) objective = OP(ss, x0, treasury_r[0], treasury_tau) objective.qnewton(print=True, all_x=True) print(objective.x) print(objective.fnorm)
def demslv09(): """ Hard nonlinear complementarity problem with Billup's function Solve hard nonlinear complementarity problem on R using semismooth and minmax methods. Problem involves Billup's function. Minmax formulation fails semismooth formulation suceeds. """ warnings.simplefilter("ignore") ''' Billups' function''' def billups(x): fval = 1.01 - (1 - x)**2 fjac = 2 * (1 - x) return fval, fjac ''' Set up the problem ''' # Generate problem test data x0 = 0.0 a = 0 b = np.inf Billups = MCP(billups, a, b) # Print table header print( 'Hundreds of seconds required to solve hard nonlinear complementarity') print('problem using Newton semismooth and minmax formulations') print('Algorithm Time Norm x') # Solve by applying Newton method to minmax formulation t1 = tic() x, z = Billups.zero(x0, transform='minmax') t1 = 100 * toc(t1) print('Newton minmax {:6.2f} {:8.0e} {:5.2f}'.format( t1, norm(minmax(x, a, b, z)), x[0])) # Solve by applying Newton method to semismooth formulation t2 = tic() x, z = Billups.zero(x0) t2 = 100 * toc(t2) print('Newton semismooth {:6.2f} {:8.0e} {:5.2f}'.format( t2, norm(minmax(x, a, b, z)), x[0])) ''' Make figure ''' # Minmax reformulation of Billups' function billupsm = lambda x: minmax(x, 0, np.inf, billups(x)[0]) # Semismooth reformulation of Billups' function billupss = lambda x: ssmooth(x, 0, np.inf, billups(x)[0]) fig = plt.figure() x = np.linspace(-0.5, 2.5, 500) y = Billups.ssmooth(x) ax1 = fig.add_subplot(121, title='Difficult NCP', aspect=1, xlabel='x', xlim=[-0.5, 2.5], ylim=[-1, 1.5]) ax1.axhline(ls='--', color='gray') ax1.plot(x, billupss(x), label='Semismooth') ax1.plot(x, billupsm(x), label='Minmax') ax1.legend(loc='bottom') x = np.linspace(-0.03, 0.03, 500) ax2 = fig.add_subplot(122, title='Difficult NCP Magnified', aspect=1, xlabel='x', xlim=[-.035, .035], ylim=[-.01, .06]) ax2.axhline(ls='--', color='gray') ax2.plot(x, billupss(x), label='Semismooth') ax2.plot(x, billupsm(x), label='Minmax') ax2.legend(loc='best') plt.show()
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) x = f.zero(0.0) # ssmooth transform by default print('Using', f.opts.transform, 'transformation, x = ', x) x = f.zero(0.0, transform='minmax') print('Using', f.opts.transform, 'transformation, x = ', x, 'FAILED TO CONVERGE') # ============================================================== ''' Exercise 3.1 ''' exercise('3.1') def newtroot(c): x = c / 2 for it in range(150): fx = x**2 - c
A = (numA / den) ** expA B = numB / den Z = A * exp(-B * r) return Z def ss(x, r, tau): k, a, s = x resid = r + 100 * log(Z(r / 100, tau, k, a, s)) / tau return -(resid ** 2).sum() def ss2(x, r, tau): tmp = lambda x: ss(x, r, tau) return jacobian(tmp, x)[0] x0 = np.array([0.51, 0.05, 0.12]) hola = MCP(ss2, np.zeros(3), np.ones(3), x0, treasury_r[0], treasury_tau) x = hola.zero(print=True) print(x) objective = OP(ss, x0, treasury_r[0], treasury_tau) objective.qnewton(print=True, all_x=True) print(objective.x) print(objective.fnorm)
def f(z): x, y = z fval = np.array([200 * x * (y - x ** 2) + 1 - x, 100 * (x ** 2 - y)]) fjac = np.array([[200 * (y - x ** 2) - 400 * x ** 2 - 1, 200 * x], [200 * x, -100]]) return fval, fjac # * Generate problem test data z = 2 * np.random.randn(2, 2) a = 1 + np.min(z, 0) b = 1 + np.max(z, 0) F = MCP(f, a, b, maxit=1500) # ### Solve by applying Newton method # We'll use a random initial guess $x$ # In[4]: F.x0 = np.random.randn(2) ''' Check the Jacobian ''' F.check_jacobian()
def demslv09(): """ Hard nonlinear complementarity problem with Billup's function Solve hard nonlinear complementarity problem on R using semismooth and minmax methods. Problem involves Billup's function. Minmax formulation fails semismooth formulation suceeds. """ warnings.simplefilter("ignore") ''' Billups' function''' def billups(x): fval = 1.01 - (1 - x) ** 2 fjac = 2 * (1 - x) return fval, fjac ''' Set up the problem ''' # Generate problem test data x0 = 0.0 a = 0 b = np.inf Billups = MCP(billups, a, b) # Print table header print('Hundreds of seconds required to solve hard nonlinear complementarity') print('problem using Newton semismooth and minmax formulations') print('Algorithm Time Norm x') # Solve by applying Newton method to minmax formulation t1 = tic() x, z = Billups.zero(x0, transform='minmax') t1 = 100 * toc(t1) print('Newton minmax {:6.2f} {:8.0e} {:5.2f}'.format(t1, norm(minmax(x, a, b, z)), x[0])) # Solve by applying Newton method to semismooth formulation t2 = tic() x, z = Billups.zero(x0) t2 = 100 * toc(t2) print('Newton semismooth {:6.2f} {:8.0e} {:5.2f}'.format(t2, norm(minmax(x, a, b, z)), x[0])) ''' Make figure ''' # Minmax reformulation of Billups' function billupsm = lambda x: minmax(x, 0, np.inf, billups(x)[0]) # Semismooth reformulation of Billups' function billupss = lambda x: ssmooth(x, 0, np.inf, billups(x)[0]) fig = plt.figure() x = np.linspace(-0.5, 2.5, 500) y = Billups.ssmooth(x) ax1 = fig.add_subplot(121, title='Difficult NCP', aspect=1, xlabel='x', xlim=[-0.5, 2.5], ylim=[-1, 1.5]) ax1.axhline(ls='--', color='gray') ax1.plot(x, billupss(x), label='Semismooth') ax1.plot(x, billupsm(x), label='Minmax') ax1.legend(loc='bottom') x = np.linspace(-0.03, 0.03, 500) ax2 = fig.add_subplot(122, title='Difficult NCP Magnified', aspect=1, xlabel='x', xlim = [-.035, .035], ylim=[ -.01, .06]) ax2.axhline(ls='--', color='gray') ax2.plot(x, billupss(x), label='Semismooth') ax2.plot(x, billupsm(x), label='Minmax') ax2.legend(loc='best') plt.show()
def market(x, jac=False): quantities = x.reshape((3,3)) ps = as_ + bs * quantities.sum(0) pd = ad - bd * quantities.sum(1) ps, pd = np.meshgrid(ps, pd) fval = (pd - ps - c).flatten() return (fval, None) if jac else fval # In[4]: a = np.zeros(9) b = np.full(9, np.inf) Market = MCP(market, a, b) # In[5]: x0 = np.zeros(9) x = Market.zero(x0, transform='minmax') # In[6]: quantities = x.reshape(3,3) prices = as_ + bs * quantities.sum(0) print('Quantities = \n', quantities)
# ### Set up the problem # The class **MCP** is used to represent mixed-complementarity problems. To create one instance, we define the objective function and the boundaries $a$ and $b$ such that for $a \leq x \leq b$ # In[3]: def billups(x): fval = 1.01 - (1 - x)**2 fjac = 2 * (1 - x) return fval, fjac a = 0 b = np.inf Billups = MCP(billups, a, b) # ### Solve by applying Newton method # * Using minmax formulation # Initial guess is $x=0$ Billups.x0 = 0.0 # In[4]: t1 = tic() x1 = Billups.zero(transform='minmax') t1 = 100 * toc(t1) n1 = Billups.fnorm # * Using semismooth formulation
# In[3]: A = np.array as_ = A([9, 3, 18]) bs = A([1, 2, 1]) ad = A([42, 54, 51]) bd = A([3, 2, 1]) c = A([[0, 3, 9], [3, 0, 3], [6, 3, 0]]) params = (as_, bs, ad, bd, c) # In[4]: a = np.zeros(9) b = np.full(9, np.inf) x0 = np.zeros(9) Market = MCP(market, a, b, x0, *params) # In[5]: x = Market.zero(print=True) print('Function value at solution\n\t', Market.original(x)) print('Lower bound is binding\n\t', Market.a_is_binding) print('Upper bound is binding\n\t', Market.b_is_binding) # print(Market.ssmooth(x)) # print(Market.minmax(x)) # In[6]: quantities = x.reshape(3, 3) prices = as_ + bs * quantities.sum(0)
def f(z): x, y = z fval = np.array([200 * x * (y - x**2) + 1 - x, 100 * (x**2 - y)]) fjac = np.array([[200 * (y - x**2) - 400 * x**2 - 1, 200 * x], [200 * x, -100]]) return fval, fjac # * Generate problem test data z = 2 * np.random.randn(2, 2) a = 1 + np.min(z, 0) b = 1 + np.max(z, 0) F = MCP(f, a, b, maxit=1500) # ### Solve by applying Newton method # We'll use a random initial guess $x$ # In[4]: F.x0 = np.random.randn(2) ''' Check the Jacobian ''' F.check_jacobian() # * Using minmax formulation # In[5]: t0 = tic()
def market(x, jac=False): quantities = x.reshape((3, 3)) ps = as_ + bs * quantities.sum(0) pd = ad - bd * quantities.sum(1) ps, pd = np.meshgrid(ps, pd) fval = (pd - ps - c).flatten() return (fval, None) if jac else fval # In[4]: a = np.zeros(9) b = np.full(9, np.inf) Market = MCP(market, a, b) # In[5]: x0 = np.zeros(9) x = Market.zero(x0, transform='minmax') # In[6]: quantities = x.reshape(3, 3) prices = as_ + bs * quantities.sum(0) print('Quantities = \n', quantities) print('Prices = \n', prices) print('Net exports =\n', quantities.sum(0) - quantities.sum(1)) # * In autarky