From aad84a876d6c9695283a2a9d05836baf58fd3ba9 Mon Sep 17 00:00:00 2001 From: schalkdaniel Date: Wed, 23 Jan 2019 08:15:35 +0100 Subject: [PATCH] update shared ptr ... --- DESCRIPTION | 2 +- NEWS.md | 2 + R/RcppExports.R | 2 +- README.Rmd | 2 +- README.md | 56 +++++++------ Readme_files/cboost-1.png | Bin 42698 -> 40052 bytes man/LoggerOobRisk.Rd | 2 +- src/baselearner.cpp | 24 +++--- src/baselearner.h | 24 +++--- src/baselearner_factory.cpp | 16 ++-- src/baselearner_factory.h | 15 ++-- src/baselearner_factory_list.cpp | 6 +- src/baselearner_factory_list.h | 4 +- src/compboost.cpp | 8 +- src/compboost.h | 2 +- src/compboost_modules.cpp | 131 ++++++++++++++----------------- src/data.cpp | 29 +------ src/data.h | 6 +- src/logger.cpp | 8 +- src/logger.h | 4 +- src/loggerlist.cpp | 4 +- src/loggerlist.h | 4 +- 22 files changed, 156 insertions(+), 195 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5de8381b..dbfbed84 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: compboost Type: Package Title: C++ Implementation of Component-Wise Boosting -Version: 0.1.0 +Version: 0.1.1 Authors@R: c( person(given = "Daniel", family = "Schalk", email = "daniel.schalk@stat.uni-muenchen.de", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-0950-1947")), person(given = "Janek", family = "Thomas", email = "janek.thomas@stat.uni-muenchen.de", role = "aut", comment = c(ORCID = "0000-0003-4511-6245")), diff --git a/NEWS.md b/NEWS.md index adf90f32..a0bc7eb2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,5 @@ +## compboost 0.1.1 + - **23.01.2019** \ **Style**: Change `.` to `_`, e.g. change `n.knots` to `n_knots`, to be more consistent with `C++` syntax. diff --git a/R/RcppExports.R b/R/RcppExports.R index 993aa33c..b39772de 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -1060,7 +1060,7 @@ NULL #' #' oob_list = list(data_source1, data_source2) #' -#' set_seed(123) +#' set.seed(123) #' y_oob = rnorm(10) #' #' # Used loss: diff --git a/README.Rmd b/README.Rmd index cf31e6d1..06e04c85 100644 --- a/README.Rmd +++ b/README.Rmd @@ -42,7 +42,7 @@ For an introduction and overview about the functionality visit the [project page #### CRAN version: ```r -instlal.packages("compboost") +install.packages("compboost") ``` #### Developer version: diff --git a/README.md b/README.md index 4443a773..272c004f 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,10 @@ install.packages("compboost") devtools::install_github("schalkdaniel/compboost") ``` -Examples [![Binder](http://mybinder.org/badge.svg)](http://beta.mybinder.org/v2/gh/schalkdaniel/compboost/master?filepath=./binder/tutorial_intro.ipynb) --------------------------------------------------------------------------------------------------------------------------------------------------------- +Examples +-------- -This examples are rendered using compboost 0.1.0. +This examples are rendered using compboost 0.1.1. To be as flexible as possible one should use the `R6` API do define base-learner, losses, stopping criteria, or optimizer as desired. Another option is to use wrapper functions as described on the [project page](https://schalkdaniel.github.io/compboost/). @@ -42,23 +42,23 @@ library(compboost) # Check installed version: packageVersion("compboost") -#> [1] '0.1.0' +#> [1] '0.1.1' # Load data set with binary classification task: data(PimaIndiansDiabetes, package = "mlbench") # Create categorical feature: -PimaIndiansDiabetes$pregnant.cat = ifelse(PimaIndiansDiabetes$pregnant == 0, "no", "yes") +PimaIndiansDiabetes$pregnant_cat = ifelse(PimaIndiansDiabetes$pregnant == 0, "no", "yes") # Define Compboost object: cboost = Compboost$new(data = PimaIndiansDiabetes, target = "diabetes", loss = LossBinomial$new()) cboost +#> #> Component-Wise Gradient Boosting #> #> Trained on PimaIndiansDiabetes with target diabetes #> Number of base-learners: 0 #> Learning rate: 0.05 #> Iterations: 0 -#> Positive class: neg #> #> LossBinomial Loss: #> @@ -67,33 +67,33 @@ cboost #> # Add p-spline base-learner with default parameter: -cboost$addBaselearner(feature = "pressure", id = "spline", bl.factory = BaselearnerPSpline) +cboost$addBaselearner(feature = "pressure", id = "spline", bl_factory = BaselearnerPSpline) # Add another p-spline learner with custom parameters: -cboost$addBaselearner(feature = "age", id = "spline", bl.factory = BaselearnerPSpline, degree = 3, - n.knots = 10, penalty = 4, differences = 2) +cboost$addBaselearner(feature = "age", id = "spline", bl_factory = BaselearnerPSpline, degree = 3, + n_knots = 10, penalty = 4, differences = 2) # Add categorical feature (as single linear base-learner): -cboost$addBaselearner(feature = "pregnant.cat", id = "category", bl.factory = BaselearnerPolynomial, +cboost$addBaselearner(feature = "pregnant_cat", id = "category", bl_factory = BaselearnerPolynomial, degree = 1, intercept = FALSE) # Check all registered base-learner: cboost$getBaselearnerNames() #> [1] "pressure_spline" "age_spline" -#> [3] "pregnant.cat_yes_category" "pregnant.cat_no_category" +#> [3] "pregnant_cat_yes_category" "pregnant_cat_no_category" # Train model: cboost$train(1000L, trace = 200L) -#> 1/1000: risk = 0.66 -#> 200/1000: risk = 0.58 -#> 400/1000: risk = 0.57 -#> 600/1000: risk = 0.57 -#> 800/1000: risk = 0.57 -#> 1000/1000: risk = 0.57 +#> 1/1000 risk = 0.68 +#> 200/1000 risk = 0.65 +#> 400/1000 risk = 0.64 +#> 600/1000 risk = 0.64 +#> 800/1000 risk = 0.64 +#> 1000/1000 risk = 0.64 #> #> #> Train 1000 iterations in 0 Seconds. -#> Final risk based on the train set: 0.57 +#> Final risk based on the train set: 0.64 cboost #> Component-Wise Gradient Boosting #> @@ -101,7 +101,6 @@ cboost #> Number of base-learners: 4 #> Learning rate: 0.05 #> Iterations: 1000 -#> Positive class: neg #> Offset: 0.3118 #> #> LossBinomial Loss: @@ -112,20 +111,20 @@ cboost cboost$getBaselearnerNames() #> [1] "pressure_spline" "age_spline" -#> [3] "pregnant.cat_yes_category" "pregnant.cat_no_category" +#> [3] "pregnant_cat_yes_category" "pregnant_cat_no_category" -selected.features = cboost$getSelectedBaselearner() -table(selected.features) -#> selected.features -#> age_spline pregnant.cat_no_category pressure_spline -#> 434 150 416 +selected_features = cboost$getSelectedBaselearner() +table(selected_features) +#> selected_features +#> age_spline pregnant_cat_no_category pressure_spline +#> 448 130 422 params = cboost$getEstimatedCoef() str(params) #> List of 4 -#> $ age_spline : num [1:14, 1] 2.99 1.501 0.588 -0.535 -0.119 ... -#> $ pregnant.cat_no_category: num [1, 1] -0.299 -#> $ pressure_spline : num [1:24, 1] -0.8087 -0.4274 -0.0602 0.2226 0.3368 ... +#> $ age_spline : num [1:14, 1] 3.717 1.5152 0.669 -0.6627 -0.0277 ... +#> $ pregnant_cat_no_category: num [1, 1] -0.41 +#> $ pressure_spline : num [1:24, 1] -0.969 -0.403 0.14 0.537 0.644 ... #> $ offset : num 0.312 cboost$train(3000) @@ -141,7 +140,6 @@ cboost$plot("age_spline", iters = c(100, 500, 1000, 2000, 3000)) +

- Benchmark --------- diff --git a/Readme_files/cboost-1.png b/Readme_files/cboost-1.png index ce2b9ed8b10c781e03cb25e4d01793563a477792..c2213024369a6a31fea17dee74eb55ba330df120 100644 GIT binary patch literal 40052 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 data0) { parameter = parameter0; blearner_identifier = blearner_identifier0; @@ -36,7 +36,7 @@ void Baselearner::copyMembers (const arma::mat& parameter0, } // Set the data pointer: -void Baselearner::setData (data::Data* data) +void Baselearner::setData (std::shared_ptr data) { data_ptr = data; } @@ -106,7 +106,7 @@ Baselearner::~Baselearner () // BaselearnerPolynomial: // ----------------------- -BaselearnerPolynomial::BaselearnerPolynomial (data::Data* data, const std::string& identifier, +BaselearnerPolynomial::BaselearnerPolynomial (std::shared_ptr data, const std::string& identifier, const unsigned int& degree, const bool& intercept) : degree ( degree ), intercept ( intercept ) @@ -185,7 +185,7 @@ arma::mat BaselearnerPolynomial::predict () const return data_ptr->getData() * parameter; } } -arma::mat BaselearnerPolynomial::predict (data::Data* newdata) const +arma::mat BaselearnerPolynomial::predict (std::shared_ptr newdata) const { return instantiateData(newdata->getData()) * parameter; } @@ -222,7 +222,7 @@ BaselearnerPolynomial::~BaselearnerPolynomial () {} * Finally we get a \f$9 - (p + 1)\f$ splines for which we can calculate the * base. * - * \param data `data::Data*` Target data used for training etc. + * \param data `std::shared_ptr` Target data used for training etc. * \param identifier `std::string` Identifier for one specific baselearner * \param degree `unsigned int` Polynomial degree of the splines * \param n_knots `unsigned int` Number of inner knots used @@ -233,7 +233,7 @@ BaselearnerPolynomial::~BaselearnerPolynomial () {} * penalty matrix. */ -BaselearnerPSpline::BaselearnerPSpline (data::Data* data, const std::string& identifier, +BaselearnerPSpline::BaselearnerPSpline (std::shared_ptr data, const std::string& identifier, const unsigned int& degree, const unsigned int& n_knots, const double& penalty, const unsigned int& differences, const bool& use_sparse_matrices) : degree ( degree ), @@ -327,11 +327,11 @@ arma::mat BaselearnerPSpline::predict () const /** * \brief Predict on newdata * - * \param newdata `data::Data*` new source data object + * \param newdata `std::shared_ptr` new source data object * * \returns `arma::mat` of predicted values */ -arma::mat BaselearnerPSpline::predict (data::Data* newdata) const +arma::mat BaselearnerPSpline::predict (std::shared_ptr newdata) const { return instantiateData(newdata->getData()) * parameter; } @@ -344,7 +344,7 @@ BaselearnerPSpline::~BaselearnerPSpline () {} // BaselearnerCustom: // ----------------------- -BaselearnerCustom::BaselearnerCustom (data::Data* data, const std::string& identifier, +BaselearnerCustom::BaselearnerCustom (std::shared_ptr data, const std::string& identifier, Rcpp::Function instantiateDataFun, Rcpp::Function trainFun, Rcpp::Function predictFun, Rcpp::Function extractParameter) : instantiateDataFun ( instantiateDataFun ), @@ -392,7 +392,7 @@ arma::mat BaselearnerCustom::predict () const return Rcpp::as(out); } -arma::mat BaselearnerCustom::predict (data::Data* newdata) const +arma::mat BaselearnerCustom::predict (std::shared_ptr newdata) const { Rcpp::NumericMatrix out = predictFun(model, instantiateData(newdata->getData())); return Rcpp::as(out); @@ -405,7 +405,7 @@ BaselearnerCustom::~BaselearnerCustom () {} // BaselearnerCustomCpp: // ----------------------- -BaselearnerCustomCpp::BaselearnerCustomCpp (data::Data* data, const std::string& identifier, +BaselearnerCustomCpp::BaselearnerCustomCpp (std::shared_ptr data, const std::string& identifier, SEXP instantiateDataFun0, SEXP trainFun0, SEXP predictFun0) { // Called from parent class 'Baselearner': @@ -457,7 +457,7 @@ arma::mat BaselearnerCustomCpp::predict () const return predictFun (data_ptr->getData(), parameter); } -arma::mat BaselearnerCustomCpp::predict (data::Data* newdata) const +arma::mat BaselearnerCustomCpp::predict (std::shared_ptr newdata) const { arma::mat temp_mat = instantiateData(newdata->getData()); return predictFun (temp_mat, parameter); diff --git a/src/baselearner.h b/src/baselearner.h index 9508ea61..937b6206 100644 --- a/src/baselearner.h +++ b/src/baselearner.h @@ -44,7 +44,7 @@ class Baselearner arma::mat getParameter () const; virtual arma::mat predict () const = 0; - virtual arma::mat predict (data::Data*) const = 0; + virtual arma::mat predict (std::shared_ptr) const = 0; // Specify how the data has to be transformed. E. g. for splines a mapping // to the higher dimension space. The overloading function with the @@ -54,14 +54,14 @@ class Baselearner // Clone function (in some places needed e.g. "optimizer.cpp") and a copy // function which is called by clone to avoid copy and pasting of the // protected members: - void copyMembers (const arma::mat&, const std::string&, data::Data*); + void copyMembers (const arma::mat&, const std::string&, std::shared_ptr); virtual Baselearner* clone () = 0; // Within 'setData' the pointer will be setted, while 'instantiateData' // overwrite the object on which 'data_ptr' points. This guarantees that // the data is just stored once in the factory and then called by reference // within the baselearner: - void setData (data::Data*); + void setData (std::shared_ptr); // arma::mat getData () const; // Get data identifier stored within the data object: @@ -86,7 +86,7 @@ class Baselearner arma::mat parameter; std::string blearner_identifier; std::string blearner_type; - data::Data* data_ptr; + std::shared_ptr data_ptr; // std::string data_identifier; }; @@ -112,7 +112,7 @@ class BaselearnerPolynomial : public Baselearner public: // (data pointer, data identifier, baselearner identifier, degree) - BaselearnerPolynomial (data::Data*, const std::string&, const unsigned int&, const bool&); + BaselearnerPolynomial (std::shared_ptr, const std::string&, const unsigned int&, const bool&); Baselearner* clone (); @@ -121,7 +121,7 @@ class BaselearnerPolynomial : public Baselearner void train (const arma::mat&); arma::mat predict () const; - arma::mat predict (data::Data*) const; + arma::mat predict (std::shared_ptr) const; ~BaselearnerPolynomial (); @@ -169,7 +169,7 @@ class BaselearnerPSpline : public Baselearner public: /// Default constructor of `BaselearnerPSpline` class - BaselearnerPSpline (data::Data*, const std::string&, const unsigned int&, + BaselearnerPSpline (std::shared_ptr, const std::string&, const unsigned int&, const unsigned int&, const double&, const unsigned int&, const bool&); /// Clean copy of baselearner @@ -185,7 +185,7 @@ class BaselearnerPSpline : public Baselearner arma::mat predict () const; /// Predict on newdata - arma::mat predict (data::Data*) const; + arma::mat predict (std::shared_ptr) const; /// Destructor @@ -216,7 +216,7 @@ class BaselearnerCustom : public Baselearner // (data pointer, data identifier, baselearner identifier, R function for // data instantiation, R function for training, R function for prediction, // R function to extract parameter): - BaselearnerCustom (data::Data*, const std::string&, Rcpp::Function, + BaselearnerCustom (std::shared_ptr, const std::string&, Rcpp::Function, Rcpp::Function, Rcpp::Function, Rcpp::Function); // Copy constructor: @@ -227,7 +227,7 @@ class BaselearnerCustom : public Baselearner void train (const arma::mat&); arma::mat predict () const; - arma::mat predict (data::Data*) const; + arma::mat predict (std::shared_ptr) const; ~BaselearnerCustom (); @@ -262,7 +262,7 @@ class BaselearnerCustomCpp : public Baselearner // (data pointer, data identifier, baselearner identifier, R function for // data instantiation, R function for training, R function for prediction, // R function to extract parameter): - BaselearnerCustomCpp (data::Data*, const std::string&, SEXP, SEXP, SEXP); + BaselearnerCustomCpp (std::shared_ptr, const std::string&, SEXP, SEXP, SEXP); // Copy constructor: Baselearner* clone (); @@ -272,7 +272,7 @@ class BaselearnerCustomCpp : public Baselearner void train (const arma::mat&); arma::mat predict () const; - arma::mat predict (data::Data*) const; + arma::mat predict (std::shared_ptr) const; ~BaselearnerCustomCpp (); }; diff --git a/src/baselearner_factory.cpp b/src/baselearner_factory.cpp index 1183b060..7dc2a249 100644 --- a/src/baselearner_factory.cpp +++ b/src/baselearner_factory.cpp @@ -56,8 +56,8 @@ std::string BaselearnerFactory::getBaselearnerType() const return blearner_type; } -void BaselearnerFactory::initializeDataObjects (data::Data* data_source0, - data::Data* data_target0) +void BaselearnerFactory::initializeDataObjects (std::shared_ptr data_source0, + std::shared_ptr data_target0) { data_source = data_source0; data_target = data_target0; @@ -79,7 +79,7 @@ BaselearnerFactory::~BaselearnerFactory () {} // ----------------------- BaselearnerPolynomialFactory::BaselearnerPolynomialFactory (const std::string& blearner_type0, - data::Data* data_source0, data::Data* data_target0, const unsigned int& degree, + std::shared_ptr data_source0, std::shared_ptr data_target0, const unsigned int& degree, const bool& intercept) : degree ( degree ), intercept ( intercept ) @@ -193,8 +193,8 @@ arma::mat BaselearnerPolynomialFactory::instantiateData (const arma::mat& newdat * * \param blearner_type0 `std::string` Name of the baselearner type (setted by * the Rcpp Wrapper classes in `compboost_modules.cpp`) - * \param data_source `data::Data*` Source of the data - * \param data_target `data::Data*` Object to store the transformed data source + * \param data_source `std::shared_ptr` Source of the data + * \param data_target `std::shared_ptr` Object to store the transformed data source * \param degree `unsigned int` Polynomial degree of the splines * \param n_knots `unsigned int` Number of inner knots used * \param penalty `double` Regularization parameter `penalty = 0` yields @@ -205,7 +205,7 @@ arma::mat BaselearnerPolynomialFactory::instantiateData (const arma::mat& newdat */ BaselearnerPSplineFactory::BaselearnerPSplineFactory (const std::string& blearner_type0, - data::Data* data_source0, data::Data* data_target0, const unsigned int& degree, + std::shared_ptr data_source0, std::shared_ptr data_target0, const unsigned int& degree, const unsigned int& n_knots, const double& penalty, const unsigned int& differences, const bool& use_sparse_matrices) : degree ( degree ), @@ -339,7 +339,7 @@ arma::mat BaselearnerPSplineFactory::instantiateData (const arma::mat& newdata) // ----------------------- BaselearnerCustomFactory::BaselearnerCustomFactory (const std::string& blearner_type0, - data::Data* data_source, data::Data* data_target, Rcpp::Function instantiateDataFun, + std::shared_ptr data_source, std::shared_ptr data_target, Rcpp::Function instantiateDataFun, Rcpp::Function trainFun, Rcpp::Function predictFun, Rcpp::Function extractParameter) : instantiateDataFun ( instantiateDataFun ), trainFun ( trainFun ), @@ -398,7 +398,7 @@ arma::mat BaselearnerCustomFactory::instantiateData (const arma::mat& newdata) c // ----------------------- BaselearnerCustomCppFactory::BaselearnerCustomCppFactory (const std::string& blearner_type0, - data::Data* data_source, data::Data* data_target, SEXP instantiateDataFun, + std::shared_ptr data_source, std::shared_ptr data_target, SEXP instantiateDataFun, SEXP trainFun, SEXP predictFun) : instantiateDataFun ( instantiateDataFun ), trainFun ( trainFun ), diff --git a/src/baselearner_factory.h b/src/baselearner_factory.h index fc6ac320..fb6c06c7 100644 --- a/src/baselearner_factory.h +++ b/src/baselearner_factory.h @@ -44,6 +44,7 @@ #include #include +#include #include "baselearner.h" #include "data.h" @@ -70,7 +71,7 @@ class BaselearnerFactory virtual arma::mat instantiateData (const arma::mat&) const = 0; virtual arma::mat getData() const = 0; - void initializeDataObjects (data::Data*, data::Data*); + void initializeDataObjects (std::shared_ptr, std::shared_ptr); // Destructor: virtual ~BaselearnerFactory (); @@ -79,8 +80,8 @@ class BaselearnerFactory // Minimal functionality every baselearner should have: std::string blearner_type; - data::Data* data_source; - data::Data* data_target; + std::shared_ptr data_source; + std::shared_ptr data_target; }; @@ -100,7 +101,7 @@ class BaselearnerPolynomialFactory : public BaselearnerFactory public: - BaselearnerPolynomialFactory (const std::string&, data::Data*, data::Data*, const unsigned int&, + BaselearnerPolynomialFactory (const std::string&, std::shared_ptr, std::shared_ptr, const unsigned int&, const bool&); blearner::Baselearner* createBaselearner (const std::string&); @@ -142,7 +143,7 @@ class BaselearnerPSplineFactory : public BaselearnerFactory public: /// Default constructor of class `PSplineBleanrerFactory` - BaselearnerPSplineFactory (const std::string&, data::Data*, data::Data*, + BaselearnerPSplineFactory (const std::string&, std::shared_ptr, std::shared_ptr, const unsigned int&, const unsigned int&, const double&, const unsigned int&, const bool&); @@ -172,7 +173,7 @@ class BaselearnerCustomFactory : public BaselearnerFactory public: - BaselearnerCustomFactory (const std::string&, data::Data*, data::Data*, + BaselearnerCustomFactory (const std::string&, std::shared_ptr, std::shared_ptr, Rcpp::Function, Rcpp::Function, Rcpp::Function, Rcpp::Function); blearner::Baselearner* createBaselearner (const std::string&); @@ -200,7 +201,7 @@ class BaselearnerCustomCppFactory : public BaselearnerFactory public: - BaselearnerCustomCppFactory (const std::string&, data::Data*, data::Data*, + BaselearnerCustomCppFactory (const std::string&, std::shared_ptr, std::shared_ptr, SEXP, SEXP, SEXP); blearner::Baselearner* createBaselearner (const std::string&); diff --git a/src/baselearner_factory_list.cpp b/src/baselearner_factory_list.cpp index 4eabf8bc..7a38711a 100644 --- a/src/baselearner_factory_list.cpp +++ b/src/baselearner_factory_list.cpp @@ -28,13 +28,13 @@ BaselearnerFactoryList::BaselearnerFactoryList () {} // Register a factory: void BaselearnerFactoryList::registerBaselearnerFactory (const std::string& factory_id, - blearnerfactory::BaselearnerFactory *blearner_factory) + std::shared_ptr blearner_factory) { // Create iterator and check if learner is already registered: - std::map::iterator it = my_factory_map.find(factory_id); + std::map>::iterator it = my_factory_map.find(factory_id); if (it == my_factory_map.end()) { - my_factory_map.insert(std::pair(factory_id, blearner_factory)); + my_factory_map.insert(std::pair>(factory_id, blearner_factory)); } else { my_factory_map[ factory_id ] = blearner_factory; } diff --git a/src/baselearner_factory_list.h b/src/baselearner_factory_list.h index 76c955db..045d7fbf 100644 --- a/src/baselearner_factory_list.h +++ b/src/baselearner_factory_list.h @@ -26,7 +26,7 @@ #include "baselearner_factory.h" // Define the type for the list (because we are lazy :)) -typedef std::map blearner_factory_map; +typedef std::map> blearner_factory_map; namespace blearnerlist { @@ -47,7 +47,7 @@ class BaselearnerFactoryList // Functions to register a baselearner factory and print all registered // factories: - void registerBaselearnerFactory (const std::string&, blearnerfactory::BaselearnerFactory*); + void registerBaselearnerFactory (const std::string&, std::shared_ptr); void printRegisteredFactories () const; // Get the actual map: diff --git a/src/compboost.cpp b/src/compboost.cpp index 2b25666b..57c7f676 100644 --- a/src/compboost.cpp +++ b/src/compboost.cpp @@ -228,7 +228,7 @@ arma::vec Compboost::predict () const // Those columns are then transformed by the corresponding transform data function of the // specific factory. After the transformation, the transformed data is multiplied by the // corresponding parameter. -arma::vec Compboost::predict (std::map data_map, const bool& as_response) const +arma::vec Compboost::predict (std::map> data_map, const bool& as_response) const { // IMPROVE THIS FUNCTION!!! See: // https://github.com/schalkdaniel/compboost/issues/206 @@ -247,10 +247,10 @@ arma::vec Compboost::predict (std::map data_map, const std::string sel_factory = it.first; // Find the element with key 'hat' - blearnerfactory::BaselearnerFactory* sel_factory_obj = used_baselearner_list.getMap().find(sel_factory)->second; + std::shared_ptr sel_factory_obj = used_baselearner_list.getMap().find(sel_factory)->second; // Select newdata corresponding to selected facotry object: - std::map::iterator it_newdata; + std::map>::iterator it_newdata; it_newdata = data_map.find(sel_factory_obj->getDataIdentifier()); // Calculate prediction by accumulating the design matrices multiplied by the estimated parameter: @@ -274,7 +274,7 @@ void Compboost::setToIteration (const unsigned int& k) if (k > max_iteration) { // Define new iteration logger for missing iterations: unsigned int iteration_diff = k - max_iteration; - logger::Logger* temp_logger = new logger::LoggerIteration("_iteration", true, iteration_diff); + std::shared_ptr temp_logger = std::make_shared("_iteration", true, iteration_diff); loggerlist::LoggerList* temp_loggerlist = new loggerlist::LoggerList(); std::string logger_id = "setToIteration.retraining" + std::to_string(logger_map.size()); diff --git a/src/compboost.h b/src/compboost.h index e058ce19..10d7f151 100644 --- a/src/compboost.h +++ b/src/compboost.h @@ -120,7 +120,7 @@ class Compboost std::pair, arma::mat> getParameterMatrix () const; arma::vec predict () const; - arma::vec predict (std::map, const bool&) const; + arma::vec predict (std::map>, const bool&) const; void setToIteration (const unsigned int&); diff --git a/src/compboost_modules.cpp b/src/compboost_modules.cpp index b6872c00..4b2c204e 100644 --- a/src/compboost_modules.cpp +++ b/src/compboost_modules.cpp @@ -38,14 +38,11 @@ class DataWrapper { public: DataWrapper () {} - - data::Data* getDataObj () { return obj; } - - virtual ~DataWrapper () { delete obj; } + std::shared_ptr getDataObj () { return sh_ptr_data; } + virtual ~DataWrapper () {} protected: - data::Data* obj; - + std::shared_ptr sh_ptr_data; }; //' In memory data class to store data in RAM @@ -122,8 +119,7 @@ class InMemoryDataWrapper : public DataWrapper // Solve this copying issue: // https://github.com/schalkdaniel/compboost/issues/123 private: - // arma::vec data_vec = arma::vec (1, arma::fill::zeros); - arma::mat data_mat = arma::mat (1, 1, arma::fill::zeros); + // arma::mat data_mat = arma::mat (1, 1, arma::fill::zeros); public: @@ -135,30 +131,23 @@ class InMemoryDataWrapper : public DataWrapper InMemoryDataWrapper () { - obj = new data::InMemoryData (); + sh_ptr_data = std::make_shared(); } - // Rcpp doesn't detect if vector or matrix if using arma::vec and arma::mat: - // InMemoryDataWrapper (Rcpp::NumericVector data0, std::string data_identifier) - // { - // data_vec = Rcpp::as(data0); - // Rcpp::Rcout << "Vector Initializer" << std::endl; - // obj = new data::InMemoryData (data_vec, data_identifier); - // } - - InMemoryDataWrapper (arma::mat data0, std::string data_identifier) + InMemoryDataWrapper (arma::mat data_mat, std::string data_identifier) { - data_mat = data0; - - obj = new data::InMemoryData (data_mat, data_identifier); + // data_mat = data0; + sh_ptr_data = std::make_shared(data_mat, data_identifier); } + arma::mat getData () const { - return obj->getData(); + return sh_ptr_data->getData(); } + std::string getIdentifier () const { - return obj->getDataIdentifier(); + return sh_ptr_data->getDataIdentifier(); } }; @@ -197,12 +186,12 @@ class BaselearnerFactoryWrapper { public: - blearnerfactory::BaselearnerFactory* getFactory () { return obj; } - virtual ~BaselearnerFactoryWrapper () { delete obj; } + std::shared_ptr getFactory () { return sh_ptr_blearner_factory; } + virtual ~BaselearnerFactoryWrapper () {} protected: - blearnerfactory::BaselearnerFactory* obj; + std::shared_ptr sh_ptr_blearner_factory; // blearner::Baselearner* test_obj; }; @@ -309,7 +298,7 @@ class BaselearnerPolynomialFactoryWrapper : public BaselearnerFactoryWrapper std::string blearner_type_temp = "polynomial_degree_" + std::to_string(degree); - obj = new blearnerfactory::BaselearnerPolynomialFactory(blearner_type_temp, data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared(blearner_type_temp, data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["degree"], internal_arg_list["intercept"]); } @@ -318,17 +307,17 @@ class BaselearnerPolynomialFactoryWrapper : public BaselearnerFactoryWrapper { internal_arg_list = helper::argHandler(internal_arg_list, arg_list, TRUE); - obj = new blearnerfactory::BaselearnerPolynomialFactory(blearner_type, data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared(blearner_type, data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["degree"], internal_arg_list["intercept"]); } - arma::mat getData () { return obj->getData(); } - std::string getDataIdentifier () { return obj->getDataIdentifier(); } - std::string getBaselearnerType () { return obj->getBaselearnerType(); } + arma::mat getData () { return sh_ptr_blearner_factory->getData(); } + std::string getDataIdentifier () { return sh_ptr_blearner_factory->getDataIdentifier(); } + std::string getBaselearnerType () { return sh_ptr_blearner_factory->getBaselearnerType(); } arma::mat transformData (const arma::mat& newdata) { - return obj->instantiateData(newdata); + return sh_ptr_blearner_factory->instantiateData(newdata); } void summarizeFactory () @@ -348,8 +337,8 @@ class BaselearnerPolynomialFactoryWrapper : public BaselearnerFactoryWrapper if (degree > 3) { Rcpp::Rcout << "Polynomial base-learner of degree " << degree << " factory:" << std::endl; } - Rcpp::Rcout << "\t- Name of the used data: " << obj->getDataIdentifier() << std::endl; - Rcpp::Rcout << "\t- Factory creates the following base-learner: " << obj->getBaselearnerType() << std::endl; + Rcpp::Rcout << "\t- Name of the used data: " << sh_ptr_blearner_factory->getDataIdentifier() << std::endl; + Rcpp::Rcout << "\t- Factory creates the following base-learner: " << sh_ptr_blearner_factory->getBaselearnerType() << std::endl; } }; @@ -458,7 +447,7 @@ class BaselearnerPSplineFactoryWrapper : public BaselearnerFactoryWrapper std::string blearner_type_temp = "spline_degree_" + std::to_string(degree); - obj = new blearnerfactory::BaselearnerPSplineFactory(blearner_type_temp, data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared(blearner_type_temp, data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["degree"], internal_arg_list["n_knots"], internal_arg_list["penalty"], internal_arg_list["differences"], TRUE); @@ -469,18 +458,18 @@ class BaselearnerPSplineFactoryWrapper : public BaselearnerFactoryWrapper { internal_arg_list = helper::argHandler(internal_arg_list, arg_list, TRUE); - obj = new blearnerfactory::BaselearnerPSplineFactory(blearner_type, data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared(blearner_type, data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["degree"], internal_arg_list["n_knots"], internal_arg_list["penalty"], internal_arg_list["differences"], TRUE); } - arma::mat getData () { return obj->getData(); } - std::string getDataIdentifier () { return obj->getDataIdentifier(); } - std::string getBaselearnerType () { return obj->getBaselearnerType(); } + arma::mat getData () { return sh_ptr_blearner_factory->getData(); } + std::string getDataIdentifier () { return sh_ptr_blearner_factory->getDataIdentifier(); } + std::string getBaselearnerType () { return sh_ptr_blearner_factory->getBaselearnerType(); } arma::mat transformData (const arma::mat& newdata) { - return obj->instantiateData(newdata); + return sh_ptr_blearner_factory->instantiateData(newdata); } void summarizeFactory () @@ -489,8 +478,8 @@ class BaselearnerPSplineFactoryWrapper : public BaselearnerFactoryWrapper int degree = internal_arg_list["degree"]; Rcpp::Rcout << "Spline factory of degree" << " " << std::to_string(degree) << std::endl; - Rcpp::Rcout << "\t- Name of the used data: " << obj->getDataIdentifier() << std::endl; - Rcpp::Rcout << "\t- Factory creates the following base-learner: " << obj->getBaselearnerType() << std::endl; + Rcpp::Rcout << "\t- Name of the used data: " << sh_ptr_blearner_factory->getDataIdentifier() << std::endl; + Rcpp::Rcout << "\t- Factory creates the following base-learner: " << sh_ptr_blearner_factory->getBaselearnerType() << std::endl; } }; @@ -628,7 +617,7 @@ class BaselearnerCustomFactoryWrapper : public BaselearnerFactoryWrapper // Don't check argument types since we don't have a Function placeholder for the default list: internal_arg_list = helper::argHandler(internal_arg_list, arg_list, FALSE); - obj = new blearnerfactory::BaselearnerCustomFactory("custom", data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared("custom", data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["instantiate_fun"], internal_arg_list["train_fun"], internal_arg_list["predict_fun"], internal_arg_list["param_fun"]); } @@ -639,26 +628,26 @@ class BaselearnerCustomFactoryWrapper : public BaselearnerFactoryWrapper // Don't check argument types since we don't have a Function placeholder for the default list: internal_arg_list = helper::argHandler(internal_arg_list, arg_list, FALSE); - obj = new blearnerfactory::BaselearnerCustomFactory(blearner_type, data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared(blearner_type, data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["instantiate_fun"], internal_arg_list["train_fun"], internal_arg_list["predict_fun"], internal_arg_list["param_fun"]); } - arma::mat getData () { return obj->getData(); } - std::string getDataIdentifier () { return obj->getDataIdentifier(); } - std::string getBaselearnerType () { return obj->getBaselearnerType(); } + arma::mat getData () { return sh_ptr_blearner_factory->getData(); } + std::string getDataIdentifier () { return sh_ptr_blearner_factory->getDataIdentifier(); } + std::string getBaselearnerType () { return sh_ptr_blearner_factory->getBaselearnerType(); } arma::mat transformData (const arma::mat& newdata) { - return obj->instantiateData(newdata); + return sh_ptr_blearner_factory->instantiateData(newdata); } void summarizeFactory () { Rcpp::Rcout << "Custom base-learner Factory:" << std::endl; - Rcpp::Rcout << "\t- Name of the used data: " << obj->getDataIdentifier() << std::endl; - Rcpp::Rcout << "\t- Factory creates the following base-learner: " << obj->getBaselearnerType() << std::endl; + Rcpp::Rcout << "\t- Name of the used data: " << sh_ptr_blearner_factory->getDataIdentifier() << std::endl; + Rcpp::Rcout << "\t- Factory creates the following base-learner: " << sh_ptr_blearner_factory->getBaselearnerType() << std::endl; } }; @@ -761,7 +750,7 @@ class BaselearnerCustomCppFactoryWrapper : public BaselearnerFactoryWrapper // Don't check argument types since we don't have a Function placeholder for the default list: internal_arg_list = helper::argHandler(internal_arg_list, arg_list, FALSE); - obj = new blearnerfactory::BaselearnerCustomCppFactory("custom_cpp", data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared("custom_cpp", data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["instantiate_ptr"], internal_arg_list["train_ptr"], internal_arg_list["predict_ptr"]); } @@ -772,26 +761,22 @@ class BaselearnerCustomCppFactoryWrapper : public BaselearnerFactoryWrapper // Don't check argument types since we don't have a Function placeholder for the default list: internal_arg_list = helper::argHandler(internal_arg_list, arg_list, FALSE); - obj = new blearnerfactory::BaselearnerCustomCppFactory(blearner_type, data_source.getDataObj(), + sh_ptr_blearner_factory = std::make_shared(blearner_type, data_source.getDataObj(), data_target.getDataObj(), internal_arg_list["instantiate_ptr"], internal_arg_list["train_ptr"], internal_arg_list["predict_ptr"]); } - arma::mat getData () { return obj->getData(); } - std::string getDataIdentifier () { return obj->getDataIdentifier(); } - std::string getBaselearnerType () { return obj->getBaselearnerType(); } + arma::mat getData () { return sh_ptr_blearner_factory->getData(); } + std::string getDataIdentifier () { return sh_ptr_blearner_factory->getDataIdentifier(); } + std::string getBaselearnerType () { return sh_ptr_blearner_factory->getBaselearnerType(); } - arma::mat transformData (const arma::mat& newdata) - { - return obj->instantiateData(newdata); - } + arma::mat transformData (const arma::mat& newdata) { return sh_ptr_blearner_factory->instantiateData(newdata); } void summarizeFactory () { Rcpp::Rcout << "Custom cpp base-learner Factory:" << std::endl; - - Rcpp::Rcout << "\t- Name of the used data: " << obj->getDataIdentifier() << std::endl; - Rcpp::Rcout << "\t- Factory creates the following base-learner: " << obj->getBaselearnerType() << std::endl; + Rcpp::Rcout << "\t- Name of the used data: " << sh_ptr_blearner_factory->getDataIdentifier() << std::endl; + Rcpp::Rcout << "\t- Factory creates the following base-learner: " << sh_ptr_blearner_factory->getBaselearnerType() << std::endl; } }; @@ -1574,9 +1559,9 @@ class LoggerWrapper LoggerWrapper () {}; - logger::Logger* getLogger () + std::shared_ptr getLogger () { - return obj; + return sh_ptr_logger; } std::string getLoggerId () @@ -1584,10 +1569,10 @@ class LoggerWrapper return logger_id; } - virtual ~LoggerWrapper () { delete obj; } + virtual ~LoggerWrapper () {} protected: - logger::Logger* obj; + std::shared_ptr sh_ptr_logger; std::string logger_id; }; @@ -1650,7 +1635,7 @@ class LoggerIterationWrapper : public LoggerWrapper use_as_stopper ( use_as_stopper ) { logger_id = logger_id0; - obj = new logger::LoggerIteration (logger_id, use_as_stopper, max_iterations); + sh_ptr_logger = std::make_shared(logger_id, use_as_stopper, max_iterations); } void summarizeLogger () @@ -1762,7 +1747,7 @@ class LoggerInbagRiskWrapper : public LoggerWrapper use_as_stopper ( use_as_stopper) { logger_id = logger_id0; - obj = new logger::LoggerInbagRisk (logger_id, use_as_stopper, used_loss.getLoss(), eps_for_break); + sh_ptr_logger = std::make_shared(logger_id, use_as_stopper, used_loss.getLoss(), eps_for_break); } void summarizeLogger () @@ -1876,7 +1861,7 @@ class LoggerInbagRiskWrapper : public LoggerWrapper //' //' oob_list = list(data_source1, data_source2) //' -//' set_seed(123) +//' set.seed(123) //' y_oob = rnorm(10) //' //' # Used loss: @@ -1903,7 +1888,7 @@ class LoggerOobRiskWrapper : public LoggerWrapper LoggerOobRiskWrapper (std::string logger_id0, bool use_as_stopper, LossWrapper& used_loss, double eps_for_break, Rcpp::List oob_data, ResponseWrapper& oob_response) { - std::map oob_data_map; + std::map> oob_data_map; // Be very careful with the wrappers. For instance: doing something like // temp = oob_data[i] within the loop will force temp to call its destructor @@ -1925,7 +1910,7 @@ class LoggerOobRiskWrapper : public LoggerWrapper } logger_id = logger_id0; - obj = new logger::LoggerOobRisk (logger_id, use_as_stopper, used_loss.getLoss(), eps_for_break, + sh_ptr_logger = std::make_shared(logger_id, use_as_stopper, used_loss.getLoss(), eps_for_break, oob_data_map, oob_response.getResponseObj()); } @@ -2014,7 +1999,7 @@ class LoggerTimeWrapper : public LoggerWrapper { // logger_id = logger_id0 + "." + time_unit; logger_id = logger_id0; - obj = new logger::LoggerTime (logger_id, use_as_stopper, max_time, time_unit); + sh_ptr_logger = std::make_shared(logger_id, use_as_stopper, max_time, time_unit); } void summarizeLogger () @@ -2578,7 +2563,7 @@ class CompboostWrapper arma::vec predict (Rcpp::List& newdata, bool as_response) { - std::map data_map; + std::map> data_map; // Create data map (see line 780, same applies here): for (unsigned int i = 0; i < newdata.size(); i++) { diff --git a/src/data.cpp b/src/data.cpp index 20e6cb52..1afb39d5 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -65,36 +65,15 @@ void Data::setDataType (const std::string& data_type0) InMemoryData::InMemoryData () {} -// InMemoryData::InMemoryData (const arma::vec& raw_data, const std::string& data_identifier0) -// { -// Rcpp::Rcout << "Vector Initializer" << std::endl; -// data_mat_ptr = &raw_data; -// data_identifier = data_identifier0; -// } - InMemoryData::InMemoryData (const arma::mat& raw_data, const std::string& data_identifier0) { - data_mat_ptr = &raw_data; + data_mat = raw_data; data_identifier = data_identifier0; } -void InMemoryData::setData (const arma::mat& transformed_data) -{ - data_mat = transformed_data; -} +void InMemoryData::setData (const arma::mat& transformed_data) { data_mat = transformed_data; } +arma::mat InMemoryData::getData () const { return data_mat; } -arma::mat InMemoryData::getData () const -{ - // Give data depending on source (by reference) or target (by value): - if (data_mat_ptr == NULL) { - return data_mat; - } else { - return *data_mat_ptr; - } -} - -InMemoryData::~InMemoryData () { - // Rcpp::Rcout << "Delete Data" << std::endl; -} +InMemoryData::~InMemoryData () {}; } // namespace data \ No newline at end of file diff --git a/src/data.h b/src/data.h index c0372066..ec2d8568 100644 --- a/src/data.h +++ b/src/data.h @@ -53,9 +53,6 @@ class Data /// Sparse matrix for design matrix (directly accessible) arma::sp_mat sparse_data_mat; - - const arma::mat* data_mat_ptr = NULL; - // Some spline specific data stuff (of course they can be used for other // classes to): @@ -84,7 +81,7 @@ class Data void setDataType (const std::string&); virtual - ~Data () { }; + ~Data () {}; }; @@ -115,7 +112,6 @@ class InMemoryData : public Data arma::mat getData() const; ~InMemoryData (); - }; } // namespace data diff --git a/src/logger.cpp b/src/logger.cpp index d23e52f2..ab18cf12 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -349,12 +349,12 @@ std::string LoggerInbagRisk::printLoggerStatus () const * \param used_loss `Loss*` which is used to calculate the empirical risk (this * can differ from the loss used while trining the model) * \param eps_for_break `double` sets value of the stopping criteria - * \param oob_data `std::map` the new data + * \param oob_data `std::map>` the new data * \param oob_response `arma::vec` response of the new data */ LoggerOobRisk::LoggerOobRisk (const std::string& logger_id0, const bool& is_a_stopper0, loss::Loss* used_loss, - const double& eps_for_break, std::map oob_data, std::shared_ptr oob_response) + const double& eps_for_break, std::map> oob_data, std::shared_ptr oob_response) : used_loss ( used_loss ), eps_for_break ( eps_for_break ), oob_data ( oob_data ), @@ -413,7 +413,7 @@ void LoggerOobRisk::logStep (const unsigned int& current_iteration, std::shared_ // Get data of corresponding selected baselearner. E.g. iteration 100 linear // baselearner of feature x_7, then get the data of feature x_7: - data::Data* oob_blearner_data = oob_data.find(blearner_id)->second; + std::shared_ptr oob_blearner_data = oob_data.find(blearner_id)->second; // Predict this data using the selected baselearner: arma::mat temp_oob_prediction = used_blearner->predict(oob_blearner_data); @@ -435,7 +435,7 @@ void LoggerOobRisk::logStep (const unsigned int& current_iteration, std::shared_ * * /////// Get data of corresponding selected baselearner. E.g. iteration 100 linear * /////// baselearner of feature x_7, then get the data of feature x_7: - * /////// data::Data* oob_blearner_data = oob_data.find(used_blearner->getDataIdentifier())->second; + * /////// std::shared_ptr oob_blearner_data = oob_data.find(used_blearner->getDataIdentifier())->second; * ///// * /////// Predict this data using the selected baselearner: * /////// arma::vec temp_oob_prediction = used_blearner->predict(oob_blearner_data); diff --git a/src/logger.h b/src/logger.h index 463559fd..267cba27 100644 --- a/src/logger.h +++ b/src/logger.h @@ -244,7 +244,7 @@ class LoggerOobRisk : public Logger arma::mat oob_prediction; /// The OOB data provided by the user - std::map oob_data; + std::map> oob_data; /* This is part of the memory saving version (see logger.cpp) * /// Transformed oob data for predicting on the oob set: @@ -259,7 +259,7 @@ class LoggerOobRisk : public Logger /// Default constructor LoggerOobRisk (const std::string&, const bool&, loss::Loss*, const double&, - std::map, std::shared_ptr); + std::map>, std::shared_ptr); /// Log current step of compboost iteration for class `LoggerOobRisk` void logStep (const unsigned int&, std::shared_ptr, diff --git a/src/loggerlist.cpp b/src/loggerlist.cpp index 866ff8d4..b342b19e 100644 --- a/src/loggerlist.cpp +++ b/src/loggerlist.cpp @@ -42,9 +42,9 @@ namespace loggerlist LoggerList::LoggerList () {} -void LoggerList::registerLogger (logger::Logger* which_logger) +void LoggerList::registerLogger (std::shared_ptr which_logger) { - log_list.insert(std::pair(which_logger->getLoggerId(), which_logger)); + log_list.insert(std::pair>(which_logger->getLoggerId(), which_logger)); if (which_logger->getIfLoggerIsStopper()) { sum_of_stopper += 1; } diff --git a/src/loggerlist.h b/src/loggerlist.h index 58fa8039..89387a52 100644 --- a/src/loggerlist.h +++ b/src/loggerlist.h @@ -27,7 +27,7 @@ #include "logger.h" #include "response.h" -typedef std::map logger_map; +typedef std::map> logger_map; namespace loggerlist { @@ -45,7 +45,7 @@ class LoggerList // LoggerList (arma::mat&, std::chrono::system_clock::time_point, double); // String for logger and the logger itselfe: - void registerLogger (logger::Logger*); + void registerLogger (std::shared_ptr); void printRegisteredLogger () const; logger_map getMap () const;