Skip to content

Commit

Permalink
Merge pull request #714 from MridulS/log_consindshock
Browse files Browse the repository at this point in the history
[wip] logging in ConsIndShockModel
  • Loading branch information
llorracc authored Jun 18, 2020
2 parents 0c5a315 + 9512022 commit ac57981
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 153 deletions.
156 changes: 76 additions & 80 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from HARK.utilities import makeGridExpMult, CRRAutility, CRRAutilityP, \
CRRAutilityPP, CRRAutilityP_inv, CRRAutility_invP, CRRAutility_inv, \
CRRAutilityP_invP
from HARK import _log
from HARK import set_verbosity_level


__all__ = ['ConsumerSolution', 'ValueFunc', 'MargValueFunc', 'MargMargValueFunc',
Expand Down Expand Up @@ -1450,7 +1452,7 @@ class PerfForesightConsumerType(AgentType):

def __init__(self,
cycles=1,
verbose=False,
verbose=1,
quiet=False,
**kwds):
'''
Expand Down Expand Up @@ -1485,7 +1487,7 @@ def __init__(self,
self.verbose = verbose
self.quiet = quiet
self.solveOnePeriod = makeOnePeriodOOSolver(ConsPerfForesightSolver)

set_verbosity_level((4-verbose)*10)

def preSolve(self):
self.updateSolutionTerminal() # Solve the terminal period problem
Expand Down Expand Up @@ -1705,8 +1707,8 @@ def checkCondition(self,
name,
test,
messages,
verbose_messages=None,
verbose=False):
verbose,
verbose_messages=None):
"""
Checks one condition.
Expand All @@ -1729,30 +1731,30 @@ def checkCondition(self,
true or false under verbose printing.
"""
self.conditions[name] = test(self)

print(messages[self.conditions[name]].format(self))
if verbose and verbose_messages:
print(verbose_messages[self.conditions[name]].format(self))
set_verbosity_level((4-verbose)*10)
_log.info(messages[self.conditions[name]].format(self))
if verbose_messages:
_log.debug(verbose_messages[self.conditions[name]].format(self))


def checkAIC(self, verbose = False):
def checkAIC(self, verbose=None):
'''
Evaluate and report on the Absolute Impatience Condition
'''
name = "AIC"
test = lambda agent : agent.thorn < 1

messages = {
True: "\nThe value of the absolute impatience factor (AIF) for the supplied parameter values satisfies the Absolute Impatience Condition.",
False: "\nThe given type violates the Absolute Impatience Condition with the supplied parameter values; the AIF is {0.thorn}"}
True: "The value of the absolute impatience factor (AIF) for the supplied parameter values satisfies the Absolute Impatience Condition.",
False: "The given type violates the Absolute Impatience Condition with the supplied parameter values; the AIF is {0.thorn}"}
verbose_messages = {
True : " Because the AIF < 1, the absolute amount of consumption is expected to fall over time.\n",
False : " Because the AIF > 1, the absolute amount of consumption is expected to grow over time\n"
True : " Because the AIF < 1, the absolute amount of consumption is expected to fall over time.",
False : " Because the AIF > 1, the absolute amount of consumption is expected to grow over time."
}
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose, verbose_messages)

self.checkCondition(name, test, messages, verbose_messages, verbose = verbose)

def checkGICPF(self,verbose = False):
def checkGICPF(self, verbose=None):
'''
Evaluate and report on the Growth Impatience Condition for the Perfect Foresight model
'''
Expand All @@ -1763,18 +1765,18 @@ def checkGICPF(self,verbose = False):
test = lambda agent : agent.GIFPF < 1

messages = {
True : '\nThe value of the Growth Patience Factor for the supplied parameter values satisfies the Perfect Foresight Growth Impatience Condition.',
False : '\nThe value of the Growth Patience Factor for the supplied parameter values fails the Perfect Foresight Growth Impatience Condition; the GIFPF is: {0.GIFPF}',
True : 'The value of the Growth Patience Factor for the supplied parameter values satisfies the Perfect Foresight Growth Impatience Condition.',
False : 'The value of the Growth Patience Factor for the supplied parameter values fails the Perfect Foresight Growth Impatience Condition; the GIFPF is: {0.GIFPF}',
}

verbose_messages = {
True: ' Therefore, for a perfect foresight consumer, the ratio of individual wealth to permanent income will fall indefinitely.\n',
False: ' Therefore, for a perfect foresight consumer, the ratio of individual wealth to permanent income is expected to grow toward infinity.\n',
True: ' Therefore, for a perfect foresight consumer, the ratio of individual wealth to permanent income will fall indefinitely.',
False: ' Therefore, for a perfect foresight consumer, the ratio of individual wealth to permanent income is expected to grow toward infinity.',
}
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose, verbose_messages)

self.checkCondition(name, test, messages, verbose_messages, verbose = verbose)

def checkRIC(self, verbose = False):
def checkRIC(self, verbose=None):
'''
Evaluate and report on the Return Impatience Condition
'''
Expand All @@ -1785,17 +1787,18 @@ def checkRIC(self, verbose = False):
test = lambda agent: self.RIF < 1

messages = {
True : '\nThe value of the Return Patience Factor for the supplied parameter values satisfies the Return Impatience Condition.',
False : '\nThe value of the Return Patience Factor for the supplied parameter values satisfies the Return Impatience Condition; the factor is {0.RIF}'
True : 'The value of the Return Patience Factor for the supplied parameter values satisfies the Return Impatience Condition.',
False : 'The value of the Return Patience Factor for the supplied parameter values satisfies the Return Impatience Condition; the factor is {0.RIF}'
}

verbose_messages = {
True : ' Therefore, the limiting consumption function is not c(m)=0 for all m\n',
False : ' Therefore, the limiting consumption function is c(m)=0 for all m\n'
True : ' Therefore, the limiting consumption function is not c(m)=0 for all m',
False : ' Therefore, the limiting consumption function is c(m)=0 for all m'
}
self.checkCondition(name, test, messages, verbose = verbose)
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose,verbose_messages)

def checkFHWC(self,verbose = False):
def checkFHWC(self, verbose=None):
'''
Evaluate and report on the Finite Human Wealth Condition
'''
Expand All @@ -1807,18 +1810,18 @@ def checkFHWC(self,verbose = False):
test = lambda agent: self.FHWF < 1

messages = {
True : '\nThe Finite Human wealth factor value for the supplied parameter values satisfies the Finite Human Wealth Condition.',
False : '\nThe given type violates the Finite Human Wealth Condition; the Finite Human wealth factor value {0.FHWF}',
True : 'The Finite Human wealth factor value for the supplied parameter values satisfies the Finite Human Wealth Condition.',
False : 'The given type violates the Finite Human Wealth Condition; the Finite Human wealth factor value {0.FHWF}',
}

verbose_messages = {
True : ' Therefore, the limiting consumption function is not c(m)=Infinity\nand human wealth normalized by permanent income is {0.hNrm}\nand the PDV of future consumption growth is {0.cNrmPDV}\n',
False : ' Therefore, the limiting consumption function is c(m)=Infinity for all m\n'
True : ' Therefore, the limiting consumption function is not c(m)=Infinity\nand human wealth normalized by permanent income is {0.hNrm}\nand the PDV of future consumption growth is {0.cNrmPDV}',
False : ' Therefore, the limiting consumption function is c(m)=Infinity for all m'
}
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose)

self.checkCondition(name, test, messages, verbose = verbose)

def checkConditions(self,verbose=False):
def checkConditions(self, verbose=None):
'''
This method checks whether the instance's type satisfies the
Absolute Impatience Condition (AIC),
Expand Down Expand Up @@ -1853,6 +1856,7 @@ def checkConditions(self,verbose=False):

self.thorn = (self.Rfree*self.DiscFac*self.LivPrb[0])**(1/self.CRRA)

verbose = self.verbose if verbose is None else verbose
self.checkAIC(verbose)
self.checkGICPF(verbose)
self.checkRIC(verbose)
Expand Down Expand Up @@ -1903,7 +1907,7 @@ class IndShockConsumerType(PerfForesightConsumerType):

def __init__(self,
cycles=1,
verbose=False,
verbose=1,
quiet=False,
**kwds):
'''
Expand Down Expand Up @@ -2178,7 +2182,7 @@ def preSolve(self):
if not self.quiet:
self.checkConditions(verbose=self.verbose)

def checkGICInd(self,verbose):
def checkGICInd(self, verbose=None):
'''
Check Individual Growth Impatience Factor.
'''
Expand All @@ -2197,10 +2201,10 @@ def checkGICInd(self,verbose):
True : ' Therefore, a target level of the individual market resources ratio m exists (see {0.url}/#onetarget for more).\n',
False : ' Therefore, a target ratio of individual market resources to individual permanent income does not exist. (see {0.url}/#onetarget for more).\n'
}
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose, verbose_messages)

self.checkCondition(name,test,messages,verbose_messages, verbose=verbose)

def checkCIGAgg(self, verbose):
def checkCIGAgg(self, verbose=None):
name = 'GICAgg'
test = lambda agent : agent.GIFAgg <= 1

Expand All @@ -2214,10 +2218,10 @@ def checkCIGAgg(self, verbose):
True : ' Therefore, a target level of the ratio of aggregate market resources to aggregate permanent income exists.\n', # (see {0.url}/#WRIC for more).',
False : ' Therefore, a target ratio of aggregate resources to aggregate permanent income may not exist.\n' # (see {0.url}/#WRIC for more).'
}
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose, verbose_messages)

self.checkCondition(name,test,messages,verbose_messages, verbose=verbose)

def checkWRIC(self, verbose):
def checkWRIC(self, verbose=None):
'''
Evaluate and report on the Weak Return Impatience Condition
[url]/#WRIF modified to incorporate LivPrb
Expand All @@ -2236,10 +2240,10 @@ def checkWRIC(self, verbose):
True : ' Therefore, a nondegenerate solution exists if the FVAC is also satisfied. (see {0.url}/#WRIC for more) \n',
False : ' Therefore, a nondegenerate solution is not available (see {0.url}/#WRIC for more). \n'
}
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose, verbose_messages)

self.checkCondition(name,test,messages,verbose_messages, verbose=verbose)

def checkFVAC(self,verbose):
def checkFVAC(self, verbose=None):
'''
Evaluate and report on the Finite Value of Autarky Condition
Hyperlink to paper: [url]/#Autarky-Value
Expand Down Expand Up @@ -2267,11 +2271,10 @@ def checkFVAC(self,verbose):
True : ' Therefore, a nondegenerate solution exists if the WRIC also holds; see {0.url}/#Conditions-Under-Which-the-Problem-Defines-a-Contraction-Mapping\n',
False: ' Therefore, a nondegenerate solution is not available (see {0.url}/#Conditions-Under-Which-the-Problem-Defines-a-Contraction-Mapping\n'
}
verbose = self.verbose if verbose is None else verbose
self.checkCondition(name, test, messages, verbose, verbose_messages)

self.checkCondition(name, test, messages, verbose_messages, verbose=verbose)


def checkConditions(self,verbose=False):
def checkConditions(self, verbose=None):
'''
This method checks whether the instance's type satisfies the Absolute Impatience Condition (AIC), Weak Return
Impatience Condition (WRIC), Finite Human Wealth Condition (FHWC) and Finite Value of
Expand Down Expand Up @@ -2324,6 +2327,7 @@ def checkConditions(self,verbose=False):
self.DiscFacGIFPFMax = ((self.PermGroFac[0])**(self.CRRA))/(self.Rfree) # DiscFac at growth impatience knife edge
self.DiscFacGIFIndMax = ((self.PermGroFac[0]*self.InvEPermShkInv)**(self.CRRA))/(self.Rfree) # DiscFac at growth impatience knife edge
self.DiscFacGIFAggMax = ((self.PermGroFac[0])**(self.CRRA))/(self.Rfree*self.LivPrb[0]) # DiscFac at growth impatience knife edge
verbose = self.verbose if verbose is None else verbose

# self.checkGICPF(verbose)
self.checkGICInd(verbose)
Expand All @@ -2333,38 +2337,36 @@ def checkConditions(self,verbose=False):

self.violated = not self.conditions['WRIC'] or not self.conditions['FVAC']

if verbose and self.violated:
print('\n[!] For more information on the conditions, see Tables 3 and 4 in "Theoretical Foundations of Buffer Stock Saving" at '+self.url+'/#Factors-Defined-And-Compared')
print('')

if verbose:
print('GIFPF = %2.6f ' % (self.GIFPF))
print('GIFInd = %2.6f ' % (self.GIFInd))
print('GIFAgg = %2.6f ' % (self.GIFAgg))
print('Thorn = AIF = %2.6f ' % (self.thorn))
print('PermGroFacAdj = %2.6f ' % (self.PermGroFacAdj))
print('uInvEpShkuInv = %2.6f ' % (self.uInvEpShkuInv))
print('FVAF = %2.6f ' % (self.FVAF))
print('WRIF = %2.6f ' % (self.WRIF))
print('DiscFacGIFIndMax = %2.6f ' % (self.DiscFacGIFIndMax))
print('DiscFacGIFAggMax = %2.6f ' % (self.DiscFacGIFAggMax))

def Ex_Mtp1_over_Ex_Ptp1(self,mRat,verbose=False):
if self.violated:
_log.warning('\n[!] For more information on the conditions, see Tables 3 and 4 in "Theoretical Foundations of Buffer Stock Saving" at '+self.url+'/#Factors-Defined-And-Compared')

_log.warning('GIFPF = %2.6f ' % (self.GIFPF))
_log.warning('GIFInd = %2.6f ' % (self.GIFInd))
_log.warning('GIFAgg = %2.6f ' % (self.GIFAgg))
_log.warning('Thorn = AIF = %2.6f ' % (self.thorn))
_log.warning('PermGroFacAdj = %2.6f ' % (self.PermGroFacAdj))
_log.warning('uInvEpShkuInv = %2.6f ' % (self.uInvEpShkuInv))
_log.warning('FVAF = %2.6f ' % (self.FVAF))
_log.warning('WRIF = %2.6f ' % (self.WRIF))
_log.warning('DiscFacGIFIndMax = %2.6f ' % (self.DiscFacGIFIndMax))
_log.warning('DiscFacGIFAggMax = %2.6f ' % (self.DiscFacGIFAggMax))

def Ex_Mtp1_over_Ex_Ptp1(self,mRat):
cRat = self.solution[-1].cFunc(mRat)
aRat = mRat-cRat
Ex_Ptp1 = PermGroFac[0]
Ex_bLev_tp1 = aRat*self.Rfree
Ex_Mtp1 = Ex_bLev_tp1
return Ex_Mtp1/Ex_Ptp1

def Ex_mtp1(self,mRat,verbose=False):
def Ex_mtp1(self,mRat):
cRat = self.solution[-1].cFunc(mRat)
aRat = mRat-cRat
Ex_bRat_tp1 = aRat*self.Rfree*self.EPermShkInv/self.PermGroFac[0]
Ex_Mtp1 = (Ex_bRat_tp1 + 1)*Ex_Ptp1 # mean TranShk and PermShk are 1
return Ex_Mtp1/Ex_Ptp1

def calcTargets(self,verbose=False):
def calcTargets(self):
'''
If the problem is one that satisfies the conditions required for target ratios of different
variables to permanent income to exist, and has been solved to within the self-defined
Expand All @@ -2373,18 +2375,15 @@ def calcTargets(self,verbose=False):
Parameters
----------
verbose : boolean
Specifies different levels of verbosity of feedback. When False, it prints no results.
When True, it reports all target values, and passes the verbosity indicator to the
checkConditions method which responds accordingly.
None
Returns
-------
None
'''
infinite_horizon = cycles_left == 0
if not infinite_horizon:
print('The calcTargets method works only for infinite horizon models.')
_log.warning('The calcTargets method works only for infinite horizon models.')
return


Expand Down Expand Up @@ -2666,7 +2665,7 @@ def getRfree(self):
RfreeNow[self.aNrmNow > 0] = self.Rsave
return RfreeNow

def checkConditions(self,verbose=False):
def checkConditions(self):
'''
This method checks whether the instance's type satisfies the Absolute Impatience Condition (AIC),
the Return Impatience Condition (RIC), the Growth Impatience Condition (GIC), the Weak Return
Expand All @@ -2676,10 +2675,7 @@ def checkConditions(self,verbose=False):
Parameters
----------
verbose : boolean
Specifies different levels of verbosity of feedback. When False, it only reports whether the
instance's type fails to satisfy a particular condition. When True, it reports all results, i.e.
the factor values for all conditions.
None
Returns
-------
Expand Down
37 changes: 37 additions & 0 deletions HARK/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
from .core import *

__version__ = "0.10.6"

'''
Logging tools for HARK.
The logger will print logged statements to STDOUT by default.
The logger wil use an informative value by default.
The user can set it to "verbose" to get more information, or "quiet" to supress informative messages.
'''

import logging

logging.basicConfig(
format="%(message)s"
)

_log = logging.getLogger("HARK")

_log.setLevel(logging.ERROR)

def disable_logging():
_log.disabled = True

def enable_logging():
_log.disabled = False

def warnings():
_log.setLevel(logging.WARNING)

def quiet():
_log.setLevel(logging.ERROR)

def verbose():
_log.setLevel(logging.INFO)

def set_verbosity_level(level):
_log.setLevel(level)
Loading

0 comments on commit ac57981

Please sign in to comment.