diff --git a/DESCRIPTION b/DESCRIPTION index 3dd7b41..4babb61 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: rEDM Type: Package Title: Empirical Dynamic Modeling ('EDM') -Version: 1.13.1 -Date: 2022-07-01 +Version: 1.14.0 +Date: 2023-01-07 Authors@R: c( person("Joseph", "Park", role = c("aut", "cre"), email = "JosephPark@IEEE.org", comment = c(ORCID = "0000-0001-5411-1409")), diff --git a/NEWS.md b/NEWS.md index 59adf88..81dd598 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ #### rEDM NEWS -2022-07-01 version 1.13.1 +2023-01-07 version 1.14.0 --- @@ -11,6 +11,9 @@ --- +##### Version 1.14 +- cppEDM core added `generateLibrary` parameter to `Simplex()` and `SMap()`. If `TRUE` the state-space library has newly generated points added. Not available due to Rcpp 20 parameter limit. + ##### Version 1.13 - Adds `embedded` and multivariate embedding to `CCM()`. - Parameters `pathOut`, `predictFile` are removed from `CCM` to accomodate the Rcpp 20 parameter limit. diff --git a/src/RcppEDMCommon.cpp b/src/RcppEDMCommon.cpp index c1b53da..400a1e3 100644 --- a/src/RcppEDMCommon.cpp +++ b/src/RcppEDMCommon.cpp @@ -56,6 +56,7 @@ auto SimplexArgs = r::List::create( r::_["verbose"] = false, r::_["validLib"] = std::vector(), r::_["generateSteps"] = 0, + //r::_["generateLibrary"] = false, // Rcpp 20 arg limit r::_["parameterList"] = false ); auto SMapArgs = r::List::create( @@ -81,6 +82,7 @@ auto SMapArgs = r::List::create( r::_["verbose"] = false, r::_["validLib"] = std::vector(), r::_["generateSteps"] = 0, + //r::_["generateLibrary"] = false, // Rcpp 20 arg limit r::_["parameterList"] = false ); auto MultiviewArgs = r::List::create( diff --git a/src/SMap.cpp b/src/SMap.cpp index 7ddcbde..d4e8380 100644 --- a/src/SMap.cpp +++ b/src/SMap.cpp @@ -25,13 +25,15 @@ r::List SMap_rcpp( std::string pathIn, bool verbose, std::vector validLib, int generateSteps, + //bool generateLibrary, // Rcpp has 20 arg limit bool parameterList ) { SMapValues SM; - std::string pathOut("./"); // Rcpp has 20 arg limit - std::string predictFile(""); // Rcpp has 20 arg limit - std::string jacobians(""); // Rcpp has 20 arg limit + std::string pathOut("./"); // Rcpp has 20 arg limit + std::string predictFile(""); // Rcpp has 20 arg limit + std::string jacobians(""); // Rcpp has 20 arg limit + bool generateLibrary = false; // Rcpp has 20 arg limit if ( dataFile.size() ) { // dataFile specified, dispatch overloaded SMap, ignore dataFrame @@ -57,6 +59,7 @@ r::List SMap_rcpp( std::string pathIn, verbose, validLib, generateSteps, + generateLibrary, parameterList ); } else if ( dataFrame.size() ) { @@ -82,6 +85,7 @@ r::List SMap_rcpp( std::string pathIn, verbose, validLib, generateSteps, + generateLibrary, parameterList ); } else { diff --git a/src/Simplex.cpp b/src/Simplex.cpp index 240a1d7..00bf3b5 100644 --- a/src/Simplex.cpp +++ b/src/Simplex.cpp @@ -23,10 +23,13 @@ r::List Simplex_rcpp( std::string pathIn, bool verbose, std::vector validLib, int generateSteps, + //bool generateLibrary, // Rcpp has 20 arg limit bool parameterList ) { SimplexValues S; + bool generateLibrary = false; // Rcpp has 20 arg limit + if ( dataFile.size() ) { // dataFile specified, dispatch overloaded Simplex, ignore dataFrame S = Simplex( pathIn, @@ -47,6 +50,7 @@ r::List Simplex_rcpp( std::string pathIn, verbose, validLib, generateSteps, + generateLibrary, parameterList ); } else if ( dataFrame.size() ) { @@ -69,6 +73,7 @@ r::List Simplex_rcpp( std::string pathIn, verbose, validLib, generateSteps, + generateLibrary, parameterList ); } else { diff --git a/src/cppEDM/src/API.cc b/src/cppEDM/src/API.cc index daab7f6..141b0c4 100644 --- a/src/cppEDM/src/API.cc +++ b/src/cppEDM/src/API.cc @@ -197,6 +197,7 @@ SimplexValues Simplex( std::string pathIn, bool verbose, std::vector validLib, int generateSteps, + bool generateLibrary, bool parameterList ) { // DataFrame constructor loads data @@ -220,6 +221,7 @@ SimplexValues Simplex( std::string pathIn, verbose, validLib, generateSteps, + generateLibrary, parameterList ); return S; @@ -245,6 +247,7 @@ SimplexValues Simplex( DataFrame< double > & DF, bool verbose, std::vector validLib, int generateSteps, + bool generateLibrary, bool parameterList ) { // Instantiate Parameters @@ -254,7 +257,8 @@ SimplexValues Simplex( DataFrame< double > & DF, exclusionRadius, columns, target, embedded, const_predict, verbose, validLib, - generateSteps, parameterList ); + generateSteps, generateLibrary, + parameterList ); // Instantiate EDM::SimplexClass object SimplexClass SimplexModel = SimplexClass( DF, std::ref( parameters ) ); @@ -298,6 +302,7 @@ SMapValues SMap( std::string pathIn, bool verbose, std::vector validLib, int generateSteps, + bool generateLibrary, bool parameterList ) { // DataFrame constructor loads data @@ -309,7 +314,8 @@ SMapValues SMap( std::string pathIn, exclusionRadius, columns, target, smapFile, derivatives, embedded, const_predict, verbose, validLib, - generateSteps, parameterList ); + generateSteps, generateLibrary, + parameterList ); return SMapOutput; } @@ -337,6 +343,7 @@ SMapValues SMap( DataFrame< double > & DF, bool verbose, std::vector validLib, int generateSteps, + bool generateLibrary, bool parameterList ) { // Call overload 4) with default SVD function @@ -346,7 +353,8 @@ SMapValues SMap( DataFrame< double > & DF, columns, target, smapFile, derivatives, & SVD, // LAPACK SVD default embedded, const_predict, verbose, validLib, - generateSteps, parameterList ); + generateSteps, generateLibrary, + parameterList ); return SMapOutput; } @@ -377,6 +385,7 @@ SMapValues SMap( std::string pathIn, bool verbose, std::vector validLib, int generateSteps, + bool generateLibrary, bool parameterList ) { // DataFrame constructor loads data @@ -388,7 +397,8 @@ SMapValues SMap( std::string pathIn, exclusionRadius, columns, target, smapFile, derivatives, solver, embedded, const_predict, verbose, - validLib, generateSteps, parameterList ); + validLib, generateSteps, generateLibrary, + parameterList ); return SMapOutput; } @@ -417,6 +427,7 @@ SMapValues SMap( DataFrame< double > & DF, bool verbose, std::vector validLib, int generateSteps, + bool generateLibrary, bool parameterList ) { if ( derivatives.size() ) {} // -Wunused-parameter @@ -427,7 +438,8 @@ SMapValues SMap( DataFrame< double > & DF, exclusionRadius, columns, target, embedded, const_predict, verbose, validLib, - generateSteps, parameterList, smapFile ); + generateSteps, generateLibrary, + parameterList, smapFile ); // Handle nan // If nan are found in library or prediction rows of columns or target, @@ -592,6 +604,7 @@ CCMValues CCM( DataFrame< double > & DF, verbose, // std::vector(), // validLib 0, // generateSteps + false, // generateLibrary parameterList, // "", // SmapFile "", // blockFile @@ -704,6 +717,7 @@ MultiviewValues Multiview( DataFrame< double > & DF, verbose, // std::vector(), // validLib 0, // generateSteps + false, // generateLibrary parameterList,// "", // SmapFile "", // blockFile diff --git a/src/cppEDM/src/API.h b/src/cppEDM/src/API.h index 31d7de7..13b7d68 100644 --- a/src/cppEDM/src/API.h +++ b/src/cppEDM/src/API.h @@ -57,6 +57,7 @@ SimplexValues Simplex( std::string pathIn = "./data/", bool verbose = true, std::vector validLib = std::vector(), int generateSteps = 0, + bool generateLibrary = false, bool parameterList = false ); SimplexValues Simplex( DataFrame< double > & dataFrameIn, @@ -76,6 +77,7 @@ SimplexValues Simplex( DataFrame< double > & dataFrameIn, bool verbose = true, std::vector validLib = std::vector(), int generateSteps = 0, + bool generateLibrary = false, bool parameterList = false ); // SMap is a special case since it can be called with a function pointer @@ -103,6 +105,7 @@ SMapValues SMap( std::string pathIn = "./data/", bool verbose = true, std::vector validLib = std::vector(), int generateSteps = 0, + bool generateLibrary = false, bool parameterList = false ); // 2) DataFrame with default SVD (LAPACK) assigned in Smap.cc 2) @@ -126,6 +129,7 @@ SMapValues SMap( DataFrame< double > &dataFrameIn, bool verbose = true, std::vector validLib = std::vector(), int generateSteps = 0, + bool generateLibrary = false, bool parameterList = false ); // 3) Data path/file with external solver object, init to default SVD @@ -153,6 +157,7 @@ SMapValues SMap( std::string pathIn = "./data/", bool verbose = true, std::vector validLib = std::vector(), int generateSteps = 0, + bool generateLibrary = false, bool parameterList = false ); @@ -180,6 +185,7 @@ SMapValues SMap( DataFrame< double > &dataFrameIn, bool verbose = true, std::vector validLib = std::vector(), int generateSteps = 0, + bool generateLibrary = false, bool parameterList = false ); CCMValues CCM( std::string pathIn = "./data/", diff --git a/src/cppEDM/src/Parameter.cc b/src/cppEDM/src/Parameter.cc index 5059ecb..b5938fe 100644 --- a/src/cppEDM/src/Parameter.cc +++ b/src/cppEDM/src/Parameter.cc @@ -32,6 +32,7 @@ Parameters::Parameters( std::vector validLib, int generateSteps, + bool generateLibrary, bool parameterList, std::string SmapOutputFile, @@ -76,6 +77,7 @@ Parameters::Parameters( validLib ( validLib ), generateSteps ( generateSteps ), + generateLibrary ( generateLibrary ), parameterList ( parameterList ), SmapOutputFile ( SmapOutputFile ), @@ -96,7 +98,7 @@ Parameters::Parameters( validated ( false ), // Instantiate Version - version( 1, 13, 1, "2022-07-01" ) + version( 1, 14, 0, "2023-01-07" ) { // Constructor code if ( method != Method::None ) { @@ -819,6 +821,10 @@ void Parameters::FillMap() { Map[ "generateSteps" ] = ss.str(); ss.str( std::string() ); + ss << generateLibrary; + Map[ "generateLibrary" ] = ss.str(); + ss.str( std::string() ); + ss << parameterList; Map[ "parameterList" ] = ss.str(); ss.str( std::string() ); diff --git a/src/cppEDM/src/Parameter.h b/src/cppEDM/src/Parameter.h index ac465c9..f82d8d6 100644 --- a/src/cppEDM/src/Parameter.h +++ b/src/cppEDM/src/Parameter.h @@ -31,22 +31,23 @@ class Parameters { int E; // dimension int Tp; // prediction interval int knn; // k nearest neighbors - int tau; // block embedding delay - double theta; // S Map localization + int tau; // embedding delay + double theta; // S-Map localization int exclusionRadius; // temporal rows to ignore in predict - std::string columns_str; - std::string target_str; + std::string columns_str; // multi argument parameters + std::string target_str; // argument parameter(s) std::vector< std::string > columnNames; // state-space column name(s) std::vector< std::string > targetNames; // target column name(s) - bool embedded; // true if data is already embedded/block + bool embedded; // true if data is already embedded bool const_predict; // true to compute non "predictor" stats bool verbose; std::vector validLib; // maps row to valid library flag int generateSteps; // Number of timesteps to feedback generate + bool generateLibrary; // Increment library with generated data bool parameterList; // Add parameter list to output @@ -102,6 +103,7 @@ class Parameters { std::vector validLib = std::vector(), int generateSteps = 0, + bool generateLibrary = false, bool parameterList = false, std::string SmapOutputFile = "", diff --git a/src/cppEDM/src/SMap.cc b/src/cppEDM/src/SMap.cc index 9adc7a3..93c6be5 100644 --- a/src/cppEDM/src/SMap.cc +++ b/src/cppEDM/src/SMap.cc @@ -180,6 +180,16 @@ void SMapClass::Generate( Solver solver ) { std::cout << " data.Time() end: " << data.Time().back() << std::endl; #endif + // Replace SMap object data with one containing only lib rows + // -- The data becomes a data library from which predictions are generated + // NOTE : JP Presume library starts at index 0 : Should be lib parameter + std::vector dataLibRows; + for ( size_t i = 0; i <= parameters.library.back(); i++ ) { + dataLibRows.push_back( i ); + } + DataFrame dataLib = data.DataFrameFromRowIndex( dataLibRows ); + this->data = dataLib; // JP is this a leak? + // Override prediction to have max( 2,Tp ) points at end of data. // We need Tp points if Tp > 1 to prevent nan gaps in prediction. // prediction & library are zero-offset in Parameters::Validate() @@ -282,7 +292,9 @@ void SMapClass::Generate( Solver solver ) { generatedTime.push_back( newTime ); // 3) Increment library by adding another row index ------------ - parameters.library.push_back( parameters.library.back() + 1 ); + if ( parameters.generateLibrary ) { + parameters.library.push_back( parameters.library.back() + 1 ); + } // 4) Increment prediction indices ----------------------------- for ( auto pi = parameters.prediction.begin(); diff --git a/src/cppEDM/src/Simplex.cc b/src/cppEDM/src/Simplex.cc index ef40291..5acae8f 100644 --- a/src/cppEDM/src/Simplex.cc +++ b/src/cppEDM/src/Simplex.cc @@ -210,6 +210,17 @@ void SimplexClass::Generate() { std::cout << " data.Time() end: " << data.Time().back() << std::endl; #endif + // Replace Simplex object data with one containing only lib rows + // -- The data becomes a data library from which predictions are generated + // NOTE : JP Presume library starts at index 0 : Should be lib parameter + std::vector dataLibRows; + for ( size_t i = 0; i <= parameters.library.back(); i++ ) { + dataLibRows.push_back( i ); + } + + DataFrame dataLib = data.DataFrameFromRowIndex( dataLibRows ); + this->data = dataLib; // JP is this a leak? + // Override prediction to have max( 2,Tp ) points at end of data. // We need Tp points if Tp > 1 to prevent nan gaps in prediction. // prediction & library are zero-offset in Parameters::Validate() @@ -302,7 +313,9 @@ void SimplexClass::Generate() { generatedTime.push_back( newTime ); // 3) Increment library by adding another row index ------------ - parameters.library.push_back( parameters.library.back() + 1 ); + if ( parameters.generateLibrary ) { + parameters.library.push_back( parameters.library.back() + 1 ); + } // 4) Increment prediction indices ----------------------------- for ( auto pi = parameters.prediction.begin();