Esempio n. 1
0
    def __init__(self, n_households):
        self.n_households = n_households
        super().__init__()
        # Chose a schedule
        self.schedule = RandomActivation(self)
        self.production = 10
        self.kapital_households = 0  # To change in a list of the sum
        self.kapital_households_speculators = 0  # # To change in a list of the sum
        self.sum_loans_households = self.n_households * loan_households
        self.travail = 0
        self.alpha = 0
        self.beta = 0

        # Create  a bank, a firm and n household
        # self.bank = Bank(1, self)
        # self.schedule.add(bank)
        # firm = Firm(2, self)
        # self.schedule.add(firm)
        x = risk_lovers_rate * self.n_households
        for i in range(self.n_households):
            if i <= x:
                h = Household(i + 2, 1, self)
                self.schedule.add(h)
            else:
                hp = Household(i + 2, -1, self)
                self.schedule.add(hp)
Esempio n. 2
0
 def init_house(self, l_0, theta, gamma, phi, omega_p=None, f=None, r=None):
     """
     Initialize a household object as instance of economy class. Refer to household class.
     :param l_0: baseline work offer,
     :param theta: preferency factors,
     :param gamma: aversion to work parameter,
     :param phi: Frisch index,
     :param omega_p: confidence parameter
     :param f: fraction of budget to save,
     :param r: savings growth rate.
     :return: Initializes household class with given parameters.
     """
     self.house = Household(l_0, theta, gamma, phi, omega_p, f, r)
Esempio n. 3
0
    def _form_single_hh(self, t, ind):
        """
        Move specified individual, with no partner, into their own household.

        :param t: the current time step.
        :type t: int
        :param i_id: the first partner in the couple.
        :type i_id: int
        :returns: the ID of the new household.
        """

        assert not ind.partner
        #        assert len(self.housemates(i_id)) > 0

        # remove any guardians
        self._remove_from_guardians(t, ind, \
                'c-', "Lost dependent %d (leaving)" % ind.ID, ind.ID)

        # remove from old household
        self._remove_individual_from_hh(t, ind, 'l', "Individual left")

        # add to newly created household
        new_hh = self.add_group('household', [ind])

        ind.with_parents = False

        self.households[new_hh] = Household(t)
        if self.logging:
            ind.add_log(t, 'l1', "Leaving household (single)")
            self.households[new_hh].add_log(t, 'f1', "Household formed", 1)

        return new_hh
Esempio n. 4
0
    def duplicate_household(self, t, hh_id):
        """
        Create a duplicate of household hh_id, consisting of 
        new individuals with same household age composition.

        Return id of newly created household.

        :param t: The current time step.
        :type t: int
        :param hh_id: The household to duplicate
        :type hh_id: int
        :returns the id of the newly created household.
        """

        new_hh = []
        for ind in self.groups['household'][hh_id]:
            new_ind = self.add_individual(ind.age,
                                          ind.sex,
                                          logging=self.logging)
            if self.logging:
                new_ind.add_log(t, 'i', "Individual (immigrated)")
            new_hh.append(new_ind)
        new_hh_id = self.add_group('household', new_hh)
        self.households[new_hh_id] = Household(t)
        self._init_household(new_hh_id)
        if self.logging:
            self.households[new_hh_id].add_log(
                t, 'i', "Household (immigrated)",
                len(self.groups['household'][new_hh_id]))

        return new_hh_id
Esempio n. 5
0
	def __init__(self, n_agents):
		"""
		Basic constructor with mostly default values

		Parameters
		n_agents : dict containing the number of each
			type of agents that we want our model to include
		"""
		# "Private parameters"
		# These parameters will be used to communicate to the agents that 
		# a new day or a new month started
		#self.daypassed = False
		self.monthpassed = False

		# Attributes related to time
		self.start_datetime = datetime(2005, 1, 1, 0, 0, 0, tzinfo=None)
		self.current_datetime = self.start_datetime
		self.step_interval = "month"

		self.n_banks = n_agents['banks']
		self.n_firms = n_agents['firms']
		self.n_households = n_agents['households']

		# Chose a scheduler
		self.scheduler = RandomActivation(self)

		# Create the required number of each agent
		for i in range(self.n_banks):
			a = Bank(i, self)
			a.liquidity = 1000
			self.scheduler.add(a)

		for i in range(self.n_firms):
			a = Firm(i + self.n_banks, self)
			self.scheduler.add(a)

		for i in range(self.n_households):
			a = Household(i + self.n_banks + self.n_firms, self)
			self.scheduler.add(a)

		# If any deposits is to be given to banks it should be given now
		# Init all firms with their employees
		self.init_all_firms()

		# Create the data collector
		self.datacollector = DataCollector(
			model_reporters = {"Household liquidity": agent2_liquidity,
							"Household deposit": agent2_deposit,
							"Bank liquidity": agent0_liquidity,
							"Networth of household": agent2_netWorth,
							"Networth of bank": agent0_netWorth,
							"Firm net worth": agent1_netWorth})

		self.running = True
 def init_households(self):
     employer_idx = 0
     for hh in range(self.hh_param.get("num_hh")):
         # first, hhs are distributed such that each firm has one employee
         # afterwards, hhs are randomly assigned to an employer
         # employers need to be informed who their employees are
         employer = self.firm_list[employer_idx] if employer_idx < len(self.firm_list) else random.choice(self.firm_list)
         new_household = Household(self, employer)
         employer.list_employees.append(new_household)
         self.hh_list.append(new_household)
         employer_idx += 1
Esempio n. 7
0
    def gen_hh_age_structured_pop(self, pop_size, hh_probs, age_probs_i,
                                  cutoffs, rng):
        """
        Generate a population of individuals with age structure and household 
        composition.

        Household composition here is approximated by the number of 
        individuals who are:

        - pre-school age (0--4)
        - school age (5--17)
        - adult (18+)

        This is a bit ad hoc, but serves current purposes.

        :param pop_size: The size of the population to be generated.
        :type pop_size: int
        :param hh_probs: A table of household size probabilities.
        :type hh_probs: list
        :param age_probs_i: A table of age probabilities.
        :type age_probs_i: list
        :param rng: The random number generator to use.
        :type rng: :class:`random.Random`
        """

        age_probs = [[x, int(y[0])] for x, y in age_probs_i]
        split_probs = split_age_probs(age_probs, cutoffs)
        split_probs.reverse()

        i = 0
        while i < pop_size:
            # get list of [adults, school age, preschool age]
            hh_type = [int(x) for x in sample_table(hh_probs, rng)]
            #            hh_type = [int(x) for x in sample_uniform(hh_probs, rng)]
            cur_hh = []
            for cur_hh_type, cur_prob in zip(hh_type, split_probs):
                for _ in itertools.repeat(None, cur_hh_type):
                    sex = rng.randint(0, 1)
                    cur_age = sample_table(cur_prob, rng)
                    cur_ind = self.add_individual(cur_age,
                                                  sex,
                                                  adam=True,
                                                  logging=self.logging)
                    if self.logging:
                        cur_ind.add_log(0, 'f', "Individual (bootstrap)")
                    cur_hh.append(cur_ind)
                    i += 1
            hh_id = self.add_group('household', cur_hh)
            self.households[hh_id] = Household(0, adam=True)
            if self.logging:
                self.households[hh_id].add_log(
                    0, 'f', "Household (bootstrap)",
                    len(self.groups['household'][hh_id]))
Esempio n. 8
0
    def _form_couple_hh(self, t, inds):
        """
        Make specified single individuals into a couple and move them into a 
        new household.  Any dependents of either individual accompany them to 
        the new household.

        :param t: the current time step.
        :type t: int
        :param i_ids: the individuals to move into a couple household.
        :type i_ids: list
        :returns: the ID of the new household.
        """

        ind_a = inds[0]
        ind_b = inds[1]

        inds[0].with_parents = False
        inds[1].with_parents = False

        # move dependents along with guardians
        new_inds = list(inds)
        combined_deps = ind_a.deps + ind_b.deps
        ind_a.deps = combined_deps[:]
        ind_b.deps = combined_deps[:]
        new_inds.extend(combined_deps)

        # remove any guardians of new couple
        self._remove_from_guardians(t, inds[0], \
                'c-', "Lost dependent %d (leaving)" % inds[0].ID, inds[0].ID)
        self._remove_from_guardians(t, inds[1], \
                'c-', "Lost dependent %d (leaving)" % inds[1].ID, inds[1].ID)

        # remove individuals from prior households and create new household
        for ind in new_inds:
            self._remove_individual_from_hh(t, ind, 'l', "Individual left")
        hh_id = self.add_group('household', new_inds)

        self.households[hh_id] = Household(t)

        if self.logging:
            ind_a.add_log(t, 'l2',
                          "Leaving household - couple with %d" % ind_b.ID)
            ind_b.add_log(t, 'l2',
                          "Leaving household - couple with %d" % ind_a.ID)
            self.households[hh_id].add_log(t, 'f2', \
                    "Household formed (%d individuals)" % \
                    len(new_inds), len(new_inds))

        return hh_id
Esempio n. 9
0
 def gen_single_hh_pop(self, hh_size, rng):
     """
     Generate a dummy population consisting of a single household.
     """
     cur_hh = []
     for i in xrange(hh_size):
         sex = rng.randint(0, 1)
         cur_ind = self.add_individual(20,
                                       sex,
                                       adam=True,
                                       logging=self.logging)
         if self.logging:
             cur_ind.add_log(0, 'f', "Individual (bootstrap)")
         cur_hh.append(cur_ind)
     hh_id = self.add_group('household', cur_hh)
     self.households[hh_id] = Household(0, adam=True)
     if self.logging:
         self.households[hh_id].add_log(
             0, 'f', "Household (bootstrap)",
             len(self.groups['household'][hh_id]))
Esempio n. 10
0
    def agents_update(self):
        '''
        Update household(and person)'s demographic status; do everything except for marriage and child birth.
        '''
        
        temp_hh_list = list()
        
        # Annual household status update
        for HID in self.hh_dict:
            temp_hh_list.append(Household.household_demographic_update(self.hh_dict[HID], self.current_year, self.model_parameters_dict))

        # Reset the households dict
        self.hh_dict = dict()
        
        # Refresh hh_dict
        for h in temp_hh_list:
            self.hh_dict[h.HID] = h
            
            if h.is_exist == 0: # If the household does not exist...                
                if h.is_dissolved_this_year == True: # ...and it becomes non-exist this year
                    # Dissolve non-existing households
                    self.dissolve_household(h.HID)                               
Esempio n. 11
0
    def agents_update(self):
        '''
        Update household(and person)'s demographic status; do everything except for marriage and child birth.
        '''
        
        temp_hh_list = list()
        
        # Annual household status update
        for HID in self.hh_dict:
            temp_hh_list.append(Household.household_demographic_update(self.hh_dict[HID], self.current_year, self.model_parameters_dict))

        # Reset the households dict
        self.hh_dict = dict()
        
        # Refresh hh_dict
        for h in temp_hh_list:
            self.hh_dict[h.HID] = h
            
            if h.is_exist == 0: # If the household does not exist...                
                if h.is_dissolved_this_year == True: # ...and it becomes non-exist this year
                    # Dissolve non-existing households
                    self.dissolve_household(h.HID)                               
Esempio n. 12
0
 def setup_households(self):
     if self.adaptive:
         for i in range(self.init_households):
             new_household = Household(model=self,
                                       coords=self.random_coords(),
                                       energy=self.init_energy,
                                       move_threshold=random(),
                                       move_dist=randint(1, 5),
                                       farm_dist=randint(1, 20),
                                       fission_rate=uniform(1, 2),
                                       min_fertility=random())
             new_household.claim_land()
     else:
         for i in range(self.init_households):
             new_household = Household(model=self,
                                       coords=self.random_coords(),
                                       energy=self.init_energy,
                                       move_threshold=(self.init_energy *
                                                       self.move_rate),
                                       move_dist=randint(1, 5),
                                       farm_dist=self.swidden_radius,
                                       fission_rate=self.fission_energy,
                                       min_fertility=0.8)
             new_household.claim_land()
Esempio n. 13
0
class Simulation():
    def __init__(self, runParameters, firmParameters, householdParameters):

        self.runParameters = runParameters
        self.firmParameters = firmParameters
        self.householdParameters = householdParameters

        self.duration = runParameters['duration']
        self.money = runParameters['money']
        self.stock = runParameters['stock']
        self.verbose = runParameters['verbose']
        self.expectation = runParameters['expectation']
        self.demandKnown = runParameters['demandKnown']

    def equilibrium(self, money, householdParameters, firmParameters):
        Lmax = householdParameters['Lmax']
        alpha = householdParameters['alpha']
        beta = householdParameters['beta']
        gamma = firmParameters['gamma']
        zeta_0 = firmParameters['zeta_0']

        L_star = beta / (alpha + beta) * Lmax
        p_star = L_star**(1 - gamma)
        S_star = L_star**gamma
        z_star = p_star * S_star**zeta_0
        print(
            'Equilibrium values are: p = {:.4f}, S = {:.4f}, L = {:.4f}, z = {:.4f}'
            .format(p_star, S_star, L_star, z_star))

        return (p_star, L_star, S_star, z_star)

    def saveSimResults(self):
        self.firmSimResults = self.firmSimResults.append(self.firm.__dict__,
                                                         ignore_index=True)
        self.householdSimResults = self.householdSimResults.append(
            self.household.__dict__, ignore_index=True)
        self.marketSimResults = self.marketSimResults.append(
            self.market.__dict__, ignore_index=True)

    def advanceAttributes(self):
        self.market.SM_t, self.market.LM_t = self.market.SM_tp1, self.market.LM_tp1

        self.firm.LD_t, self.firm.SSP_t, self.firm.SS_t = self.firm.LD_tp1, self.firm.SSP_tp1, self.firm.SS_tp1
        self.firm.p_t = self.firm.p_tp1
        self.firm.z_t, self.firm.zeta_t = self.firm.z_tp1, self.firm.zeta_tp1
        if self.stock: self.firm.stock_t = self.firm.stock_tp1
        if self.money: self.firm.mF_t = self.firm.mF_tp1

        self.household.LS_t, self.household.SD_t = self.household.LS_tp1, self.household.SD_tp1
        if self.money: self.household.mH_t = self.household.mH_tp1

    def Run(self):
        self.p_star, self.L_star, self.S_star, self.z_star = self.equilibrium(
            self.money, self.householdParameters, self.firmParameters)

        self.firm = Firm(self.money, self.firmParameters, self.p_star,
                         self.S_star, self.L_star, self.z_star,
                         self.expectation)
        self.household = Household(self.householdParameters, self.p_star,
                                   self.S_star, self.z_star, self.firm.zeta_0)
        self.market = Market(self.S_star, self.L_star)

        self.firmSimResults = pd.DataFrame()
        self.householdSimResults = pd.DataFrame()
        self.marketSimResults = pd.DataFrame()

        for t in range(self.duration):

            if self.verbose: print('\nstep ', str(t + 1))
            #add time step as instance attribute
            self.market.step = t + 1
            self.firm.step = t + 1
            self.household.step = t + 1

            #firms plan sugar production
            self.firm.decideProduction(self.verbose, self.money,
                                       self.market.SM_t, self.household.Lmax)

            #households decide labor supply
            self.household.decideLabor(self.verbose)

            #market decides labor supply
            self.market.laborTransaction(self.verbose, self.firm.LD_tp1,
                                         self.household.LS_tp1)

            #firms produce sugar
            self.firm.produce(self.verbose, self.market.LM_tp1)

            #households decide sugar consumption
            self.household.decideConsumption(self.verbose, self.money,
                                             self.market.LM_tp1,
                                             self.firm.p_tp1)

            #market decides demand for sugar
            self.market.stuffTransaction(self.verbose, self.firm.SS_tp1,
                                         self.household.SD_tp1)

            #update firm stock
            if self.stock:
                self.firm.updateStock(self.verbose, self.market.SM_tp1)

            #update firm ledgers
            if self.money:
                self.firm.updateLedger(self.verbose, self.market.SM_tp1,
                                       self.market.LM_tp1)

            #no labor curve updating first round
            if t == 0: self.market.LM_t = self.market.LM_tp1

            #update sugar demand an labor supply function parameters
            if self.demandKnown:
                self.firm.updateExpectations(self.verbose, self.money,
                                             self.household.SD_t,
                                             self.household.SD_tp1,
                                             self.market.LM_tp1,
                                             self.market.LM_t,
                                             self.market.LM_tp1)
            else:
                self.firm.updateExpectations(self.verbose, self.money,
                                             self.market.SM_t,
                                             self.market.SM_tp1,
                                             self.market.LM_tp1,
                                             self.market.LM_t,
                                             self.market.LM_tp1)

            #update household ledgers
            if self.money:
                self.household.updateLedger(self.verbose, self.firm.p_tp1,
                                            self.market.SM_tp1,
                                            self.market.LM_tp1)

            #save step results
            self.saveSimResults()

            # update timed variables
            self.advanceAttributes()

            #print('step', t + 1, 'complete')

        print(
            'Final simulation values are: p = {:.4f}, S = {:.4f}, L = {:.4f}'.
            format(self.firm.p_tp1, self.market.SM_t, self.market.LM_t))

        return self.firmSimResults, self.householdSimResults, self.marketSimResults
Esempio n. 14
0
class Economy:
    def __init__(self, n, d, netstring, directed, j0, a0, q, b):

        # Network initialization
        self.n = n
        self.j = create_net(netstring, directed, n, d)
        self.j0 = j0
        self.j_a = None
        self.a0 = a0
        a = np.multiply(np.random.uniform(0, 1, (n, n)), self.j)
        self.a = np.array([(1 - a0[i]) * a[i] / np.sum(a[i])
                           for i in range(n)])
        self.a_a = None
        self.q = q
        self.zeta = 1 / (q + 1)
        self.b = b

        # Auxiliary network variables
        self.lamb = None
        self.a_a = None
        self.j_a = None
        self.lamb_a = None
        self.m_cal = None
        self.v = None
        self.kappa = None
        self.zeros_j_a = None

        # Firms and household sub-classes
        self.firms = None
        self.house = None

        # Equilibrium quantities
        self.p_eq = None
        self.g_eq = None
        self.mu_eq = None
        self.labour_eq = None
        self.cons_eq = None
        self.b_eq = None
        self.utility_eq = None

    def init_house(self, l_0, theta, gamma, phi, omega_p=None, f=None, r=None):
        """
        Initialize a household object as instance of economy class. Refer to household class.
        :param l_0: baseline work offer,
        :param theta: preferency factors,
        :param gamma: aversion to work parameter,
        :param phi: Frisch index,
        :param omega_p: confidence parameter
        :param f: fraction of budget to save,
        :param r: savings growth rate.
        :return: Initializes household class with given parameters.
        """
        self.house = Household(l_0, theta, gamma, phi, omega_p, f, r)

    def init_firms(self, z, sigma, alpha, alpha_p, beta, beta_p, omega):
        """
        Initialize a firms object as instance of economy class. Refer to firms class.
        :param z: Productivity factors,
        :param sigma: Depreciation of stocks parameters,
        :param alpha: Log-elasticity of prices' growth rates against surplus,
        :param alpha_p: Log-elasticity of prices' growth rates against profits,
        :param beta: Log-elasticity of productions' growth rates against profits,
        :param beta_p: Log-elasticity of productions' growth rates against surplus,
        :param omega: Log-elasticity of wages' growth rates against labor-market tensions.
        :return: Initializes firms class with given parameters.
        """
        self.firms = Firms(z, sigma, alpha, alpha_p, beta, beta_p, omega)

    # Setters for class instances

    def set_house(self, house):
        """
        Sets a household object as instance of economy class.
        :param house:
        :return:
        """
        self.house = house

    def set_firms(self, firms):
        """
        Sets a firms object as instance of economy class.
        :param firms:
        :return:
        """
        self.firms = firms

    # Update methods for firms and household

    def update_firms_z(self, z):
        self.firms.update_z(z)
        self.set_quantities()
        self.compute_eq()

    def update_firms_sigma(self, sigma):
        self.firms.update_sigma(sigma)

    def update_firms_alpha(self, alpha):
        self.firms.update_alpha(alpha)

    def update_firms_alpha_p(self, alpha_p):
        self.firms.update_alpha_p(alpha_p)

    def update_firms_beta(self, beta):
        self.firms.update_beta(beta)

    def update_firms_beta_p(self, beta_p):
        self.firms.update_beta_p(beta_p)

    def update_firms_w(self, omega):
        self.firms.update_w(omega)

    def update_house_labour(self, labour):
        self.house.update_labour(labour)
        self.compute_eq()

    def update_house_theta(self, theta):
        self.house.update_theta(theta)
        self.compute_eq()

    def update_house_gamma(self, gamma):
        self.house.update_gamma(gamma)
        self.compute_eq()

    def update_house_phi(self, phi):
        self.house.update_phi(phi)
        self.compute_eq()

    def update_house_w_p(self, omega_p):
        self.house.update_w_p(omega_p)

    def update_house_f(self, f):
        self.house.update_f(f)

    def update_house_r(self, r):
        self.house.update_r(r)

    # Setters for the networks and subsequent instances

    def set_j(self, j):
        """
        Sets a particular input-output network.
        :param j: a n by n matrix.
        :return: side effect
        """
        if j.shape != (self.n, self.n):
            raise ValueError('Input-output network must be of size (%d, %d)' %
                             (self.n, self.n))

        self.j = j
        self.set_quantities()
        self.compute_eq()

    def set_a(self, a):
        """
        Sets a particular input-output network.
        :param a: a n by n matrix.
        :return: side effect
        """
        if a.shape != (self.n, self.n):
            raise ValueError('Substitution network must be of size (%d, %d)' %
                             (self.n, self.n))
        self.a = a
        self.set_quantities()
        self.compute_eq()

    def set_quantities(self):
        """
        Sets redundant economy quantities as class instances.
        :return: side effect
        """
        if self.q == 0:
            self.lamb = self.j
            self.a_a = np.hstack((np.array([self.a0]).T, self.a))
            self.j_a = np.hstack((np.array([self.j0]).T, self.j))
            self.lamb_a = self.j_a
            self.m_cal = np.diag(self.firms.z) - self.lamb
            self.v = np.array(self.lamb_a[:, 0])
        elif self.q == np.inf:
            self.lamb = self.a
            self.a_a = np.hstack((np.array([self.a0]).T, self.a))
            self.j_a = np.hstack((np.array([self.j0]).T, self.j))
            self.lamb_a = self.a_a
            self.m_cal = np.eye(self.n) - self.lamb
            self.v = np.array(self.lamb_a[:, 0])
        else:
            self.lamb = np.multiply(np.power(self.a, self.q * self.zeta),
                                    np.power(self.j, self.zeta))
            self.a_a = np.hstack((np.array([self.a0]).T, self.a))
            self.j_a = np.hstack((np.array([self.j0]).T, self.j))
            self.lamb_a = np.multiply(np.power(self.a_a, self.q * self.zeta),
                                      np.power(self.j_a, self.zeta))
            self.m_cal = np.diag(np.power(self.firms.z, self.zeta)) - self.lamb
            self.v = np.array(self.lamb_a[:, 0])
        self.mu_eq = np.power(
            np.power(self.house.gamma, 1. / self.house.phi) *
            np.sum(self.house.theta) * (1 - (1 - self.house.f) *
                                        (1 + self.house.r)) /
            (self.house.f * np.power(self.house.l_0, 1 + 1. / self.house.phi)),
            self.house.phi / (1 + self.house.phi))
        self.kappa = self.house.theta / self.mu_eq
        self.zeros_j_a = self.j_a != 0

    def get_eps_cal(self):
        """
        Computes the smallest eigenvalue of the economy matrix
        :return: smallest eigenvalue
        """
        return np.min(np.real(np.linalg.eigvals(self.m_cal)))

    def set_eps_cal(self, eps):
        """
        Modifies firms instance to set smallest eigenvalue of economy matrix to given epsilon.
        :param eps: a real number,
        :return: side effect.
        """
        min_eig = self.get_eps_cal()
        z_n = self.firms.z * np.power(
            1 +
            (eps - min_eig) / np.power(self.firms.z, self.zeta), self.q + 1)
        sigma = self.firms.sigma
        alpha = self.firms.alpha
        alpha_p = self.firms.alpha_p
        beta = self.firms.beta
        beta_p = self.firms.beta_p
        omega = self.firms.omega
        self.init_firms(z_n, sigma, alpha, alpha_p, beta, beta_p, omega)
        self.set_quantities()
        self.compute_eq()

    def update_b(self, b):
        """
        Sets return to scale parameter
        :param b: return to scale
        :return: side effect
        """
        self.b = b
        self.compute_eq()

    def update_q(self, q):
        self.q = q
        self.zeta = 1 / (q + 1)
        self.set_quantities()
        self.compute_eq()

    def update_network(self, netstring, directed, d, n):
        self.j = create_net(netstring, directed, n, d)
        a = np.multiply(np.random.uniform(0, 1, (n, n)), self.j)
        self.a = np.array([(1 - self.a0[i]) * a[i] / np.sum(a[i])
                           for i in range(n)])
        self.set_quantities()
        self.compute_eq()

    def update_a0(self, a0):
        self.a0 = a0
        a = np.multiply(np.random.uniform(0, 1, (self.n, self.n)), self.j)
        self.a = np.array([(1 - self.a0[i]) * a[i] / np.sum(a[i])
                           for i in range(self.n)])
        self.set_quantities()
        self.compute_eq()

    def update_j0(self, j0):
        self.j0 = j0
        self.set_quantities()
        self.compute_eq()

    def production_function(self, q_available):
        """
        CES production function.
        :param q_available: matrix of available labour and goods for production,
        :return: production levels of the firms.
        """
        if self.q == 0:
            return np.power(
                np.nanmin(np.divide(q_available, self.j_a), axis=1), self.b)
        elif self.q == np.inf:
            return np.power(
                np.nanprod(np.power(np.divide(q_available, self.j_a),
                                    self.a_a),
                           axis=1), self.b)
        else:
            return np.power(
                np.nansum(self.a_a * np.power(self.j_a, 1. / self.q) /
                          np.power(q_available, 1. / self.q),
                          axis=1), -self.b * self.q)

    def compute_eq(self):
        """
        Computes the competitive equilibrium of the economy. We use least-squares to compute solutions of linear
        systems Ax=b for memory and computational efficiency. The non-linear equations for non-constant return to scale
        parameters are solved using generalized least-squares with initial guesses taken to be the solution of the b=1
        linear equation. For a high number of firms, high heterogeneity of close to 0 epsilon, this function might
        can output erroneous results or errors.
        :return: side effect.
        """
        if self.q == np.inf:
            h = np.sum(
                self.a_a *
                np.log(np.ma.masked_invalid(np.divide(self.j_a, self.a_a))),
                axis=1)
            v = lstsq(np.eye(self.n) - self.a.T, self.kappa, rcond=10e-7)[0]
            log_p = lstsq(np.eye(self.n) / self.b - self.a,
                          -np.log(self.firms.z) / self.b +
                          (1 - self.b) * np.log(v) / self.b + h,
                          rcond=10e-7)[0]
            log_g = -np.log(self.firms.z) - log_p + np.log(v)
            self.p_eq, self.g_eq = np.exp(log_p), np.exp(log_g)
        else:
            if self.b != 1:
                if self.q == 0:
                    init_guess_peq = lstsq(self.m_cal, self.v, rcond=10e-7)[0]
                    init_guess_geq = lstsq(self.m_cal.T,
                                           np.divide(self.kappa,
                                                     init_guess_peq),
                                           rcond=10e-7)[0]

                    par = (self.firms.z, self.v, self.m_cal, self.b - 1,
                           self.kappa)

                    pert_peq = lstsq(self.m_cal,
                                     self.firms.z * init_guess_peq *
                                     np.log(init_guess_geq),
                                     rcond=10e-7)[0]

                    pert_geq = lstsq(
                        np.transpose(self.m_cal),
                        -np.divide(self.kappa, np.power(init_guess_peq, 2)) *
                        pert_peq +
                        self.firms.z * init_guess_geq * np.log(init_guess_geq),
                        rcond=10e-7)[0]

                    pg = leastsq(
                        lambda x: self.non_linear_eq_qzero(x, *par),
                        np.array(
                            np.concatenate(
                                (init_guess_peq + (1 - self.b) * pert_peq,
                                 np.power(
                                     init_guess_geq + (1 - self.b) *
                                     (pert_geq -
                                      init_guess_geq * np.log(init_guess_geq)),
                                     1 / self.b))).reshape(2 * self.n)))[0]

                    # pylint: disable=unbalanced-tuple-unpacking
                    self.p_eq, g = np.split(pg, 2)
                    self.g_eq = np.power(g, self.b)

                else:

                    # The numerical solving is done for variables u = p_eq ^ zeta and
                    # w = z ^ (q * zeta) * u ^ q * g_eq ^ (zeta * (bq+1) / b)

                    init_guess_u = lstsq(self.m_cal, self.v, rcond=None)[0]
                    init_guess_w = lstsq(self.m_cal.T,
                                         np.divide(self.kappa, init_guess_u),
                                         rcond=None)[0]

                    par = (np.power(self.firms.z,
                                    self.zeta), self.v, self.m_cal, self.q,
                           (self.b - 1) / (self.b * self.q + 1), self.kappa)

                    uw = leastsq(
                        lambda x: self.non_linear_eq_qnonzero(x, *par),
                        np.concatenate((init_guess_u, init_guess_w)),
                    )[0]

                    # pylint: disable=unbalanced-tuple-unpacking
                    u, w = np.split(uw, 2)
                    self.p_eq = np.power(u, 1. / self.zeta)
                    self.g_eq = np.power(
                        np.divide(
                            w,
                            np.power(self.firms.z, self.q * self.zeta) *
                            np.power(u, self.q)),
                        self.b / (self.zeta * (self.b * self.q + 1)))
            else:
                if self.q == 0:
                    self.p_eq = lstsq(self.m_cal, self.v, rcond=10e-7)[0]
                    self.g_eq = lstsq(self.m_cal.T,
                                      np.divide(self.kappa, self.p_eq),
                                      rcond=10e-7)[0]
                else:

                    # The numerical solving is done for variables u = p_eq ^ zeta and
                    # w = z ^ (q * zeta) * u ^ q * g_eq

                    u = lstsq(self.m_cal, self.v, rcond=None)[0]
                    self.p_eq = np.power(u, 1. / self.zeta)
                    w = lstsq(self.m_cal.T,
                              np.divide(self.kappa, u),
                              rcond=None)[0]
                    self.g_eq = np.divide(
                        w,
                        np.power(self.firms.z, self.q * self.zeta) *
                        np.power(u, self.q))

        self.labour_eq = np.power(self.mu_eq * self.house.f,
                                  1. / self.house.phi) / self.house.v_phi
        self.cons_eq = self.kappa / self.p_eq
        self.b_eq = np.sum(self.house.theta) / self.mu_eq
        self.utility_eq = np.dot(self.house.theta, np.log(
            self.cons_eq)) - self.house.gamma * np.power(
                self.labour_eq / self.house.l_0,
                self.house.phi + 1) / (self.house.phi + 1)

    def save_eco(self, name):
        """
        Saves the economy as multi-indexed data-frame in hdf format along with networks in npy format.
        :param name: name of file,
        """
        first_index = np.concatenate(
            (np.repeat('Firms', 11), np.repeat('Household', 11)))
        second_index = np.concatenate(([
            'q', 'b', 'z', 'sigma', 'alpha', 'alpha_p', 'beta', 'beta_p', 'w',
            'p_eq', 'g_eq'
        ], ['l', 'theta', 'gamma', 'phi']))
        multi_index = [first_index, second_index]
        values = np.vstack((
            self.q * np.ones(self.n),
            self.b * np.ones(self.n),
            self.firms.z,
            self.firms.sigma,
            self.firms.alpha * np.ones(self.n),
            self.firms.alpha_p * np.ones(self.n),
            self.firms.beta * np.ones(self.n),
            self.firms.beta_p * np.ones(self.n),
            self.firms.w * np.ones(self.n),
            self.p_eq,
            self.g_eq,
            self.house.l_0 * np.ones(self.n),
            self.house.theta,
            self.house.gamma * np.ones(self.n),
            self.house.phi * np.ones(self.n),
        ))

        df_eco = pd.DataFrame(values,
                              index=multi_index,
                              columns=[np.arange(1, self.n + 1)])
        df_eco.to_hdf(name + '/eco.h5', key='df', mode='w')
        np.save(name + '/network.npy', self.j_a)
        if self.q != 0:
            np.save(name + '/sub_network.npy', self.a_a)

    # Fixed point equations for equilibrium computation

    @staticmethod
    def non_linear_eq_qnonzero(x, *p):
        """
        Function used for computation of equilibrium with non constant return to scale
        and general CES production function.
        :param x: guess for equilibrium
        :param p: tuple z, z_zeta, v, m_cal, zeta, q, theta, theta_bar, power
        :return: function's value at x
        """
        if len(x) % 2 != 0:
            raise ValueError("x must be of even length")

        # pylint: disable=unbalanced-tuple-unpacking
        u, w = np.split(x, 2)
        z_zeta, v, m_cal, q, exponent, kappa = p
        w_over_uq_p = np.power(
            np.divide(w,
                      np.power(z_zeta, q) * np.power(u, q)), exponent)
        v1 = np.multiply(z_zeta, np.multiply(u, 1 - w_over_uq_p))
        m1 = np.dot(m_cal, u)
        m2 = u * np.dot(m_cal.T, w) - w * m1
        return np.concatenate((m1 - v1 - v, m2 + w * v - kappa))

    @staticmethod
    def non_linear_eq_qzero(x, *par):
        """
        Function used for computation of equilibrium with non constant return to scale
        and Leontieff production function.
        :param x: guess for equilibrium
        :param par: tuple z_zeta, v, m_cal, q power
        :return: function's value at x
        """

        if len(x) % 2 != 0:
            raise ValueError('x must be of even length')

        # pylint: disable=unbalanced-tuple-unpacking
        p, g = np.split(x, 2)
        z, v, m_cal, exponent, kappa = par
        v1 = np.multiply(z, np.multiply(p, 1 - np.power(g, exponent)))
        m1 = np.dot(m_cal, p)
        m2 = g * m1 - p * np.dot(m_cal.T, g)
        return np.concatenate((m1 - v1 - v, m2 - g * v + kappa))
Esempio n. 15
0
    def __init__(self, db, model_table_name, model_table, hh_table_name, hh_table, pp_table_name, pp_table, 
                 land_table_name, land_table, business_sector_table_name, business_sector_table, 
                 policy_table_name, policy_table, stat_table_name, stat_table, start_year):
        '''
        Initialize the society class;
        '''
        
        # Set the start year and current time stamps
        self.start_year = start_year
        self.current_year = start_year
        
        # Create a dictionary to store model parameters, indexed by Variable_Name, and contents are Variable_Value      
        self.model_parameters_dict = dict()        
        # Fill in the model parameters dictionary from the model table (fetched from DB)
        for record in model_table:
            self.model_parameters_dict[record.Variable_Name] = record.Variable_Value
          
        
        # Get the variable lists for household, person, land, business sector, policy, and statistics classes 
        self.hh_var_list = DataAccess.get_var_list(db, hh_table_name)
        self.pp_var_list = DataAccess.get_var_list(db, pp_table_name)
        self.land_var_list = DataAccess.get_var_list(db, land_table_name)
        self.business_sector_var_list = DataAccess.get_var_list(db, business_sector_table_name)
        self.policy_var_list = DataAccess.get_var_list(db, policy_table_name)
        self.stat_var_list = DataAccess.get_var_list(db, stat_table_name)


        # Initialize the land instances, and create a land dictionary to store all the land parcels
        # Note that the land parcels here do not necessarily belong to any household. i.e. land_parcel.HID could be "None".
        self.land_dict = dict()
        for land in land_table:
            land_parcel = Land(land, self.land_var_list, self.current_year)
            self.land_dict[land_parcel.ParcelID] = land_parcel # Indexed by ParcelID


        # Initialize the household instances (household capital property and land class instances are initialized at the initialization of household class);
        # And create a dictionary to store them, indexed by HID.
        self.hh_dict = dict()        
        # Add household instances to hh_dict
        for hh in hh_table:
            hh_temp = Household(hh, self.hh_var_list, self.current_year, db, pp_table_name, pp_table, 
                                self.land_dict, self.model_parameters_dict)
            self.hh_dict[hh_temp.HID] = hh_temp # Indexed by HID

        
        # Initialize the business sector instances;
        # And create a dictionary to store them, indexed by sector name.
        self.business_sector_dict = dict()
        for sector in business_sector_table:
            sector_temp = BusinessSector(sector, self.business_sector_var_list)
            self.business_sector_dict[sector_temp.SectorName] = sector_temp # Indexed by SectorName
            
        
        # Initialize the policy program instances;
        # And create a dictionary to store them, indexed by policy program type.
        self.policy_dict = dict()
        for program in policy_table:
            program_temp = Policy(program, self.policy_var_list)
            self.policy_dict[program_temp.PolicyType] = program_temp # Indexed by PolicyType
        
                        
        # Create a statistics dictionary; indexed by Variable Names.To be filled later in Statistics Class.
        self.stat_dict = dict()
        
        # Create some variables to record the confiscated (due to ownerlessness) money and land
        self.ownerless_land = list()
        self.ownerless_money = 0
Esempio n. 16
0
 def editHousehold(self, hhid, newhhid,  householdname, dateofcollection):
     household = Household( self.pid,  hhid )
     household.setData( householdname, dateofcollection,  newhhid )
     return household
Esempio n. 17
0
    def Run(self):
        self.p_star, self.L_star, self.S_star, self.z_star = self.equilibrium(
            self.money, self.householdParameters, self.firmParameters)

        self.firm = Firm(self.money, self.firmParameters, self.p_star,
                         self.S_star, self.L_star, self.z_star,
                         self.expectation)
        self.household = Household(self.householdParameters, self.p_star,
                                   self.S_star, self.z_star, self.firm.zeta_0)
        self.market = Market(self.S_star, self.L_star)

        self.firmSimResults = pd.DataFrame()
        self.householdSimResults = pd.DataFrame()
        self.marketSimResults = pd.DataFrame()

        for t in range(self.duration):

            if self.verbose: print('\nstep ', str(t + 1))
            #add time step as instance attribute
            self.market.step = t + 1
            self.firm.step = t + 1
            self.household.step = t + 1

            #firms plan sugar production
            self.firm.decideProduction(self.verbose, self.money,
                                       self.market.SM_t, self.household.Lmax)

            #households decide labor supply
            self.household.decideLabor(self.verbose)

            #market decides labor supply
            self.market.laborTransaction(self.verbose, self.firm.LD_tp1,
                                         self.household.LS_tp1)

            #firms produce sugar
            self.firm.produce(self.verbose, self.market.LM_tp1)

            #households decide sugar consumption
            self.household.decideConsumption(self.verbose, self.money,
                                             self.market.LM_tp1,
                                             self.firm.p_tp1)

            #market decides demand for sugar
            self.market.stuffTransaction(self.verbose, self.firm.SS_tp1,
                                         self.household.SD_tp1)

            #update firm stock
            if self.stock:
                self.firm.updateStock(self.verbose, self.market.SM_tp1)

            #update firm ledgers
            if self.money:
                self.firm.updateLedger(self.verbose, self.market.SM_tp1,
                                       self.market.LM_tp1)

            #no labor curve updating first round
            if t == 0: self.market.LM_t = self.market.LM_tp1

            #update sugar demand an labor supply function parameters
            if self.demandKnown:
                self.firm.updateExpectations(self.verbose, self.money,
                                             self.household.SD_t,
                                             self.household.SD_tp1,
                                             self.market.LM_tp1,
                                             self.market.LM_t,
                                             self.market.LM_tp1)
            else:
                self.firm.updateExpectations(self.verbose, self.money,
                                             self.market.SM_t,
                                             self.market.SM_tp1,
                                             self.market.LM_tp1,
                                             self.market.LM_t,
                                             self.market.LM_tp1)

            #update household ledgers
            if self.money:
                self.household.updateLedger(self.verbose, self.firm.p_tp1,
                                            self.market.SM_tp1,
                                            self.market.LM_tp1)

            #save step results
            self.saveSimResults()

            # update timed variables
            self.advanceAttributes()

            #print('step', t + 1, 'complete')

        print(
            'Final simulation values are: p = {:.4f}, S = {:.4f}, L = {:.4f}'.
            format(self.firm.p_tp1, self.market.SM_t, self.market.LM_t))

        return self.firmSimResults, self.householdSimResults, self.marketSimResults
 def create_households(self):
     """Creates X number of households and adds them to list of households."""
     for i, _ in enumerate(range(self.NEIGHBORHOOD_APARTMENTS), 1):
         household = Household(i)
         self.households.append(household)
Esempio n. 19
0
    def __init__(self, n_households, df3):
        self.n_households = n_households
        self.df3 = pd.read_excel(df3)
        super().__init__()
        # Chose a schedule
        self.schedule = RandomActivation(self)
        self.production = 0
        self.kapital_households = []
        self.kapital_households_speculators = []
        self.kapital_global_btcModel = []
        self.kapital_global = 7.5 * n_households
        self.kh_high = 0
        self.kh_medium = 0
        self.kh_low = 0
        self.kh = 0
        self.sum_speculator_portfolio = 0
        self.sum_wages_households = 0
        self.sum_consumption_households = 0
        self.sum_loans_households = 0
        self.travail = 1000
        self.alpha = 0.5
        self.beta = 0.5
        self.techno = 1.3  # technology factor
        self.gamma = 0.67  # coefficient of production applie to salaries 0.67
        self.n = 12

        self.start_datetime = datetime(2017, 1, 1, tzinfo=None)
        self.current_datetime = self.start_datetime

        self.datacollector = DataCollector(model_reporters={
            "Production": production,
            "KapitalG": evolution_kapital_global,
            "KapitalH": kapital_new,
            "Kapital_households_risk_averse":
            graph_households_risk_averse_kapital,
            "Kapital_households_speculator":
            graph_households_speculator_kapital,
            "WagesH": graph_households_wage,
            "sum_wage": increase_wages_households,
            "Conso": graph_households_conso,
            "KapitalF": graph_kapital_firm,
            "KapitalB": graph_kapital_bank,
            "diff": diff
        },
                                           agent_reporters={"Wage": "wage"})

        self.running = True

        # Create  a bank, a firm and n household
        self.firm = Firm(2, self)
        self.bank = Bank(1, self)

        xh = risk_high_rate * self.n_households
        xm = xh + risk_medium_rate * self.n_households
        xl = xm + risk_low_rate * self.n_households
        for i in range(self.n_households):
            if i < xh:
                h = Household(i + 2, 2, P2, self)
                self.schedule.add(h)
            elif i >= xh and i < xm:
                h = Household(i + 2, 1, P1, self)
                self.schedule.add(h)
            elif i >= xm and i < xl:
                h = Household(i + 2, 0, P0, self)
                self.schedule.add(h)
            else:
                h = Household(i + 2, -1, 0, self)
                self.schedule.add(h)

        #Init production with kapital initialisation of agents and give loans
        production(self)
        self.bank.give_loan()