Skip to content

Commit

Permalink
Undo nan_bool merge (#236)
Browse files Browse the repository at this point in the history
* Revert "Fix one line break"

This reverts commit 39cc609.

* Revert "Merge pull request #193 from TimMunday/NanBool"

This reverts commit 4d19ea9, reversing
changes made to 7e690d9.
  • Loading branch information
mnwhite authored Mar 7, 2019
1 parent b84ee59 commit 6d6b295
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 70 deletions.
4 changes: 2 additions & 2 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ def usePointsForInterpolation(self,cNrm,mNrm,interpolator):
cFuncNowUnc = interpolator(mNrm,cNrm)

# Combine the constrained and unconstrained functions into the true consumption function
cFuncNow = LowerEnvelope(cFuncNowUnc, self.cFuncNowCnst, nan_bool = False)
cFuncNow = LowerEnvelope(cFuncNowUnc,self.cFuncNowCnst)

# Make the marginal value function and the marginal marginal value function
vPfuncNow = MargValueFunc(cFuncNow,self.CRRA)
Expand Down Expand Up @@ -1214,7 +1214,7 @@ def solveConsIndShock(solution_next,IncomeDstn,LivPrb,DiscFac,CRRA,Rfree,PermGro
included in the reported solution.
CubicBool: boolean
Indicator for whether the solver should use cubic or linear interpolation.
Returns
-------
solution_now : ConsumerSolution
Expand Down
98 changes: 30 additions & 68 deletions HARK/interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1642,29 +1642,19 @@ class LowerEnvelope(HARKinterpolator1D):
'''
distance_criteria = ['functions']

def __init__(self, *functions, nan_bool = True):
def __init__(self,*functions):
'''
Constructor to make a new lower envelope iterpolation.
Parameters
----------
*functions : function
Any number of real functions; often instances of HARKinterpolator1D
nan_bool : boolean
An indicator for whether the solver should exclude NA's when forming
the lower envelope.
Returns
-------
new instance of LowerEnvelope
'''

if nan_bool:
self.compare = np.nanmin
self.argcompare = np.nanargmin
else:
self.compare = np.min
self.argcompare = np.argmin

self.functions = []
for function in functions:
self.functions.append(function)
Expand All @@ -1675,24 +1665,22 @@ def _evaluate(self,x):
Returns the level of the function at each value in x as the minimum among
all of the functions. Only called internally by HARKinterpolator1D.__call__.
'''

if _isscalar(x):
y = self.compare([f(x) for f in self.functions])
y = np.nanmin([f(x) for f in self.functions])
else:
m = len(x)
fx = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
fx[:,j] = self.functions[j](x)
y = self.compare(fx,axis=1)

y = np.nanmin(fx,axis=1)
return y

def _der(self,x):
'''
Returns the first derivative of the function at each value in x. Only
called internally by HARKinterpolator1D.derivative.
'''
y,dydx = self._evalAndDer(x)
y,dydx = self.eval_with_derivative(x)
return dydx # Sadly, this is the fastest / most convenient way...

def _evalAndDer(self,x):
Expand All @@ -1704,14 +1692,16 @@ def _evalAndDer(self,x):
fx = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
fx[:,j] = self.functions[j](x)
i = self.argcompare(fx,axis=1)
fx[np.isnan(fx)] = np.inf
i = np.argmin(fx,axis=1)
y = fx[np.arange(m),i]
dydx = np.zeros_like(y)
for j in range(self.funcCount):
c = i == j
dydx[c] = self.functions[j].derivative(x[c])
return y,dydx


class UpperEnvelope(HARKinterpolator1D):
'''
The upper envelope of a finite set of 1D functions, each of which can be of
Expand All @@ -1720,29 +1710,19 @@ class UpperEnvelope(HARKinterpolator1D):
'''
distance_criteria = ['functions']

def __init__(self,*functions, nan_bool=True):
def __init__(self,*functions):
'''
Constructor to make a new upper envelope iterpolation.
Parameters
----------
*functions : function
Any number of real functions; often instances of HARKinterpolator1D
nan_bool : boolean
An indicator for whether the solver should exclude NA's when forming
the lower envelope.
Returns
-------
new instance of UpperEnvelope
'''
if nan_bool:
self.compare = np.nanmax
self.argcompare = np.nanargmax
else:
self.compare = np.max
self.argcompare = np.argmax

self.functions = []
for function in functions:
self.functions.append(function)
Expand All @@ -1754,22 +1734,21 @@ def _evaluate(self,x):
all of the functions. Only called internally by HARKinterpolator1D.__call__.
'''
if _isscalar(x):
y = self.compare([f(x) for f in self.functions])
y = np.nanmax([f(x) for f in self.functions])
else:
m = len(x)
fx = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
fx[:,j] = self.functions[j](x)
y = self.compare(fx,axis=1)

y = np.nanmax(fx,axis=1)
return y

def _der(self,x):
'''
Returns the first derivative of the function at each value in x. Only
called internally by HARKinterpolator1D.derivative.
'''
y,dydx = self._evalAndDer(x)
y,dydx = self.eval_with_derivative(x)
return dydx # Sadly, this is the fastest / most convenient way...

def _evalAndDer(self,x):
Expand All @@ -1781,7 +1760,8 @@ def _evalAndDer(self,x):
fx = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
fx[:,j] = self.functions[j](x)
i = self.argcompare(fx,axis=1)
fx[np.isnan(fx)] = np.inf
i = np.argmax(fx,axis=1)
y = fx[np.arange(m),i]
dydx = np.zeros_like(y)
for j in range(self.funcCount):
Expand All @@ -1798,29 +1778,19 @@ class LowerEnvelope2D(HARKinterpolator2D):
'''
distance_criteria = ['functions']

def __init__(self,*functions, nan_bool = True):
def __init__(self,*functions):
'''
Constructor to make a new lower envelope iterpolation.
Parameters
----------
*functions : function
Any number of real functions; often instances of HARKinterpolator2D
nan_bool : boolean
An indicator for whether the solver should exclude NA's when forming
the lower envelope.
Returns
-------
new instance of LowerEnvelope2D
'''

if nan_bool:
self.compare = np.nanmin
self.argcompare = np.nanargmin
else:
self.compare = np.min
self.argcompare = np.argmin
self.functions = []
for function in functions:
self.functions.append(function)
Expand All @@ -1832,16 +1802,14 @@ def _evaluate(self,x,y):
among all of the functions. Only called internally by
HARKinterpolator2D.__call__.
'''

if _isscalar(x):
f = self.compare([f(x,y) for f in self.functions])
f = np.nanmin([f(x,y) for f in self.functions])
else:
m = len(x)
temp = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
temp[:,j] = self.functions[j](x,y)
f = self.compare(temp,axis=1)

f = np.nanmin(temp,axis=1)
return f

def _derX(self,x,y):
Expand All @@ -1853,7 +1821,8 @@ def _derX(self,x,y):
temp = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
temp[:,j] = self.functions[j](x,y)
i = self.argcompare(temp,axis=1)
temp[np.isnan(temp)] = np.inf
i = np.argmin(temp,axis=1)
dfdx = np.zeros_like(x)
for j in range(self.funcCount):
c = i == j
Expand All @@ -1869,7 +1838,8 @@ def _derY(self,x,y):
temp = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
temp[:,j] = self.functions[j](x,y)
i = self.argcompare(temp,axis=1)
temp[np.isnan(temp)] = np.inf
i = np.argmin(temp,axis=1)
y = temp[np.arange(m),i]
dfdy = np.zeros_like(x)
for j in range(self.funcCount):
Expand All @@ -1886,28 +1856,19 @@ class LowerEnvelope3D(HARKinterpolator3D):
'''
distance_criteria = ['functions']

def __init__(self,*functions, nan_bool = True):
def __init__(self,*functions):
'''
Constructor to make a new lower envelope iterpolation.
Parameters
----------
*functions : function
Any number of real functions; often instances of HARKinterpolator3D
nan_bool : boolean
An indicator for whether the solver should exclude NA's when forming
the lower envelope.
Returns
-------
None
'''
if nan_bool:
self.compare = np.nanmin
self.argcompare = np.nanargmin
else:
self.compare = np.min
self.argcompare = np.argmin
self.functions = []
for function in functions:
self.functions.append(function)
Expand All @@ -1919,16 +1880,14 @@ def _evaluate(self,x,y,z):
among all of the functions. Only called internally by
HARKinterpolator3D.__call__.
'''

if _isscalar(x):
f = self.compare([f(x,y,z) for f in self.functions])
f = np.nanmin([f(x,y,z) for f in self.functions])
else:
m = len(x)
temp = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
temp[:,j] = self.functions[j](x,y,z)
f = self.compare(temp,axis=1)

f = np.nanmin(temp,axis=1)
return f

def _derX(self,x,y,z):
Expand All @@ -1940,7 +1899,8 @@ def _derX(self,x,y,z):
temp = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
temp[:,j] = self.functions[j](x,y,z)
i = self.argcompare(temp,axis=1)
temp[np.isnan(temp)] = np.inf
i = np.argmin(temp,axis=1)
dfdx = np.zeros_like(x)
for j in range(self.funcCount):
c = i == j
Expand All @@ -1956,7 +1916,8 @@ def _derY(self,x,y,z):
temp = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
temp[:,j] = self.functions[j](x,y,z)
i = self.argcompare(temp,axis=1)
temp[np.isnan(temp)] = np.inf
i = np.argmin(temp,axis=1)
y = temp[np.arange(m),i]
dfdy = np.zeros_like(x)
for j in range(self.funcCount):
Expand All @@ -1973,7 +1934,8 @@ def _derZ(self,x,y,z):
temp = np.zeros((m,self.funcCount))
for j in range(self.funcCount):
temp[:,j] = self.functions[j](x,y,z)
i = self.argcompare(temp,axis=1)
temp[np.isnan(temp)] = np.inf
i = np.argmin(temp,axis=1)
y = temp[np.arange(m),i]
dfdz = np.zeros_like(x)
for j in range(self.funcCount):
Expand Down

0 comments on commit 6d6b295

Please sign in to comment.