program define boost, eclass
*! version 0.0.7  Mar 23, 2005 Matthias Schonlau

 version 8.1
 syntax [varlist] [if] [in], DISTribution(str) maxiter(int) [ INfluence  /*
  	*/ PREDict(str) TRAINfraction(real 0.8)	/*
	*/ shrink(real 0.01) bag(real 0.5)  INTERaction(int 5) /*
	*/ seed(int 0) ]

 local k : word count `varlist'
 if `k'<2  {
   di as error " Error: need at least 2 variables"
   exit
 }

*prepare matrix to transport one value per variable back from c++ program
 tempname influence_mat
 tempname A
 matrix `A'=(-1)
 matrix input `influence_mat'=(-1)
  while (rowsof(`influence_mat')< `k'-1) {
 	 matrix `influence_mat' = `influence_mat' \ `A'
  }

*prepare matrix to transport one value per iteration back from c++ program
 tempname lltrain_mat
 tempname lltest_mat
 matrix input `lltrain_mat'=(-1)
 matrix input `lltest_mat'=(-1)
*while (rowsof(`lltrain_mat')< `maxiter'-1) {
* 40 is the default maximum matrix size
 while (rowsof(`lltrain_mat')< 40) {
	matrix `lltrain_mat' = `lltrain_mat' \ `A'
	matrix `lltest_mat' = `lltest_mat' \ `A'
 }

if (length("`distribution'")==0) {
	local distribution="normal"
}
if ("`distribution'"!="poisson" & "`distribution'"!="logistic" & "`distribution'"!="normal") {
      di as error "Error: Distribution must be one of: normal, logistic, poisson"
	exit
}

if (length("`predict'")==0) {
	local predict="nopredict"
}
tempvar temp_predict
qui gen `temp_predict'=.


local influence = "`influence'" != ""
if (`influence'==1) {
	di "influence"
}

di as input "Distribution=`distribution'"
di as input "predict=`predict'"
di as input "Trainfraction=`trainfraction' Shrink=`shrink' Bag=`bag' maxiter=`maxiter' Interaction=`interaction'"
local nleafs=`interaction'+1

plugin call boost_plugin `varlist' `temp_predict' `if' `in',  /*
      	*/ `maxiter' `nleafs' `shrink' `bag' `distribution' /*
	*/ `trainfraction'  `influence' `predict' `influence_mat' `seed' /*
 	*/ `lltrain_mat' `lltest_mat'


ereturn clear


di as res "bestiter= " iter
ereturn scalar bestiter = iter

*di as res "test ll0= " test_ll0
ereturn scalar test_ll0 = test_ll0

*di as res "test ll1= " test_ll1
ereturn scalar test_ll1 = test_ll1

di as res "Test R2= " test_R2
ereturn scalar test_R2 = test_R2

di as res "trainn= " trainn
ereturn scalar trainn = trainn

*di as res "train ll0= " train_ll0
ereturn scalar train_ll0 = train_ll0

*di as res "train ll1= " train_ll1
ereturn scalar train_ll1 = train_ll1

di as res "Train R2= " train_R2
ereturn scalar train_R2 = train_R2


if (`influence') {
 display as result "Influence of each variable (Percent):"
 local i=0
 foreach var of local varlist {
	if (`i'>0) {
		* ignore the first variable (y)
 		di as result "`var' " `influence_mat'[`i',1] " "
	}
	local i=`i'+1
 }
 ereturn matrix influence =  `influence_mat'
}


if ("`predict'"!="nopredict") {
	gen `predict'=`temp_predict'
}




end