9898dynpv <- function (
9999 uptakes = 1 ,
100100 payoffs ,
101- horizon = length( payoffs ) ,
101+ horizon = NA ,
102102 tzero = 0 ,
103- prices = rep( 1 , length( payoffs ) + tzero ) ,
103+ prices = NA ,
104104 discrate = 0
105105 ){
106+ # If payoffs are discrete
107+ if (class(payoffs )== " numeric" ) {
108+ # Horizon defaults to length of payoffs
109+ if (class(horizon )== " logical" ) {horizon <- length(payoffs )}
110+ # Price index defaults to (1, ..., 1)
111+ if (class(prices )== " logical" ) {prices <- rep(1 , length(payoffs )+ tzero )}
112+ # Call calculation
113+ dpv <- dynpv_discrete(uptakes , payoffs , horizon , tzero , prices , discrate )
114+ }
115+ # If payoffs are not discrete and uptake is discrete
116+ if ((class(uptakes )== " numeric" ) & (class(payoffs )== " function" )) {
117+ dpv <- dynpv_semicts(uptakes , payoffs , horizon , tzero , prices , discrate )
118+ }
119+ # If payoffs and uptake are not discrete
120+ if ((class(uptakes )== " function" ) & (class(payoffs )== " function" )) {
121+ dpv <- dynpv_fullycts(uptakes , payoffs , horizon , tzero , prices , discrate )
122+ }
123+ # Return
124+ return (dpv )
125+ }
126+
127+ # Discrete function
128+ dynpv_discrete <- function (uptakes , payoffs , horizon , tzero , prices , discrate ){
106129 # Avoid no visible binding note
107130 j <- k <- l <- uj <- pk <- R <- v <- NULL
108131 # Trim
@@ -137,3 +160,42 @@ trim_vec <- function(vec){
137160 # Return trimmed vector
138161 return (vec [1 : trimto ])
139162}
163+
164+ # Function if payoffs, prices and discounting are functions; but uptakes is a vector
165+ dynpv_semicts <- function (uptakes , payoffs , horizon , tzero , prices , discrate ){
166+ # Avoid no visible binding note
167+ j <- uj <- pRv <- pv <- NULL
168+ # Trim
169+ uptakes <- trim_vec(uptakes )
170+ # Integrand function
171+ integrand <- function (k , j ) {
172+ payoffs(k ) * prices(j + k + tzero ) * discrate(j + k )
173+ }
174+ # Create a dataset for each combination of time
175+ df <- expand_grid(j = 1 : length(uptakes )) | >
176+ dplyr :: mutate(
177+ uj = uptakes [j ],
178+ pRv = stats :: integrate(integrand , lower = 0 , upper = horizon - j , j = j )$ value ,
179+ pv = uj * pRv
180+ )
181+ class(df ) <- c(" dynpv" , class(df ))
182+ return (df )
183+ }
184+
185+ # Function if uptakes, payoffs, prices and discounting are functions
186+ dynpv_fullycts <- function (uptakes , payoffs , horizon , tzero , prices , discrate ){
187+ # First integrand function - pRv, to be integrated between k=0 and k=T-j
188+ integrand1 <- function (k , j ) {
189+ payoffs(k ) * prices(j + k + tzero ) * discrate(j + k )
190+ }
191+ # Second integrand function, uj I, to be integrated between j=0 and j=T
192+ integrand2 <- function (j ) {
193+ pRv <- stats :: integrate(integrand1 , lower = 0 , upper = horizon - j , j = j )$ value
194+ uptakes(j ) * pRv
195+ }
196+ # Needs to be vectorized before integrating
197+ integrand2 <- Vectorize(integrand2 , " j" )
198+ # Calculate double integral
199+ df <- stats :: integrate(integrand2 , lower = 0 , upper = horizon )
200+ return (df $ value )
201+ }
0 commit comments