diff --git a/DESCRIPTION b/DESCRIPTION index a57bb5b..8997757 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: rEDM Type: Package Title: Empirical Dynamic Modeling ('EDM') -Version: 1.15.0 -Date: 2023-10-21 +Version: 1.15.1 +Date: 2023-10-27 Authors@R: c( person("Joseph", "Park", role = c("aut", "cre"), email = "JosephPark@IEEE.org", comment = c(ORCID = "0000-0001-5411-1409")), diff --git a/R/EDM.R b/R/EDM.R index 98822d7..0997fc1 100644 --- a/R/EDM.R +++ b/R/EDM.R @@ -433,7 +433,8 @@ CCM = function( pathIn = "./", plot( libSize, ccm.df[ , V1 ], ylim = range( ccm.df[ , V1 ], ccm.df[ , V2 ] ), main = title, col = "blue", type = "l", lwd = 3, - xlab = 'Library Size', ylab = 'Prediction Skill (\U03C1)' ) + xlab = 'Library Size', + ylab = expression( "Prediction Skill (" * rho * ")" ) ) lines( libSize, ccm.df[ , V2 ], col = "red", lwd = 3 ) abline( h = 0 ) legend( 'topright', c( V1, V2 ), @@ -524,7 +525,8 @@ EmbedDimension = function ( pathIn = "./", if ( showPlot ) { title = paste(dataFile , "\nTp=" , Tp ) plot( df $ E, df $ rho, main = title, xlab = "Embedding Dimension", - ylab = "Prediction Skill (\U03C1)", type = "l", lwd = 3 ) + ylab = expression( "Prediction Skill (" * rho * ")" ), + type = "l", lwd = 3 ) } return ( df ) @@ -604,7 +606,8 @@ PredictInterval = function( pathIn = "./", if ( showPlot ) { title = paste( dataFile , "\nE=" , E ) plot( df $ Tp, df $ rho, main = title, xlab = "Forecast Interval", - ylab = "Prediction Skill (\U03C1)", type = "l", lwd = 3 ) + ylab = expression( "Prediction Skill (" * rho * ")" ), + type = "l", lwd = 3 ) } return( df ) @@ -631,6 +634,7 @@ PredictNonlinear = function( pathIn = "./", embedded = FALSE, verbose = FALSE, validLib = vector(), + ignoreNan = TRUE, numThreads = 4, showPlot = TRUE, noTime = FALSE ) { @@ -686,12 +690,14 @@ PredictNonlinear = function( pathIn = "./", embedded, verbose, validLib, + ignoreNan, numThreads ) if ( showPlot ) { title = paste(dataFile , "\nE=", E ) plot( df $ Theta, df $ rho, main=title, - xlab = "S-map Localisation", ylab = "Prediction Skill (\U03C1)", + xlab = "S-map Localisation", + ylab = expression( "Prediction Skill (" * rho * ")" ), type = "l", lwd = 3 ) } diff --git a/man/PredictNonlinear.Rd b/man/PredictNonlinear.Rd index 0f0e625..766def4 100644 --- a/man/PredictNonlinear.Rd +++ b/man/PredictNonlinear.Rd @@ -6,7 +6,8 @@ PredictNonlinear(pathIn = "./", dataFile = "", dataFrame = NULL, pathOut = "./", predictFile = "", lib = "", pred = "", theta = "", E = 1, Tp = 1, knn = 0, tau = -1, exclusionRadius = 0, columns = "", target = "", embedded = FALSE, verbose = FALSE, - validLib = vector(), numThreads = 4, showPlot = TRUE, noTime = FALSE ) + validLib = vector(), ignoreNan = TRUE, numThreads = 4, + showPlot = TRUE, noTime = FALSE ) } \arguments{ \item{pathIn}{path to \code{dataFile}.} @@ -59,6 +60,8 @@ input data used to create the library.} rows. Any data row represented in this vector as FALSE, will not be included in the library.} +\item{ignoreNan}{logical to internally redefine library to avoid nan.} + \item{numThreads}{number of parallel threads for computation.} \item{showPlot}{logical to plot results.} diff --git a/src/PredictNL.cpp b/src/PredictNL.cpp index 5df4bc2..5e7d5b8 100644 --- a/src/PredictNL.cpp +++ b/src/PredictNL.cpp @@ -22,6 +22,7 @@ r::DataFrame PredictNonlinear_rcpp( std::string pathIn, bool embedded, bool verbose, std::vector validLib, + bool ignoreNan, unsigned numThreads ) { DataFrame< double > PredictDF; @@ -46,6 +47,7 @@ r::DataFrame PredictNonlinear_rcpp( std::string pathIn, embedded, verbose, validLib, + ignoreNan, numThreads ); } else if ( dataFrame.size() ) { @@ -67,6 +69,7 @@ r::DataFrame PredictNonlinear_rcpp( std::string pathIn, embedded, verbose, validLib, + ignoreNan, numThreads ); } else { diff --git a/src/RcppEDMCommon.cpp b/src/RcppEDMCommon.cpp index b5ec857..77c3fe0 100644 --- a/src/RcppEDMCommon.cpp +++ b/src/RcppEDMCommon.cpp @@ -190,6 +190,7 @@ auto PredictNonlinearArgs = r::List::create( r::_["embedded"] = false, r::_["verbose"] = false, r::_["validLib"] = std::vector(), + r::_["ignoreNan"] = true, r::_["numThreads"] = 4 ); //------------------------------------------------------------------------- diff --git a/src/RcppEDMCommon.h b/src/RcppEDMCommon.h index 64ddcb7..e97fe46 100644 --- a/src/RcppEDMCommon.h +++ b/src/RcppEDMCommon.h @@ -135,6 +135,7 @@ r::DataFrame PredictNonlinear_rcpp( std::string pathIn, bool embedded, bool verbose, std::vector validLib, + bool ignoreNan, unsigned numThreads ); r::DataFrame PredictInterval_rcpp( std::string pathIn, diff --git a/src/cppEDM/src/API.h b/src/cppEDM/src/API.h index 7e148a1..b1b0235 100644 --- a/src/cppEDM/src/API.h +++ b/src/cppEDM/src/API.h @@ -359,6 +359,7 @@ DataFrame< double > PredictNonlinear( std::string pathIn = "./data/", bool verbose = true, std::vector validLib = std::vector(), + bool ignoreNan = true, unsigned nThreads = 4 ); DataFrame< double > PredictNonlinear( DataFrame< double > & dataFrameIn, @@ -378,5 +379,6 @@ DataFrame< double > PredictNonlinear( DataFrame< double > & dataFrameIn, bool verbose = true, std::vector validLib = std::vector(), + bool ignoreNan = true, unsigned nThreads = 4 ); #endif diff --git a/src/cppEDM/src/DataFrame.h b/src/cppEDM/src/DataFrame.h index f997753..3f00571 100644 --- a/src/cppEDM/src/DataFrame.h +++ b/src/cppEDM/src/DataFrame.h @@ -59,13 +59,13 @@ class DataFrame { //----------------------------------------------------------------- DataFrame(): n_rows( 0 ), n_columns( 0 ), elements( 0 ), - maxRowPrint( 10 ), noTime( false ) {} + nanFound( false ), maxRowPrint( 10 ), noTime( false ) {} //----------------------------------------------------------------- // Load data from CSV file path/fileName, populate DataFrame //----------------------------------------------------------------- DataFrame( std::string path, std::string fileName, bool noTime = false ): - maxRowPrint( 10 ), noTime( noTime ) + nanFound( false ), maxRowPrint( 10 ), noTime( noTime ) { ReadData( path, fileName ); SetupDataFrame(); // Process parsedData into a DataFrame @@ -76,7 +76,7 @@ class DataFrame { //----------------------------------------------------------------- DataFrame( size_t rows, size_t columns ): n_rows( rows ), n_columns( columns ), elements( columns * rows ), - maxRowPrint( 10 ), noTime( false ) {} + nanFound( false ), maxRowPrint( 10 ), noTime( false ) {} //----------------------------------------------------------------- // Empty DataFrame of size (rows, columns) with column names in a @@ -84,8 +84,8 @@ class DataFrame { //----------------------------------------------------------------- DataFrame( size_t rows, size_t columns, std::string colNames ): n_rows( rows ), n_columns( columns ), elements( columns * rows ), - columnNames( std::vector(columns) ), maxRowPrint( 10 ), - noTime( false ) + columnNames( std::vector(columns) ), + nanFound( false ), maxRowPrint( 10 ), noTime( false ) { BuildColumnNameIndex( colNames ); } @@ -97,7 +97,7 @@ class DataFrame { DataFrame( size_t rows, size_t columns, std::vector< std::string > columnNames ): n_rows( rows ), n_columns( columns ), elements( columns * rows ), - columnNames( columnNames ), maxRowPrint( 10 ), + columnNames( columnNames ), nanFound( false ), maxRowPrint( 10 ), noTime( false ) { BuildColumnNameIndex(); diff --git a/src/cppEDM/src/Eval.cc b/src/cppEDM/src/Eval.cc index d4c4e26..3d77c79 100644 --- a/src/cppEDM/src/Eval.cc +++ b/src/cppEDM/src/Eval.cc @@ -79,7 +79,8 @@ void SMapThread( EDM_Eval::WorkQueue &workQ, std::string target, bool embedded, bool verbose, - std::vector validLib ); + std::vector validLib, + bool ignoreNan ); //---------------------------------------------------------------- // EmbedDimension() : Evaluate Simplex rho vs. dimension E @@ -497,6 +498,7 @@ DataFrame< double > PredictNonlinear( std::string pathIn, bool embedded, bool verbose, std::vector validLib, + bool ignoreNan, unsigned nThreads ) { // Create DataFrame (constructor loads data) @@ -518,6 +520,7 @@ DataFrame< double > PredictNonlinear( std::string pathIn, embedded, verbose, validLib, + ignoreNan, nThreads ); return Theta_rho; } @@ -542,6 +545,7 @@ DataFrame< double > PredictNonlinear( DataFrame< double > & data, bool embedded, bool verbose, std::vector validLib, + bool ignoreNan, unsigned nThreads ) { std::vector ThetaValues( { 0.01, 0.1, 0.3, 0.5, 0.75, 1, @@ -600,7 +604,8 @@ DataFrame< double > PredictNonlinear( DataFrame< double > & data, target, embedded, verbose, - validLib ) ); + validLib, + ignoreNan ) ); } // join threads @@ -647,7 +652,8 @@ void SMapThread( EDM_Eval::WorkQueue &workQ, std::string target, bool embedded, bool verbose, - std::vector validLib ) + std::vector validLib, + bool ignoreNan ) { std::size_t i = std::atomic_fetch_add( &EDM_Eval::smap_count_i, std::size_t(1) ); @@ -679,7 +685,8 @@ void SMapThread( EDM_Eval::WorkQueue &workQ, embedded, false, // const_predict verbose, - validLib ); + validLib, + ignoreNan ); DataFrame< double > predictions = S.predictions; DataFrame< double > coefficients = S.coefficients; diff --git a/src/cppEDM/src/Parameter.cc b/src/cppEDM/src/Parameter.cc index 8187497..b33a06b 100644 --- a/src/cppEDM/src/Parameter.cc +++ b/src/cppEDM/src/Parameter.cc @@ -102,7 +102,7 @@ Parameters::Parameters( validated ( false ), // Instantiate Version - version( 1, 15, 0, "2023-10-21" ) + version( 1, 15, 1, "2023-10-27" ) { // Constructor code if ( method != Method::None ) { @@ -184,14 +184,15 @@ void Parameters::Validate() { if ( randomLib ) { if ( subSamples < 1 ) { std::string errMsg( "Parameters::Validate(): " - "CCM samples must be > 0.\n" ); + "CCM sample must be > 0.\n" ); throw std::runtime_error( errMsg ); } } // CCM librarySizes if ( not libSizes_str.size() ) { - std::string errMsg( "Parameters::Validate(): CCM libSize empty.\n" ); + std::string errMsg( "Parameters::Validate(): " + "CCM libSizes empty.\n" ); throw std::runtime_error( errMsg ); } diff --git a/src/cppEDM/src/SMap.cc b/src/cppEDM/src/SMap.cc index 78f5e5b..36bc769 100644 --- a/src/cppEDM/src/SMap.cc +++ b/src/cppEDM/src/SMap.cc @@ -490,6 +490,11 @@ void SMapClass::WriteOutput () { } } +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +// Do not use LAPACK on Windog: use scikit-learn LinearRegression +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#if !defined _WIN32 || defined USING_R + //---------------------------------------------------------------- // Singular Value Decomposition : wrapper for Lapack_SVD() //---------------------------------------------------------------- @@ -504,11 +509,11 @@ SVDValues SVD( DataFrame < double > A, double *b = &( B[0] ); - SVDValues SVD_ = Lapack_SVD( A.NRows(), // number of rows - A.NColumns(), // number of columns - a, // A - b, // b - 1.E-9 ); // rcond + SVDValues SVD_ = Lapack_SVD( A.NRows(), // number of rows + A.NColumns(), // number of columns + a, // A + b, // b + 1.E-9 ); // rcond #ifdef DEBUG_ALL std::cout << "SVD------------------------\n"; @@ -657,3 +662,18 @@ SVDValues Lapack_SVD( int m, // rows in matrix return SVD_; } +#else +//----------------------------------------------------------------- +// Singular Value Decomposition : SVD() dummy function: Replaced by +// scikit-learn LinearRegression on Windog. LAPACK is not feasible. +//----------------------------------------------------------------- +SVDValues SVD( DataFrame < double > A, + std::valarray< double > B ) { + if ( A.NRows() == B.size() ) {} // Avoid compiler unused warn + SVDValues SVD_; + return SVD_; +} +#endif +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +// Do not use LAPACK on Windog: use scikit-learn LinearRegression +//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< diff --git a/src/cppEDM/src/SMap.h b/src/cppEDM/src/SMap.h index 6a5d948..fe0469a 100644 --- a/src/cppEDM/src/SMap.h +++ b/src/cppEDM/src/SMap.h @@ -11,11 +11,16 @@ using Solver = SVDValues (*) ( DataFrame < double >, // Prototype declaration of general functions SVDValues SVD( DataFrame < double > A, std::valarray< double > B ); +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +// Do not use LAPACK on Windog: use scikit-learn LinearRegression +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +#if !defined _WIN32 || defined USING_R SVDValues Lapack_SVD( int m, // number of rows in matrix int n, // number of columns in matrix double *a, // pointer to top-left corner double *b, double rcond ); +#endif //---------------------------------------------------------------- // SMap class inherits from EDM class and defines