Exemple #1
0
def simulate(respy_obj):
    """ Simulate dataset of synthetic agent following the model specified in
    the initialization file.
    """
    # Cleanup
    for fname in ['sim.respy.log', 'sol.respy.log']:
        if os.path.exists(fname):
            os.unlink(fname)

    # Distribute class attributes
    is_debug, version, num_agents_sim, is_store = \
        dist_class_attributes(respy_obj, 'is_debug', 'version',
                'num_agents_sim', 'is_store')

    # Select appropriate interface
    if version in ['PYTHON']:
        solution, data_array = respy_interface(respy_obj, 'simulate')
    elif version in ['FORTRAN']:
        solution, data_array = resfort_interface(respy_obj, 'simulate')
    else:
        raise NotImplementedError

    # Attach solution to class instance
    respy_obj = add_solution(respy_obj, *solution)

    respy_obj.unlock()
    respy_obj.set_attr('is_solved', True)
    respy_obj.lock()

    # Store object to file
    if is_store:
        respy_obj.store('solution.respy.pkl')

    # Create pandas data frame with missing values.
    data_frame = pd.DataFrame(replace_missing_values(data_array))

    # Wrapping up by running some checks on the dataset and then writing out
    # the file and some basic information.
    if is_debug:
        check_dataset(data_frame, respy_obj, 'sim')

    write_out(respy_obj, data_frame)

    write_info(respy_obj, data_frame)

    # Finishing
    return respy_obj
Exemple #2
0
    def _check_integrity_results(self):
        """ This methods check the integrity of the results.
        """
        # Check if solution attributes well maintained.
        for label in SOLUTION_ATTR:
            if self.attr['is_solved']:
                assert (self.attr[label] is not None)
            else:
                assert (self.attr[label] is None)

        # Distribute class attributes
        num_periods = self.attr['num_periods']

        edu_start = self.attr['edu_start']

        edu_max = self.attr['edu_max']

        # Distribute results
        periods_payoffs_systematic = self.attr['periods_payoffs_systematic']

        states_number_period = self.attr['states_number_period']

        mapping_state_idx = self.attr['mapping_state_idx']

        periods_emax = self.attr['periods_emax']

        states_all = self.attr['states_all']

        # Replace missing value with NAN. This allows to easily select the
        # valid subsets of the containers
        if mapping_state_idx is not None:
            mapping_state_idx = replace_missing_values(mapping_state_idx)
        if states_all is not None:
            states_all = replace_missing_values(states_all)
        if periods_payoffs_systematic is not None:
            periods_payoffs_systematic = replace_missing_values(periods_payoffs_systematic)
        if periods_emax is not None:
            periods_emax = replace_missing_values(periods_emax)

        # Check the creation of the state space
        is_applicable = (states_all is not None)
        is_applicable = is_applicable and (states_number_period is not None)
        is_applicable = is_applicable and (mapping_state_idx is not None)

        if is_applicable:
            # If the agent never increased their level of education, the lagged
            # education variable cannot take a value larger than zero.
            for period in range(1, num_periods):
                indices = (np.where(states_all[period, :, :][:, 2] == 0))
                for index in indices:
                    assert (np.all(states_all[period, :, :][index, 3]) == 0)

            # No values can be larger than constraint time. The exception in the
            # lagged schooling variable in the first period, which takes value
            # one but has index zero.
            for period in range(num_periods):
                assert (np.nanmax(states_all[period, :, :3]) <= period)

            # Lagged schooling can only take value zero or one if finite.
            # In fact, it can only take value one in the first period.
            for period in range(num_periods):
                assert (np.all(states_all[0, :, 3]) == 1)
                assert (np.nanmax(states_all[period, :, 3]) == 1)
                assert (np.nanmin(states_all[period, :, :3]) == 0)

            # All finite values have to be larger or equal to zero. The loop is
            # required as np.all evaluates to FALSE for this condition
            # (see NUMPY documentation).
            for period in range(num_periods):
                assert (np.all(
                    states_all[period, :states_number_period[period]] >= 0))

            # The maximum number of additional education years is never larger
            # than (EDU_MAX - EDU_START).
            for period in range(num_periods):
                assert (np.nanmax(states_all[period, :, :][:, 2], axis=0) <= (
                    edu_max - edu_start))

            # Check for duplicate rows in each period
            for period in range(num_periods):
                assert (np.sum(pd.DataFrame(
                    states_all[period, :states_number_period[period],
                    :]).duplicated()) == 0)

            # Checking validity of state space values. All valid
            # values need to be finite.
            for period in range(num_periods):
                assert (np.all(np.isfinite(
                    states_all[period, :states_number_period[period]])))

            # There are no infinite values in final period.
            assert (np.all(np.isfinite(states_all[(num_periods - 1), :, :])))

            # There are is only one finite realization in period one.
            assert (np.sum(np.isfinite(mapping_state_idx[0, :, :, :, :])) == 1)

            # If valid, the number of state space realizations in period two is
            # four.
            if num_periods > 1:
                assert (
                np.sum(np.isfinite(mapping_state_idx[1, :, :, :, :])) == 4)

            # Check that mapping is defined for all possible realizations of the
            # state space by period. Check that mapping is not defined for all
            # inadmissible values.
            is_infinite = np.tile(False, reps=mapping_state_idx.shape)
            for period in range(num_periods):
                # Subsetting valid indices
                indices = states_all[period, :states_number_period[
                    period], :].astype('int')
                for index in indices:
                    # Check for finite value at admissible state
                    assert (np.isfinite(mapping_state_idx[period, index[0],
                        index[1], index[2], index[3]]))
                    # Record finite value
                    is_infinite[
                        period, index[0], index[1], index[2], index[3]] = True
            # Check that all admissible states are finite
            assert (np.all(np.isfinite(mapping_state_idx[is_infinite == True])))

            # Check that all inadmissible states are infinite
            assert (np.all(np.isfinite(
                mapping_state_idx[is_infinite == False])) == False)

        # Check the calculated systematic payoffs
        is_applicable = (states_all is not None)
        is_applicable = is_applicable and (states_number_period is not None)
        is_applicable = is_applicable and (periods_payoffs_systematic is not None)

        if is_applicable:
            # Check that the payoffs are finite for all admissible values and
            # infinite for all others.
            is_infinite = np.tile(False, reps=periods_payoffs_systematic.shape)
            for period in range(num_periods):
                # Loop over all possible states
                for k in range(states_number_period[period]):
                    # Check that wages are all positive
                    assert (np.all(periods_payoffs_systematic[period, k, :2] >= 0.0))
                    # Check for finite value at admissible state
                    assert (np.all(np.isfinite(periods_payoffs_systematic[
                    period, k, :])))
                    # Record finite value
                    is_infinite[period, k, :] = True
                # Check that all admissible states are finite
                assert (np.all(np.isfinite(periods_payoffs_systematic[
                    is_infinite == True])))
                # Check that all inadmissible states are infinite
                if num_periods > 1:
                    assert (np.all(np.isfinite(periods_payoffs_systematic[is_infinite == False])) == False)

        # Check the expected future value
        is_applicable = (periods_emax is not None)

        if is_applicable:
            # Check that the payoffs are finite for all admissible values and
            # infinite for all others.
            is_infinite = np.tile(False, reps=periods_emax.shape)
            for period in range(num_periods):
                # Loop over all possible states
                for k in range(states_number_period[period]):
                    # Check for finite value at admissible state
                    assert (np.all(np.isfinite(periods_emax[period, k])))
                    # Record finite value
                    is_infinite[period, k] = True
                # Check that all admissible states are finite
                assert (np.all(np.isfinite(periods_emax[is_infinite == True])))
                # Check that all inadmissible states are infinite
                if num_periods == 1:
                    assert (len(periods_emax[is_infinite == False]) == 0)
                else:
                    assert (np.all(np.isfinite(periods_emax[is_infinite == False])) == False)
def check_model_solution(attr_dict):
    solution_attributes = [
        "periods_rewards_systematic",
        "states_number_period",
        "mapping_state_idx",
        "periods_emax",
        "states_all",
    ]

    for label in solution_attributes:
        if attr_dict["is_solved"]:
            assert attr_dict[label] is not None
        else:
            assert attr_dict[label] is None

    if attr_dict["is_solved"]:
        # Distribute class attributes
        num_initial = len(attr_dict["edu_spec"]["start"])
        edu_start = attr_dict["edu_spec"]["start"]
        edu_start_max = max(edu_start)
        edu_max = attr_dict["edu_spec"]["max"]
        num_periods = attr_dict["num_periods"]
        num_types = attr_dict["num_types"]

        # Distribute results
        periods_rewards_systematic = attr_dict["periods_rewards_systematic"]
        states_number_period = attr_dict["states_number_period"]
        mapping_state_idx = attr_dict["mapping_state_idx"]
        periods_emax = attr_dict["periods_emax"]
        states_all = attr_dict["states_all"]

        # Replace missing value with NAN. This allows to easily select the
        # valid subsets of the containers
        mapping_state_idx = replace_missing_values(mapping_state_idx)
        states_all = replace_missing_values(states_all)
        periods_rewards_systematic = replace_missing_values(
            periods_rewards_systematic)
        periods_emax = replace_missing_values(periods_emax)

        # No values can be larger than constraint time. The exception in
        # the lagged schooling variable in the first period, which takes
        # value one but has index zero.
        for period in range(num_periods):
            assert np.nanmax(
                states_all[period, :, :3]) <= (period + edu_start_max)

        # Lagged schooling can only take value zero or one if finite.
        for period in range(num_periods):
            assert np.nanmax(states_all[period, :, 3]) in [1, 2, 3, 4]
            assert np.nanmin(states_all[period, :, :3]) == 0

        # All finite values have to be larger or equal to zero.
        # The loop is required as np.all evaluates to FALSE for this
        # condition (see NUMPY documentation).
        for period in range(num_periods):
            assert np.all(
                states_all[period, :states_number_period[period]] >= 0)

        # The maximum of education years is never larger than `edu_max'.
        for period in range(num_periods):
            assert np.nanmax(states_all[period, :, :][:, 2], axis=0) <= edu_max

        # Check for duplicate rows in each period. We only have possible
        # duplicates if there are multiple initial conditions.
        for period in range(num_periods):
            nstates = states_number_period[period]
            assert (np.sum(
                pd.DataFrame(
                    states_all[period, :nstates, :]).duplicated()) == 0)

        # Checking validity of state space values. All valid values need
        # to be finite.
        for period in range(num_periods):
            assert np.all(
                np.isfinite(states_all[period, :states_number_period[period]]))

        # There are no infinite values in final period.
        assert np.all(np.isfinite(states_all[(num_periods - 1), :, :]))

        # Check the number of states in the first time period.
        num_states_start = num_types * num_initial * 2
        assert np.sum(np.isfinite(mapping_state_idx[0])) == num_states_start

        # Check that mapping is defined for all possible realizations of
        # the state space by period. Check that mapping is not defined for
        # all inadmissible values.
        is_infinite = np.full(mapping_state_idx.shape, False)
        for period in range(num_periods):
            nstates = states_number_period[period]
            indices = states_all[period, :nstates, :].astype("int")
            for index in indices:
                assert np.isfinite(mapping_state_idx[period, index[0],
                                                     index[1], index[2],
                                                     index[3] - 1, index[4]])
                is_infinite[period, index[0], index[1], index[2], index[3] - 1,
                            index[4]] = True
        assert np.all(np.isfinite(mapping_state_idx[is_infinite]))
        assert not np.all(np.isfinite(mapping_state_idx[~is_infinite]))

        # Check the calculated systematic rewards (finite for admissible values
        # and infinite rewards otherwise).
        is_infinite = np.full(periods_rewards_systematic.shape, False)
        for period in range(num_periods):
            for k in range(states_number_period[period]):
                assert np.all(
                    np.isfinite(periods_rewards_systematic[period, k, :]))
                is_infinite[period, k, :] = True
            assert np.all(np.isfinite(periods_rewards_systematic[is_infinite]))
            if num_periods > 1:
                assert not np.all(
                    np.isfinite(periods_rewards_systematic[~is_infinite]))

        # Check the expected future value (finite for admissible values
        # and infinite rewards otherwise).
        is_infinite = np.full(periods_emax.shape, False)
        for period in range(num_periods):
            for k in range(states_number_period[period]):
                assert np.all(np.isfinite(periods_emax[period, k]))
                is_infinite[period, k] = True
            assert np.all(np.isfinite(periods_emax[is_infinite]))
            if num_periods == 1:
                assert len(periods_emax[~is_infinite]) == 0
            else:
                assert not np.all(np.isfinite(periods_emax[~is_infinite]))
    def test_6(self):
        """ Further tests for the interpolation routines.
        """
        params_spec, options_spec = generate_random_model()
        respy_obj = RespyCls(params_spec, options_spec)
        respy_obj = simulate_observed(respy_obj)

        # Extract class attributes
        (
            periods_rewards_systematic,
            mapping_state_idx,
            seed_prob,
            periods_emax,
            num_periods,
            states_all,
            num_points_interp,
            edu_spec,
            num_draws_emax,
            is_myopic,
            is_debug,
            is_interpolated,
            optim_paras,
            optimizer_options,
            file_sim,
            num_types,
        ) = dist_class_attributes(
            respy_obj,
            "periods_rewards_systematic",
            "mapping_state_idx",
            "seed_prob",
            "periods_emax",
            "num_periods",
            "states_all",
            "num_points_interp",
            "edu_spec",
            "num_draws_emax",
            "is_myopic",
            "is_debug",
            "is_interpolated",
            "optim_paras",
            "optimizer_options",
            "file_sim",
            "num_types",
        )

        shocks_cholesky = optim_paras["shocks_cholesky"]
        shocks_cov = shocks_cholesky.dot(shocks_cholesky.T)
        coeffs_common = optim_paras["coeffs_common"]
        coeffs_a = optim_paras["coeffs_a"]
        coeffs_b = optim_paras["coeffs_b"]
        delta = optim_paras["delta"]

        # Add some additional objects required for the interfaces to the functions.
        period = np.random.choice(num_periods)

        periods_draws_emax = create_draws(num_periods, num_draws_emax,
                                          seed_prob, is_debug)

        draws_emax_standard = periods_draws_emax[period, :, :]

        draws_emax_risk = transform_disturbances(draws_emax_standard,
                                                 np.zeros(4), shocks_cholesky)

        # Initialize Python version and solve.
        state_space = StateSpace(num_periods, num_types, edu_spec["start"],
                                 edu_spec["max"], optim_paras)

        # Integrate periods_emax in state_space
        state_space.emaxs = np.column_stack((
            np.zeros((state_space.num_states, 4)),
            periods_emax[~np.isnan(periods_emax)
                         & (periods_emax != MISSING_FLOAT)],
        ))

        # Fill emaxs_a - emaxs_home in the requested period
        states_period = state_space.get_attribute_from_period("states", period)

        # Do not get the emaxs from the previous period if we are in the last one.
        if period != state_space.num_periods - 1:
            state_space.emaxs = get_emaxs_of_subsequent_period(
                states_period, state_space.indexer, state_space.emaxs,
                edu_spec["max"])

        num_states = state_space.states_per_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.
        is_simulated = get_simulated_indicator(num_points_interp, num_states,
                                               period, is_debug)

        # Unpack necessary attributes
        rewards_period = state_space.get_attribute_from_period(
            "rewards", period)
        emaxs_period = state_space.get_attribute_from_period("emaxs",
                                                             period)[:, :4]
        max_education = (state_space.get_attribute_from_period(
            "states", period)[:, 3] >= edu_spec["max"])

        # Construct the exogenous variables for all points of the state space.
        exogenous, max_emax = get_exogenous_variables(rewards_period,
                                                      emaxs_period, shifts,
                                                      optim_paras["delta"],
                                                      max_education)

        # Align output between Python and Fortran version.
        py = (exogenous, max_emax)

        f90 = fort_debug.wrapper_get_exogenous_variables(
            period,
            num_periods,
            num_states,
            periods_rewards_systematic,
            shifts,
            mapping_state_idx,
            periods_emax,
            states_all,
            edu_spec["start"],
            edu_spec["max"],
            delta,
            coeffs_common,
            coeffs_a,
            coeffs_b,
            num_types,
        )

        assert_almost_equal(py[0], f90[0])
        assert_almost_equal(py[1], f90[1])

        # Construct endogenous variable so that the prediction model can be fitted.
        endogenous = get_endogenous_variable(
            rewards_period,
            emaxs_period,
            max_emax,
            is_simulated,
            draws_emax_risk,
            optim_paras["delta"],
            max_education,
        )

        f90 = fort_debug.wrapper_get_endogenous_variable(
            period,
            num_periods,
            num_states,
            periods_rewards_systematic,
            mapping_state_idx,
            periods_emax,
            states_all,
            is_simulated,
            num_draws_emax,
            max_emax,
            draws_emax_risk,
            edu_spec["start"],
            edu_spec["max"],
            shocks_cov,
            delta,
            coeffs_common,
            coeffs_a,
            coeffs_b,
        )
        assert_almost_equal(endogenous, replace_missing_values(f90))

        py = get_predictions(endogenous, exogenous, max_emax, is_simulated)

        f90 = fort_debug.wrapper_get_predictions(
            endogenous,
            exogenous,
            max_emax,
            is_simulated,
            num_points_interp,
            num_states,
            file_sim,
            False,
        )

        # This assertion fails if a column is all zeros.
        if not exogenous.any(axis=0).any():
            assert_array_almost_equal(py, f90)
Exemple #5
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)
Exemple #6
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)
Exemple #7
0
    def simulate(self):
        """Simulate dataset of synthetic agents following the model."""
        # Distribute class attributes
        is_debug, version, is_store, file_sim = dist_class_attributes(
            self, "is_debug", "version", "is_store", "file_sim"
        )

        # Cleanup
        for ext in ["sim", "sol", "dat", "info"]:
            fname = file_sim + ".respy." + ext
            if os.path.exists(fname):
                os.unlink(fname)

        # Select appropriate interface
        if version in ["python"]:
            state_space, data_array = respy_interface(self, "simulate")
        elif version in ["fortran"]:
            solution, data_array = resfort_interface(self, "simulate")
        else:
            raise NotImplementedError

        # Attach solution to class instance
        if version == "fortran":
            self = add_solution(self, *solution)
        elif version == "python":
            self.unlock()
            self.set_attr("state_space", state_space)
            self.lock()
            (
                states_all,
                mapping_state_idx,
                periods_rewards_systematic,
                periods_emax,
            ) = state_space._get_fortran_counterparts()
            self = add_solution(
                self,
                periods_rewards_systematic,
                state_space.states_per_period,
                mapping_state_idx,
                periods_emax,
                states_all,
            )
        else:
            raise NotImplementedError

        self.unlock()
        self.set_attr("is_solved", True)
        self.lock()

        # Store object to file
        if is_store:
            self.store("solution.respy.pkl")

        # ====================================================================
        # todo: harmonize python and fortran
        # ====================================================================
        if self.attr["version"] == "python":
            data_frame = data_array[DATA_LABELS_SIM]
        elif self.attr["version"] == "fortran":
            data_frame = pd.DataFrame(
                data=replace_missing_values(data_array), columns=DATA_LABELS_SIM
            )
        else:
            raise NotImplementedError

        data_frame = data_frame.astype(DATA_FORMATS_SIM)

        # ====================================================================
        data_frame.set_index(["Identifier", "Period"], drop=False, inplace=True)

        # Checks
        if is_debug:
            check_dataset_sim(data_frame, self)

        write_out(self, data_frame)
        write_info(self, data_frame)

        return self, data_frame
Exemple #8
0
    def _check_integrity_results(self):
        """ This methods check the integrity of the results.
        """
        # Check if solution attributes well maintained.
        for label in SOLUTION_ATTR:
            if self.attr['is_solved']:
                assert (self.attr[label] is not None)
            else:
                assert (self.attr[label] is None)

        # Distribute class attributes
        num_periods = self.attr['num_periods']

        edu_start = self.attr['edu_start']

        edu_max = self.attr['edu_max']

        # Distribute results
        periods_payoffs_systematic = self.attr['periods_payoffs_systematic']

        states_number_period = self.attr['states_number_period']

        mapping_state_idx = self.attr['mapping_state_idx']

        periods_emax = self.attr['periods_emax']

        states_all = self.attr['states_all']

        # Replace missing value with NAN. This allows to easily select the
        # valid subsets of the containers
        if mapping_state_idx is not None:
            mapping_state_idx = replace_missing_values(mapping_state_idx)
        if states_all is not None:
            states_all = replace_missing_values(states_all)
        if periods_payoffs_systematic is not None:
            periods_payoffs_systematic = replace_missing_values(
                periods_payoffs_systematic)
        if periods_emax is not None:
            periods_emax = replace_missing_values(periods_emax)

        # Check the creation of the state space
        is_applicable = (states_all is not None)
        is_applicable = is_applicable and (states_number_period is not None)
        is_applicable = is_applicable and (mapping_state_idx is not None)

        if is_applicable:
            # If the agent never increased their level of education, the lagged
            # education variable cannot take a value larger than zero.
            for period in range(1, num_periods):
                indices = (np.where(states_all[period, :, :][:, 2] == 0))
                for index in indices:
                    assert (np.all(states_all[period, :, :][index, 3]) == 0)

            # No values can be larger than constraint time. The exception in the
            # lagged schooling variable in the first period, which takes value
            # one but has index zero.
            for period in range(num_periods):
                assert (np.nanmax(states_all[period, :, :3]) <= period)

            # Lagged schooling can only take value zero or one if finite.
            # In fact, it can only take value one in the first period.
            for period in range(num_periods):
                assert (np.all(states_all[0, :, 3]) == 1)
                assert (np.nanmax(states_all[period, :, 3]) == 1)
                assert (np.nanmin(states_all[period, :, :3]) == 0)

            # All finite values have to be larger or equal to zero. The loop is
            # required as np.all evaluates to FALSE for this condition
            # (see NUMPY documentation).
            for period in range(num_periods):
                assert (np.all(
                    states_all[period, :states_number_period[period]] >= 0))

            # The maximum number of additional education years is never larger
            # than (EDU_MAX - EDU_START).
            for period in range(num_periods):
                assert (np.nanmax(states_all[period, :, :][:, 2], axis=0) <=
                        (edu_max - edu_start))

            # Check for duplicate rows in each period
            for period in range(num_periods):
                assert (np.sum(
                    pd.DataFrame(
                        states_all[period, :states_number_period[period], :]).
                    duplicated()) == 0)

            # Checking validity of state space values. All valid
            # values need to be finite.
            for period in range(num_periods):
                assert (np.all(
                    np.isfinite(
                        states_all[period, :states_number_period[period]])))

            # There are no infinite values in final period.
            assert (np.all(np.isfinite(states_all[(num_periods - 1), :, :])))

            # There are is only one finite realization in period one.
            assert (np.sum(np.isfinite(mapping_state_idx[0, :, :, :, :])) == 1)

            # If valid, the number of state space realizations in period two is
            # four.
            if num_periods > 1:
                assert (np.sum(np.isfinite(
                    mapping_state_idx[1, :, :, :, :])) == 4)

            # Check that mapping is defined for all possible realizations of the
            # state space by period. Check that mapping is not defined for all
            # inadmissible values.
            is_infinite = np.tile(False, reps=mapping_state_idx.shape)
            for period in range(num_periods):
                # Subsetting valid indices
                indices = states_all[
                    period, :states_number_period[period], :].astype('int')
                for index in indices:
                    # Check for finite value at admissible state
                    assert (np.isfinite(mapping_state_idx[period, index[0],
                                                          index[1], index[2],
                                                          index[3]]))
                    # Record finite value
                    is_infinite[period, index[0], index[1], index[2],
                                index[3]] = True
            # Check that all admissible states are finite
            assert (np.all(np.isfinite(
                mapping_state_idx[is_infinite == True])))

            # Check that all inadmissible states are infinite
            assert (np.all(np.isfinite(
                mapping_state_idx[is_infinite == False])) == False)

        # Check the calculated systematic payoffs
        is_applicable = (states_all is not None)
        is_applicable = is_applicable and (states_number_period is not None)
        is_applicable = is_applicable and (periods_payoffs_systematic
                                           is not None)

        if is_applicable:
            # Check that the payoffs are finite for all admissible values and
            # infinite for all others.
            is_infinite = np.tile(False, reps=periods_payoffs_systematic.shape)
            for period in range(num_periods):
                # Loop over all possible states
                for k in range(states_number_period[period]):
                    # Check that wages are all positive
                    assert (np.all(
                        periods_payoffs_systematic[period, k, :2] >= 0.0))
                    # Check for finite value at admissible state
                    assert (np.all(
                        np.isfinite(periods_payoffs_systematic[period, k, :])))
                    # Record finite value
                    is_infinite[period, k, :] = True
                # Check that all admissible states are finite
                assert (np.all(
                    np.isfinite(
                        periods_payoffs_systematic[is_infinite == True])))
                # Check that all inadmissible states are infinite
                if num_periods > 1:
                    assert (np.all(
                        np.isfinite(periods_payoffs_systematic[
                            is_infinite == False])) == False)

        # Check the expected future value
        is_applicable = (periods_emax is not None)

        if is_applicable:
            # Check that the payoffs are finite for all admissible values and
            # infinite for all others.
            is_infinite = np.tile(False, reps=periods_emax.shape)
            for period in range(num_periods):
                # Loop over all possible states
                for k in range(states_number_period[period]):
                    # Check for finite value at admissible state
                    assert (np.all(np.isfinite(periods_emax[period, k])))
                    # Record finite value
                    is_infinite[period, k] = True
                # Check that all admissible states are finite
                assert (np.all(np.isfinite(periods_emax[is_infinite == True])))
                # Check that all inadmissible states are infinite
                if num_periods == 1:
                    assert (len(periods_emax[is_infinite == False]) == 0)
                else:
                    assert (np.all(
                        np.isfinite(
                            periods_emax[is_infinite == False])) == False)