***************************
**   Maximo Sangiacomo   **
** Feb 2013. Version 1.0 **
***************************
program define pvvar, rclass
version 10
syntax varlist(min=2 max=2 numeric) [if] [in] [, GENerate(string) due(integer 0) ]
marksample touse
markout `touse' `time'
quietly count if `touse'
if `r(N)' == 0 error 2000
*Due
if (`due'!=0&`due'!=1) {
disp as err "{bf:due} should be one (1) or zero (0)"
exit 198
}
*Gen
if ("`generate'"=="") {
local generate d
}
gettoken v_cf v_rate: varlist
confirm new var `v_cf'_`generate'`due'
qui gen `v_cf'_`generate'`due'=.
mata: pvvar("`v_cf'", "`v_rate'", "`v_cf'_`generate'`due'", `due', "`touse'")
disp as txt "Present Value = " as res scalar(PV)
return scalar PV = scalar(PV)
return scalar due = scalar(due)
end

mata:
void pvvar(string scalar v_cf,
string scalar v_rate,
string scalar v_cf_d,
real scalar due,
string scalar touse)
{
	st_view(vcf=., ., v_cf, touse)
	st_view(vr=., ., v_rate, touse)
	st_view(vcfd=., ., v_cf_d, touse)
// validate rate
	for (i=1;i<=rows(vr);i++) {
		if (vr[i]<0|vr[i]>1) {
		errprintf("Each discount rate in {bf:%s} should be a number between 0 and 1\n", v_rate)
		exit(198)
		}
	}
	vrd = J(rows(vr), 1, 0)
	if (due==0) {
		for (i=1;i<=rows(vrd);i++) {
			vrd[i] =(1+vr[i])^(-i)
		}
	}
	else {
		for (i=1;i<=rows(vrd);i++) {
			j = i - 1
			vrd[i] =(1+vr[i])^(-j)
		}
	}

	vpv = vcf'*vrd
	vcfd[.,.]=vcf:*vrd
	st_numscalar("PV", vpv)
	st_numscalar("due", due)
}
end