def test_3(self): """ This test just locks in the evaluation of the criterion function for the original Keane & Wolpin data. """ # Sample one task resources = ['kw_data_one.ini', 'kw_data_two.ini', 'kw_data_three.ini'] fname = np.random.choice(resources) # Select expected result rslt = None if 'one' in fname: rslt = 0.261487735867433 elif 'two' in fname: rslt = 1.126138097174159 elif 'three' in fname: rslt = 1.895699121131644 # Evaluate criterion function at true values. respy_obj = RespyCls(TEST_RESOURCES_DIR + '/' + fname) respy_obj.unlock() respy_obj.set_attr('maxfun', 0) respy_obj.lock() simulate(respy_obj) _, val = estimate(respy_obj) np.testing.assert_allclose(val, rslt)
def test_1(self): """ Compare results from the RESTUD program and the RESPY package. """ # Impose some constraints on the initialization file which ensures that # the problem can be solved by the RESTUD code. The code is adjusted to # run with zero draws. constraints = dict() constraints['edu'] = (10, 20) constraints['is_deterministic'] = True # Generate random initialization file. The RESTUD code uses the same # random draws for the solution and simulation of the model. Thus, # the number of draws is required to be less or equal to the number # of agents. init_dict = generate_random_dict(constraints) num_agents_sim = init_dict['SIMULATION']['agents'] num_draws_emax = init_dict['SOLUTION']['draws'] if num_draws_emax < num_agents_sim: init_dict['SOLUTION']['draws'] = num_agents_sim print_init_dict(init_dict) # Indicate RESTUD code the special case of zero disturbance. open('.restud.testing.scratch', 'a').close() # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') # This flag aligns the random components between the RESTUD program and # RESPY package. The existence of the file leads to the RESTUD program # to write out the random components. model_paras, edu_start, edu_max, num_agents_sim, num_periods, \ num_draws_emax, delta = \ dist_class_attributes(respy_obj, 'model_paras', 'edu_start', 'edu_max', 'num_agents_sim', 'num_periods', 'num_draws_emax', 'delta') transform_respy_to_restud(model_paras, edu_start, edu_max, num_agents_sim, num_periods, num_draws_emax, delta) # Solve model using RESTUD code. cmd = TEST_RESOURCES_DIR + '/kw_dp3asim' subprocess.check_call(cmd, shell=True) # Solve model using RESPY package. simulate(respy_obj) # Compare the simulated datasets generated by the programs. py = pd.DataFrame( np.array(np.genfromtxt('data.respy.dat', missing_values='.'), ndmin=2)[:, -4:]) fort = pd.DataFrame( np.array(np.genfromtxt('ftest.txt', missing_values='.'), ndmin=2)[:, -4:]) assert_frame_equal(py, fort)
def test_5(self): """ Test the scripts. """ # Constraints that ensure that two alternative initialization files # can be used for the same simulated data. for _ in range(10): constr = dict() constr['periods'] = np.random.randint(1, 4) constr['agents'] = np.random.randint(5, 100) constr['is_estimation'] = True constr['edu'] = (7, 15) # Simulate a dataset generate_init(constr) respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) # Create output to process a baseline. respy_obj.unlock() respy_obj.set_attr('maxfun', 0) respy_obj.lock() estimate(respy_obj) # Potentially evaluate at different points. generate_init(constr) init_file = 'test.respy.ini' file_sim = 'sim.respy.dat' gradient = np.random.choice([True, False]) single = np.random.choice([True, False]) resume = np.random.choice([True, False]) update = np.random.choice([True, False]) action = np.random.choice(['fix', 'free', 'value']) num_draws = np.random.randint(1, 20) # The set of identifiers is a little complicated as we only allow # sampling of the diagonal terms of the covariance matrix. Otherwise, # we sometimes run into the problem of very ill conditioned matrices # resulting in a failed Cholesky decomposition. set_ = list(range(16)) + [16, 18, 21, 25] identifiers = np.random.choice(set_, num_draws, replace=False) values = np.random.uniform(size=num_draws) scripts_estimate(resume, single, init_file, gradient) scripts_update(init_file) # The error can occur as the RESPY package is actually running an # estimation step that can result in very ill-conditioned covariance # matrices. try: scripts_simulate(update, init_file, file_sim, None) scripts_modify(identifiers, values, action, init_file) except np.linalg.linalg.LinAlgError: pass
def run(spec_dict, fname, grid_slaves): """ Run an estimation task that allows to get a sense of the scalability of the code. """ dirname = fname.replace('.ini', '') os.mkdir(dirname) os.chdir(dirname) respy_obj = respy.RespyCls(SPEC_DIR + fname) respy_obj.unlock() respy_obj.set_attr('is_debug', False) respy_obj.set_attr('file_est', '../data.respy.dat') for key_ in spec_dict.keys(): respy_obj.set_attr(key_, spec_dict[key_]) respy_obj.lock() maxfun = respy_obj.get_attr('maxfun') min_slave = min(grid_slaves) # Simulate the baseline dataset, which is used regardless of the number # of slaves. respy.simulate(respy_obj) respy_obj.write_out() # Iterate over the grid of requested slaves. for num_slaves in grid_slaves: dirname = '{:}'.format(num_slaves) os.mkdir(dirname) os.chdir(dirname) respy_obj.unlock() respy_obj.set_attr('num_procs', num_slaves + 1) if num_slaves > 1: respy_obj.set_attr('is_parallel', True) else: respy_obj.set_attr('is_parallel', False) respy_obj.lock() respy_obj.write_out() start_time = datetime.now() respy.estimate(respy_obj) finish_time = datetime.now() if num_slaves == min_slave: duration_baseline = finish_time - start_time num_evals = get_actual_evaluations() os.chdir('../') record_information(start_time, finish_time, num_slaves, maxfun, duration_baseline, num_evals, min_slave) os.chdir('../')
def test_5(self): """ This test ensures that the logging looks exactly the same for the different versions. """ max_draws = np.random.randint(10, 300) # Generate random initialization file constr = dict() constr['flag_parallelism'] = False constr['max_draws'] = max_draws constr['flag_interpolation'] = False constr['maxfun'] = 0 # Generate random initialization file init_dict = generate_init(constr) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') # Iterate over alternative implementations base_sol_log, base_est_info_log, base_est_log = None, None, None base_sim_log = None num_periods = init_dict['BASICS']['periods'] write_draws(num_periods, max_draws) for version in ['FORTRAN', 'PYTHON']: respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() simulate(respy_obj) estimate(respy_obj) # Check for identical logging if base_sol_log is None: base_sol_log = open('sol.respy.log', 'r').read() assert open('sol.respy.log', 'r').read() == base_sol_log # Check for identical logging if base_sim_log is None: base_sim_log = open('sim.respy.log', 'r').read() assert open('sim.respy.log', 'r').read() == base_sim_log if base_est_info_log is None: base_est_info_log = open('est.respy.info', 'r').read() assert open('est.respy.info', 'r').read() == base_est_info_log if base_est_log is None: base_est_log = open('est.respy.log', 'r').readlines() compare_est_log(base_est_log)
def test_6(self): """ This test ensures that the logging looks exactly the same for the different versions. """ max_draws = np.random.randint(10, 300) # Generate random initialization file constr = dict() constr['flag_parallelism'] = False constr['max_draws'] = max_draws constr['flag_interpolation'] = False constr['maxfun'] = 0 # Generate random initialization file init_dict = generate_init(constr) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') # Iterate over alternative implementations base_sol_log, base_est_info_log, base_est_log = None, None, None base_sim_log = None num_periods = init_dict['BASICS']['periods'] write_draws(num_periods, max_draws) for version in ['FORTRAN', 'PYTHON']: respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() simulate(respy_obj) estimate(respy_obj) # Check for identical logging if base_sol_log is None: base_sol_log = open('sol.respy.log', 'r').read() assert open('sol.respy.log', 'r').read() == base_sol_log # Check for identical logging if base_sim_log is None: base_sim_log = open('sim.respy.log', 'r').read() assert open('sim.respy.log', 'r').read() == base_sim_log if base_est_info_log is None: base_est_info_log = open('est.respy.info', 'r').read() assert open('est.respy.info', 'r').read() == base_est_info_log if base_est_log is None: base_est_log = open('est.respy.log', 'r').readlines() compare_est_log(base_est_log)
def test_1(self): """ Compare results from the RESTUD program and the RESPY package. """ # Impose some constraints on the initialization file which ensures that # the problem can be solved by the RESTUD code. The code is adjusted to # run with zero draws. constraints = dict() constraints['edu'] = (10, 20) constraints['is_deterministic'] = True # Generate random initialization file. The RESTUD code uses the same # random draws for the solution and simulation of the model. Thus, # the number of draws is required to be less or equal to the number # of agents. init_dict = generate_random_dict(constraints) num_agents_sim = init_dict['SIMULATION']['agents'] num_draws_emax = init_dict['SOLUTION']['draws'] if num_draws_emax < num_agents_sim: init_dict['SOLUTION']['draws'] = num_agents_sim print_init_dict(init_dict) # Indicate RESTUD code the special case of zero disturbance. open('.restud.testing.scratch', 'a').close() # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') # This flag aligns the random components between the RESTUD program and # RESPY package. The existence of the file leads to the RESTUD program # to write out the random components. model_paras, edu_start, edu_max, num_agents_sim, num_periods, \ num_draws_emax, delta = \ dist_class_attributes(respy_obj, 'model_paras', 'edu_start', 'edu_max', 'num_agents_sim', 'num_periods', 'num_draws_emax', 'delta') transform_respy_to_restud(model_paras, edu_start, edu_max, num_agents_sim, num_periods, num_draws_emax, delta) # Solve model using RESTUD code. cmd = TEST_RESOURCES_DIR + '/kw_dp3asim' subprocess.check_call(cmd, shell=True) # Solve model using RESPY package. simulate(respy_obj) # Compare the simulated datasets generated by the programs. py = pd.DataFrame(np.array(np.genfromtxt('data.respy.dat', missing_values='.'), ndmin=2)[:, -4:]) fort = pd.DataFrame(np.array(np.genfromtxt('ftest.txt', missing_values='.'), ndmin=2)[:, -4:]) assert_frame_equal(py, fort)
def test_1(self): """ Testing whether random model specifications can be simulated and processed. """ # Generate random initialization file generate_init() respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) process(respy_obj)
def simulate_specification(respy_obj, subdir, update, paras=None): """ Simulate results to assess the estimation performance. Note that we do not update the object that is passed in. """ os.mkdir(subdir) os.chdir(subdir) respy_copy = deepcopy(respy_obj) if update: assert (paras is not None) respy_copy.update_model_paras(paras) respy_copy.write_out() respy.simulate(respy_copy) os.chdir('../')
def test_6(self): """ Test short estimation tasks. """ # Constraints that ensures that the maximum number of iterations and # the number of function evaluations is set to the minimum values of # one. constr = dict() constr['is_estimation'] = True generate_init(constr) # Run estimation task. respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) estimate(respy_obj)
def test_2(self): """ This test ensures that the evaluation of the criterion function at the starting value is identical between the different versions. """ max_draws = np.random.randint(10, 100) # Generate random initialization file constr = dict() constr['flag_parallelism'] = False constr['max_draws'] = max_draws constr['flag_interpolation'] = False constr['maxfun'] = 0 # Generate random initialization file init_dict = generate_init(constr) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') # Simulate a dataset simulate(respy_obj) # Iterate over alternative implementations base_x, base_val = None, None num_periods = init_dict['BASICS']['periods'] write_draws(num_periods, max_draws) for version in ['FORTRAN', 'PYTHON']: respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() x, val = estimate(respy_obj) # Check for the returned parameters. if base_x is None: base_x = x np.testing.assert_allclose(base_x, x) # Check for the value of the criterion function. if base_val is None: base_val = val np.testing.assert_allclose(base_val, val)
def test_4(self): """ Test the solution of deterministic model with ambiguity and interpolation. This test has the same result as in the absence of random variation in payoffs, it does not matter whether the environment is ambiguous or not. """ # Solve specified economy for version in ['FORTRAN', 'PYTHON']: respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_fifth.respy.ini') respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() respy_obj = simulate(respy_obj) # Assess expected future value val = respy_obj.get_attr('periods_emax')[0, :1] np.testing.assert_allclose(val, 88750) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, -1.0)
def test_3(self): """ Test the solution of deterministic model with ambiguity and interpolation. This test has the same result as in the absence of random variation in payoffs, it does not matter whether the environment is ambiguous or not. """ # Solve specified economy for version in ['FORTRAN', 'PYTHON']: respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_fifth.respy.ini') respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() respy_obj = simulate(respy_obj) # Assess expected future value val = respy_obj.get_attr('periods_emax')[0, :1] np.testing.assert_allclose(val, 88750) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, -1.0)
def test_3(self): """ Testing whether the a simulated dataset and the evaluation of the criterion function are the same for a tiny delta and a myopic agent. """ # Generate random initialization dictionary constr = dict() constr['maxfun'] = 0 generate_init(constr) # Iterate over alternative discount rates. base_data, base_val = None, None for delta in [0.00, 0.000001]: respy_obj = RespyCls('test.respy.ini') respy_obj.unlock() respy_obj.set_attr('delta', delta) respy_obj.lock() simulate(respy_obj) # This parts checks the equality of simulated dataset for the # different versions of the code. data_frame = pd.read_csv('data.respy.dat', delim_whitespace=True) if base_data is None: base_data = data_frame.copy() assert_frame_equal(base_data, data_frame) # This part checks the equality of an evaluation of the # criterion function. _, crit_val = estimate(respy_obj) if base_val is None: base_val = crit_val np.testing.assert_allclose(base_val, crit_val, rtol=1e-03, atol=1e-03)
def test_1(self): """ Testing ten admissible realizations of state space for the first three periods. """ # Generate constraint periods constraints = dict() constraints['periods'] = np.random.randint(3, 5) # Generate random initialization file generate_init(constraints) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Distribute class attributes states_number_period = respy_obj.get_attr('states_number_period') states_all = respy_obj.get_attr('states_all') # The next hard-coded results assume that at least two more # years of education are admissible. edu_max = respy_obj.get_attr('edu_max') edu_start = respy_obj.get_attr('edu_start') if edu_max - edu_start < 2: return # The number of admissible states in the first three periods for j, number_period in enumerate([1, 4, 13]): assert (states_number_period[j] == number_period) # The actual realizations of admissible states in period one assert ((states_all[0, 0, :] == [0, 0, 0, 1]).all()) # The actual realizations of admissible states in period two states = [[0, 0, 0, 0], [0, 0, 1, 1], [0, 1, 0, 0]] states += [[1, 0, 0, 0]] for j, state in enumerate(states): assert ((states_all[1, j, :] == state).all()) # The actual realizations of admissible states in period three states = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 1, 1]] states += [[0, 0, 2, 1], [0, 1, 0, 0], [0, 1, 1, 0]] states += [[0, 1, 1, 1], [0, 2, 0, 0], [1, 0, 0, 0]] states += [[1, 0, 1, 0], [1, 0, 1, 1], [1, 1, 0, 0]] states += [[2, 0, 0, 0]] for j, state in enumerate(states): assert ((states_all[2, j, :] == state).all())
def scripts_simulate(update, init_file, file_sim, solved): """ Wrapper for the estimation. """ # Read in baseline model specification. if solved is not None: respy_obj = pkl.load(open(solved, 'rb')) else: respy_obj = RespyCls(init_file) # Update parametrization of the model if resuming from a previous # estimation run. if update: respy_obj.update_model_paras(get_est_info()['paras_step']) # Update file for output. if file_sim is not None: respy_obj.unlock() respy_obj.set_attr('file_sim', file_sim) respy_obj.lock() # Optimize the criterion function. simulate(respy_obj)
def test_2(self): """ This test ensures that the record files are identical. """ # Generate random initialization file. The number of periods is # higher than usual as only FORTRAN implementations are used to # solve the random request. This ensures that also some cases of # interpolation are explored. constr = dict() constr['version'] = 'FORTRAN' constr['periods'] = np.random.randint(3, 10) constr['maxfun'] = 0 init_dict = generate_random_dict(constr) base_sol_log, base_est_info_log, base_est_log = None, None, None for is_parallel in [False, True]: init_dict['PARALLELISM']['flag'] = is_parallel print_init_dict(init_dict) respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) estimate(respy_obj) # Check for identical records if base_sol_log is None: base_sol_log = open('sol.respy.log', 'r').read() assert open('sol.respy.log', 'r').read() == base_sol_log if base_est_info_log is None: base_est_info_log = open('est.respy.info', 'r').read() assert open('est.respy.info', 'r').read() == base_est_info_log if base_est_log is None: base_est_log = open('est.respy.log', 'r').readlines() compare_est_log(base_est_log)
def test_5(self): """ This test reproduces the results from evaluations of the criterion function for previously analyzed scenarios. """ # Prepare setup version = str(sys.version_info[0]) fname = 'test_vault_' + version + '.respy.pkl' tests = pkl.load(open(TEST_RESOURCES_DIR + '/' + fname, 'rb')) # We want this test to run even when not FORTRAN version is available. while True: idx = np.random.randint(0, len(tests)) init_dict, crit_val = tests[idx] version = init_dict['PROGRAM']['version'] if not IS_FORTRAN and version == 'FORTRAN': pass else: break # In the case where no parallelism is available, we need to ensure # that the request remains valid. This is fine as the disturbances # are aligned across parallel and scalar implementation. if not IS_PARALLEL: init_dict['PARALLELISM']['flag'] = False if not IS_FORTRAN: init_dict['PROGRAM']['version'] = 'PYTHON' print_init_dict(init_dict) respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) _, val = estimate(respy_obj) np.testing.assert_almost_equal(val, crit_val)
def test_4(self): """ Test the evaluation of the criterion function for random requests, not just at the true values. """ # Constraints that ensure that two alternative initialization files # can be used for the same simulated data. constr = dict() constr['periods'] = np.random.randint(1, 4) constr['agents'] = np.random.randint(1, 100) constr['edu'] = (7, 15) constr['maxfun'] = 0 # Simulate a dataset generate_init(constr) respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) # Evaluate at different points, ensuring that the simulated dataset # still fits. generate_init(constr) respy_obj = RespyCls('test.respy.ini') estimate(respy_obj)
def test_4(self): """ Test the solution of model with ambiguity. """ # Solve specified economy respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_fourth.respy.ini') respy_obj = simulate(respy_obj) # Assess expected future value val = respy_obj.get_attr('periods_emax')[0, :1] np.testing.assert_allclose(val, 75.719528) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, 2.802285449312437)
def test_3(self): """ Test the solution of model with ambiguity. """ # Solve specified economy respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_third.respy.ini') respy_obj = simulate(respy_obj) # Assess expected future value val = respy_obj.get_attr('periods_emax')[0, :1] np.testing.assert_allclose(val, 86121.335057) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, 1.9162587639887239)
def test_1(self): """ Compare the evaluation of the criterion function for the ambiguity optimization and the simulated expected future value between the FORTRAN and PYTHON implementations. These tests are set up a separate test case due to the large setup cost to construct the ingredients for the interface. """ # Generate constraint periods constraints = dict() constraints['version'] = 'PYTHON' # Generate random initialization file generate_init(constraints) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Extract class attributes periods_payoffs_systematic, states_number_period, mapping_state_idx, \ periods_emax, num_periods, states_all, num_draws_emax, edu_start, \ edu_max, delta = \ dist_class_attributes(respy_obj, 'periods_payoffs_systematic', 'states_number_period', 'mapping_state_idx', 'periods_emax', 'num_periods', 'states_all', 'num_draws_emax', 'edu_start', 'edu_max', 'delta') # Sample draws draws_standard = np.random.multivariate_normal(np.zeros(4), np.identity(4), (num_draws_emax, )) # Sampling of random period and admissible state index period = np.random.choice(range(num_periods)) k = np.random.choice(range(states_number_period[period])) # Select systematic payoffs payoffs_systematic = periods_payoffs_systematic[period, k, :] # Evaluation of simulated expected future values args = (num_periods, num_draws_emax, period, k, draws_standard, payoffs_systematic, edu_max, edu_start, periods_emax, states_all, mapping_state_idx, delta) py = get_future_value(*args) f90 = fort_debug.wrapper_get_future_value(*args) np.testing.assert_allclose(py, f90, rtol=1e-05, atol=1e-06)
def test_1(self): """ Test solution of simple model against hard-coded results. """ # Solve specified economy respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_first.respy.ini') respy_obj = simulate(respy_obj) # Assess expected future value val = respy_obj.get_attr('periods_emax')[0, :1] np.testing.assert_allclose(val, 103320.40501) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, 1.9775860444869962)
def test_1(self): """ Compare the evaluation of the criterion function for the ambiguity optimization and the simulated expected future value between the FORTRAN and PYTHON implementations. These tests are set up a separate test case due to the large setup cost to construct the ingredients for the interface. """ # Generate constraint periods constraints = dict() constraints['version'] = 'PYTHON' # Generate random initialization file generate_init(constraints) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Extract class attributes periods_payoffs_systematic, states_number_period, mapping_state_idx, \ periods_emax, num_periods, states_all, num_draws_emax, edu_start, \ edu_max, delta = \ dist_class_attributes(respy_obj, 'periods_payoffs_systematic', 'states_number_period', 'mapping_state_idx', 'periods_emax', 'num_periods', 'states_all', 'num_draws_emax', 'edu_start', 'edu_max', 'delta') # Sample draws draws_standard = np.random.multivariate_normal(np.zeros(4), np.identity(4), (num_draws_emax,)) # Sampling of random period and admissible state index period = np.random.choice(range(num_periods)) k = np.random.choice(range(states_number_period[period])) # Select systematic payoffs payoffs_systematic = periods_payoffs_systematic[period, k, :] # Evaluation of simulated expected future values args = (num_periods, num_draws_emax, period, k, draws_standard, payoffs_systematic, edu_max, edu_start, periods_emax, states_all, mapping_state_idx, delta) py = get_future_value(*args) f90 = fort_debug.wrapper_get_future_value(*args) np.testing.assert_allclose(py, f90, rtol=1e-05, atol=1e-06)
def test_2(self): """ If there is no random variation in payoffs then the number of draws to simulate the expected future value should have no effect. """ # Generate constraints constr = dict() constr['is_deterministic'] = True # Generate random initialization file generate_init(constr) # Initialize auxiliary objects base = None for _ in range(2): # Draw a random number of draws for # expected future value calculations. num_draws_emax = np.random.randint(1, 100) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') respy_obj.unlock() respy_obj.set_attr('num_draws_emax', num_draws_emax) respy_obj.lock() respy_obj = simulate(respy_obj) # Distribute class attributes periods_emax = respy_obj.get_attr('periods_emax') if base is None: base = periods_emax.copy() # Statistic diff = np.max( abs( np.ma.masked_invalid(base) - np.ma.masked_invalid(periods_emax))) # Checks assert (np.isfinite(diff)) assert (diff < 10e-10)
def test_2(self): """ If there is no random variation in payoffs then the number of draws to simulate the expected future value should have no effect. """ # Generate constraints constr = dict() constr['is_deterministic'] = True # Generate random initialization file generate_init(constr) # Initialize auxiliary objects base = None for _ in range(2): # Draw a random number of draws for # expected future value calculations. num_draws_emax = np.random.randint(1, 100) # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') respy_obj.unlock() respy_obj.set_attr('num_draws_emax', num_draws_emax) respy_obj.lock() respy_obj = simulate(respy_obj) # Distribute class attributes periods_emax = respy_obj.get_attr('periods_emax') if base is None: base = periods_emax.copy() # Statistic diff = np.max(abs(np.ma.masked_invalid(base) - np.ma.masked_invalid( periods_emax))) # Checks assert (np.isfinite(diff)) assert (diff < 10e-10)
def test_2(self): """ This test compares the results from a solution using the interpolation code for the special case where the number of interpolation points is exactly the number of states in the final period. In this case the interpolation code is run and then all predicted values replaced with their actual values. """ # Set initial constraints constraints = dict() constraints['flag_interpolation'] = False constraints['periods'] = np.random.randint(3, 6) # Initialize request init_dict = generate_random_dict(constraints) baseline = None # Solve with and without interpolation code for _ in range(2): # Write out request print_init_dict(init_dict) # Process and solve respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Extract class attributes states_number_period, periods_emax = \ dist_class_attributes(respy_obj, 'states_number_period', 'periods_emax') # Store and check results if baseline is None: baseline = periods_emax else: np.testing.assert_array_almost_equal(baseline, periods_emax) # Updates for second iteration init_dict['INTERPOLATION']['points'] = max(states_number_period) init_dict['INTERPOLATION']['flag'] = True
def test_1(self): """ This is the special case where the EMAX better be equal to the MAXE. """ # Set initial constraints constraints = dict() constraints['flag_interpolation'] = False constraints['periods'] = np.random.randint(3, 6) constraints['is_deterministic'] = True # Initialize request init_dict = generate_random_dict(constraints) baseline = None # Solve with and without interpolation code for _ in range(2): # Write out request print_init_dict(init_dict) # Process and solve respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Extract class attributes states_number_period, periods_emax = \ dist_class_attributes(respy_obj, 'states_number_period', 'periods_emax') # Store and check results if baseline is None: baseline = periods_emax else: np.testing.assert_array_almost_equal(baseline, periods_emax) # Updates for second iteration. This ensures that there is at least # one interpolation taking place. init_dict['INTERPOLATION']['points'] = max( states_number_period) - 1 init_dict['INTERPOLATION']['flag'] = True
def test_1(self): """ This is the special case where the EMAX better be equal to the MAXE. """ # Set initial constraints constraints = dict() constraints['flag_interpolation'] = False constraints['periods'] = np.random.randint(3, 6) constraints['is_deterministic'] = True # Initialize request init_dict = generate_random_dict(constraints) baseline = None # Solve with and without interpolation code for _ in range(2): # Write out request print_init_dict(init_dict) # Process and solve respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Extract class attributes states_number_period, periods_emax = \ dist_class_attributes(respy_obj, 'states_number_period', 'periods_emax') # Store and check results if baseline is None: baseline = periods_emax else: np.testing.assert_array_almost_equal(baseline, periods_emax) # Updates for second iteration. This ensures that there is at least # one interpolation taking place. init_dict['INTERPOLATION']['points'] = max(states_number_period) - 1 init_dict['INTERPOLATION']['flag'] = True
def test_1(self): """ This test ensures that it makes no difference whether the criterion function is evaluated in parallel or not. """ # Generate random initialization file constr = dict() constr['version'] = 'FORTRAN' constr['maxfun'] = np.random.randint(0, 50) init_dict = generate_random_dict(constr) base = None for is_parallel in [True, False]: init_dict['PARALLELISM']['flag'] = is_parallel print_init_dict(init_dict) respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) _, crit_val = estimate(respy_obj) if base is None: base = crit_val np.testing.assert_equal(base, crit_val)
def test_4(self): """ Test the solution of deterministic model without ambiguity, but with interpolation. As a deterministic model is requested, all versions should yield the same result without any additional effort. """ # Solve specified economy for version in ['FORTRAN', 'PYTHON']: respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_fifth.respy.ini') respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() respy_obj = simulate(respy_obj) # Assess expected future value val = respy_obj.get_attr('periods_emax')[0, :1] np.testing.assert_allclose(val, 88750) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, -1.0)
def test_5(self): """ Test the solution of deterministic model without ambiguity, but with interpolation. As a deterministic model is requested, all versions should yield the same result without any additional effort. """ # Solve specified economy for version in ['FORTRAN', 'PYTHON']: respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_fifth.respy.ini') respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() respy_obj = simulate(respy_obj) # Assess expected future value val = respy_obj.get_attr('periods_emax')[0, :1] np.testing.assert_allclose(val, 88750) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, -1.0)
from codes.random_init import generate_init ############################################################################ # RUN ############################################################################ fname = 'test_vault_' + str(PYTHON_VERSION) + '.respy.pkl' tests = [] for idx in range(num_tests): print('\n Creating Test ', idx, 'with version ', PYTHON_VERSION) constr = dict() constr['maxfun'] = int(np.random.choice([0, 1, 2, 3, 5, 6], p=[0.5, 0.1, 0.1, 0.1, 0.1, 0.1])) constr['flag_scaling'] = np.random.choice([True, False], p=[0.1, 0.9]) constr['flag_scaling'] = np.random.choice([True, False], p=[0.1, 0.9]) constr['is_store'] = False init_dict = generate_init(constr) respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) crit_val = estimate(respy_obj)[1] test = (init_dict, crit_val) tests += [test] pkl.dump(tests, open(fname, 'wb'))
from respy.python.evaluate.evaluate_auxiliary import check_input from respy.python.evaluate.evaluate_auxiliary import check_output from respy.python.shared.shared_auxiliary import dist_class_attributes from respy.python.shared.shared_auxiliary import create_draws from respy import simulate, RespyCls, estimate import numpy as np import pickle as pkl respy_obj = RespyCls('model.respy.ini') simulate(respy_obj) base = None for num_procs in [1, 2]: respy_obj.unlock() respy_obj.set_attr('num_procs', num_procs) respy_obj.set_attr('is_parallel', (num_procs > 1)) respy_obj.lock() x, crit_val = estimate(respy_obj) if base is None: base = crit_val np.testing.assert_equal(crit_val, base)
def run(args): """ Test the different releases against each other. """ # Set up auxiliary information to construct commands. env_dir = os.environ['HOME'] + '/.envs' old_exec = env_dir + '/' + OLD_RELEASE + '/bin/python' new_exec = env_dir + '/' + NEW_RELEASE + '/bin/python' # # Create fresh virtual environments. # for release in [OLD_RELEASE, NEW_RELEASE]: # cmd = ['pyvenv', env_dir + '/' + release, '--clear'] # subprocess.check_call(cmd) # # # Set up the virtual environments with the two releases under investigation. # for which in ['old', 'new']: # if which == 'old': # release, python_exec = OLD_RELEASE, old_exec # elif which == 'new': # release, python_exec = NEW_RELEASE, new_exec # else: # raise AssertionError # cmd = [python_exec, '../_modules/auxiliary_release.py', release] # subprocess.check_call(cmd) # Run tests # TODO: How about log files. cleanup() is_failed = False # Evaluation loop. start, timeout = datetime.now(), timedelta(hours=args.hours) num_tests = 0 is_running = True while is_running: num_tests += 1 # Set seed. seed = random.randrange(1, 100000) np.random.seed(seed) # Create a random estimation task. constr = dict() constr['is_estimation'] = True generate_init(constr) respy_obj = RespyCls('test.respy.ini') simulate(respy_obj) crit_val = None for which in ['old', 'new']: if which == 'old': release, python_exec = OLD_RELEASE, old_exec elif which == 'new': release, python_exec = NEW_RELEASE, new_exec else: raise AssertionError cmd = [python_exec, '../_modules/auxiliary_release.py'] subprocess.check_call(cmd) if crit_val is None: crit_val = np.genfromtxt('.crit_val') try: np.testing.assert_equal(crit_val, np.genfromtxt( '.crit_val')) except AssertionError: is_failed = True is_running = False # Timeout. if timeout < datetime.now() - start: break send_notification('release', hours=args.hours, is_failed=is_failed, seed=seed, num_tests=num_tests)
def test_1(self): """ Testing the equality of an evaluation of the criterion function for a random request. """ # Run evaluation for multiple random requests. is_deterministic = np.random.choice([True, False], p=[0.10, 0.9]) is_interpolated = np.random.choice([True, False], p=[0.10, 0.9]) is_myopic = np.random.choice([True, False], p=[0.10, 0.9]) max_draws = np.random.randint(10, 100) # Generate random initialization file constr = dict() constr['is_deterministic'] = is_deterministic constr['flag_parallelism'] = False constr['is_myopic'] = is_myopic constr['max_draws'] = max_draws constr['maxfun'] = 0 init_dict = generate_random_dict(constr) # The use of the interpolation routines is a another special case. # Constructing a request that actually involves the use of the # interpolation routine is a little involved as the number of # interpolation points needs to be lower than the actual number of # states. And to know the number of states each period, I need to # construct the whole state space. if is_interpolated: # Extract from future initialization file the information # required to construct the state space. The number of periods # needs to be at least three in order to provide enough state # points. num_periods = np.random.randint(3, 6) edu_start = init_dict['EDUCATION']['start'] edu_max = init_dict['EDUCATION']['max'] min_idx = min(num_periods, (edu_max - edu_start + 1)) max_states_period = pyth_create_state_space( num_periods, edu_start, edu_max, min_idx)[3] # Updates to initialization dictionary that trigger a use of the # interpolation code. init_dict['BASICS']['periods'] = num_periods init_dict['INTERPOLATION']['flag'] = True init_dict['INTERPOLATION']['points'] = \ np.random.randint(10, max_states_period) # Print out the relevant initialization file. print_init_dict(init_dict) # Write out random components and interpolation grid to align the # three implementations. num_periods = init_dict['BASICS']['periods'] write_draws(num_periods, max_draws) write_interpolation_grid('test.respy.ini') # Clean evaluations based on interpolation grid, base_val, base_data = None, None for version in ['PYTHON', 'FORTRAN']: respy_obj = RespyCls('test.respy.ini') # Modify the version of the program for the different requests. respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() # Solve the model respy_obj = simulate(respy_obj) # This parts checks the equality of simulated dataset for the # different versions of the code. data_frame = pd.read_csv('data.respy.dat', delim_whitespace=True) if base_data is None: base_data = data_frame.copy() assert_frame_equal(base_data, data_frame) # This part checks the equality of an evaluation of the # criterion function. _, crit_val = estimate(respy_obj) if base_val is None: base_val = crit_val np.testing.assert_allclose(base_val, crit_val, rtol=1e-05, atol=1e-06) # We know even more for the deterministic case. if constr['is_deterministic']: assert (crit_val in [-1.0, 0.0])
def test_6(self): """ Further tests for the interpolation routines. """ # Generate random initialization file generate_init() # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Extract class attributes periods_payoffs_systematic, states_number_period, mapping_state_idx, seed_prob, periods_emax, num_periods, states_all, num_points_interp, edu_start, num_draws_emax, is_debug, edu_max, delta = dist_class_attributes( respy_obj, 'periods_payoffs_systematic', 'states_number_period', 'mapping_state_idx', 'seed_prob', 'periods_emax', 'num_periods', 'states_all', 'num_points_interp', 'edu_start', 'num_draws_emax', 'is_debug', 'edu_max', 'delta') # Add some additional objects required for the interfaces to the # functions. period = np.random.choice(range(num_periods)) periods_draws_emax = create_draws(num_periods, num_draws_emax, seed_prob, is_debug) draws_emax = periods_draws_emax[period, :, :] num_states = states_number_period[period] shifts = np.random.randn(4) # Slight modification of request which assures that the # interpolation code is working. num_points_interp = min(num_points_interp, num_states) # Get the IS_SIMULATED indicator for the subset of points which are # used for the predication model. args = (num_points_interp, num_states, period, is_debug) is_simulated = get_simulated_indicator(*args) # Construct the exogenous variables for all points of the state # space. args = (period, num_periods, num_states, delta, periods_payoffs_systematic, shifts, edu_max, edu_start, mapping_state_idx, periods_emax, states_all) py = get_exogenous_variables(*args) f90 = fort_debug.wrapper_get_exogenous_variables(*args) np.testing.assert_equal(py, f90) # Distribute validated results for further functions. exogenous, maxe = py # Construct endogenous variable so that the prediction model can be # fitted. args = (period, num_periods, num_states, delta, periods_payoffs_systematic, edu_max, edu_start, mapping_state_idx, periods_emax, states_all, is_simulated, num_draws_emax, maxe, draws_emax) py = get_endogenous_variable(*args) f90 = fort_debug.wrapper_get_endogenous_variable(*args) np.testing.assert_equal(py, replace_missing_values(f90)) # Distribute validated results for further functions. endogenous = py args = (endogenous, exogenous, maxe, is_simulated, num_points_interp, num_states, is_debug) py = get_predictions(*args) f90 = fort_debug.wrapper_get_predictions(*args[:-1]) np.testing.assert_array_almost_equal(py, f90)
import respy as rp import sys import pandas as pd import os if __name__ == '__main__': if not os.path.exists('simulated_data'): os.mkdir('simulated_data') model_name = sys.argv[1] params, options, _ = rp.get_example_model(model_name) options['solution_draws'] = 250 options['simulation_agents'] = 750 state_space, data = rp.simulate(params, options) pd.to_pickle(data, os.path.join("simulated_data", f"{model_name}.pickle"))
def test_1(self): """ Testing the equality of an evaluation of the criterion function for a random request. """ # Run evaluation for multiple random requests. is_deterministic = np.random.choice([True, False], p=[0.10, 0.9]) is_interpolated = np.random.choice([True, False], p=[0.10, 0.9]) is_myopic = np.random.choice([True, False], p=[0.10, 0.9]) max_draws = np.random.randint(10, 100) # Generate random initialization file constr = dict() constr['is_deterministic'] = is_deterministic constr['flag_parallelism'] = False constr['is_myopic'] = is_myopic constr['max_draws'] = max_draws constr['maxfun'] = 0 init_dict = generate_random_dict(constr) # The use of the interpolation routines is a another special case. # Constructing a request that actually involves the use of the # interpolation routine is a little involved as the number of # interpolation points needs to be lower than the actual number of # states. And to know the number of states each period, I need to # construct the whole state space. if is_interpolated: # Extract from future initialization file the information # required to construct the state space. The number of periods # needs to be at least three in order to provide enough state # points. num_periods = np.random.randint(3, 6) edu_start = init_dict['EDUCATION']['start'] edu_max = init_dict['EDUCATION']['max'] min_idx = min(num_periods, (edu_max - edu_start + 1)) max_states_period = pyth_create_state_space(num_periods, edu_start, edu_max, min_idx)[3] # Updates to initialization dictionary that trigger a use of the # interpolation code. init_dict['BASICS']['periods'] = num_periods init_dict['INTERPOLATION']['flag'] = True init_dict['INTERPOLATION']['points'] = \ np.random.randint(10, max_states_period) # Print out the relevant initialization file. print_init_dict(init_dict) # Write out random components and interpolation grid to align the # three implementations. num_periods = init_dict['BASICS']['periods'] write_draws(num_periods, max_draws) write_interpolation_grid('test.respy.ini') # Clean evaluations based on interpolation grid, base_val, base_data = None, None for version in ['PYTHON', 'FORTRAN']: respy_obj = RespyCls('test.respy.ini') # Modify the version of the program for the different requests. respy_obj.unlock() respy_obj.set_attr('version', version) respy_obj.lock() # Solve the model respy_obj = simulate(respy_obj) # This parts checks the equality of simulated dataset for the # different versions of the code. data_frame = pd.read_csv('data.respy.dat', delim_whitespace=True) if base_data is None: base_data = data_frame.copy() assert_frame_equal(base_data, data_frame) # This part checks the equality of an evaluation of the # criterion function. _, crit_val = estimate(respy_obj) if base_val is None: base_val = crit_val np.testing.assert_allclose(base_val, crit_val, rtol=1e-05, atol=1e-06) # We know even more for the deterministic case. if constr['is_deterministic']: assert (crit_val in [-1.0, 0.0])
def test_6(self): """ Further tests for the interpolation routines. """ # Generate random initialization file generate_init() # Perform toolbox actions respy_obj = RespyCls('test.respy.ini') respy_obj = simulate(respy_obj) # Extract class attributes periods_payoffs_systematic, states_number_period, mapping_state_idx, seed_prob, periods_emax, num_periods, states_all, num_points_interp, edu_start, num_draws_emax, is_debug, edu_max, delta = dist_class_attributes( respy_obj, 'periods_payoffs_systematic', 'states_number_period', 'mapping_state_idx', 'seed_prob', 'periods_emax', 'num_periods', 'states_all', 'num_points_interp', 'edu_start', 'num_draws_emax', 'is_debug', 'edu_max', 'delta') # Add some additional objects required for the interfaces to the # functions. period = np.random.choice(range(num_periods)) periods_draws_emax = create_draws(num_periods, num_draws_emax, seed_prob, is_debug) draws_emax = periods_draws_emax[period, :, :] num_states = states_number_period[period] shifts = np.random.randn(4) # Slight modification of request which assures that the # interpolation code is working. num_points_interp = min(num_points_interp, num_states) # Get the IS_SIMULATED indicator for the subset of points which are # used for the predication model. args = (num_points_interp, num_states, period, is_debug) is_simulated = get_simulated_indicator(*args) # Construct the exogenous variables for all points of the state # space. args = ( period, num_periods, num_states, delta, periods_payoffs_systematic, shifts, edu_max, edu_start, mapping_state_idx, periods_emax, states_all) py = get_exogenous_variables(*args) f90 = fort_debug.wrapper_get_exogenous_variables(*args) np.testing.assert_equal(py, f90) # Distribute validated results for further functions. exogenous, maxe = py # Construct endogenous variable so that the prediction model can be # fitted. args = (period, num_periods, num_states, delta, periods_payoffs_systematic, edu_max, edu_start, mapping_state_idx, periods_emax, states_all, is_simulated, num_draws_emax, maxe, draws_emax) py = get_endogenous_variable(*args) f90 = fort_debug.wrapper_get_endogenous_variable(*args) np.testing.assert_equal(py, replace_missing_values(f90)) # Distribute validated results for further functions. endogenous = py args = (endogenous, exogenous, maxe, is_simulated, num_points_interp, num_states, is_debug) py = get_predictions(*args) f90 = fort_debug.wrapper_get_predictions(*args[:-1]) np.testing.assert_array_almost_equal(py, f90)
import shutil import glob import os import respy # We can simply iterate over the different model specifications outlined in # Table 1 of the paper. for spec in ['kw_data_one.ini', 'kw_data_two.ini', 'kw_data_three.ini']: # Process relevant model initialization file respy_obj = respy.RespyCls(spec) # Let us simulate the datasets discussed on the page 658. respy.simulate(respy_obj) # To start estimations for the Monte Carlo exercises. For now, we just # evaluate the model at the starting values, i.e. maxfun set to zero in # the initialization file. respy_obj.unlock() respy_obj.set_attr('maxfun', 0) respy_obj.lock() respy.estimate(respy_obj) # Store results in directory for later inspection. dirname = spec.replace('.ini', '') os.mkdir(dirname) for fname in glob.glob('*.respy.*'): shutil.move(fname, dirname)
def test_2(self): """ Compare the solution of simple model against hard-coded results. """ # Solve specified economy respy_obj = RespyCls(TEST_RESOURCES_DIR + '/test_second.respy.ini') respy_obj = simulate(respy_obj) # Distribute class attributes systematic = respy_obj.get_attr('periods_payoffs_systematic') emax = respy_obj.get_attr('periods_emax') # PERIOD 3: Check the systematic payoffs against hand calculations. vals = [[2.7456010000000000, 07.5383250000000000, -3999.60, 1.140]] vals += [[3.0343583944356758, 09.2073308658822519, -3999.60, 1.140]] vals += [[3.0343583944356758, 09.2073308658822519, 0000.90, 1.140]] vals += [[3.3534846500000000, 11.2458593100000000, 0000.40, 1.140]] vals += [[3.5966397255692826, 12.0612761204447200, -3999.60, 1.140]] vals += [[3.9749016274947495, 14.7316759204425760, -3999.60, 1.140]] vals += [[3.9749016274947495, 14.7316759204425760, 0000.90, 1.140]] vals += [[6.2338866585247175, 31.1869581683094590, -3999.60, 1.140]] vals += [[3.4556134647626764, 11.5883467192233920, -3999.60, 1.140]] vals += [[3.8190435053663370, 14.1540386453758080, -3999.60, 1.140]] vals += [[3.8190435053663370, 14.1540386453758080, 0000.90, 1.140]] vals += [[4.5267307943142532, 18.5412874597468690, -3999.60, 1.140]] vals += [[5.5289614776240041, 27.6603505585167470, -3999.60, 1.140]] for i, val in enumerate(vals): (np.testing.assert_allclose(systematic[2, i, :], val)) # PERIOD 3: Check expected future values. As there are no # random draws, this corresponds to the maximum # value in the last period. vals = [7.53832493366, 9.20733086588, 9.20733086588, 11.2458593149] vals += [12.06127612040, 14.7316759204, 14.7316759204, 31.1869581683] vals += [11.58834671922, 14.1540386453, 14.1540386453, 18.5412874597] vals += [27.660350558516747] for i, val in enumerate(vals): (np.testing.assert_allclose(emax[2, i], [val])) # PERIOD 2: Check the systematic payoffs against hand calculations. vals = [[2.7456010150169163, 07.5383249336619222, -3999.60, 1.140]] vals += [[3.0343583944356758, 09.2073308658822519, 0000.90, 1.140]] vals += [[3.5966397255692826, 12.0612761204447200, -3999.60, 1.140]] vals += [[3.4556134647626764, 11.5883467192233920, -3999.60, 1.140]] for i, val in enumerate(vals): (np.testing.assert_allclose(systematic[1, i, :], val)) # PERIOD 2: Check expected future values. vals = [18.9965372481, 23.2024229903, 41.6888863803, 29.7329464954] for i, val in enumerate(vals): (np.testing.assert_allclose(emax[1, i], [val])) # PERIOD 1: Check the systematic payoffs against hand calculations. vals = [[2.7456010150169163, 7.5383249336619222, 0.90, 1.140]] for i, val in enumerate(vals): (np.testing.assert_allclose(systematic[0, i, :], val)) # PERIOD 1 Check expected future values. vals = [47.142766995] for i, val in enumerate(vals): (np.testing.assert_allclose(emax[0, 0], [val])) # Assess evaluation _, val = estimate(respy_obj) np.testing.assert_allclose(val, 0.00)