def test_infinite_bounds(self): import numpy f = lambda x: [-x**3 + 1.2, -numpy.atleast_2d(3*x**2)] lb = numpy.array([-numpy.inf]) ub = numpy.array([numpy.inf]) x0 = numpy.array([0.3]) res = ncpsolve(f, lb, ub, x0)
def test_serial_solve(self): from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0 = np.array([1.25, 0.01, 0.01, 0.50]) lb = np.array([0.00, 0.00, 0.00, 0.00]) ub = np.array([inf, inf, inf, inf]) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal assert_almost_equal(sol, resp) N = 100 d = len(x0) s_x0 = np.column_stack([x0] * N) s_lb = np.column_stack([lb] * N) s_ub = np.column_stack([ub] * N) def serial_fun(xvec): resp = np.zeros((d, N)) dresp = np.zeros((d, d, N)) for n in range(N): [v, dv] = fun(xvec[:, n]) resp[:, n] = v dresp[:, :, n] = dv return [resp, dresp] serial_fun(s_x0) serial_sol = ncpsolve(serial_fun, s_lb, s_ub, s_x0, serial=True)
def test_serial_solve(self): from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0=np.array( [1.25, 0.01, 0.01, 0.50] ) lb=np.array( [0.00, 0.00, 0.00, 0.00] ) ub=np.array( [inf, inf, inf, inf] ) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [ 1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal assert_almost_equal(sol, resp) N = 100 d = len(x0) s_x0 = np.column_stack([x0]*N) s_lb = np.column_stack([lb]*N) s_ub = np.column_stack([ub]*N) def serial_fun(xvec): resp = np.zeros( (d,N) ) dresp = np.zeros( (d,d,N) ) for n in range(N): [v, dv] = fun(xvec[:,n]) resp[:,n] = v dresp[:,:,n] = dv return [resp, dresp] serial_fun(s_x0) serial_sol = ncpsolve( serial_fun, s_lb, s_ub, s_x0, serial=True)
def test_complementarities(self): import numpy from numpy.testing import assert_almost_equal f = lambda x: [-x**3 + 1.2, -numpy.atleast_2d(3*x**2)] lb = numpy.array([-1]) ub = numpy.array([1]) x0 = numpy.array([0.3]) res = ncpsolve(f, lb, ub, x0) assert_almost_equal( res, 1.0)
def test_josephy(self): import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0=np.array( [1.25, 0.01, 0.01, 0.50] ) lb=np.array( [0.00, 0.00, 0.00, 0.00] ) ub=np.array( [inf, inf, inf, inf] ) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = numpy.array( [ 1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal assert_almost_equal(sol, resp)
def test_serial_problems(self): from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0 = np.array([1.25, 0.01, 0.01, 0.50]) lb = np.array([0.00, 0.00, 0.00, 0.00]) ub = np.array([inf, inf, inf, inf]) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal, assert_equal assert_almost_equal(sol, resp) N = 10 d = len(x0) serial_sol_check = np.zeros((d, N)) for n in range(N): serial_sol_check[:, n] = resp[0] s_x0 = np.column_stack([x0] * N) s_lb = np.column_stack([lb] * N) s_ub = np.column_stack([ub] * N) def serial_fun(xvec, deriv=None): resp = np.zeros((d, N)) if deriv == 'serial': dresp = np.zeros((d, d, N)) elif deriv == 'full': dresp = np.zeros((d, N, d, N)) for n in range(N): [v, dv] = fun(xvec[:, n]) resp[:, n] = v if deriv == 'serial': dresp[:, :, n] = dv elif deriv == 'full': dresp[:, n, :, n] = dv # if deriv=='full': # dresp = dresp.swapaxes(0,2).swapaxes(1,3) if deriv is None: return resp else: return [resp, dresp] serial_fun_val = lambda x: serial_fun(x) serial_fun_serial_jac = lambda x: serial_fun(x, deriv='serial')[1] serial_fun_full_jac = lambda x: serial_fun(x, deriv='full')[1] from dolo.numeric.solver import solver print("Serial Bounded solution : ncpsolve") serial_sol_with_bounds_without_jac = solver(serial_fun_val, s_x0, lb=s_lb, ub=s_ub, method='ncpsolve', serial_problem=True) print("Serial Bounded solution (with jacobian) : ncpsolve") serial_sol_with_bounds_with_jac = solver(serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_serial_jac, method='ncpsolve', serial_problem=True) print("Bounded solution : ncpsolve") sol_with_bounds_without_jac = solver(serial_fun_val, s_x0, s_lb, s_ub, method='ncpsolve', serial_problem=False) print("Bounded solution (with jacobian) : ncpsolve") sol_with_bounds_with_jac = solver(serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_full_jac, method='ncpsolve', serial_problem=False) print("Serial Unbounded solution : ncpsolve") serial_sol_without_bounds_without_jac = solver(serial_fun_val, s_x0, method='newton', serial_problem=True) print("Unbounded solution : fsolve") sol_without_bounds_without_jac = solver(serial_fun_val, s_x0, method='fsolve', serial_problem=False) print("Unbounded solution (with jacobian) : fsolve") sol_without_bounds = solver(serial_fun_val, s_x0, jac=serial_fun_full_jac, method='fsolve', serial_problem=False) print("Unbounded solution : lmmcp") sol_without_bounds = solver(serial_fun_val, s_x0, jac=serial_fun_full_jac, method='lmmcp', serial_problem=False)
def deterministic_solve_comp(model, start_s, T=10): # simulation is assumed to return to steady-state dr = approximate_controls(model, order=1, ) final_s = model.calibration['states'].copy() final_x = model.calibration['controls'].copy() start_x = dr( numpy.atleast_2d( start_s.ravel()).T ).flatten() final = numpy.concatenate( [final_s, final_x]) start = numpy.concatenate( [start_s, start_x]) print(final) print(start) n_s = len(final_s) n_x = len(final_x) initial_guess = numpy.concatenate( [start*(1-l) + final*l for l in linspace(0.0,1.0,T+1)] ) initial_guess = initial_guess.reshape( (-1, n_s + n_x)).T N = initial_guess.shape[1] initial_guess = numpy.row_stack( [initial_guess, numpy.zeros( (n_x, N) ), numpy.zeros( (n_x, N) )] ) # initial_guess = initial_guess[n_s:-n_x] lower_bound = initial_guess*0 lower_bound[:n_s+n_x,:] = -big_number lower_bound[:,-1] = -big_number upper_bound = lower_bound*0 + big_number print( sum( (upper_bound - initial_guess)<=0 ) ) print( sum( (lower_bound - initial_guess)>0 ) ) res = det_residual_comp(model, initial_guess, start_s, final_x) print(abs(res).max()) sh = initial_guess.shape fobj = lambda vec: det_residual_comp(model, vec, start_s, final_x) fobj = lambda vec: det_residual_comp(model, vec.reshape(sh), start_s, final_x).ravel() from dolo.numeric.solver import MyJacobian # dres = MyJacobian(fobj)(initial_guess.ravel()) # # print(dres.shape) # print(numpy.linalg.matrix_rank(dres)) f = lambda x: [fobj(x), MyJacobian(fobj)(x)] import time t = time.time() initial_guess = initial_guess.ravel() lower_bound = lower_bound.ravel() upper_bound = upper_bound.ravel() from dolo.numeric.ncpsolve import ncpsolve sol = ncpsolve( f, lower_bound, upper_bound, initial_guess, verbose=True) # from dolo.numeric.solver import solver # sol = solver(fobj, initial_guess, lb=lower_bound, ub=upper_bound, serial_problem=False, method='ncpsolve', verbose=True) print(sol.shape) s = time.time() print('Elapsed : {}'.format(s-t)) return sol[:n_s+n_x,:]
if __name__ == '__main__': from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0=np.array( [1.25, 0.01, 0.01, 0.50] ) lb=np.array( [0.00, 0.00, 0.00, 0.00] ) ub=np.array( [inf, inf, inf, inf] ) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [ 1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal, assert_equal assert_almost_equal(sol, resp[0]) N = 2 d = len(x0) serial_sol_check = np.zeros((d,N)) for n in range(N): serial_sol_check[:,n] = resp[0]
def deterministic_solve_comp(model, start_s, T=10): # simulation is assumed to return to steady-state dr = approximate_controls(model, order=1) final_s = model.calibration["states"].copy() final_x = model.calibration["controls"].copy() start_x = dr(numpy.atleast_2d(start_s.ravel()).T).flatten() final = numpy.concatenate([final_s, final_x]) start = numpy.concatenate([start_s, start_x]) print(final) print(start) n_s = len(final_s) n_x = len(final_x) initial_guess = numpy.concatenate([start * (1 - l) + final * l for l in linspace(0.0, 1.0, T + 1)]) initial_guess = initial_guess.reshape((-1, n_s + n_x)).T N = initial_guess.shape[1] initial_guess = numpy.row_stack([initial_guess, numpy.zeros((n_x, N)), numpy.zeros((n_x, N))]) # initial_guess = initial_guess[n_s:-n_x] lower_bound = initial_guess * 0 lower_bound[: n_s + n_x, :] = -big_number lower_bound[:, -1] = -big_number upper_bound = lower_bound * 0 + big_number print(sum((upper_bound - initial_guess) <= 0)) print(sum((lower_bound - initial_guess) > 0)) res = det_residual_comp(model, initial_guess, start_s, final_x) print(abs(res).max()) sh = initial_guess.shape fobj = lambda vec: det_residual_comp(model, vec, start_s, final_x) fobj = lambda vec: det_residual_comp(model, vec.reshape(sh), start_s, final_x).ravel() from dolo.numeric.solver import MyJacobian # dres = MyJacobian(fobj)(initial_guess.ravel()) # # print(dres.shape) # print(numpy.linalg.matrix_rank(dres)) f = lambda x: [fobj(x), MyJacobian(fobj)(x)] import time t = time.time() initial_guess = initial_guess.ravel() lower_bound = lower_bound.ravel() upper_bound = upper_bound.ravel() from dolo.numeric.ncpsolve import ncpsolve sol = ncpsolve(f, lower_bound, upper_bound, initial_guess, verbose=True) # from dolo.numeric.solver import solver # sol = solver(fobj, initial_guess, lb=lower_bound, ub=upper_bound, serial_problem=False, method='ncpsolve', verbose=True) print(sol.shape) s = time.time() print("Elapsed : {}".format(s - t)) return sol[: n_s + n_x, :]
def solver(fobj, x0, lb=None, ub=None, jac=None, method='lmmcp', infos=False, serial_problem=False, verbose=False, options={}): in_shape = x0.shape if serial_problem: ffobj = fobj else: ffobj = lambda x: fobj(x.reshape(in_shape)).flatten() # standardize jacobian if jac is not None: if not serial_problem: pp = np.prod(in_shape) def Dffobj(t): tt = t.reshape(in_shape) dval = jac(tt) return dval.reshape((pp, pp)) else: Dffobj = jac elif serial_problem: from dolo.numeric.newton import SerialDifferentiableFunction Dffobj = SerialDifferentiableFunction(fobj, in_shape) else: Dffobj = MyJacobian(ffobj) if lb == None: lb = -np.inf * np.ones(len(x0.flatten())) if ub == None: ub = np.inf * np.ones(len(x0.flatten())).flatten() if not serial_problem: lb = lb.flatten() ub = ub.flatten() if not serial_problem: x0 = x0.flatten() if method == 'fsolve': import scipy.optimize as optimize factor = options.get('factor') factor = factor if factor else 1 [sol, infodict, ier, msg] = optimize.fsolve(ffobj, x0, fprime=Dffobj, factor=factor, full_output=True, xtol=1e-10, epsfcn=1e-9) if ier != 1: print(msg) elif method == 'newton': from dolo.numeric.newton import serial_newton as newton_solver fun = lambda x: [ffobj(x), Dffobj(x)] [sol, nit] = newton_solver(fun, x0, verbose=verbose) elif method == 'lmmcp': from dolo.numeric.extern.lmmcp import lmmcp sol = lmmcp(lambda t: -ffobj(t), lambda u: -Dffobj(u), x0, lb, ub, verbose=verbose, options=options) elif method == 'ncpsolve': from dolo.numeric.ncpsolve import ncpsolve fun = lambda x: [ffobj(x), Dffobj(x)] if serial_problem: jactype = 'serial' [sol, nit] = ncpsolve(fun, lb, ub, x0, verbose=verbose, infos=True, jactype='serial') else: raise Exception('Unknown method : ' + str(method)) sol = sol.reshape(in_shape) if infos: return [sol, nit] else: return sol
def solver(fobj, x0, lb=None, ub=None, jac=None, method='lmmcp', infos=False, serial_problem=False, verbose=False, options={}): in_shape = x0.shape if serial_problem: ffobj = fobj else: ffobj = lambda x: fobj(x.reshape(in_shape)).flatten() # standardize jacobian if jac is not None: if not serial_problem: pp = np.prod(in_shape) def Dffobj(t): tt = t.reshape(in_shape) dval = jac(tt) return dval.reshape( (pp,pp) ) else: Dffobj = jac elif serial_problem: Dffobj = MySerialJacobian(fobj, in_shape) else: Dffobj = MyJacobian(ffobj) if lb == None: lb = -np.inf*np.ones(len(x0.flatten())) if ub == None: ub = np.inf*np.ones(len(x0.flatten())).flatten() if not serial_problem: lb = lb.flatten() ub = ub.flatten() if not serial_problem: x0 = x0.flatten() if method == 'fsolve': import scipy.optimize as optimize factor = options.get('factor') factor = factor if factor else 1 [sol,infodict,ier,msg] = optimize.fsolve(ffobj, x0, fprime=Dffobj, factor=factor, full_output=True, xtol=1e-10, epsfcn=1e-9) if ier != 1: print(msg) elif method == 'newton': from dolo.numeric.newton import newton_solver fun = lambda x: [ffobj(x), Dffobj(x) ] [sol,nit] = newton_solver(fun,x0, verbose=verbose, infos=True) elif method == 'lmmcp': from dolo.numeric.extern.lmmcp import lmmcp sol = lmmcp(lambda t: -ffobj(t), lambda u: -Dffobj(u),x0,lb,ub,verbose=verbose,options=options) elif method == 'ncpsolve': from dolo.numeric.ncpsolve import ncpsolve fun = lambda x: [ffobj(x), Dffobj(x) ] [sol,nit] = ncpsolve(fun,lb,ub,x0, verbose=verbose, infos=True, serial=serial_problem) sol = sol.reshape(in_shape) if infos: return [sol, nit] else: return sol
serial_fun(s_x0) serial_sol = ncpsolve(serial_fun, s_lb, s_ub, s_x0, serial=True) if __name__ == '__main__': from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0 = np.array([1.25, 0.01, 0.01, 0.50]) lb = np.array([0.00, 0.00, 0.00, 0.00]) ub = np.array([inf, inf, inf, inf]) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal, assert_equal assert_almost_equal(sol, resp[0]) N = 2 d = len(x0) serial_sol_check = np.zeros((d, N)) for n in range(N): serial_sol_check[:, n] = resp[0]
def test_serial_problems(self): from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0=np.array( [1.25, 0.01, 0.01, 0.50] ) lb=np.array( [0.00, 0.00, 0.00, 0.00] ) ub=np.array( [inf, inf, inf, inf] ) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [ 1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal, assert_equal assert_almost_equal(sol, resp) N = 10 d = len(x0) serial_sol_check = np.zeros((d,N)) for n in range(N): serial_sol_check[:,n] = resp[0] s_x0 = np.column_stack([x0]*N) s_lb = np.column_stack([lb]*N) s_ub = np.column_stack([ub]*N) def serial_fun(xvec, deriv=None): resp = np.zeros( (d,N) ) if deriv=='serial': dresp = np.zeros( (d,d,N) ) elif deriv=='full': dresp = np.zeros( (d,N,d,N) ) for n in range(N): [v, dv] = fun(xvec[:,n]) resp[:,n] = v if deriv=='serial': dresp[:,:,n] = dv elif deriv=='full': dresp[:,n,:,n] = dv # if deriv=='full': # dresp = dresp.swapaxes(0,2).swapaxes(1,3) if deriv is None: return resp else: return [resp, dresp] serial_fun_val = lambda x: serial_fun(x) serial_fun_serial_jac = lambda x: serial_fun(x,deriv='serial')[1] serial_fun_full_jac = lambda x: serial_fun(x,deriv='full')[1] from dolo.numeric.solver import solver print("Serial Bounded solution : ncpsolve") serial_sol_with_bounds_without_jac = solver( serial_fun_val, s_x0, lb=s_lb, ub=s_ub, method='ncpsolve', serial_problem=True) print("Serial Bounded solution (with jacobian) : ncpsolve") serial_sol_with_bounds_with_jac = solver( serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_serial_jac, method='ncpsolve', serial_problem=True) print("Bounded solution : ncpsolve") sol_with_bounds_without_jac = solver( serial_fun_val, s_x0, s_lb, s_ub, method='ncpsolve', serial_problem=False) print("Bounded solution (with jacobian) : ncpsolve") sol_with_bounds_with_jac = solver( serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_full_jac, method='ncpsolve', serial_problem=False) print("Serial Unbounded solution : ncpsolve") serial_sol_without_bounds_without_jac = solver( serial_fun_val, s_x0, method='newton', serial_problem=True) print("Unbounded solution : fsolve") sol_without_bounds_without_jac = solver( serial_fun_val, s_x0, method='fsolve', serial_problem=False) print("Unbounded solution (with jacobian) : fsolve") sol_without_bounds = solver( serial_fun_val, s_x0, jac=serial_fun_full_jac, method='fsolve', serial_problem=False) print("Unbounded solution : lmmcp") sol_without_bounds = solver( serial_fun_val, s_x0, jac=serial_fun_full_jac, method='lmmcp', serial_problem=False)