ufun2.r

#
#

utility function

#
  1. IN:
    • consumption $ c \in \mathbb{R} $,
    • params = list(cutoff=$c^*$,CRRA=1.4,diag.plot=FALSE)
  2. OUT: $$ u(c), u'(c), u''(c) $$
    • for consumption $ c \leq c^* $, return taylor series approx around $c^*$, denoted $\tilde{u}(c)$
#

Definition:

$$ \begin{eqnarray*} u(c) & = & \begin{cases} \frac{c^{1-\sigma}-1}{1-\sigma} & \text{if }\sigma\neq1,c>c^{*}\\ \ln c & \text{if }\sigma=1,c>c^{*}\\ \tilde{u}(c) & \text{if }c\leq c^{*} \end{cases} \end{eqnarray*} $$

utility <- function(x,params){
	
	if (params$CRRA != 1){
#

if $ CRRA \neq 1 $

		floor.x                    <- x             # copy actual consumption (can be negative) into floored consumption
		floor.x[x < params$cutoff] <- params$cutoff # replace consumption below cutoff with cutoff
#

$$ diff.cons = c - c^* $$

		diff.cons                  <- x - floor.x   # difference between actual and floored consumption
#

$$ floor.x^{1-CRRA} $$

		tmp.x     <- floor.x^(1-params$CRRA)
#

gradient of utility: $ \frac{du}{dx} $

		du.dx     <- tmp.x/floor.x
#

hessian of utility: $ \frac{d^2 u}{dx^2} $

		ddu.dxx   <- -params$CRRA*du.dx/floor.x
#

third derivative of u: $ \frac{d^3 u}{dx^3} $

		dddu.dxxx <- -(1+params$CRRA)*ddu.dxx/floor.x
#

CRRA utility at floor.x: $ u = \frac{floor.x^{1- CRRA} - 1}{1-CRRA} $

		util      <- (tmp.x - 1)/(1-params$CRRA)      
	} else {
#

else if CRRA==1, log utility

		floor.x                    <- x
		floor.x[x < params$cutoff] <- params$cutoff # replace consumption below cutoff with cutoff
		diff.cons                  <- x - floor.x   # difference between actual and floored consumption

		util      <- log(floor.x) # u(cons)
		du.dx     <- 1/floor.x    # u'(cons)
		ddu.dxx   <- -1/floor.x^2 # u"(cons)
		dddu.dxxx <- 2/floor.x^3  # u'''(cons)
	}
#

cubic approximation:

if $ c\leq c^*$, apply the following transformation. notice that $diff.cons = c-c^* = 0$ if $c>c^*$.

#

$$ \tilde{u}(c) = u\left(c^{*}\right)+u'\left(c^{*}\right)\left[c-c^{*}\right]+\frac{1}{2}u''\left(c^{*}\right)\left[c-c^{*}\right]^{2}+\frac{1}{6}u'''\left(c^{*}\right)\left[c-c^{*}\right]^{3} $$

	return.util <- util + du.dx*diff.cons + 0.5*ddu.dxx*diff.cons^2 + 1/6*dddu.dxxx*diff.cons^3
#

$$ \frac{d\tilde{u}(c)}{dc} = u'\left(c^{*}\right)+u''\left(c^{*}\right)\left[c-c^{*}\right]+\frac{1}{2}u'''\left(c^{*}\right)\left[c-c^{*}\right]^{2} $$

	return.grad <- du.dx + ddu.dxx*diff.cons + 0.5*dddu.dxxx*diff.cons^2
#

$$ \frac{d^{2}\tilde{u}(c)}{dc^{2}} = u''\left(c^{*}\right)+u'''\left(c^{*}\right)\left[c-c^{*}\right] $$

	return.hess <- ddu.dxx + dddu.dxxx*diff.cons
#

make plot if diag.plot was set to TRUE

	if (params$diag.plot){
		par(mfcol=c(3,2))
		plot(x=x,return.util,type="l",main="approx. utility",xlab="consumption",ylab="utility")
		abline(v = params$cutoff,col="red")
		grid()
		plot(x=x,return.grad,type="l",main="approx. gradient",xlab="consumption",ylab="gradient")
		abline(v = params$cutoff,col="red")
		grid()
		plot(x=x,return.hess,type="l",main="approx. hessian",xlab="consumption",ylab="hessian")
		abline(v = params$cutoff,col="red")
		grid()
		plot(x=x,util,type="l",main="capped utility",xlab="consumption",ylab="capped utility")
		grid()
		plot(x=x,du.dx,type="l",main="capped gradient",xlab="consumption",ylab="capped gradient")
		grid()
		plot(x=x,ddu.dxx,type="l",main="capped hessian",xlab="consumption",ylab="capped hessian")
		grid()
		par(mfcol=c(1,1))
	}
#

return list of values

	return(list(utility=return.util,gradient=return.grad,hessian=return.hess))
}