diff --git a/inst/include/common/data_object.hpp b/inst/include/common/data_object.hpp index e2cc5768..ad05c7a3 100644 --- a/inst/include/common/data_object.hpp +++ b/inst/include/common/data_object.hpp @@ -11,8 +11,8 @@ #include #include -#include "model_object.hpp" #include "fims_vector.hpp" +#include "model_object.hpp" namespace fims_data_object { @@ -21,14 +21,14 @@ namespace fims_data_object { */ template struct DataObject : public fims_model_object::FIMSObject { - static uint32_t id_g; /**< id of the Data Object >*/ + static uint32_t id_g; /**< id of the Data Object >*/ fims::Vector data; /**< vector of the data >*/ - size_t dimensions; /**< dimension of the Data object >*/ - size_t imax; /**<1st dimension of data object >*/ - size_t jmax; /**< 2nd dimension of data object>*/ - size_t kmax; /**< 3rd dimension of data object>*/ - size_t lmax; /**< 4th dimension of data object>*/ - Type na_value = -999; /**< specifying the NA value >*/ + size_t dimensions; /**< dimension of the Data object >*/ + size_t imax; /**<1st dimension of data object >*/ + size_t jmax; /**< 2nd dimension of data object>*/ + size_t kmax; /**< 3rd dimension of data object>*/ + size_t lmax; /**< 4th dimension of data object>*/ + Type na_value = -999; /**< specifying the NA value >*/ /** * Constructs a one-dimensional data object. diff --git a/inst/include/common/def.hpp b/inst/include/common/def.hpp index 75a31f74..7c484cce 100644 --- a/inst/include/common/def.hpp +++ b/inst/include/common/def.hpp @@ -7,31 +7,28 @@ */ #ifndef DEF_HPP #define DEF_HPP -#include -#include -#include -#include -#include -#include - +#include +#include -#include #include -#include -#include -#include -#include -#include -#include #include +#include #include - +#include +#include +#include +#include +#include +#include #include - +#include +#include +#include #if defined(linux) || defined(__linux) || defined(__linux__) #define FIMS_LINUX -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) #define FIMS_BSD #elif defined(sun) || defined(__sun) #define FIMS_SOLARIS @@ -86,466 +83,479 @@ namespace fims { - /** - * Log entry. - */ - struct LogEntry { - /** The date/time that the log entry was created, e.g., "Oct 28 09:18:51 2024". You can track how long it took to work through each portion of the model by analyzing the progression of the timestamp through the log file.*/ - std::string timestamp; - /** The description of the log entry, e.g., "Adding Selectivity object to TMB" or "Mismatch dimension error", where the descriptions are predefined in the C++ code. Please make a GitHub issue or contact a developer if you have ideas for a more informative description.*/ - std::string message; - /** The logging level, which is a result of which macro was used to generate the message, e.g., FIMS_INFO_LOG(), FIMS_WARNING_LOG(), or FIMS_ERROR_LOG() results in "info", "warning", or "error", respectively, in the log file. An additional level is available to developers from FIMS_DEBUG_LOG(), resulting in a level of "debug", but this macro is only available in branches other than main.*/ - std::string level; - /** The message id, directly corresponds to the order in which the entries were created, e.g., "1", which is helpful for knowing the order of operations within the code base and comparing log files across model runs.*/ - size_t rank; - /** The user name registered to the computer where the log file was created, e.g., "John.Doe".*/ - std::string user; - /** The working directory for the R environment that created the log file, e.g., "C:/github/NOAA-FIMS/FIMS/vignettes" if you are on a Windows machine or "/home/oppy/FIMS-Testing/dev/dev_logging/FIMS/vignettes" if you are on a linux machine.*/ - std::string wd; - /** The full file path of the file that triggered the log entry, e.g., "C:/github/NOAA-FIMS/FIMS/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp".*/ - std::string file; - /** The function or method that led to the initialization the log entry, e.g., "virtual bool LogisticSelectivityInterface::add_to_fims_tmb()". If the function is templated, then the function type will be reported here in square brackets after the function name, e.g., "bool fims_info::Information::CreateModel() [with Type = double]".*/ - std::string routine; - /** The line in `file` where the log entry was initiated, e.g., "219", which will be a line inside of the `routine` listed above.*/ - int line; - - /** - * Convert this object to a string. - */ - std::string to_string() { - std::stringstream ss; - ss << "\"timestamp\" : " << "\"" << this->timestamp << "\"" << ",\n"; - ss << "\"level\" : " << "\"" << this->level << "\",\n"; - ss << "\"message\" : " << "\"" << this->message << "\",\n"; - ss << "\"id\" : " << "\"" << this->rank << "\",\n"; - ss << "\"user\" : " << "\"" << this->user << "\",\n"; - ss << "\"wd\" : " << "\"" << this->wd << "\",\n"; - ss << "\"file\" : " << "\"" << this->file << "\",\n"; - ss << "\"routine\" : " << "\"" << this->routine << "\",\n"; - ss << "\"line\" : " << "\"" << this->line << "\"\n"; - return ss.str(); - } +/** + * Log entry. + */ +struct LogEntry { + /** The date/time that the log entry was created, e.g., "Oct 28 09:18:51 + * 2024". You can track how long it took to work through each portion of the + * model by analyzing the progression of the timestamp through the log file.*/ + std::string timestamp; + /** The description of the log entry, e.g., "Adding Selectivity object to TMB" + * or "Mismatch dimension error", where the descriptions are predefined in the + * C++ code. Please make a GitHub issue or contact a developer if you have + * ideas for a more informative description.*/ + std::string message; + /** The logging level, which is a result of which macro was used to generate + * the message, e.g., FIMS_INFO_LOG(), FIMS_WARNING_LOG(), or FIMS_ERROR_LOG() + * results in "info", "warning", or "error", respectively, in the log file. An + * additional level is available to developers from FIMS_DEBUG_LOG(), + * resulting in a level of "debug", but this macro is only available in + * branches other than main.*/ + std::string level; + /** The message id, directly corresponds to the order in which the entries + * were created, e.g., "1", which is helpful for knowing the order of + * operations within the code base and comparing log files across model + * runs.*/ + size_t rank; + /** The user name registered to the computer where the log file was created, + * e.g., "John.Doe".*/ + std::string user; + /** The working directory for the R environment that created the log file, + * e.g., "C:/github/NOAA-FIMS/FIMS/vignettes" if you are on a Windows machine + * or "/home/oppy/FIMS-Testing/dev/dev_logging/FIMS/vignettes" if you are on a + * linux machine.*/ + std::string wd; + /** The full file path of the file that triggered the log entry, e.g., + * "C:/github/NOAA-FIMS/FIMS/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp".*/ + std::string file; + /** The function or method that led to the initialization the log entry, e.g., + * "virtual bool LogisticSelectivityInterface::add_to_fims_tmb()". If the + * function is templated, then the function type will be reported here in + * square brackets after the function name, e.g., "bool + * fims_info::Information::CreateModel() [with Type = double]".*/ + std::string routine; + /** The line in `file` where the log entry was initiated, e.g., "219", which + * will be a line inside of the `routine` listed above.*/ + int line; + + /** + * Convert this object to a string. + */ + std::string to_string() { + std::stringstream ss; + ss << "\"timestamp\" : " + << "\"" << this->timestamp << "\"" + << ",\n"; + ss << "\"level\" : " + << "\"" << this->level << "\",\n"; + ss << "\"message\" : " + << "\"" << this->message << "\",\n"; + ss << "\"id\" : " + << "\"" << this->rank << "\",\n"; + ss << "\"user\" : " + << "\"" << this->user << "\",\n"; + ss << "\"wd\" : " + << "\"" << this->wd << "\",\n"; + ss << "\"file\" : " + << "\"" << this->file << "\",\n"; + ss << "\"routine\" : " + << "\"" << this->routine << "\",\n"; + ss << "\"line\" : " + << "\"" << this->line << "\"\n"; + return ss.str(); + } +}; - }; - - /** - * FIMS logging class. - */ - class FIMSLog { - std::vector entries; - std::vector log_entries; - size_t entry_number = 0; - std::string path = "fims.log"; - size_t warning_count = 0; - size_t error_count = 0; - - /** - * Get username. - * - * @return username. - */ - std::string get_user() { - char * user; - std::string user_ret = "UNKOWN_USER"; +/** + * FIMS logging class. + */ +class FIMSLog { + std::vector entries; + std::vector log_entries; + size_t entry_number = 0; + std::string path = "fims.log"; + size_t warning_count = 0; + size_t error_count = 0; + + /** + * Get username. + * + * @return username. + */ + std::string get_user() { + char* user; + std::string user_ret = "UNKOWN_USER"; #ifdef FIMS_WINDOWS - user = getenv("username"); - user_ret = std::string(user); + user = getenv("username"); + user_ret = std::string(user); #endif #ifdef FIMS_LINUX - user = getenv("USER"); - user_ret = std::string(user); + user = getenv("USER"); + user_ret = std::string(user); #endif #ifdef FIMS_MACOS - user = getenv("USER"); - user_ret = std::string(user); + user = getenv("USER"); + user_ret = std::string(user); #endif - return user_ret; - } - public: - bool write_on_exit = true; /*!*/ - bool throw_on_error = false; /*!*/ - static std::shared_ptr fims_log; /*!*/ - - /** - * Default constructor. - */ - FIMSLog() { - - } - - /** - * Destructor. If write_on_exit is set to true, - * the log will be written to the disk in JSON format. - */ - ~FIMSLog() { - if (this->write_on_exit) { - std::ofstream log(this->path); - log << this->get_log(); - log.close(); - } - } - - /** - * @brief Get the Absolute Path Without Dot Dot object - * - * Dot dot notation is for relative paths, where this function replaces - * all dot dots with the actual full path. - * - * @param relativePath A path in your file system. - * @return std::filesystem::path - */ - std::filesystem::path getAbsolutePathWithoutDotDot(const std::filesystem::path& relativePath) { - std::filesystem::path absolutePath = std::filesystem::absolute(relativePath); - - std::filesystem::path result; - for (const auto& part : absolutePath) { - if (part == "..") { - if (!result.empty()) { - result = result.parent_path(); - } - } else { - result /= part; - } - } - - return result.generic_string(); - } - - /** - * Set a path for the log file. - * - * @param path - */ - void set_path(std::string path) { - this->path = path; - } - - /** - * Get the path for the log file. - * - * @return - */ - std::string get_path() { - return this->path; - } - - /** - * Add a "info" level message to the log. - * - * @param str - * @param line - * @param file - * @param func - */ - void info_message(std::string str, int line, const char* file, const char* func) { - std::filesystem::path relativePath = file; - std::filesystem::path absolutePath = getAbsolutePathWithoutDotDot(relativePath); - std::filesystem::path cwd = std::filesystem::current_path(); - std::stringstream ss; - auto now = std::chrono::system_clock::now(); - std::time_t now_time = std::chrono::system_clock::to_time_t(now); - std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); - - LogEntry l; - l.timestamp = ctime_no_newline; - l.message = str; - l.level = "info"; - l.rank = this->log_entries.size(); - l.user = this->get_user(); - l.wd = cwd.generic_string(); - l.file = absolutePath.string(); - l.line = line; - l.routine = func; - this->log_entries.push_back(l); - - } - - /** - * Add a "debug" level message to the log. - * - * @param str - * @param line - * @param file - * @param func - */ - void debug_message(std::string str, int line, const char* file, const char* func) { - std::filesystem::path relativePath = file; - std::filesystem::path absolutePath = getAbsolutePathWithoutDotDot(relativePath); - std::filesystem::path cwd = std::filesystem::current_path(); - std::stringstream ss; - auto now = std::chrono::system_clock::now(); - std::time_t now_time = std::chrono::system_clock::to_time_t(now); - std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); - - LogEntry l; - l.timestamp = ctime_no_newline; - l.message = str; - l.level = "debug"; - l.rank = this->log_entries.size(); - l.user = this->get_user(); - l.wd = cwd.generic_string(); - l.file = absolutePath.string(); - l.line = line; - l.routine = func; - this->log_entries.push_back(l); - - } - - /** - * Add a "error" level message to the log. - * - * @param str - * @param line - * @param file - * @param func - */ - void error_message(std::string str, int line, const char* file, const char* func) { - this->error_count++; - std::filesystem::path relativePath = file; - std::filesystem::path absolutePath = getAbsolutePathWithoutDotDot(relativePath); - std::filesystem::path cwd = std::filesystem::current_path(); - - std::stringstream ss; - auto now = std::chrono::system_clock::now(); - std::time_t now_time = std::chrono::system_clock::to_time_t(now); - std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); - - LogEntry l; - l.timestamp = ctime_no_newline; - l.message = str; - l.level = "error"; - l.rank = this->log_entries.size(); - l.user = this->get_user(); - l.wd = cwd.generic_string(); - l.file = absolutePath.string(); - l.line = line; - l.routine = func; - this->log_entries.push_back(l); - - if (this->throw_on_error) { - std::stringstream ss; - ss << "\n\n" << l.to_string() << "\n\n"; - throw std::runtime_error(ss.str().c_str()); - } - - } - - /** - * Add a "warning" level message to the log. - * - * @param str - * @param line - * @param file - * @param func - */ - void warning_message(std::string str, int line, const char* file, const char* func) { - this->warning_count++; - std::filesystem::path relativePath = file; - std::filesystem::path absolutePath = getAbsolutePathWithoutDotDot(relativePath); - std::filesystem::path cwd = std::filesystem::current_path(); - - std::stringstream ss; - auto now = std::chrono::system_clock::now(); - std::time_t now_time = std::chrono::system_clock::to_time_t(now); - std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); - - LogEntry l; - l.timestamp = ctime_no_newline; - l.message = str; - l.level = "warning"; - l.rank = this->log_entries.size(); - l.user = this->get_user(); - l.wd = cwd.generic_string(); - l.file = absolutePath.string(); - l.line = line; - l.routine = func; - this->log_entries.push_back(l); - - } - - /** - * Get the log as a string object. - * - * @return - */ - std::string get_log() { - std::stringstream ss; - if (log_entries.size() == 0) { - ss << "[\n]"; - } else { - ss << "[\n"; - for (size_t i = 0; i < log_entries.size() - 1; i++) { - ss << "{\n" << this->log_entries[i].to_string() << "},\n"; - - } - ss << "{\n" << this->log_entries[log_entries.size() - 1].to_string() << "}\n]"; - } - return ss.str(); - } - - /** - * Return only error entries from the log. - * - * @return - */ - std::string get_errors() { - std::stringstream ss; - std::vector errors; - for (size_t i = 0; i < log_entries.size(); i++) { - if (log_entries[i].level == "error") { - errors.push_back(this->log_entries[i]); - } - } - - if (errors.size() == 0) { - ss << "[\n]"; - } else { - ss << "[\n"; - for (size_t i = 0; i < errors.size() - 1; i++) { - - ss << "{\n" << errors[i].to_string() << "},\n"; - - } - - ss << "{\n" << errors[errors.size() - 1].to_string() << "}\n]"; - - } - return ss.str(); - } - - /** - * Return only warning entries from the log. - * - * @return - */ - std::string get_warnings() { - std::stringstream ss; - std::vector warnings; - for (size_t i = 0; i < log_entries.size(); i++) { - if (log_entries[i].level == "warning") { - warnings.push_back(this->log_entries[i]); - } - } - - if (warnings.size() == 0) { - ss << "[\n]"; - } else { - ss << "[\n"; - for (size_t i = 0; i < warnings.size() - 1; i++) { - - ss << "{\n" << warnings[i].to_string() << "},\n"; - - } - - ss << "{\n" << warnings[warnings.size() - 1].to_string() << "}\n]"; - - } - return ss.str(); - } - - /** - * Return only info entries from the log. - * - * @return - */ - std::string get_info() { - std::stringstream ss; - std::vector info; - for (size_t i = 0; i < log_entries.size(); i++) { - if (log_entries[i].level == "info") { - info.push_back(this->log_entries[i]); - } - } - - if (info.size() == 0) { - ss << "[\n]"; - } else { - ss << "[\n"; - for (size_t i = 0; i < info.size() - 1; i++) { - - ss << "{\n" << info[i].to_string() << "},\n"; - - } - - ss << "{\n" << info[info.size() - 1].to_string() << "}\n]"; - - } - return ss.str(); - } - - /** - * Query the log by module. - * - * @param module - * @return - */ - std::string get_module(const std::string& module) { - std::stringstream ss; - std::vector info; - for (size_t i = 0; i < log_entries.size(); i++) { - if (log_entries[i].file.find(module) != std::string::npos) { - info.push_back(this->log_entries[i]); - } - } - - if (info.size() == 0) { - ss << "[\n]"; - } else { - ss << "[\n"; - for (size_t i = 0; i < info.size() - 1; i++) { - - ss << "{\n" << info[i].to_string() << "},\n"; - - } - - ss << "{\n" << info[info.size() - 1].to_string() << "}\n]"; - - } - return ss.str(); - } - - /** - * @brief Get the counts of the number of errors - */ - size_t get_error_count() const { - return error_count; - } - - /** - * @brief Get the counts of the number of warnings - */ - size_t get_warning_count() const { - return warning_count; + return user_ret; + } + + public: + bool write_on_exit = true; /*!*/ + bool throw_on_error = false; /*!*/ + static std::shared_ptr fims_log; /*!*/ + + /** + * Default constructor. + */ + FIMSLog() {} + + /** + * Destructor. If write_on_exit is set to true, + * the log will be written to the disk in JSON format. + */ + ~FIMSLog() { + if (this->write_on_exit) { + std::ofstream log(this->path); + log << this->get_log(); + log.close(); + } + } + + /** + * @brief Get the Absolute Path Without Dot Dot object + * + * Dot dot notation is for relative paths, where this function replaces + * all dot dots with the actual full path. + * + * @param relativePath A path in your file system. + * @return std::filesystem::path + */ + std::filesystem::path getAbsolutePathWithoutDotDot( + const std::filesystem::path& relativePath) { + std::filesystem::path absolutePath = + std::filesystem::absolute(relativePath); + + std::filesystem::path result; + for (const auto& part : absolutePath) { + if (part == "..") { + if (!result.empty()) { + result = result.parent_path(); } + } else { + result /= part; + } + } - /** - * @brief Clears all pointers/references of a FIMS model. - * - */ - void clear() { - this->entries.clear(); - this->log_entries.clear(); - this->warning_count = 0; - this->entry_number = 0; - } + return result.generic_string(); + } + + /** + * Set a path for the log file. + * + * @param path + */ + void set_path(std::string path) { this->path = path; } + + /** + * Get the path for the log file. + * + * @return + */ + std::string get_path() { return this->path; } + + /** + * Add a "info" level message to the log. + * + * @param str + * @param line + * @param file + * @param func + */ + void info_message(std::string str, int line, const char* file, + const char* func) { + std::filesystem::path relativePath = file; + std::filesystem::path absolutePath = + getAbsolutePathWithoutDotDot(relativePath); + std::filesystem::path cwd = std::filesystem::current_path(); + std::stringstream ss; + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); + + LogEntry l; + l.timestamp = ctime_no_newline; + l.message = str; + l.level = "info"; + l.rank = this->log_entries.size(); + l.user = this->get_user(); + l.wd = cwd.generic_string(); + l.file = absolutePath.string(); + l.line = line; + l.routine = func; + this->log_entries.push_back(l); + } + + /** + * Add a "debug" level message to the log. + * + * @param str + * @param line + * @param file + * @param func + */ + void debug_message(std::string str, int line, const char* file, + const char* func) { + std::filesystem::path relativePath = file; + std::filesystem::path absolutePath = + getAbsolutePathWithoutDotDot(relativePath); + std::filesystem::path cwd = std::filesystem::current_path(); + std::stringstream ss; + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); + + LogEntry l; + l.timestamp = ctime_no_newline; + l.message = str; + l.level = "debug"; + l.rank = this->log_entries.size(); + l.user = this->get_user(); + l.wd = cwd.generic_string(); + l.file = absolutePath.string(); + l.line = line; + l.routine = func; + this->log_entries.push_back(l); + } + + /** + * Add a "error" level message to the log. + * + * @param str + * @param line + * @param file + * @param func + */ + void error_message(std::string str, int line, const char* file, + const char* func) { + this->error_count++; + std::filesystem::path relativePath = file; + std::filesystem::path absolutePath = + getAbsolutePathWithoutDotDot(relativePath); + std::filesystem::path cwd = std::filesystem::current_path(); + + std::stringstream ss; + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); + + LogEntry l; + l.timestamp = ctime_no_newline; + l.message = str; + l.level = "error"; + l.rank = this->log_entries.size(); + l.user = this->get_user(); + l.wd = cwd.generic_string(); + l.file = absolutePath.string(); + l.line = line; + l.routine = func; + this->log_entries.push_back(l); + + if (this->throw_on_error) { + std::stringstream ss; + ss << "\n\n" << l.to_string() << "\n\n"; + throw std::runtime_error(ss.str().c_str()); + } + } + + /** + * Add a "warning" level message to the log. + * + * @param str + * @param line + * @param file + * @param func + */ + void warning_message(std::string str, int line, const char* file, + const char* func) { + this->warning_count++; + std::filesystem::path relativePath = file; + std::filesystem::path absolutePath = + getAbsolutePathWithoutDotDot(relativePath); + std::filesystem::path cwd = std::filesystem::current_path(); + + std::stringstream ss; + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); + + LogEntry l; + l.timestamp = ctime_no_newline; + l.message = str; + l.level = "warning"; + l.rank = this->log_entries.size(); + l.user = this->get_user(); + l.wd = cwd.generic_string(); + l.file = absolutePath.string(); + l.line = line; + l.routine = func; + this->log_entries.push_back(l); + } + + /** + * Get the log as a string object. + * + * @return + */ + std::string get_log() { + std::stringstream ss; + if (log_entries.size() == 0) { + ss << "[\n]"; + } else { + ss << "[\n"; + for (size_t i = 0; i < log_entries.size() - 1; i++) { + ss << "{\n" << this->log_entries[i].to_string() << "},\n"; + } + ss << "{\n" + << this->log_entries[log_entries.size() - 1].to_string() << "}\n]"; + } + return ss.str(); + } + + /** + * Return only error entries from the log. + * + * @return + */ + std::string get_errors() { + std::stringstream ss; + std::vector errors; + for (size_t i = 0; i < log_entries.size(); i++) { + if (log_entries[i].level == "error") { + errors.push_back(this->log_entries[i]); + } + } - }; + if (errors.size() == 0) { + ss << "[\n]"; + } else { + ss << "[\n"; + for (size_t i = 0; i < errors.size() - 1; i++) { + ss << "{\n" << errors[i].to_string() << "},\n"; + } + ss << "{\n" << errors[errors.size() - 1].to_string() << "}\n]"; + } + return ss.str(); + } + + /** + * Return only warning entries from the log. + * + * @return + */ + std::string get_warnings() { + std::stringstream ss; + std::vector warnings; + for (size_t i = 0; i < log_entries.size(); i++) { + if (log_entries[i].level == "warning") { + warnings.push_back(this->log_entries[i]); + } + } - std::shared_ptr FIMSLog::fims_log = std::make_shared(); + if (warnings.size() == 0) { + ss << "[\n]"; + } else { + ss << "[\n"; + for (size_t i = 0; i < warnings.size() - 1; i++) { + ss << "{\n" << warnings[i].to_string() << "},\n"; + } -} // namespace fims + ss << "{\n" << warnings[warnings.size() - 1].to_string() << "}\n]"; + } + return ss.str(); + } + + /** + * Return only info entries from the log. + * + * @return + */ + std::string get_info() { + std::stringstream ss; + std::vector info; + for (size_t i = 0; i < log_entries.size(); i++) { + if (log_entries[i].level == "info") { + info.push_back(this->log_entries[i]); + } + } + if (info.size() == 0) { + ss << "[\n]"; + } else { + ss << "[\n"; + for (size_t i = 0; i < info.size() - 1; i++) { + ss << "{\n" << info[i].to_string() << "},\n"; + } + ss << "{\n" << info[info.size() - 1].to_string() << "}\n]"; + } + return ss.str(); + } + + /** + * Query the log by module. + * + * @param module + * @return + */ + std::string get_module(const std::string& module) { + std::stringstream ss; + std::vector info; + for (size_t i = 0; i < log_entries.size(); i++) { + if (log_entries[i].file.find(module) != std::string::npos) { + info.push_back(this->log_entries[i]); + } + } + if (info.size() == 0) { + ss << "[\n]"; + } else { + ss << "[\n"; + for (size_t i = 0; i < info.size() - 1; i++) { + ss << "{\n" << info[i].to_string() << "},\n"; + } + ss << "{\n" << info[info.size() - 1].to_string() << "}\n]"; + } + return ss.str(); + } + + /** + * @brief Get the counts of the number of errors + */ + size_t get_error_count() const { return error_count; } + + /** + * @brief Get the counts of the number of warnings + */ + size_t get_warning_count() const { return warning_count; } + + /** + * @brief Clears all pointers/references of a FIMS model. + * + */ + void clear() { + this->entries.clear(); + this->log_entries.clear(); + this->warning_count = 0; + this->entry_number = 0; + } +}; + +std::shared_ptr FIMSLog::fims_log = std::make_shared(); + +} // namespace fims #ifdef FIMS_DEBUG -#define FIMS_DEBUG_LOG(MESSAGE) FIMSLog::fims_log->debug_message(MESSAGE, __LINE__, __FILE__, __PRETTY_FUNCTION__); +#define FIMS_DEBUG_LOG(MESSAGE) \ + FIMSLog::fims_log->debug_message(MESSAGE, __LINE__, __FILE__, \ + __PRETTY_FUNCTION__); #else @@ -553,76 +563,81 @@ namespace fims { #endif -#define FIMS_INFO_LOG(MESSAGE) fims::FIMSLog::fims_log->info_message(MESSAGE, __LINE__, __FILE__, __PRETTY_FUNCTION__); /**< Print MESSAGE to info log */ - -#define FIMS_WARNING_LOG(MESSAGE) fims::FIMSLog::fims_log->warning_message(MESSAGE, __LINE__, __FILE__, __PRETTY_FUNCTION__); /**< Print MESSAGE to warning log */ +#define FIMS_INFO_LOG(MESSAGE) \ + fims::FIMSLog::fims_log->info_message( \ + MESSAGE, __LINE__, __FILE__, \ + __PRETTY_FUNCTION__); /**< Print MESSAGE to info log */ -#define FIMS_ERROR_LOG(MESSAGE) fims::FIMSLog::fims_log->error_message(MESSAGE, __LINE__, __FILE__, __PRETTY_FUNCTION__); /**< Print MESSAGE to error log */ +#define FIMS_WARNING_LOG(MESSAGE) \ + fims::FIMSLog::fims_log->warning_message( \ + MESSAGE, __LINE__, __FILE__, \ + __PRETTY_FUNCTION__); /**< Print MESSAGE to warning log */ -#define FIMS_STR(s) #s /**< String of s */ +#define FIMS_ERROR_LOG(MESSAGE) \ + fims::FIMSLog::fims_log->error_message( \ + MESSAGE, __LINE__, __FILE__, \ + __PRETTY_FUNCTION__); /**< Print MESSAGE to error log */ +#define FIMS_STR(s) #s /**< String of s */ namespace fims { - /** - * Signal intercept function. Writes the log to the disk before - * a crash occurs. - * - * @param sig - */ - void WriteAtExit(int sig) { - - std::string signal_error = "NA"; - switch (sig) { - case SIGSEGV: - signal_error = "Invalid memory access (segmentation fault)"; - break; - case SIGINT: - signal_error = "External interrupt, possibly initiated by the user."; - break; - case SIGABRT: - signal_error = "Abnormal termination condition, possible call to std::abort."; - break; - case SIGFPE: - signal_error = "Erroneous arithmetic operation."; - break; - case SIGILL: - signal_error = "Invalid program image or invalid instruction"; - break; - case SIGTERM: - signal_error = "Termination request, sent to the program."; - break; - default: - signal_error = "Unknown signal thrown"; - - } - - FIMSLog::fims_log->error_message(signal_error, -999, "?", "?"); - - - if (FIMSLog::fims_log->write_on_exit) { - - std::ofstream log(FIMSLog::fims_log->get_path()); - log << FIMSLog::fims_log->get_log(); - log.close(); - } - std::signal(sig, SIG_DFL); - raise(sig); - } - - /** - * Converts an object T to a string. - * - * @param v - * @return - */ - template - std::string to_string(T v) { - std::stringstream ss; - ss << v; - return ss.str(); - } +/** + * Signal intercept function. Writes the log to the disk before + * a crash occurs. + * + * @param sig + */ +void WriteAtExit(int sig) { + std::string signal_error = "NA"; + switch (sig) { + case SIGSEGV: + signal_error = "Invalid memory access (segmentation fault)"; + break; + case SIGINT: + signal_error = "External interrupt, possibly initiated by the user."; + break; + case SIGABRT: + signal_error = + "Abnormal termination condition, possible call to std::abort."; + break; + case SIGFPE: + signal_error = "Erroneous arithmetic operation."; + break; + case SIGILL: + signal_error = "Invalid program image or invalid instruction"; + break; + case SIGTERM: + signal_error = "Termination request, sent to the program."; + break; + default: + signal_error = "Unknown signal thrown"; + } + + FIMSLog::fims_log->error_message(signal_error, -999, "?", "?"); + + if (FIMSLog::fims_log->write_on_exit) { + std::ofstream log(FIMSLog::fims_log->get_path()); + log << FIMSLog::fims_log->get_log(); + log.close(); + } + std::signal(sig, SIG_DFL); + raise(sig); +} +/** + * Converts an object T to a string. + * + * @param v + * @return + */ +template +std::string to_string(T v) { + std::stringstream ss; + ss << v; + return ss.str(); } +} // namespace fims + #endif /* TRAITS_HPP */ diff --git a/inst/include/common/fims_math.hpp b/inst/include/common/fims_math.hpp index 28203f05..66b426ab 100644 --- a/inst/include/common/fims_math.hpp +++ b/inst/include/common/fims_math.hpp @@ -100,32 +100,32 @@ inline const double log(const double &x) { template inline const Type cos(const Type &x) { - return cos(x); + return cos(x); } template <> inline const double cos(const double &x) { - return std::cos(x); + return std::cos(x); } template inline const Type sqrt(const Type &x) { - return sqrt(x); + return sqrt(x); } template <> inline const double sqrt(const double &x) { - return std::sqrt(x); + return std::sqrt(x); } template inline const Type pow(const Type &x, const Type &y) { - return pow(x, y); + return pow(x, y); } template <> inline const double pow(const double &x, const double &y) { - return std::pow(x, y); + return std::pow(x, y); } #endif @@ -261,39 +261,39 @@ inline const Type ad_max(const Type &a, const Type &b, Type C = 1e-5) { return (a + b + fims_math::ad_fabs(a - b, C)) * static_cast(.5); } - /** - * Sum elements of a vector - * - * @brief - * - * @param v A vector of constants. - * @return A single numeric value. - */ - template - T sum(const std::vector& v) { - T ret = 0.0; - for (int i = 0; i < v.size(); i++) { - ret += v[i]; - } - return ret; - } - - /** - * Sum elements of a vector - * - * @brief - * - * @param v A vector of constants. - * @return A single numeric value. - */ - template - T sum(const fims::Vector& v) { - T ret = 0.0; - for (int i = 0; i < v.size(); i++) { - ret += v[i]; - } - return ret; - } +/** + * Sum elements of a vector + * + * @brief + * + * @param v A vector of constants. + * @return A single numeric value. + */ +template +T sum(const std::vector &v) { + T ret = 0.0; + for (int i = 0; i < v.size(); i++) { + ret += v[i]; + } + return ret; +} + +/** + * Sum elements of a vector + * + * @brief + * + * @param v A vector of constants. + * @return A single numeric value. + */ +template +T sum(const fims::Vector &v) { + T ret = 0.0; + for (int i = 0; i < v.size(); i++) { + ret += v[i]; + } + return ret; +} } // namespace fims_math diff --git a/inst/include/common/fims_vector.hpp b/inst/include/common/fims_vector.hpp index fca5d33e..ae05100a 100644 --- a/inst/include/common/fims_vector.hpp +++ b/inst/include/common/fims_vector.hpp @@ -8,8 +8,9 @@ #ifndef FIMS_VECTOR_HPP #define FIMS_VECTOR_HPP -#include "../interface/interface.hpp" #include + +#include "../interface/interface.hpp" namespace fims { /** @@ -23,470 +24,366 @@ namespace fims { */ template class Vector { - std::vector vec_m; - - /** - * @brief friend comparison operator. Allows the operartor to see private - * members of fims::Vector. - */ - template - friend bool operator==(const fims::Vector& lhs, - const fims::Vector& rhs); - -public: - // Member Types - - typedef - typename std::vector::value_type value_type; /*!*/ - typedef typename std::vector::allocator_type - allocator_type; /*!*/ - typedef typename std::vector::size_type size_type; /*!*/ - typedef typename std::vector::difference_type - difference_type; /*!*/ - typedef typename std::vector::reference - reference; /*!*/ - typedef typename std::vector::const_reference - const_reference; /*!*/ - typedef typename std::vector::pointer pointer; /*!*/ - typedef typename std::vector::const_pointer - const_pointer; /*!*/ - typedef typename std::vector::iterator iterator; /*!*/ - typedef typename std::vector::const_iterator - const_iterator; /*!*/ - typedef typename std::vector::reverse_iterator - reverse_iterator; /*!*/ - typedef typename std::vector::const_reverse_iterator - const_reverse_iterator; /*!*/ - - // Constructors - - /** - * Default constructor. - */ - Vector() - { - } - - /** - * @brief Constructs a Vector of length "size" and sets the elements with the - * value from input "value". - */ - Vector(size_t size, const Type& value = Type()) - { - this->vec_m.resize(size, value); - } + std::vector vec_m; + + /** + * @brief friend comparison operator. Allows the operartor to see private + * members of fims::Vector. + */ + template + friend bool operator==(const fims::Vector& lhs, + const fims::Vector& rhs); + + public: + // Member Types + + typedef + typename std::vector::value_type value_type; /*!*/ + typedef typename std::vector::allocator_type + allocator_type; /*!*/ + typedef typename std::vector::size_type size_type; /*!*/ + typedef typename std::vector::difference_type + difference_type; /*!*/ + typedef typename std::vector::reference + reference; /*!*/ + typedef typename std::vector::const_reference + const_reference; /*!*/ + typedef typename std::vector::pointer pointer; /*!*/ + typedef typename std::vector::const_pointer + const_pointer; /*!*/ + typedef typename std::vector::iterator iterator; /*!*/ + typedef typename std::vector::const_iterator + const_iterator; /*!*/ + typedef typename std::vector::reverse_iterator + reverse_iterator; /*!*/ + typedef typename std::vector::const_reverse_iterator + const_reverse_iterator; /*!*/ + + // Constructors + + /** + * Default constructor. + */ + Vector() {} + + /** + * @brief Constructs a Vector of length "size" and sets the elements with the + * value from input "value". + */ + Vector(size_t size, const Type& value = Type()) { + this->vec_m.resize(size, value); + } - /** - * @brief Copy constructor. - */ - Vector(const Vector& other) - { - this->vec_m.resize(other.size()); - for (size_t i = 0; i < this->vec_m.size(); i++) { - this->vec_m[i] = other[i]; - } + /** + * @brief Copy constructor. + */ + Vector(const Vector& other) { + this->vec_m.resize(other.size()); + for (size_t i = 0; i < this->vec_m.size(); i++) { + this->vec_m[i] = other[i]; } + } - /** - * @brief Initialization constructor from std::vector type. - */ - Vector(const std::vector& other) - { - this->vec_m = other; - } + /** + * @brief Initialization constructor from std::vector type. + */ + Vector(const std::vector& other) { this->vec_m = other; } - // TMB specific constructor + // TMB specific constructor #ifdef TMB_MODEL - /** - * @brief Initialization constructor from tmbutils::vector type. - */ - Vector(const tmbutils::vector& other) - { - this->vec_m.resize(other.size()); - for (size_t i = 0; i < this->vec_m.size(); i++) { - this->vec_m[i] = other[i]; - } + /** + * @brief Initialization constructor from tmbutils::vector type. + */ + Vector(const tmbutils::vector& other) { + this->vec_m.resize(other.size()); + for (size_t i = 0; i < this->vec_m.size(); i++) { + this->vec_m[i] = other[i]; } + } #endif - /** - * The following are std::vector functions copied over from the standard - * library. While some of these may not be called explicitly in FIMS, they may - * be required to run other std library functions. - */ - - /** - * @brief Returns a reference to the element at specified location pos. No - * bounds checking is performed. - */ - inline Type& operator[](size_t pos) - { - return this->vec_m[pos]; - } - - /** - * @brief Returns a constant reference to the element at specified location - * pos. No bounds checking is performed. - */ - inline const Type& operator[](size_t n) const - { - return this->vec_m[n]; - } - - /** - * @brief Returns a reference to the element at specified location pos. Bounds - * checking is performed. - */ - inline Type& at(size_t n) - { - return this->vec_m.at(n); - } - - /** - * @brief Returns a constant reference to the element at specified location - * pos. Bounds checking is performed. - */ - inline const Type& at(size_t n) const - { - return this->vec_m.at(n); - } - - /** - * @brief If this vector is size 1 and pos is greater than zero, - * the first index is returned. If this vector has size - * greater than 1 and pos is greater than size, a invalid_argument - * exception is thrown. Otherwise, the value at index pos is returned. - * - * @param pos - * @return a constant reference to the element at specified location - */ - inline Type& get_force_scalar(size_t pos) - { - if (this->size() == 1 && pos > 0) { - return this->at(0); - } else if (this->size() > 1 && pos >= this->size()) { - throw std::invalid_argument("force_get fims::Vector index out of bounds."); - } else { - return this->at(pos); - } - } - - /** - * @brief Returns a reference to the first element in the container. - */ - inline reference front() - { - return this->vec_m.front(); - } - - /** - * @brief Returns a constant reference to the first element in the container. - */ - inline const_reference front() const - { - return this->vec_m.front(); - } - - /** - * @brief Returns a reference to the last element in the container. - */ - inline reference back() - { - return this->vec_m.back(); - } - - /** - * @brief Returns a constant reference to the last element in the container. - */ - inline const_reference back() const - { - return this->vec_m.back(); - } - - /** - * @brief Returns a pointer to the underlying data array. - */ - inline pointer data() - { - return this->vec_m.data(); - } - - /** - * @brief Returns a constant pointer to the underlying data array. - */ - inline const_pointer data() const - { - return this->vec_m.data(); - } - - // iterators - - /** - * @brief Returns an iterator to the first element of the vector. - */ - inline iterator begin() - { - return this->vec_m.begin(); - } - - /** - * @brief Returns an iterator to the element following the last element of the - * vector. - */ - inline iterator end() - { - return this->vec_m.end(); - } - - /** - * @brief Returns a reverse iterator to the first element of the reversed - * vector. It corresponds to the last element of the non-reversed vector. - */ - inline reverse_iterator rbegin() - { - return this->vec_m.rbegin(); - } - - /** - * @brief Returns a reverse iterator to the element following the last element - * of the reversed vector. It corresponds to the element preceding the first - * element of the non-reversed vector. - */ - inline reverse_iterator rend() - { - return this->vec_m.rend(); - } - - /** - * @brief Returns a constant reverse iterator to the first element of the - * reversed vector. It corresponds to the last element of the non-reversed - * vector. - */ - inline const_reverse_iterator rbegin() const - { - return this->vec_m.rbegin(); - } - - /** - * @brief Returns a constant reverse iterator to the element following the - * last element of the reversed vector. It corresponds to the element - * preceding the first element of the non-reversed vector. - */ - inline const_reverse_iterator rend() const - { - return this->vec_m.rend(); - } - - // capacity - - /** - * @brief Checks whether the container is empty. - */ - inline bool empty() - { - return this->vec_m.empty(); - } - - /** - * @brief Returns the number of elements. - */ - inline size_type size() const - { - return this->vec_m.size(); - } - - /** - * @brief Returns the maximum possible number of elements. - */ - inline size_type max_size() const - { - return this->vec_m.max_size(); - } - - /** - * @brief Reserves storage. - */ - inline void reserve(size_type cap) - { - this->vec_m.reserve(cap); - } - - /** - * @brief Returns the number of elements that can be held in currently - * allocated storage. - */ - inline size_type capacity() - { - return this->vec_m.capacity(); - } - - /** - * @brief Reduces memory usage by freeing unused memory. - */ - inline void shrink_to_fit() - { - this->vec_m.shrink_to_fit(); - } - - // modifiers - - /** - * @brief Clears the contents. - */ - inline void clear() - { - this->vec_m.clear(); - } - - /** - * @brief Inserts value before pos. - */ - inline iterator insert(const_iterator pos, const Type& value) - { - return this->vec_m.insert(pos, value); + /** + * The following are std::vector functions copied over from the standard + * library. While some of these may not be called explicitly in FIMS, they may + * be required to run other std library functions. + */ + + /** + * @brief Returns a reference to the element at specified location pos. No + * bounds checking is performed. + */ + inline Type& operator[](size_t pos) { return this->vec_m[pos]; } + + /** + * @brief Returns a constant reference to the element at specified location + * pos. No bounds checking is performed. + */ + inline const Type& operator[](size_t n) const { return this->vec_m[n]; } + + /** + * @brief Returns a reference to the element at specified location pos. Bounds + * checking is performed. + */ + inline Type& at(size_t n) { return this->vec_m.at(n); } + + /** + * @brief Returns a constant reference to the element at specified location + * pos. Bounds checking is performed. + */ + inline const Type& at(size_t n) const { return this->vec_m.at(n); } + + /** + * @brief If this vector is size 1 and pos is greater than zero, + * the first index is returned. If this vector has size + * greater than 1 and pos is greater than size, a invalid_argument + * exception is thrown. Otherwise, the value at index pos is returned. + * + * @param pos + * @return a constant reference to the element at specified location + */ + inline Type& get_force_scalar(size_t pos) { + if (this->size() == 1 && pos > 0) { + return this->at(0); + } else if (this->size() > 1 && pos >= this->size()) { + throw std::invalid_argument( + "force_get fims::Vector index out of bounds."); + } else { + return this->at(pos); } + } - /** - * @brief Inserts count copies of the value before pos. - */ - inline iterator insert(const_iterator pos, size_type count, - const Type& value) - { - return this->vec_m.insert(pos, count, value); - } + /** + * @brief Returns a reference to the first element in the container. + */ + inline reference front() { return this->vec_m.front(); } + + /** + * @brief Returns a constant reference to the first element in the container. + */ + inline const_reference front() const { return this->vec_m.front(); } + + /** + * @brief Returns a reference to the last element in the container. + */ + inline reference back() { return this->vec_m.back(); } + + /** + * @brief Returns a constant reference to the last element in the container. + */ + inline const_reference back() const { return this->vec_m.back(); } + + /** + * @brief Returns a pointer to the underlying data array. + */ + inline pointer data() { return this->vec_m.data(); } + + /** + * @brief Returns a constant pointer to the underlying data array. + */ + inline const_pointer data() const { return this->vec_m.data(); } + + // iterators + + /** + * @brief Returns an iterator to the first element of the vector. + */ + inline iterator begin() { return this->vec_m.begin(); } + + /** + * @brief Returns an iterator to the element following the last element of the + * vector. + */ + inline iterator end() { return this->vec_m.end(); } + + /** + * @brief Returns a reverse iterator to the first element of the reversed + * vector. It corresponds to the last element of the non-reversed vector. + */ + inline reverse_iterator rbegin() { return this->vec_m.rbegin(); } + + /** + * @brief Returns a reverse iterator to the element following the last element + * of the reversed vector. It corresponds to the element preceding the first + * element of the non-reversed vector. + */ + inline reverse_iterator rend() { return this->vec_m.rend(); } + + /** + * @brief Returns a constant reverse iterator to the first element of the + * reversed vector. It corresponds to the last element of the non-reversed + * vector. + */ + inline const_reverse_iterator rbegin() const { return this->vec_m.rbegin(); } + + /** + * @brief Returns a constant reverse iterator to the element following the + * last element of the reversed vector. It corresponds to the element + * preceding the first element of the non-reversed vector. + */ + inline const_reverse_iterator rend() const { return this->vec_m.rend(); } + + // capacity + + /** + * @brief Checks whether the container is empty. + */ + inline bool empty() { return this->vec_m.empty(); } + + /** + * @brief Returns the number of elements. + */ + inline size_type size() const { return this->vec_m.size(); } + + /** + * @brief Returns the maximum possible number of elements. + */ + inline size_type max_size() const { return this->vec_m.max_size(); } + + /** + * @brief Reserves storage. + */ + inline void reserve(size_type cap) { this->vec_m.reserve(cap); } + + /** + * @brief Returns the number of elements that can be held in currently + * allocated storage. + */ + inline size_type capacity() { return this->vec_m.capacity(); } + + /** + * @brief Reduces memory usage by freeing unused memory. + */ + inline void shrink_to_fit() { this->vec_m.shrink_to_fit(); } + + // modifiers + + /** + * @brief Clears the contents. + */ + inline void clear() { this->vec_m.clear(); } + + /** + * @brief Inserts value before pos. + */ + inline iterator insert(const_iterator pos, const Type& value) { + return this->vec_m.insert(pos, value); + } - /** - * @brief Inserts elements from range [first, last) before pos. - */ - template - iterator insert(const_iterator pos, InputIt first, InputIt last) - { - return this->vec_m.insert(pos, first, last); - } + /** + * @brief Inserts count copies of the value before pos. + */ + inline iterator insert(const_iterator pos, size_type count, + const Type& value) { + return this->vec_m.insert(pos, count, value); + } - /** - * @brief Inserts elements from initializer list ilist before pos. - */ + /** + * @brief Inserts elements from range [first, last) before pos. + */ + template + iterator insert(const_iterator pos, InputIt first, InputIt last) { + return this->vec_m.insert(pos, first, last); + } - iterator insert(const_iterator pos, std::initializer_list ilist) - { - return this->vec_m.insert(pos, ilist); - } + /** + * @brief Inserts elements from initializer list ilist before pos. + */ - /** - * @brief Constructs element in-place. - */ - template - iterator emplace(const_iterator pos, Args&&... args) - { - return this->vec_m.emplace(pos, std::forward(args)...); - } + iterator insert(const_iterator pos, std::initializer_list ilist) { + return this->vec_m.insert(pos, ilist); + } - /** - * @brief Removes the element at pos. - */ - inline iterator erase(iterator pos) - { - return this->vec_m.erase(pos); - } + /** + * @brief Constructs element in-place. + */ + template + iterator emplace(const_iterator pos, Args&&... args) { + return this->vec_m.emplace(pos, std::forward(args)...); + } - /** - * @brief Removes the elements in the range [first, last). - */ - inline iterator erase(iterator first, iterator last) - { - return this->vec_m.erase(first, last); - } + /** + * @brief Removes the element at pos. + */ + inline iterator erase(iterator pos) { return this->vec_m.erase(pos); } - /** - * @brief Adds an element to the end. - */ - inline void push_back(const Type&& value) - { - this->vec_m.push_back(value); - } + /** + * @brief Removes the elements in the range [first, last). + */ + inline iterator erase(iterator first, iterator last) { + return this->vec_m.erase(first, last); + } - /** - * @brief Constructs an element in-place at the end. - */ - template - void emplace_back(Args&&... args) - { - this->vec_m.emplace_back(std::forward(args)...); - } + /** + * @brief Adds an element to the end. + */ + inline void push_back(const Type&& value) { this->vec_m.push_back(value); } + + /** + * @brief Constructs an element in-place at the end. + */ + template + void emplace_back(Args&&... args) { + this->vec_m.emplace_back(std::forward(args)...); + } - /** - * @brief Removes the last element. - */ - inline void pop_back() - { - this->vec_m.pop_back(); - } + /** + * @brief Removes the last element. + */ + inline void pop_back() { this->vec_m.pop_back(); } - /** - * @brief Changes the number of elements stored. - */ - inline void resize(size_t s) - { - this->vec_m.resize(s); - } + /** + * @brief Changes the number of elements stored. + */ + inline void resize(size_t s) { this->vec_m.resize(s); } - /** - * @brief Swaps the contents. - */ - inline void swap(Vector& other) - { - this->vec_m.swap(other.vec_m); - } + /** + * @brief Swaps the contents. + */ + inline void swap(Vector& other) { this->vec_m.swap(other.vec_m); } - // end std::vector functions + // end std::vector functions - /** - * Conversion operators - */ + /** + * Conversion operators + */ - /** - * @brief Converts fims::Vector to std::vector - */ - inline operator std::vector() - { - return this->vec_m; - } + /** + * @brief Converts fims::Vector to std::vector + */ + inline operator std::vector() { return this->vec_m; } #ifdef TMB_MODEL - /** - * @brief Converts fims::Vector to tmbutils::vectorconst - */ - operator tmbutils::vector() const - { - tmbutils::vector ret; - ret.resize(this->vec_m.size()); - for (size_t i = 0; i < this->vec_m.size(); i++) { - ret[i] = this->vec_m[i]; - } - return ret; + /** + * @brief Converts fims::Vector to tmbutils::vectorconst + */ + operator tmbutils::vector() const { + tmbutils::vector ret; + ret.resize(this->vec_m.size()); + for (size_t i = 0; i < this->vec_m.size(); i++) { + ret[i] = this->vec_m[i]; } + return ret; + } - /** - * @brief Converts fims::Vector to tmbutils::vector - */ - operator tmbutils::vector() - { - tmbutils::vector ret; - ret.resize(this->vec_m.size()); - for (size_t i = 0; i < this->vec_m.size(); i++) { - ret[i] = this->vec_m[i]; - } - return ret; + /** + * @brief Converts fims::Vector to tmbutils::vector + */ + operator tmbutils::vector() { + tmbutils::vector ret; + ret.resize(this->vec_m.size()); + for (size_t i = 0; i < this->vec_m.size(); i++) { + ret[i] = this->vec_m[i]; } + return ret; + } #endif -private: -}; // end fims::Vector class + private: +}; // end fims::Vector class /** * @brief Comparison operator. @@ -496,16 +393,16 @@ bool operator==(const fims::Vector& lhs, const fims::Vector& rhs) { return lhs.vec_m == rhs.vec_m; } -} // namespace fims +} // namespace fims /** * @brief Output for std::ostream& for a vector. * * @param out The stream. * @param v A vector. - * @return std::ostream& + * @return std::ostream& */ -template +template std::ostream& operator<<(std::ostream& out, fims::Vector& v) { out << "["; @@ -521,5 +418,4 @@ std::ostream& operator<<(std::ostream& out, fims::Vector& v) { return out; } - #endif diff --git a/inst/include/common/information.hpp b/inst/include/common/information.hpp index 99ebeecf..94be4963 100644 --- a/inst/include/common/information.hpp +++ b/inst/include/common/information.hpp @@ -9,10 +9,10 @@ #ifndef FIMS_COMMON_INFORMATION_HPP #define FIMS_COMMON_INFORMATION_HPP +#include #include #include #include -#include #include "../distributions/distributions.hpp" #include "../population_dynamics/fleet/fleet.hpp" @@ -26,695 +26,707 @@ namespace fims_info { - /** - * @brief Stores FIMS model information and creates model. Contains all objects - * and data pre-model construction - */ - template - class Information { - public: - size_t nyears = 0; /**< number of years >*/ - size_t nseasons = 1; /**< number of seasons >*/ - size_t nages = 0; /**< number of ages>*/ - - static std::shared_ptr > - fims_information; /**< singleton instance >*/ - std::vector parameters; /**< list of all estimated parameters >*/ - std::vector - random_effects_parameters; /**< list of all random effects parameters >*/ - std::vector - fixed_effects_parameters; /**< list of all fixed effects parameters >*/ - std::vector - parameter_names; /**< list of all parameter names estimated in the model */ - - // data objects - std::map > > - data_objects; /**< map that holds data objects >*/ - typedef typename std::map< - uint32_t, std::shared_ptr > >::iterator - data_iterator; /**< iterator for the data objects */ - - // life history modules - std::map > > - recruitment_models; /** > >::iterator - recruitment_models_iterator; - /**< iterator for recruitment objects>*/ - - std::map > > - selectivity_models; /** > >::iterator - selectivity_models_iterator; - /**< iterator for selectivity objects>*/ - - std::map > > - growth_models; /** > >::iterator - growth_models_iterator; - /**< iterator for growth objects>*/ - - std::map > > - maturity_models; /** > >::iterator - maturity_models_iterator; - /**< iterator for maturity objects>*/ - - // fleet modules - std::map > > - fleets; /** > >::iterator - fleet_iterator; - /**< iterator for fleet objects>*/ - - // populations - std::map > > - populations; /** +class Information { + public: + size_t nyears = 0; /**< number of years >*/ + size_t nseasons = 1; /**< number of seasons >*/ + size_t nages = 0; /**< number of ages>*/ + + static std::shared_ptr > + fims_information; /**< singleton instance >*/ + std::vector parameters; /**< list of all estimated parameters >*/ + std::vector + random_effects_parameters; /**< list of all random effects parameters >*/ + std::vector + fixed_effects_parameters; /**< list of all fixed effects parameters >*/ + std::vector parameter_names; /**< list of all parameter names + estimated in the model */ + + // data objects + std::map > > + data_objects; /**< map that holds data objects >*/ + typedef typename std::map< + uint32_t, std::shared_ptr > >::iterator + data_iterator; /**< iterator for the data objects */ + + // life history modules + std::map > > + recruitment_models; /** > >::iterator + recruitment_models_iterator; + /**< iterator for recruitment objects>*/ + + std::map > > + selectivity_models; /** > >::iterator + selectivity_models_iterator; + /**< iterator for selectivity objects>*/ + + std::map > > + growth_models; /** > >::iterator - population_iterator; - /**< iterator for population objects>*/ - - // distributions - std::map > > - density_components; /** > >::iterator - density_components_iterator; - /**< iterator for distribution objects>*/ - - std::unordered_map* > - variable_map; /*** >::iterator - variable_map_iterator; /**< iterator for variable map>*/ - - Information() { - } - - virtual ~Information() { - } - - /** - * @brief Clears all containers. - * - */ - void Clear(){ - this->data_objects.clear(); - this->density_components.clear(); - this->fixed_effects_parameters.clear(); - this->fleets.clear(); - this->growth_models.clear(); - this->maturity_models.clear(); - this->parameter_names.clear(); - this->parameters.clear(); - this->random_effects_parameters.clear(); - this->recruitment_models.clear(); - this->selectivity_models.clear(); - this->variable_map.clear(); - this->nyears = 0; - this->nseasons = 0; - this->nages = 0; - } - - /** - * @brief Returns a singleton Information object for type T. - * - * @return singleton for type T - */ - static std::shared_ptr > GetInstance() { - if (Information::fims_information == nullptr) { - Information::fims_information = - std::make_shared >(); - } - return Information::fims_information; - } - - /** - * @brief Register a parameter as estimable. - * - * @param p - */ - void RegisterParameter(Type& p) { - this->fixed_effects_parameters.push_back(&p); - } - - /** - * @brief Register a random effect as estimable. - * - * @param re - */ - void RegisterRandomEffect(Type& re) { - this->random_effects_parameters.push_back(&re); - } - - /** - * @brief Register a parameter name. - * - * @param p_name - */ - void RegisterParameterName(std::string p_name) { - this->parameter_names.push_back(p_name); - } - - /** - * @brief Loop over distributions and set links to distribution x value if distribution is a prior type. - */ - void SetupPriors() { - for (density_components_iterator it = density_components.begin(); it != density_components.end(); ++it) { - std::shared_ptr > d = (*it).second; - if (d->input_type == "prior") { - FIMS_INFO_LOG("Setup prior for distribution " + fims::to_string(d->id)); - variable_map_iterator vmit; - FIMS_INFO_LOG("Link prior from distribution " + fims::to_string(d->id) + " to parameter " + fims::to_string(d->key[0])); - vmit = this->variable_map.find(d->key[0]); - d->x = *(*vmit).second; - for (size_t i = 1; i < d->key.size(); i++) { - FIMS_INFO_LOG("Link prior from distribution " + fims::to_string(d->id) - + " to parameter " + fims::to_string(d->key[0])); - vmit = this->variable_map.find(d->key[i]); - d->x.insert(std::end(d->x), - std::begin(*(*vmit).second), std::end(*(*vmit).second)); - } - FIMS_INFO_LOG("Prior size for distribution " + fims::to_string(d->id) + "is: " + fims::to_string(d->x.size())); - } - } - } - - /** - * @brief Loop over distributions and set links to distribution x value if distribution is a random effects type. - */ - void SetupRandomEffects() { - for (density_components_iterator it = this->density_components.begin(); it != this->density_components.end(); ++it) { - std::shared_ptr > d = (*it).second; - if (d->input_type == "random_effects") { - FIMS_INFO_LOG("Setup random effects for distribution " + fims::to_string(d->id)); - variable_map_iterator vmit; - FIMS_INFO_LOG("Link random effects from distribution " - + fims::to_string(d->id) + " to derived value " + fims::to_string(d->key[0])); - vmit = this->variable_map.find(d->key[0]); - d->x = *(*vmit).second; - for (size_t i = 1; i < d->key.size(); i++) { - FIMS_INFO_LOG("Link random effects from distribution " + fims::to_string(d->id) - + " to derived value " + fims::to_string(d->key[0])); - vmit = this->variable_map.find(d->key[i]); - d->x.insert(std::end(d->x), - std::begin(*(*vmit).second), std::end(*(*vmit).second)); - } - FIMS_INFO_LOG("Random effect size for distribution " + fims::to_string(d->id) + " is: " + fims::to_string(d->x.size())); - } - } - } - - /** - * @brief Loop over distributions and set links to distribution expected value if distribution is a data type. - */ - void SetupData() { - for (density_components_iterator it = this->density_components.begin(); it != this->density_components.end(); ++it) { - std::shared_ptr > d = (*it).second; - if (d->input_type == "data") { - FIMS_INFO_LOG("Setup expected value for data distribution " + fims::to_string(d->id)); - variable_map_iterator vmit; - FIMS_INFO_LOG("Link expected value from distribution " + fims::to_string(d->id) - + " to derived value " + fims::to_string(d->key[0])); - vmit = this->variable_map.find(d->key[0]); - d->expected_values = *(*vmit).second; - - for (size_t i = 1; i < d->key.size(); i++) { - vmit = this->variable_map.find(d->key[i]); - FIMS_INFO_LOG("Link expected value from distribution " - + fims::to_string(d->id) + " to derived value " + fims::to_string(d->key[i])); - d->expected_values.insert(std::end(d->expected_values), - std::begin(*(*vmit).second), std::end(*(*vmit).second)); - } - FIMS_INFO_LOG("Expected value size for distribution " + fims::to_string(d->id) - + " is: " + fims::to_string(d->expected_values.size())); - } - } - } - - /** - * @brief Set pointers to index data in the fleet module. - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - * @param f shared pointer to fleet module - */ - void SetFleetIndexData( - bool &valid_model, - std::shared_ptr > f) { - if (f->fleet_observed_index_data_id_m != -999) { - uint32_t observed_index_id = - static_cast (f->fleet_observed_index_data_id_m); - data_iterator it = this->data_objects.find(observed_index_id); - if (it != this->data_objects.end()) { - f->observed_index_data = (*it).second; - FIMS_INFO_LOG("Index data for fleet " - + fims::to_string(f->id) + " successfully set to " - + fims::to_string(f->observed_index_data->at(1))); - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected index data not defined for fleet " - + fims::to_string(f->id) + ", index " - + fims::to_string(observed_index_id)); - } - } else { - valid_model = false; - // TODO: explore why index data is required because it should not be - FIMS_ERROR_LOG("No index data observed for fleet " - + fims::to_string(f->id) + ". FIMS requires index data for all fleets."); - } - } - - /** - * @brief Set pointers to age composition data in the fleet module. - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - * @param f shared pointer to fleet module - */ - void SetAgeCompositionData( - bool &valid_model, - std::shared_ptr > f) { - if (f->fleet_observed_agecomp_data_id_m != -999) { - uint32_t observed_agecomp_id = - static_cast (f->fleet_observed_agecomp_data_id_m); - data_iterator it = this->data_objects.find(observed_agecomp_id); - if (it != this->data_objects.end()) { - f->observed_agecomp_data = (*it).second; - FIMS_INFO_LOG("Observed input age-composition data for fleet " - + fims::to_string(f->id) + " successfully set to " - + fims::to_string(f->observed_agecomp_data->at(1))); - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected age-composition observations not defined for fleet " - + fims::to_string(f->id)); - } - } - } - - /** - * @brief Set pointers to length composition data in the fleet module. - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - * @param f shared pointer to fleet module - */ - void SetLengthCompositionData( - bool &valid_model, - std::shared_ptr > f) { - if (f->fleet_observed_lengthcomp_data_id_m != -999) { - uint32_t observed_lengthcomp_id = - static_cast (f->fleet_observed_lengthcomp_data_id_m); - data_iterator it = this->data_objects.find(observed_lengthcomp_id); - if (it != this->data_objects.end()) { - f->observed_lengthcomp_data = (*it).second; - FIMS_INFO_LOG("Observed input length-composition data for fleet " - + fims::to_string(f->id) + " successfully set to " - + fims::to_string(f->observed_lengthcomp_data->at(1))); - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected length-composition observations not defined for fleet " - + fims::to_string(f->id)); - } - } - } - - /** - * @brief Set pointers to the selectivity module referenced in the fleet module. - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - * @param f shared pointer to fleet module - */ - void SetFleetSelectivityModel( - bool &valid_model, - std::shared_ptr > f) { - if (f->fleet_selectivity_id_m != -999) { - uint32_t sel_id = static_cast ( - f->fleet_selectivity_id_m); // cast as unsigned integer - selectivity_models_iterator it = this->selectivity_models.find( - sel_id); // if find, set it, otherwise invalid - - if (it != this->selectivity_models.end()) { - f->selectivity = (*it).second; // elements in container held in pair - FIMS_INFO_LOG("Selectivity model " - + fims::to_string(f->fleet_selectivity_id_m) - + " successfully set to fleet " + fims::to_string(f->id)); - - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected selectivity pattern not defined for fleet " - + fims::to_string(f->id) + ", selectivity pattern " + fims::to_string(sel_id)); - } - - } else { - valid_model = false; - FIMS_ERROR_LOG("Error: No selectivity pattern defined for fleet " + fims::to_string(f->id) - + ". FIMS requires selectivity be defined for all fleets."); - } - } - - /** - * @brief Set pointers to the recruitment module referened in the population module. - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - * @param p shared pointer to population module - */ - void SetRecruitment( - bool &valid_model, - std::shared_ptr > p) { - if (p->recruitment_id != -999) { - uint32_t recruitment_uint = static_cast (p->recruitment_id); - recruitment_models_iterator it = - this->recruitment_models.find(recruitment_uint); - - if (it != this->recruitment_models.end()) { - p->recruitment = - (*it).second; // recruitment defined in population.hpp - FIMS_INFO_LOG("Recruitment model " - + fims::to_string(recruitment_uint) - + " successfully set to population " - + fims::to_string(p->id)); - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected recruitment function not defined for " - "population " - + fims::to_string(p->id) + ", recruitment function " - + fims::to_string(recruitment_uint)); - } - - } else { - valid_model = false; - FIMS_ERROR_LOG("No recruitment function defined for population " - + fims::to_string(p->id) - + ". FIMS requires recruitment functions be defined for all " - "populations."); - } - } - - /** - * @brief Set pointers to the growth module referened in the population module. - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - * @param p shared pointer to population module - */ - void SetGrowth( - bool &valid_model, - std::shared_ptr > p) { - if (p->growth_id != -999) { - uint32_t growth_uint = static_cast (p->growth_id); - growth_models_iterator it = this->growth_models.find( - growth_uint); // growth_models is specified in information.hpp - // and used in rcpp - // at the head of information.hpp; are the - // dimensions of ages defined in rcpp or where? - if (it != this->growth_models.end()) { - p->growth = - (*it).second; // growth defined in population.hpp (the object - // is called p, growth is within p) - FIMS_INFO_LOG("Growth model " - + fims::to_string(growth_uint) - + " successfully set to population " + fims::to_string(p->id)); - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected growth function not defined for population " - + fims::to_string(p->id) + ", growth function " - + fims::to_string(growth_uint)); - } - - } else { - valid_model = false; - FIMS_ERROR_LOG("No growth function defined for population " - + fims::to_string(p->id) - + ". FIMS requires growth functions be defined for all " - "populations."); - } - } - - /** - * @brief Set pointers to the maturity module referened in the population module. - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - * @param p shared pointer to population module - */ - void SetMaturity( - bool &valid_model, - std::shared_ptr > p) { - if (p->maturity_id != -999) { - uint32_t maturity_uint = static_cast (p->maturity_id); - maturity_models_iterator it = this->maturity_models.find( - maturity_uint); // >maturity_models is specified in - // information.hpp and used in rcpp - if (it != this->maturity_models.end()) { - p->maturity = (*it).second; // >maturity defined in population.hpp - FIMS_INFO_LOG("Maturity model " - + fims::to_string(maturity_uint) - + " successfully set to population " + fims::to_string(p->id)); - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected maturity function not defined for population " - + fims::to_string(p->id) + ", maturity function " - + fims::to_string(maturity_uint)); - } - } else { - - valid_model = false; - FIMS_ERROR_LOG("No maturity function defined for population " - + fims::to_string(p->id) - + ". FIMS requires maturity functions be defined for all " - "populations."); - } - } - - /** - * @brief Loop over all fleets and set pointers to fleet objects - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - */ - void CreateFleetObjects(bool &valid_model) { - for (fleet_iterator it = this->fleets.begin(); it != this->fleets.end(); - ++it) { - - std::shared_ptr > f = (*it).second; - FIMS_INFO_LOG("Initializing fleet " + fims::to_string(f->id)); - - f->Initialize(f->nyears, f->nages, f->nlengths); - - SetFleetIndexData(valid_model, f); - - SetAgeCompositionData(valid_model, f); - - SetLengthCompositionData(valid_model, f); - - SetFleetSelectivityModel(valid_model, f); - } - } - - /** - * @brief Loop over all density components and set pointers to data objects - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - */ - void SetDataObjects(bool &valid_model) { - for (density_components_iterator it = this->density_components.begin(); - it != this->density_components.end(); ++it) { - std::shared_ptr > d = (*it).second; - - //set data objects if distribution is a data type - if (d->input_type == "data") { - if (d->observed_data_id_m != -999) { - uint32_t observed_data_id = static_cast (d->observed_data_id_m); - data_iterator it = this->data_objects.find(observed_data_id); - - if (it != this->data_objects.end()) { - d->observed_values = (*it).second; - FIMS_INFO_LOG("Observed data " - + fims::to_string(observed_data_id) - + " successfully set to density component " + fims::to_string(d->id)); - } else { - valid_model = false; - FIMS_ERROR_LOG("Expected data observations not defined for density component " - + fims::to_string(d->id) + ", observed data " + fims::to_string(observed_data_id)); - } - - } else { - valid_model = false; - FIMS_ERROR_LOG("No data input for density component" + fims::to_string(d->id)); - } - } - } - - } - - /** - * @brief Loop over all populations and set pointers to population objects - * - * @param &valid_model reference to true/false boolean indicating whether model is valid. - */ - void CreatePopulationObjects(bool &valid_model) { - for (population_iterator it = this->populations.begin(); - it != this->populations.end(); ++it) { - std::shared_ptr > p = (*it).second; - - FIMS_INFO_LOG("Initializing population " + fims::to_string(p->id)); - // error check and set population elements - // check me - add another fleet iterator to push information from - for (fleet_iterator it = this->fleets.begin(); it != this->fleets.end(); - ++it) { - // Initialize fleet object - std::shared_ptr > f = (*it).second; - // population to the individual fleets This is to pass catch at age - // from population to fleets? - // any shared member in p (population is pushed into fleets) - p->fleets.push_back(f); - } - - p->Initialize(p->nyears, p->nseasons, p->nages); - - //set information dimensions - this->nyears = std::max(this->nyears, p->nyears); - this->nages = std::max(this->nages, p->nages); - this->nseasons = std::max(this->nseasons, p->nseasons); - - SetRecruitment(valid_model, p); - - SetGrowth(valid_model, p); - - SetMaturity(valid_model, p); - - } - } - - /** - * @brief Create the generalized stock assessment model that will evaluate the - * objective function. Does error checking to make sure the program has - * all necessary components for the model and that they're in the right - * dimensions. This sets up pointers to all memory objects and initializes - * fleet and population objects. - * - * @return True if valid model, False if invalid model, check fims.log for - * errors. - */ - bool CreateModel() { - bool valid_model = true; - - CreateFleetObjects(valid_model); - - SetDataObjects(valid_model); - - CreatePopulationObjects(valid_model); - - //setup priors, random effect, and data density components - SetupPriors(); - - return valid_model; - } - - /** - * @brief Get the Nages object - * - * @return size_t - */ - size_t GetNages() const { - - return nages; - } - - /** - * @brief Set the Nages object - * - * @param nages - */ - void SetNages(size_t nages) { - - this->nages = nages; - } - - /** - * @brief Get the Nseasons object - * - * @return size_t - */ - size_t GetNseasons() const { - - return nseasons; - } - - /** - * @brief Set the Nseasons object - * - * @param nseasons - */ - void SetNseasons(size_t nseasons) { - - this->nseasons = nseasons; - } - - /** - * @brief Get the Nyears object - * - * @return size_t - */ - size_t GetNyears() const { - - return nyears; + typedef typename std::map< + uint32_t, std::shared_ptr > >::iterator + growth_models_iterator; + /**< iterator for growth objects>*/ + + std::map > > + maturity_models; /** > >::iterator + maturity_models_iterator; + /**< iterator for maturity objects>*/ + + // fleet modules + std::map > > + fleets; /** > >::iterator + fleet_iterator; + /**< iterator for fleet objects>*/ + + // populations + std::map > > + populations; /** > >::iterator + population_iterator; + /**< iterator for population objects>*/ + + // distributions + std::map > > + density_components; /** > >:: + iterator density_components_iterator; + /**< iterator for distribution objects>*/ + + std::unordered_map *> + variable_map; /** *>::iterator + variable_map_iterator; /**< iterator for variable map>*/ + + Information() {} + + virtual ~Information() {} + + /** + * @brief Clears all containers. + * + */ + void Clear() { + this->data_objects.clear(); + this->density_components.clear(); + this->fixed_effects_parameters.clear(); + this->fleets.clear(); + this->growth_models.clear(); + this->maturity_models.clear(); + this->parameter_names.clear(); + this->parameters.clear(); + this->random_effects_parameters.clear(); + this->recruitment_models.clear(); + this->selectivity_models.clear(); + this->variable_map.clear(); + this->nyears = 0; + this->nseasons = 0; + this->nages = 0; + } + + /** + * @brief Returns a singleton Information object for type T. + * + * @return singleton for type T + */ + static std::shared_ptr > GetInstance() { + if (Information::fims_information == nullptr) { + Information::fims_information = + std::make_shared >(); + } + return Information::fims_information; + } + + /** + * @brief Register a parameter as estimable. + * + * @param p + */ + void RegisterParameter(Type &p) { + this->fixed_effects_parameters.push_back(&p); + } + + /** + * @brief Register a random effect as estimable. + * + * @param re + */ + void RegisterRandomEffect(Type &re) { + this->random_effects_parameters.push_back(&re); + } + + /** + * @brief Register a parameter name. + * + * @param p_name + */ + void RegisterParameterName(std::string p_name) { + this->parameter_names.push_back(p_name); + } + + /** + * @brief Loop over distributions and set links to distribution x value if + * distribution is a prior type. + */ + void SetupPriors() { + for (density_components_iterator it = density_components.begin(); + it != density_components.end(); ++it) { + std::shared_ptr > d = + (*it).second; + if (d->input_type == "prior") { + FIMS_INFO_LOG("Setup prior for distribution " + fims::to_string(d->id)); + variable_map_iterator vmit; + FIMS_INFO_LOG("Link prior from distribution " + fims::to_string(d->id) + + " to parameter " + fims::to_string(d->key[0])); + vmit = this->variable_map.find(d->key[0]); + d->x = *(*vmit).second; + for (size_t i = 1; i < d->key.size(); i++) { + FIMS_INFO_LOG("Link prior from distribution " + + fims::to_string(d->id) + " to parameter " + + fims::to_string(d->key[0])); + vmit = this->variable_map.find(d->key[i]); + d->x.insert(std::end(d->x), std::begin(*(*vmit).second), + std::end(*(*vmit).second)); } - - /** - * @brief Set the Nyears object - * - * @param nyears - */ - void SetNyears(size_t nyears) { - - this->nyears = nyears; - } - - /** - * @brief Get the Parameters object - * - * @return std::vector& - */ - std::vector& GetParameters() { - - return parameters; + FIMS_INFO_LOG("Prior size for distribution " + fims::to_string(d->id) + + "is: " + fims::to_string(d->x.size())); + } + } + } + + /** + * @brief Loop over distributions and set links to distribution x value if + * distribution is a random effects type. + */ + void SetupRandomEffects() { + for (density_components_iterator it = this->density_components.begin(); + it != this->density_components.end(); ++it) { + std::shared_ptr > d = + (*it).second; + if (d->input_type == "random_effects") { + FIMS_INFO_LOG("Setup random effects for distribution " + + fims::to_string(d->id)); + variable_map_iterator vmit; + FIMS_INFO_LOG("Link random effects from distribution " + + fims::to_string(d->id) + " to derived value " + + fims::to_string(d->key[0])); + vmit = this->variable_map.find(d->key[0]); + d->x = *(*vmit).second; + for (size_t i = 1; i < d->key.size(); i++) { + FIMS_INFO_LOG("Link random effects from distribution " + + fims::to_string(d->id) + " to derived value " + + fims::to_string(d->key[0])); + vmit = this->variable_map.find(d->key[i]); + d->x.insert(std::end(d->x), std::begin(*(*vmit).second), + std::end(*(*vmit).second)); } - - /** - * @brief Get the Fixed Effects Parameters object - * - * @return std::vector& - */ - std::vector& GetFixedEffectsParameters() { - - return fixed_effects_parameters; + FIMS_INFO_LOG("Random effect size for distribution " + + fims::to_string(d->id) + + " is: " + fims::to_string(d->x.size())); + } + } + } + + /** + * @brief Loop over distributions and set links to distribution expected value + * if distribution is a data type. + */ + void SetupData() { + for (density_components_iterator it = this->density_components.begin(); + it != this->density_components.end(); ++it) { + std::shared_ptr > d = + (*it).second; + if (d->input_type == "data") { + FIMS_INFO_LOG("Setup expected value for data distribution " + + fims::to_string(d->id)); + variable_map_iterator vmit; + FIMS_INFO_LOG("Link expected value from distribution " + + fims::to_string(d->id) + " to derived value " + + fims::to_string(d->key[0])); + vmit = this->variable_map.find(d->key[0]); + d->expected_values = *(*vmit).second; + + for (size_t i = 1; i < d->key.size(); i++) { + vmit = this->variable_map.find(d->key[i]); + FIMS_INFO_LOG("Link expected value from distribution " + + fims::to_string(d->id) + " to derived value " + + fims::to_string(d->key[i])); + d->expected_values.insert(std::end(d->expected_values), + std::begin(*(*vmit).second), + std::end(*(*vmit).second)); } - - /** - * @brief Get the Random Effects Parameters object - * - * @return std::vector& - */ - std::vector& GetRandomEffectsParameters() { - return random_effects_parameters; + FIMS_INFO_LOG("Expected value size for distribution " + + fims::to_string(d->id) + + " is: " + fims::to_string(d->expected_values.size())); + } + } + } + + /** + * @brief Set pointers to index data in the fleet module. + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + * @param f shared pointer to fleet module + */ + void SetFleetIndexData(bool &valid_model, + std::shared_ptr > f) { + if (f->fleet_observed_index_data_id_m != -999) { + uint32_t observed_index_id = + static_cast(f->fleet_observed_index_data_id_m); + data_iterator it = this->data_objects.find(observed_index_id); + if (it != this->data_objects.end()) { + f->observed_index_data = (*it).second; + FIMS_INFO_LOG("Index data for fleet " + fims::to_string(f->id) + + " successfully set to " + + fims::to_string(f->observed_index_data->at(1))); + } else { + valid_model = false; + FIMS_ERROR_LOG("Expected index data not defined for fleet " + + fims::to_string(f->id) + ", index " + + fims::to_string(observed_index_id)); + } + } else { + valid_model = false; + // TODO: explore why index data is required because it should not be + FIMS_ERROR_LOG("No index data observed for fleet " + + fims::to_string(f->id) + + ". FIMS requires index data for all fleets."); + } + } + + /** + * @brief Set pointers to age composition data in the fleet module. + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + * @param f shared pointer to fleet module + */ + void SetAgeCompositionData(bool &valid_model, + std::shared_ptr > f) { + if (f->fleet_observed_agecomp_data_id_m != -999) { + uint32_t observed_agecomp_id = + static_cast(f->fleet_observed_agecomp_data_id_m); + data_iterator it = this->data_objects.find(observed_agecomp_id); + if (it != this->data_objects.end()) { + f->observed_agecomp_data = (*it).second; + FIMS_INFO_LOG("Observed input age-composition data for fleet " + + fims::to_string(f->id) + " successfully set to " + + fims::to_string(f->observed_agecomp_data->at(1))); + } else { + valid_model = false; + FIMS_ERROR_LOG( + "Expected age-composition observations not defined for fleet " + + fims::to_string(f->id)); + } + } + } + + /** + * @brief Set pointers to length composition data in the fleet module. + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + * @param f shared pointer to fleet module + */ + void SetLengthCompositionData(bool &valid_model, + std::shared_ptr > f) { + if (f->fleet_observed_lengthcomp_data_id_m != -999) { + uint32_t observed_lengthcomp_id = + static_cast(f->fleet_observed_lengthcomp_data_id_m); + data_iterator it = this->data_objects.find(observed_lengthcomp_id); + if (it != this->data_objects.end()) { + f->observed_lengthcomp_data = (*it).second; + FIMS_INFO_LOG("Observed input length-composition data for fleet " + + fims::to_string(f->id) + " successfully set to " + + fims::to_string(f->observed_lengthcomp_data->at(1))); + } else { + valid_model = false; + FIMS_ERROR_LOG( + "Expected length-composition observations not defined for fleet " + + fims::to_string(f->id)); + } + } + } + + /** + * @brief Set pointers to the selectivity module referenced in the fleet + * module. + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + * @param f shared pointer to fleet module + */ + void SetFleetSelectivityModel(bool &valid_model, + std::shared_ptr > f) { + if (f->fleet_selectivity_id_m != -999) { + uint32_t sel_id = static_cast( + f->fleet_selectivity_id_m); // cast as unsigned integer + selectivity_models_iterator it = this->selectivity_models.find( + sel_id); // if find, set it, otherwise invalid + + if (it != this->selectivity_models.end()) { + f->selectivity = (*it).second; // elements in container held in pair + FIMS_INFO_LOG("Selectivity model " + + fims::to_string(f->fleet_selectivity_id_m) + + " successfully set to fleet " + fims::to_string(f->id)); + + } else { + valid_model = false; + FIMS_ERROR_LOG("Expected selectivity pattern not defined for fleet " + + fims::to_string(f->id) + ", selectivity pattern " + + fims::to_string(sel_id)); + } + + } else { + valid_model = false; + FIMS_ERROR_LOG("Error: No selectivity pattern defined for fleet " + + fims::to_string(f->id) + + ". FIMS requires selectivity be defined for all fleets."); + } + } + + /** + * @brief Set pointers to the recruitment module referened in the population + * module. + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + * @param p shared pointer to population module + */ + void SetRecruitment(bool &valid_model, + std::shared_ptr > p) { + if (p->recruitment_id != -999) { + uint32_t recruitment_uint = static_cast(p->recruitment_id); + recruitment_models_iterator it = + this->recruitment_models.find(recruitment_uint); + + if (it != this->recruitment_models.end()) { + p->recruitment = (*it).second; // recruitment defined in population.hpp + FIMS_INFO_LOG("Recruitment model " + fims::to_string(recruitment_uint) + + " successfully set to population " + + fims::to_string(p->id)); + } else { + valid_model = false; + FIMS_ERROR_LOG( + "Expected recruitment function not defined for " + "population " + + fims::to_string(p->id) + ", recruitment function " + + fims::to_string(recruitment_uint)); + } + + } else { + valid_model = false; + FIMS_ERROR_LOG("No recruitment function defined for population " + + fims::to_string(p->id) + + ". FIMS requires recruitment functions be defined for all " + "populations."); + } + } + + /** + * @brief Set pointers to the growth module referened in the population + * module. + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + * @param p shared pointer to population module + */ + void SetGrowth(bool &valid_model, + std::shared_ptr > p) { + if (p->growth_id != -999) { + uint32_t growth_uint = static_cast(p->growth_id); + growth_models_iterator it = this->growth_models.find( + growth_uint); // growth_models is specified in information.hpp + // and used in rcpp + // at the head of information.hpp; are the + // dimensions of ages defined in rcpp or where? + if (it != this->growth_models.end()) { + p->growth = + (*it).second; // growth defined in population.hpp (the object + // is called p, growth is within p) + FIMS_INFO_LOG("Growth model " + fims::to_string(growth_uint) + + " successfully set to population " + + fims::to_string(p->id)); + } else { + valid_model = false; + FIMS_ERROR_LOG("Expected growth function not defined for population " + + fims::to_string(p->id) + ", growth function " + + fims::to_string(growth_uint)); + } + + } else { + valid_model = false; + FIMS_ERROR_LOG("No growth function defined for population " + + fims::to_string(p->id) + + ". FIMS requires growth functions be defined for all " + "populations."); + } + } + + /** + * @brief Set pointers to the maturity module referened in the population + * module. + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + * @param p shared pointer to population module + */ + void SetMaturity(bool &valid_model, + std::shared_ptr > p) { + if (p->maturity_id != -999) { + uint32_t maturity_uint = static_cast(p->maturity_id); + maturity_models_iterator it = this->maturity_models.find( + maturity_uint); // >maturity_models is specified in + // information.hpp and used in rcpp + if (it != this->maturity_models.end()) { + p->maturity = (*it).second; // >maturity defined in population.hpp + FIMS_INFO_LOG("Maturity model " + fims::to_string(maturity_uint) + + " successfully set to population " + + fims::to_string(p->id)); + } else { + valid_model = false; + FIMS_ERROR_LOG( + "Expected maturity function not defined for population " + + fims::to_string(p->id) + ", maturity function " + + fims::to_string(maturity_uint)); + } + } else { + valid_model = false; + FIMS_ERROR_LOG("No maturity function defined for population " + + fims::to_string(p->id) + + ". FIMS requires maturity functions be defined for all " + "populations."); + } + } + + /** + * @brief Loop over all fleets and set pointers to fleet objects + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + */ + void CreateFleetObjects(bool &valid_model) { + for (fleet_iterator it = this->fleets.begin(); it != this->fleets.end(); + ++it) { + std::shared_ptr > f = (*it).second; + FIMS_INFO_LOG("Initializing fleet " + fims::to_string(f->id)); + + f->Initialize(f->nyears, f->nages, f->nlengths); + + SetFleetIndexData(valid_model, f); + + SetAgeCompositionData(valid_model, f); + + SetLengthCompositionData(valid_model, f); + + SetFleetSelectivityModel(valid_model, f); + } + } + + /** + * @brief Loop over all density components and set pointers to data objects + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + */ + void SetDataObjects(bool &valid_model) { + for (density_components_iterator it = this->density_components.begin(); + it != this->density_components.end(); ++it) { + std::shared_ptr > d = + (*it).second; + + // set data objects if distribution is a data type + if (d->input_type == "data") { + if (d->observed_data_id_m != -999) { + uint32_t observed_data_id = + static_cast(d->observed_data_id_m); + data_iterator it = this->data_objects.find(observed_data_id); + + if (it != this->data_objects.end()) { + d->observed_values = (*it).second; + FIMS_INFO_LOG("Observed data " + fims::to_string(observed_data_id) + + " successfully set to density component " + + fims::to_string(d->id)); + } else { + valid_model = false; + FIMS_ERROR_LOG( + "Expected data observations not defined for density " + "component " + + fims::to_string(d->id) + ", observed data " + + fims::to_string(observed_data_id)); + } + + } else { + valid_model = false; + FIMS_ERROR_LOG("No data input for density component" + + fims::to_string(d->id)); } - }; - - template - std::shared_ptr > Information::fims_information = - nullptr; // singleton instance - -} // namespace fims_info + } + } + } + + /** + * @brief Loop over all populations and set pointers to population objects + * + * @param &valid_model reference to true/false boolean indicating whether + * model is valid. + */ + void CreatePopulationObjects(bool &valid_model) { + for (population_iterator it = this->populations.begin(); + it != this->populations.end(); ++it) { + std::shared_ptr > p = (*it).second; + + FIMS_INFO_LOG("Initializing population " + fims::to_string(p->id)); + // error check and set population elements + // check me - add another fleet iterator to push information from + for (fleet_iterator it = this->fleets.begin(); it != this->fleets.end(); + ++it) { + // Initialize fleet object + std::shared_ptr > f = (*it).second; + // population to the individual fleets This is to pass catch at age + // from population to fleets? + // any shared member in p (population is pushed into fleets) + p->fleets.push_back(f); + } + + p->Initialize(p->nyears, p->nseasons, p->nages); + + // set information dimensions + this->nyears = std::max(this->nyears, p->nyears); + this->nages = std::max(this->nages, p->nages); + this->nseasons = std::max(this->nseasons, p->nseasons); + + SetRecruitment(valid_model, p); + + SetGrowth(valid_model, p); + + SetMaturity(valid_model, p); + } + } + + /** + * @brief Create the generalized stock assessment model that will evaluate the + * objective function. Does error checking to make sure the program has + * all necessary components for the model and that they're in the right + * dimensions. This sets up pointers to all memory objects and initializes + * fleet and population objects. + * + * @return True if valid model, False if invalid model, check fims.log for + * errors. + */ + bool CreateModel() { + bool valid_model = true; + + CreateFleetObjects(valid_model); + + SetDataObjects(valid_model); + + CreatePopulationObjects(valid_model); + + // setup priors, random effect, and data density components + SetupPriors(); + + return valid_model; + } + + /** + * @brief Get the Nages object + * + * @return size_t + */ + size_t GetNages() const { return nages; } + + /** + * @brief Set the Nages object + * + * @param nages + */ + void SetNages(size_t nages) { this->nages = nages; } + + /** + * @brief Get the Nseasons object + * + * @return size_t + */ + size_t GetNseasons() const { return nseasons; } + + /** + * @brief Set the Nseasons object + * + * @param nseasons + */ + void SetNseasons(size_t nseasons) { this->nseasons = nseasons; } + + /** + * @brief Get the Nyears object + * + * @return size_t + */ + size_t GetNyears() const { return nyears; } + + /** + * @brief Set the Nyears object + * + * @param nyears + */ + void SetNyears(size_t nyears) { this->nyears = nyears; } + + /** + * @brief Get the Parameters object + * + * @return std::vector& + */ + std::vector &GetParameters() { return parameters; } + + /** + * @brief Get the Fixed Effects Parameters object + * + * @return std::vector& + */ + std::vector &GetFixedEffectsParameters() { + return fixed_effects_parameters; + } + + /** + * @brief Get the Random Effects Parameters object + * + * @return std::vector& + */ + std::vector &GetRandomEffectsParameters() { + return random_effects_parameters; + } +}; + +template +std::shared_ptr > Information::fims_information = + nullptr; // singleton instance + +} // namespace fims_info #endif /* FIMS_COMMON_INFORMATION_HPP */ diff --git a/inst/include/common/model.hpp b/inst/include/common/model.hpp index 5aa5bf2c..b367af79 100644 --- a/inst/include/common/model.hpp +++ b/inst/include/common/model.hpp @@ -15,273 +15,270 @@ namespace fims_model { - /** - * @brief Model class. FIMS objective function. - */ - template - class Model { // may need singleton - public: - static std::shared_ptr > - fims_model; /**< Create a shared fims_model as a pointer to Model*/ - std::shared_ptr > - fims_information; /**< Create a shared fims_information as a pointer to - Information*/ +/** + * @brief Model class. FIMS objective function. + */ +template +class Model { // may need singleton + public: + static std::shared_ptr > + fims_model; /**< Create a shared fims_model as a pointer to Model*/ + std::shared_ptr > + fims_information; /**< Create a shared fims_information as a pointer to + Information*/ #ifdef TMB_MODEL - ::objective_function *of; + ::objective_function *of; #endif - // constructor - - virtual ~Model() { - } - - /** - * Returns a single Information object for type Type. - * - * @return singleton for type Type - */ - static std::shared_ptr > GetInstance() { - if (Model::fims_model == nullptr) { - Model::fims_model = std::make_shared >(); - Model::fims_model->fims_information = - fims_info::Information::GetInstance(); - } - return Model::fims_model; - } - - /** - * @brief Evaluate. Calculates the joint negative log-likelihood function. - */ - const Type Evaluate() { - // jnll = negative-log-likelihood (the objective function) - Type jnll = 0.0; - - - int n_fleets = fims_information->fleets.size(); - int n_pops = fims_information->populations.size(); - - // Create vector lists to store output for reporting + // constructor + + virtual ~Model() {} + + /** + * Returns a single Information object for type Type. + * + * @return singleton for type Type + */ + static std::shared_ptr > GetInstance() { + if (Model::fims_model == nullptr) { + Model::fims_model = std::make_shared >(); + Model::fims_model->fims_information = + fims_info::Information::GetInstance(); + } + return Model::fims_model; + } + + /** + * @brief Evaluate. Calculates the joint negative log-likelihood function. + */ + const Type Evaluate() { + // jnll = negative-log-likelihood (the objective function) + Type jnll = 0.0; + + int n_fleets = fims_information->fleets.size(); + int n_pops = fims_information->populations.size(); + + // Create vector lists to store output for reporting #ifdef TMB_MODEL - // vector< vector > creates a nested vector structure where - // each vector can be a different dimension. Does not work with ADREPORT - // fleets - vector > exp_index(n_fleets); - vector > exp_catch(n_fleets); - vector > cnaa(n_fleets); - vector > cwaa(n_fleets); - vector > cnal(n_fleets); - vector > pcnaa(n_fleets); - vector > pcnal(n_fleets); - vector > F_mort(n_fleets); - vector > q(n_fleets); - // populations - vector > naa(n_pops); - vector > ssb(n_pops); - vector > biomass(n_pops); - vector > log_recruit_dev(n_pops); - vector > recruitment(n_pops); - vector > M(n_pops); - vector nll_components(this->fims_information->density_components.size()); + // vector< vector > creates a nested vector structure where + // each vector can be a different dimension. Does not work with ADREPORT + // fleets + vector > exp_index(n_fleets); + vector > exp_catch(n_fleets); + vector > cnaa(n_fleets); + vector > cwaa(n_fleets); + vector > cnal(n_fleets); + vector > pcnaa(n_fleets); + vector > pcnal(n_fleets); + vector > F_mort(n_fleets); + vector > q(n_fleets); + // populations + vector > naa(n_pops); + vector > ssb(n_pops); + vector > biomass(n_pops); + vector > log_recruit_dev(n_pops); + vector > recruitment(n_pops); + vector > M(n_pops); + vector nll_components( + this->fims_information->density_components.size()); #endif - // Loop over densities and evaluate joint negative log densities for priors - typename fims_info::Information::density_components_iterator d_it; - nll_components.fill(0); - int nll_components_idx = 0; - size_t n_priors = 0; - - for (d_it = this->fims_information->density_components.begin(); - d_it != this->fims_information->density_components.end(); ++d_it) { - std::shared_ptr > d = (*d_it).second; + // Loop over densities and evaluate joint negative log densities for priors + typename fims_info::Information::density_components_iterator d_it; + nll_components.fill(0); + int nll_components_idx = 0; + size_t n_priors = 0; + + for (d_it = this->fims_information->density_components.begin(); + d_it != this->fims_information->density_components.end(); ++d_it) { + std::shared_ptr > d = + (*d_it).second; #ifdef TMB_MODEL - d->of = this->of; + d->of = this->of; #endif - if (d->input_type == "prior") { - nll_components[nll_components_idx] = -d->evaluate(); - jnll += nll_components[nll_components_idx]; - n_priors += 1; - nll_components_idx += 1; - } - } - - - - // Loop over populations and evaluate recruitment component - - typename fims_info::Information::population_iterator p_it; - - - for (p_it = this->fims_information->populations.begin(); - p_it != this->fims_information->populations.end(); ++p_it) { - //(*p_it).second points to the Population module - std::shared_ptr > p = (*p_it).second; - - // Prepare recruitment - p->recruitment->Prepare(); - - } - - // Loop over densities and evaluate joint negative log-likelihoods for random effects - this->fims_information->SetupRandomEffects(); - size_t n_random_effects = 0; - for (d_it = this->fims_information->density_components.begin(); - d_it != this->fims_information->density_components.end(); ++d_it) { - std::shared_ptr > d = (*d_it).second; + if (d->input_type == "prior") { + nll_components[nll_components_idx] = -d->evaluate(); + jnll += nll_components[nll_components_idx]; + n_priors += 1; + nll_components_idx += 1; + } + } + + // Loop over populations and evaluate recruitment component + + typename fims_info::Information::population_iterator p_it; + + for (p_it = this->fims_information->populations.begin(); + p_it != this->fims_information->populations.end(); ++p_it) { + //(*p_it).second points to the Population module + std::shared_ptr > p = (*p_it).second; + + // Prepare recruitment + p->recruitment->Prepare(); + } + + // Loop over densities and evaluate joint negative log-likelihoods for + // random effects + this->fims_information->SetupRandomEffects(); + size_t n_random_effects = 0; + for (d_it = this->fims_information->density_components.begin(); + d_it != this->fims_information->density_components.end(); ++d_it) { + std::shared_ptr > d = + (*d_it).second; #ifdef TMB_MODEL - d->of = this->of; + d->of = this->of; #endif - if (d->input_type == "random_effects") { - nll_components[nll_components_idx] = -d->evaluate(); - jnll += nll_components[nll_components_idx]; - n_random_effects += 1; - nll_components_idx += 1; - } - } - - - // Loop over and evaluate populations - for (p_it = this->fims_information->populations.begin(); - p_it != this->fims_information->populations.end(); ++p_it) { - //(*p_it).second points to the Population module - std::shared_ptr > p = (*p_it).second; - // link to TMB objective function + if (d->input_type == "random_effects") { + nll_components[nll_components_idx] = -d->evaluate(); + jnll += nll_components[nll_components_idx]; + n_random_effects += 1; + nll_components_idx += 1; + } + } + + // Loop over and evaluate populations + for (p_it = this->fims_information->populations.begin(); + p_it != this->fims_information->populations.end(); ++p_it) { + //(*p_it).second points to the Population module + std::shared_ptr > p = (*p_it).second; + // link to TMB objective function #ifdef TMB_MODEL - p->of = this->of; + p->of = this->of; #endif - // Evaluate population - p->Evaluate(); - } - - typename fims_info::Information::fleet_iterator f_it; - // Loop over fleets/surveys, and evaluate age comp and index expected values - for (f_it = this->fims_information->fleets.begin(); - f_it != this->fims_information->fleets.end(); ++f_it) { - //(*f_it).second points to each individual Fleet module - std::shared_ptr > f = (*f_it).second; + // Evaluate population + p->Evaluate(); + } + + typename fims_info::Information::fleet_iterator f_it; + // Loop over fleets/surveys, and evaluate age comp and index expected values + for (f_it = this->fims_information->fleets.begin(); + f_it != this->fims_information->fleets.end(); ++f_it) { + //(*f_it).second points to each individual Fleet module + std::shared_ptr > f = (*f_it).second; #ifdef TMB_MODEL - f->of = this->of; + f->of = this->of; #endif - f->evaluate_age_comp(); - if (f->nlengths > 0) { - f->evaluate_length_comp(); - } - f->evaluate_index(); - } - this->fims_information->SetupData(); - // Loop over and evaluate data joint negative log-likelihoods - int n_data = 0; - for (d_it = this->fims_information->density_components.begin(); - d_it != this->fims_information->density_components.end(); ++d_it) { - std::shared_ptr > d = (*d_it).second; + f->evaluate_age_comp(); + if (f->nlengths > 0) { + f->evaluate_length_comp(); + } + f->evaluate_index(); + } + this->fims_information->SetupData(); + // Loop over and evaluate data joint negative log-likelihoods + int n_data = 0; + for (d_it = this->fims_information->density_components.begin(); + d_it != this->fims_information->density_components.end(); ++d_it) { + std::shared_ptr > d = + (*d_it).second; #ifdef TMB_MODEL - d->of = this->of; - //d->keep = this->keep; + d->of = this->of; + // d->keep = this->keep; #endif - if (d->input_type == "data") { - nll_components[nll_components_idx] = -d->evaluate(); - jnll += nll_components[nll_components_idx]; - n_data += 1; - nll_components_idx += 1; - } - } - - // initiate population index for structuring report out objects - int pop_idx = 0; - for (p_it = this->fims_information->populations.begin(); - p_it != this->fims_information->populations.end(); ++p_it) { - std::shared_ptr > p = (*p_it).second; + if (d->input_type == "data") { + nll_components[nll_components_idx] = -d->evaluate(); + jnll += nll_components[nll_components_idx]; + n_data += 1; + nll_components_idx += 1; + } + } + + // initiate population index for structuring report out objects + int pop_idx = 0; + for (p_it = this->fims_information->populations.begin(); + p_it != this->fims_information->populations.end(); ++p_it) { + std::shared_ptr > p = (*p_it).second; #ifdef TMB_MODEL - naa(pop_idx) = vector(p->numbers_at_age); - ssb(pop_idx) = vector(p->spawning_biomass); - log_recruit_dev(pop_idx) = - vector(p->recruitment->log_recruit_devs); - recruitment(pop_idx) = vector(p->expected_recruitment); - biomass(pop_idx) = vector(p->biomass); - M(pop_idx) = vector(p->M); + naa(pop_idx) = vector(p->numbers_at_age); + ssb(pop_idx) = vector(p->spawning_biomass); + log_recruit_dev(pop_idx) = vector(p->recruitment->log_recruit_devs); + recruitment(pop_idx) = vector(p->expected_recruitment); + biomass(pop_idx) = vector(p->biomass); + M(pop_idx) = vector(p->M); #endif - pop_idx += 1; - } - - // initiate fleet index for structuring report out objects - int fleet_idx = 0; - for (f_it = this->fims_information->fleets.begin(); - f_it != this->fims_information->fleets.end(); ++f_it) { - std::shared_ptr > f = (*f_it).second; + pop_idx += 1; + } + + // initiate fleet index for structuring report out objects + int fleet_idx = 0; + for (f_it = this->fims_information->fleets.begin(); + f_it != this->fims_information->fleets.end(); ++f_it) { + std::shared_ptr > f = (*f_it).second; #ifdef TMB_MODEL - exp_index(fleet_idx) = f->expected_index; - exp_catch(fleet_idx) = f->expected_catch; - F_mort(fleet_idx) = f->Fmort; - q(fleet_idx) = f->q; - cnaa(fleet_idx) = f->catch_numbers_at_age; - cnal(fleet_idx) = f->catch_numbers_at_length; - pcnaa(fleet_idx) = f->proportion_catch_numbers_at_age; - pcnal(fleet_idx) = f->proportion_catch_numbers_at_length; - cwaa(fleet_idx) = f->catch_weight_at_age; + exp_index(fleet_idx) = f->expected_index; + exp_catch(fleet_idx) = f->expected_catch; + F_mort(fleet_idx) = f->Fmort; + q(fleet_idx) = f->q; + cnaa(fleet_idx) = f->catch_numbers_at_age; + cnal(fleet_idx) = f->catch_numbers_at_length; + pcnaa(fleet_idx) = f->proportion_catch_numbers_at_age; + pcnal(fleet_idx) = f->proportion_catch_numbers_at_length; + cwaa(fleet_idx) = f->catch_weight_at_age; #endif - fleet_idx += 1; - } + fleet_idx += 1; + } - // Reporting + // Reporting #ifdef TMB_MODEL - //FIMS_REPORT_F(rec_nll, of); - //FIMS_REPORT_F(age_comp_nll, of); - //FIMS_REPORT_F(index_nll, of); - FIMS_REPORT_F(jnll, of); - FIMS_REPORT_F(naa, of); - FIMS_REPORT_F(ssb, of); - FIMS_REPORT_F(log_recruit_dev, of); - FIMS_REPORT_F(recruitment, of); - FIMS_REPORT_F(biomass, of); - FIMS_REPORT_F(M, of); - FIMS_REPORT_F(exp_index, of); - FIMS_REPORT_F(exp_catch, of); - FIMS_REPORT_F(F_mort, of); - FIMS_REPORT_F(q, of); - FIMS_REPORT_F(cnaa, of); - FIMS_REPORT_F(cnal, of); - FIMS_REPORT_F(pcnaa, of); - FIMS_REPORT_F(pcnal, of); - FIMS_REPORT_F(cwaa, of); - FIMS_REPORT_F(nll_components, of); - - /*ADREPORT using ADREPORTvector defined in - * inst/include/interface/interface.hpp: - * function collapses the nested vector into a single vector - */ - vector NAA = ADREPORTvector(naa); - vector Biomass = ADREPORTvector(biomass); - vector SSB = ADREPORTvector(ssb); - vector LogRecDev = ADREPORTvector(log_recruit_dev); - vector FMort = ADREPORTvector(F_mort); - vector Q = ADREPORTvector(q); - vector ExpectedIndex = ADREPORTvector(exp_index); - vector CNAA = ADREPORTvector(cnaa); - vector CNAL = ADREPORTvector(cnal); - vector PCNAA = ADREPORTvector(pcnaa); - vector PCNAL = ADREPORTvector(pcnal); - - ADREPORT_F(NAA, of); - ADREPORT_F(Biomass, of); - ADREPORT_F(SSB, of); - ADREPORT_F(LogRecDev, of); - ADREPORT_F(FMort, of); - ADREPORT_F(Q, of); - ADREPORT_F(ExpectedIndex, of); - ADREPORT_F(CNAA, of); - ADREPORT_F(CNAL, of); - ADREPORT_F(PCNAA, of); - ADREPORT_F(PCNAL, of); + // FIMS_REPORT_F(rec_nll, of); + // FIMS_REPORT_F(age_comp_nll, of); + // FIMS_REPORT_F(index_nll, of); + FIMS_REPORT_F(jnll, of); + FIMS_REPORT_F(naa, of); + FIMS_REPORT_F(ssb, of); + FIMS_REPORT_F(log_recruit_dev, of); + FIMS_REPORT_F(recruitment, of); + FIMS_REPORT_F(biomass, of); + FIMS_REPORT_F(M, of); + FIMS_REPORT_F(exp_index, of); + FIMS_REPORT_F(exp_catch, of); + FIMS_REPORT_F(F_mort, of); + FIMS_REPORT_F(q, of); + FIMS_REPORT_F(cnaa, of); + FIMS_REPORT_F(cnal, of); + FIMS_REPORT_F(pcnaa, of); + FIMS_REPORT_F(pcnal, of); + FIMS_REPORT_F(cwaa, of); + FIMS_REPORT_F(nll_components, of); + + /*ADREPORT using ADREPORTvector defined in + * inst/include/interface/interface.hpp: + * function collapses the nested vector into a single vector + */ + vector NAA = ADREPORTvector(naa); + vector Biomass = ADREPORTvector(biomass); + vector SSB = ADREPORTvector(ssb); + vector LogRecDev = ADREPORTvector(log_recruit_dev); + vector FMort = ADREPORTvector(F_mort); + vector Q = ADREPORTvector(q); + vector ExpectedIndex = ADREPORTvector(exp_index); + vector CNAA = ADREPORTvector(cnaa); + vector CNAL = ADREPORTvector(cnal); + vector PCNAA = ADREPORTvector(pcnaa); + vector PCNAL = ADREPORTvector(pcnal); + + ADREPORT_F(NAA, of); + ADREPORT_F(Biomass, of); + ADREPORT_F(SSB, of); + ADREPORT_F(LogRecDev, of); + ADREPORT_F(FMort, of); + ADREPORT_F(Q, of); + ADREPORT_F(ExpectedIndex, of); + ADREPORT_F(CNAA, of); + ADREPORT_F(CNAL, of); + ADREPORT_F(PCNAA, of); + ADREPORT_F(PCNAL, of); #endif - return jnll; - } - }; + return jnll; + } +}; - // Create singleton instance of Model class - template - std::shared_ptr > Model::fims_model = - nullptr; // singleton instance -} // namespace fims_model +// Create singleton instance of Model class +template +std::shared_ptr > Model::fims_model = + nullptr; // singleton instance +} // namespace fims_model #endif /* FIMS_COMMON_MODEL_HPP */ diff --git a/inst/include/common/model_object.hpp b/inst/include/common/model_object.hpp index 56b21d55..2ba81dad 100644 --- a/inst/include/common/model_object.hpp +++ b/inst/include/common/model_object.hpp @@ -17,46 +17,42 @@ namespace fims_model_object { - /** - * @brief FIMSObject struct that defines member types and returns the unique id - */ - template - struct FIMSObject { - uint32_t id; /**< unique identifier assigned for all fims objects */ - std::vector parameters; /**< list of estimable parameters */ - std::vector - random_effects_parameters; /**< list of all random effects parameters */ - std::vector - fixed_effects_parameters; /**< list of fixed effects parameters */ - - virtual ~FIMSObject() { - } - - /** - * @brief Getter that returns the unique id for parameters in the model - */ - uint32_t GetId() const { - return id; - } - - /** - * @brief Check the dimensions of an object - * - * @param actual The actual dimensions. - * @param expected The expected dimensions. - * @return true - * @return false - */ - inline bool CheckDimensions(size_t actual, size_t expected) { - if (actual != expected) { - return false; - } - - return true; - } - - }; - -} // namespace fims_model_object +/** + * @brief FIMSObject struct that defines member types and returns the unique id + */ +template +struct FIMSObject { + uint32_t id; /**< unique identifier assigned for all fims objects */ + std::vector parameters; /**< list of estimable parameters */ + std::vector + random_effects_parameters; /**< list of all random effects parameters */ + std::vector + fixed_effects_parameters; /**< list of fixed effects parameters */ + + virtual ~FIMSObject() {} + + /** + * @brief Getter that returns the unique id for parameters in the model + */ + uint32_t GetId() const { return id; } + + /** + * @brief Check the dimensions of an object + * + * @param actual The actual dimensions. + * @param expected The expected dimensions. + * @return true + * @return false + */ + inline bool CheckDimensions(size_t actual, size_t expected) { + if (actual != expected) { + return false; + } + + return true; + } +}; + +} // namespace fims_model_object #endif /* FIMS_COMMON_MODEL_OBJECT_HPP */ diff --git a/inst/include/distributions/functors/density_components_base.hpp b/inst/include/distributions/functors/density_components_base.hpp index d0c27100..e7dd1dd1 100644 --- a/inst/include/distributions/functors/density_components_base.hpp +++ b/inst/include/distributions/functors/density_components_base.hpp @@ -13,10 +13,10 @@ #define DENSITY_COMPONENT_BASE_HPP #include "../../common/data_object.hpp" +#include "../../common/fims_math.hpp" +#include "../../common/fims_vector.hpp" #include "../../common/model_object.hpp" #include "../../interface/interface.hpp" -#include "../../common/fims_vector.hpp" -#include "../../common/fims_math.hpp" namespace fims_distributions { @@ -31,21 +31,29 @@ struct DensityComponentBase : public fims_model_object::FIMSObject { // this is like a memory tracker. // Assigning each one its own ID is a way to keep track of // all the instances of the DensityComponentBase class. - static uint32_t id_g; /**< global unique identifier for distribution modules */ - int observed_data_id_m = -999; /*!< id of observed data component*/ - std::shared_ptr> - observed_values; /**< observed data*/ - fims::Vector x; /**< input value of distribution function for priors or random effects*/ - fims::Vector expected_values; /**< expected value of distribution function */ - fims::Vector lpdf_vec; /**< vector to record observation level negative log-likelihood values */ - std::string input_type; /**< string classifies the type of the negative log-likelihood; options are: "priors", "random_effects", and "data" */ - bool osa_flag = false; /**< Boolean; if true, osa residuals are calculated */ - bool simulate_flag = false; /**< Boolean; if true, data are simulated from the distribution */ - std::vector key; /**< unique id for variable map that points to a fims::Vector */ + static uint32_t + id_g; /**< global unique identifier for distribution modules */ + int observed_data_id_m = -999; /*!< id of observed data component*/ + std::shared_ptr> + observed_values; /**< observed data*/ + fims::Vector x; /**< input value of distribution function for priors or + random effects*/ + fims::Vector + expected_values; /**< expected value of distribution function */ + fims::Vector lpdf_vec; /**< vector to record observation level negative + log-likelihood values */ + std::string input_type; /**< string classifies the type of the negative + log-likelihood; options are: "priors", + "random_effects", and "data" */ + bool osa_flag = false; /**< Boolean; if true, osa residuals are calculated */ + bool simulate_flag = + false; /**< Boolean; if true, data are simulated from the distribution */ + std::vector + key; /**< unique id for variable map that points to a fims::Vector */ - #ifdef TMB_MODEL - ::objective_function *of; /**< Pointer to the TMB objective function */ - #endif +#ifdef TMB_MODEL + ::objective_function *of; /**< Pointer to the TMB objective function */ +#endif /** @brief Constructor. */ diff --git a/inst/include/distributions/functors/lognormal_lpdf.hpp b/inst/include/distributions/functors/lognormal_lpdf.hpp index aa99c9ab..11b37722 100644 --- a/inst/include/distributions/functors/lognormal_lpdf.hpp +++ b/inst/include/distributions/functors/lognormal_lpdf.hpp @@ -10,91 +10,95 @@ #ifndef LOGNORMAL_LPDF #define LOGNORMAL_LPDF -#include "density_components_base.hpp" -#include "../../common/fims_vector.hpp" #include "../../common/def.hpp" +#include "../../common/fims_vector.hpp" +#include "density_components_base.hpp" -namespace fims_distributions -{ - /** - * LogNormal Log Probability Density Function - */ - template - struct LogNormalLPDF : public DensityComponentBase - { - fims::Vector log_sd; /**< natural log of the standard deviation of the distribution on the log scale; can be a vector or scalar */ - Type lpdf = 0.0; /**< total log probability density contribution of the distribution */ - // data_indicator , Type> keep; /**< Indicator used in TMB one-step-ahead residual calculations */ +namespace fims_distributions { +/** + * LogNormal Log Probability Density Function + */ +template +struct LogNormalLPDF : public DensityComponentBase { + fims::Vector + log_sd; /**< natural log of the standard deviation of the distribution on + the log scale; can be a vector or scalar */ + Type lpdf = 0.0; /**< total log probability density contribution of the + distribution */ + // data_indicator , Type> keep; /**< Indicator used in + // TMB one-step-ahead residual calculations */ - /** @brief Constructor. - */ - LogNormalLPDF() : DensityComponentBase() - { - } + /** @brief Constructor. + */ + LogNormalLPDF() : DensityComponentBase() {} - /** @brief Destructor. - */ - virtual ~LogNormalLPDF() {} + /** @brief Destructor. + */ + virtual ~LogNormalLPDF() {} - /** - * @brief Evaluates the lognormal probability density function - */ - virtual const Type evaluate() - { - // set vector size based on input type (prior, process, or data) - size_t n_x; - if(this->input_type == "data"){ - n_x = this->observed_values->data.size(); - } else { - n_x = this->x.size(); - } - // setup vector for recording the log probability density function values - this->lpdf_vec.resize(n_x); - std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0); - lpdf = 0; + /** + * @brief Evaluates the lognormal probability density function + */ + virtual const Type evaluate() { + // set vector size based on input type (prior, process, or data) + size_t n_x; + if (this->input_type == "data") { + n_x = this->observed_values->data.size(); + } else { + n_x = this->x.size(); + } + // setup vector for recording the log probability density function values + this->lpdf_vec.resize(n_x); + std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0); + lpdf = 0; - for (size_t i = 0; i < n_x; i++) - { - #ifdef TMB_MODEL - if(this->input_type == "data"){ - // if data, check if there are any NA values and skip lpdf calculation if there are - // See Deroba and Miller, 2016 (https://doi.org/10.1016/j.fishres.2015.12.002) for - // the use of lognormal constant - if(this->observed_values->at(i) != this->observed_values->na_value){ - this->lpdf_vec[i] = dnorm(log(this->observed_values->at(i)), this->expected_values.get_force_scalar(i), - fims_math::exp(log_sd.get_force_scalar(i)), true) - log(this->observed_values->at(i)); - } else { - this->lpdf_vec[i] = 0; - } - // if not data (i.e. prior or process), use x vector instead of observed_values and no lognormal constant needs to be applied - } else { - this->lpdf_vec[i] = dnorm(log(this->x[i]), this->expected_values.get_force_scalar(i), - fims_math::exp(log_sd.get_force_scalar(i)), true); - } + for (size_t i = 0; i < n_x; i++) { +#ifdef TMB_MODEL + if (this->input_type == "data") { + // if data, check if there are any NA values and skip lpdf calculation + // if there are See Deroba and Miller, 2016 + // (https://doi.org/10.1016/j.fishres.2015.12.002) for the use of + // lognormal constant + if (this->observed_values->at(i) != this->observed_values->na_value) { + this->lpdf_vec[i] = + dnorm(log(this->observed_values->at(i)), + this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i)), true) - + log(this->observed_values->at(i)); + } else { + this->lpdf_vec[i] = 0; + } + // if not data (i.e. prior or process), use x vector instead of + // observed_values and no lognormal constant needs to be applied + } else { + this->lpdf_vec[i] = + dnorm(log(this->x[i]), this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i)), true); + } - lpdf += this->lpdf_vec[i]; - if (this->simulate_flag) - { - FIMS_SIMULATE_F(this->of) - { // preprocessor definition in interface.hpp - // this simulates data that is mean biased - if(this->input_type == "data"){ - this->observed_values->at(i) = fims_math::exp(rnorm(this->expected_values.get_force_scalar(i), - fims_math::exp(log_sd.get_force_scalar(i)))); - } else { - this->x[i] = fims_math::exp(rnorm(this->expected_values.get_force_scalar(i), - fims_math::exp(log_sd.get_force_scalar(i)))); - } - } - } - #endif - } - #ifdef TMB_MODEL - vector lognormal_x = this->x; - // FIMS_REPORT_F(lognormal_x, this->of); - #endif - return (lpdf); + lpdf += this->lpdf_vec[i]; + if (this->simulate_flag) { + FIMS_SIMULATE_F(this->of) { // preprocessor definition in interface.hpp + // this simulates data that is mean biased + if (this->input_type == "data") { + this->observed_values->at(i) = fims_math::exp( + rnorm(this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i)))); + } else { + this->x[i] = fims_math::exp( + rnorm(this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i)))); + } } - }; -} // namespace fims_distributions + } +#endif + } +#ifdef TMB_MODEL + vector lognormal_x = this->x; + // FIMS_REPORT_F(lognormal_x, this->of); +#endif + return (lpdf); + } +}; +} // namespace fims_distributions #endif diff --git a/inst/include/distributions/functors/multinomial_lpmf.hpp b/inst/include/distributions/functors/multinomial_lpmf.hpp index 4c6f9137..18a97e82 100644 --- a/inst/include/distributions/functors/multinomial_lpmf.hpp +++ b/inst/include/distributions/functors/multinomial_lpmf.hpp @@ -10,117 +10,117 @@ #ifndef MULTINOMIAL_LPMF #define MULTINOMIAL_LPMF -#include "density_components_base.hpp" -#include "../../common/fims_vector.hpp" #include "../../common/def.hpp" +#include "../../common/fims_vector.hpp" +#include "density_components_base.hpp" -namespace fims_distributions -{ - /** - * Multinomial Log Probability Mass Function - */ - template - struct MultinomialLPMF : public DensityComponentBase - { - Type lpdf = 0.0; /**< total negative log-likelihood contribution of the distribution */ - fims::Vector dims; /**< Dimensions of the number of rows and columns of the multivariate dataset */ - - /** @brief Constructor. - */ - MultinomialLPMF() : DensityComponentBase() - { - } - - /** @brief Destructor. - */ - virtual ~MultinomialLPMF() {} +namespace fims_distributions { +/** + * Multinomial Log Probability Mass Function + */ +template +struct MultinomialLPMF : public DensityComponentBase { + Type lpdf = 0.0; /**< total negative log-likelihood contribution of the + distribution */ + fims::Vector dims; /**< Dimensions of the number of rows and columns + of the multivariate dataset */ - /** - * @brief Evaluates the multinomial probability mass function - */ - virtual const Type evaluate() - { - // set dims using observed_values if no user input - if(dims.size() != 2){ - dims.resize(2); - dims[0] = this->observed_values->get_imax(); - dims[1] = this->observed_values->get_jmax(); - } + /** @brief Constructor. + */ + MultinomialLPMF() : DensityComponentBase() {} + /** @brief Destructor. + */ + virtual ~MultinomialLPMF() {} - // setup vector for recording the log probability density function values - Type lpdf = 0.0; /**< total log probability mass contribution of the distribution */ - this->lpdf_vec.resize(dims[0]); - std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0); + /** + * @brief Evaluates the multinomial probability mass function + */ + virtual const Type evaluate() { + // set dims using observed_values if no user input + if (dims.size() != 2) { + dims.resize(2); + dims[0] = this->observed_values->get_imax(); + dims[1] = this->observed_values->get_jmax(); + } - if (dims[0]*dims[1] != this->expected_values.size()) { - FIMS_ERROR_LOG("Observed age comp is of size " + fims::to_string(dims[0]*dims[1]) - + " and expected is of size " + fims::to_string(this->expected_values.size())); - } else { - for (size_t i = 0; i < dims[0]; i++) - { - // for each row, create new x and prob vectors - fims::Vector x_vector; - fims::Vector prob_vector; - x_vector.resize(dims[1]); - prob_vector.resize(dims[1]); + // setup vector for recording the log probability density function values + Type lpdf = + 0.0; /**< total log probability mass contribution of the distribution */ + this->lpdf_vec.resize(dims[0]); + std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0); - bool containsNA = - false; /**< skips the entire row if any values are NA */ + if (dims[0] * dims[1] != this->expected_values.size()) { + FIMS_ERROR_LOG("Observed age comp is of size " + + fims::to_string(dims[0] * dims[1]) + + " and expected is of size " + + fims::to_string(this->expected_values.size())); + } else { + for (size_t i = 0; i < dims[0]; i++) { + // for each row, create new x and prob vectors + fims::Vector x_vector; + fims::Vector prob_vector; + x_vector.resize(dims[1]); + prob_vector.resize(dims[1]); - #ifdef TMB_MODEL - for (size_t j = 0; j < dims[1]; j++){ - if(this->input_type == "data"){ - // if data, check if there are any NA values and skip lpdf calculation for entire row if there are - if (this->observed_values->at(i, j) == - this->observed_values->na_value) { - containsNA = true; - break; - } - if(!containsNA){ - size_t idx = (i * dims[1]) + j; - x_vector[j] = this->observed_values->at(i, j); - prob_vector[j] = this->expected_values[idx]; - } - } else { - // if not data (i.e. prior or process), use x vector instead of observed_values - size_t idx = (i * dims[1]) + j; - x_vector[j] = this->x[idx]; - prob_vector[j] = this->expected_values[idx]; - } - } + bool containsNA = + false; /**< skips the entire row if any values are NA */ - if(!containsNA){ - this->lpdf_vec[i] = dmultinom((vector)x_vector, (vector) prob_vector, true); - } else { - this->lpdf_vec[i] = 0; - } - lpdf += this->lpdf_vec[i]; - /* - if (this->simulate_flag) - { - FIMS_SIMULATE_F(this->of) - { - fims::Vector sim_observed; - sim_observed.resize(dims[1]); - sim_observed = rmultinom(prob_vector); - sim_observed.resize(this->x); - for (size_t j = 0; j < dims[1]; j++) - { - idx = (i * dims[1]) + j; - this->x[idx] = sim_observed[j]; - } - } - } - */ - #endif - } +#ifdef TMB_MODEL + for (size_t j = 0; j < dims[1]; j++) { + if (this->input_type == "data") { + // if data, check if there are any NA values and skip lpdf + // calculation for entire row if there are + if (this->observed_values->at(i, j) == + this->observed_values->na_value) { + containsNA = true; + break; } - #ifdef TMB_MODEL - #endif - return (lpdf); + if (!containsNA) { + size_t idx = (i * dims[1]) + j; + x_vector[j] = this->observed_values->at(i, j); + prob_vector[j] = this->expected_values[idx]; + } + } else { + // if not data (i.e. prior or process), use x vector instead of + // observed_values + size_t idx = (i * dims[1]) + j; + x_vector[j] = this->x[idx]; + prob_vector[j] = this->expected_values[idx]; + } } + if (!containsNA) { + this->lpdf_vec[i] = dmultinom((vector)x_vector, + (vector)prob_vector, true); + } else { + this->lpdf_vec[i] = 0; + } + lpdf += this->lpdf_vec[i]; +/* +if (this->simulate_flag) +{ + FIMS_SIMULATE_F(this->of) + { + fims::Vector sim_observed; + sim_observed.resize(dims[1]); + sim_observed = rmultinom(prob_vector); + sim_observed.resize(this->x); + for (size_t j = 0; j < dims[1]; j++) + { + idx = (i * dims[1]) + j; + this->x[idx] = sim_observed[j]; + } + } +} +*/ +#endif + } + } +#ifdef TMB_MODEL +#endif + return (lpdf); + } }; -} // namespace fims_distributions +} // namespace fims_distributions #endif diff --git a/inst/include/distributions/functors/normal_lpdf.hpp b/inst/include/distributions/functors/normal_lpdf.hpp index d85cfc77..ae5e67c1 100644 --- a/inst/include/distributions/functors/normal_lpdf.hpp +++ b/inst/include/distributions/functors/normal_lpdf.hpp @@ -11,84 +11,94 @@ #ifndef NORMAL_LPDF #define NORMAL_LPDF -#include "density_components_base.hpp" -#include "../../common/fims_vector.hpp" #include "../../common/def.hpp" +#include "../../common/fims_vector.hpp" +#include "density_components_base.hpp" namespace fims_distributions { /** * Normal Log Probability Density Function */ -template +template struct NormalLPDF : public DensityComponentBase { - fims::Vector log_sd; /**< the natural log of the standard deviation of the distribution; can be a vector or scalar */ - Type lpdf = 0.0; /**< total log probability density contribution of the distribution */ + fims::Vector log_sd; /**< the natural log of the standard deviation of + the distribution; can be a vector or scalar */ + Type lpdf = 0.0; /**< total log probability density contribution of the + distribution */ - /** @brief Constructor. - */ - NormalLPDF() : DensityComponentBase() { + /** @brief Constructor. + */ + NormalLPDF() : DensityComponentBase() {} - } + /** @brief Destructor. + */ + virtual ~NormalLPDF() {} - /** @brief Destructor. - */ - virtual ~NormalLPDF() {} + /** + * @brief Evaluates the normal probability density function + */ + virtual const Type evaluate() { + // set vector size based on input type (prior, process, or data) + size_t n_x; + if (this->input_type == "data") { + n_x = this->observed_values->data.size(); + } else { + n_x = this->x.size(); + } + // setup vector for recording the log probability density function values + this->lpdf_vec.resize(n_x); + std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0); + lpdf = 0; - /** - * @brief Evaluates the normal probability density function - */ - virtual const Type evaluate(){ - // set vector size based on input type (prior, process, or data) - size_t n_x; - if(this->input_type == "data"){ - n_x = this->observed_values->data.size(); + for (size_t i = 0; i < n_x; i++) { +#ifdef TMB_MODEL + if (this->input_type == "data") { + // if data, check if there are any NA values and skip lpdf calculation + // if there are + if (this->observed_values->at(i) != this->observed_values->na_value) { + this->lpdf_vec[i] = + dnorm(this->observed_values->at(i), + this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i)), true); + } else { + this->lpdf_vec[i] = 0; + } + // if not data (i.e. prior or process), use x vector instead of + // observed_values } else { - n_x = this->x.size(); + this->lpdf_vec[i] = + dnorm(this->x[i], this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i)), true); } - // setup vector for recording the log probability density function values - this->lpdf_vec.resize(n_x); - std::fill(this->lpdf_vec.begin(), this->lpdf_vec.end(), 0); - lpdf = 0; - - for(size_t i=0; iinput_type == "data"){ - // if data, check if there are any NA values and skip lpdf calculation if there are - if(this->observed_values->at(i) != this->observed_values->na_value){ - this->lpdf_vec[i] = dnorm(this->observed_values->at(i), this->expected_values.get_force_scalar(i), fims_math::exp(log_sd.get_force_scalar(i)), true); + lpdf += this->lpdf_vec[i]; + if (this->simulate_flag) { + FIMS_SIMULATE_F(this->of) { + if (this->input_type == "data") { + this->observed_values->at(i) = + rnorm(this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i))); } else { - this->lpdf_vec[i] = 0; + this->x[i] = rnorm(this->expected_values.get_force_scalar(i), + fims_math::exp(log_sd.get_force_scalar(i))); } - // if not data (i.e. prior or process), use x vector instead of observed_values - } else { - this->lpdf_vec[i] = dnorm(this->x[i], this->expected_values.get_force_scalar(i), fims_math::exp(log_sd.get_force_scalar(i)), true); - } - lpdf += this->lpdf_vec[i]; - if(this->simulate_flag){ - FIMS_SIMULATE_F(this->of){ - if(this->input_type == "data"){ - this->observed_values->at(i) = rnorm(this->expected_values.get_force_scalar(i), fims_math::exp(log_sd.get_force_scalar(i))); - } else { - this->x[i] = rnorm(this->expected_values.get_force_scalar(i), fims_math::exp(log_sd.get_force_scalar(i))); - } - } - } - #endif - /* osa not working yet - if(osa_flag){//data observation type implements osa residuals - //code for osa cdf method - this->lpdf_vec[i] = this->keep.cdf_lower[i] * log( pnorm(this->x[i], this->expected_values.get_force_scalar(i), sd[i]) ); - this->lpdf_vec[i] = this->keep.cdf_upper[i] * log( 1.0 - pnorm(this->x[i], this->expected_values.get_force_scalar(i), sd[i]) ); - } */ - } - #ifdef TMB_MODEL - vector normal_x = this->x; - #endif - return(lpdf); + } +#endif + /* osa not working yet + if(osa_flag){//data observation type implements osa residuals + //code for osa cdf method + this->lpdf_vec[i] = this->keep.cdf_lower[i] * log( pnorm(this->x[i], + this->expected_values.get_force_scalar(i), sd[i]) ); this->lpdf_vec[i] = + this->keep.cdf_upper[i] * log( 1.0 - pnorm(this->x[i], + this->expected_values.get_force_scalar(i), sd[i]) ); + } */ } - +#ifdef TMB_MODEL + vector normal_x = this->x; +#endif + return (lpdf); + } }; -} // namespace fims_distributions +} // namespace fims_distributions #endif diff --git a/inst/include/interface/init.hpp b/inst/include/interface/init.hpp index 5d23af44..e991ac53 100644 --- a/inst/include/interface/init.hpp +++ b/inst/include/interface/init.hpp @@ -30,7 +30,7 @@ /** * @brief TODO: provide a brief description. - * + * */ #define CALLDEF(name, n) \ { #name, (DL_FUNC)&name, n } @@ -39,28 +39,28 @@ extern "C" { /** * @brief TODO: provide a brief description. - * - * @param mean - * @param nu - * @return SEXP + * + * @param mean + * @param nu + * @return SEXP */ SEXP compois_calc_var(SEXP mean, SEXP nu); /** * @brief TODO: provide a brief description. - * - * @return SEXP + * + * @return SEXP */ SEXP omp_check(); /** * @brief TODO: provide a brief description. - * - * @return SEXP + * + * @return SEXP */ SEXP omp_num_threads(SEXP); /** * @brief TODO: provide a brief description. - * - * @return SEXP + * + * @return SEXP */ SEXP _rcpp_module_boot_fims(); diff --git a/inst/include/interface/interface.hpp b/inst/include/interface/interface.hpp index a0121951..f2d78f7f 100644 --- a/inst/include/interface/interface.hpp +++ b/inst/include/interface/interface.hpp @@ -24,7 +24,7 @@ #include // define REPORT, ADREPORT, and SIMULATE -#define FIMS_REPORT_F(name, F) \ +#define FIMS_REPORT_F(name, F) \ if (isDouble::value && F->current_parallel_region < 0) { \ Rf_defineVar(Rf_install(#name), PROTECT(asSEXP(name)), F->report); \ UNPROTECT(1); \ @@ -50,25 +50,23 @@ vector ADREPORTvector(vector > x) { return res; } - - #define FIMS_SIMULATE_F(F) if (isDouble::value && F->do_simulate) #endif /* TMB_MODEL */ #ifndef TMB_MODEL - /** - * @brief TODO: provide a brief description. - */ - #define FIMS_SIMULATE_F(F) - /** - * @brief TODO: provide a brief description. - */ - #define FIMS_REPORT_F(name, F) - /** - * @brief TODO: provide a brief description. - */ - #define ADREPORT_F(name, F) +/** + * @brief TODO: provide a brief description. + */ +#define FIMS_SIMULATE_F(F) +/** + * @brief TODO: provide a brief description. + */ +#define FIMS_REPORT_F(name, F) +/** + * @brief TODO: provide a brief description. + */ +#define ADREPORT_F(name, F) #endif #endif /* FIMS_INTERFACE_HPP */ diff --git a/inst/include/interface/rcpp/rcpp_interface.hpp b/inst/include/interface/rcpp/rcpp_interface.hpp index 3dc27457..3eac9087 100644 --- a/inst/include/interface/rcpp/rcpp_interface.hpp +++ b/inst/include/interface/rcpp/rcpp_interface.hpp @@ -9,17 +9,17 @@ #ifndef FIMS_INTERFACE_RCPP_INTERFACE_HPP #define FIMS_INTERFACE_RCPP_INTERFACE_HPP +#include "../../common/model.hpp" +#include "../../utilities/fims_json.hpp" #include "rcpp_objects/rcpp_data.hpp" +#include "rcpp_objects/rcpp_distribution.hpp" #include "rcpp_objects/rcpp_fleet.hpp" #include "rcpp_objects/rcpp_growth.hpp" #include "rcpp_objects/rcpp_maturity.hpp" #include "rcpp_objects/rcpp_natural_mortality.hpp" -#include "../../common/model.hpp" #include "rcpp_objects/rcpp_population.hpp" #include "rcpp_objects/rcpp_recruitment.hpp" #include "rcpp_objects/rcpp_selectivity.hpp" -#include "rcpp_objects/rcpp_distribution.hpp" -#include "../../utilities/fims_json.hpp" /** * @brief TODO: provide a brief description. @@ -81,28 +81,28 @@ bool CreateTMBModel() { FIMS_INFO_LOG("adding FIMS objects to TMB"); for (size_t i = 0; i < FIMSRcppInterfaceBase::fims_interface_objects.size(); - i++) { + i++) { FIMSRcppInterfaceBase::fims_interface_objects[i]->add_to_fims_tmb(); } // base model - std::shared_ptr> d0 = - fims_info::Information::GetInstance(); + std::shared_ptr> d0 = + fims_info::Information::GetInstance(); d0->CreateModel(); // first-order derivative - std::shared_ptr> d1 = - fims_info::Information::GetInstance(); + std::shared_ptr> d1 = + fims_info::Information::GetInstance(); d1->CreateModel(); // second-order derivative - std::shared_ptr> d2 = - fims_info::Information::GetInstance(); + std::shared_ptr> d2 = + fims_info::Information::GetInstance(); d2->CreateModel(); // third-order derivative - std::shared_ptr> d3 = - fims_info::Information::GetInstance(); + std::shared_ptr> d3 = + fims_info::Information::GetInstance(); d3->CreateModel(); return true; @@ -113,40 +113,40 @@ bool CreateTMBModel() { * quantities. Updates parameter estimates from model core objects. */ void finalize_objects(Rcpp::NumericVector p) { - FIMS_function_parameters = p; + FIMS_function_parameters = p; - std::shared_ptr> information = + std::shared_ptr> information = fims_info::Information::GetInstance(); - std::shared_ptr> model = + std::shared_ptr> model = fims_model::Model::GetInstance(); - for (size_t i = 0; i < information->fixed_effects_parameters.size(); i++) { - *information->fixed_effects_parameters[i] = p[i]; - } + for (size_t i = 0; i < information->fixed_effects_parameters.size(); i++) { + *information->fixed_effects_parameters[i] = p[i]; + } - model->Evaluate(); + model->Evaluate(); - Rcpp::Function f = Rcpp::as(FIMS_objective_function); - Rcpp::Function g = Rcpp::as(FIMS_gradient_function); - double ret = Rcpp::as(f(p)); - Rcpp::NumericVector grad = Rcpp::as(g(p)); + Rcpp::Function f = Rcpp::as(FIMS_objective_function); + Rcpp::Function g = Rcpp::as(FIMS_gradient_function); + double ret = Rcpp::as(f(p)); + Rcpp::NumericVector grad = Rcpp::as(g(p)); - FIMS_function_value = ret; - FIMS_function_gradient = grad; - Rcpp::Rcout << "Final value = " << FIMS_function_value << "\nGradient: \n"; - double maxgc = -999; - for (R_xlen_t i = 0; i < FIMS_function_gradient.size(); i++) { - if (std::fabs(FIMS_function_gradient[i]) > maxgc) { - maxgc = std::fabs(FIMS_function_gradient[i]); - } + FIMS_function_value = ret; + FIMS_function_gradient = grad; + Rcpp::Rcout << "Final value = " << FIMS_function_value << "\nGradient: \n"; + double maxgc = -999; + for (R_xlen_t i = 0; i < FIMS_function_gradient.size(); i++) { + if (std::fabs(FIMS_function_gradient[i]) > maxgc) { + maxgc = std::fabs(FIMS_function_gradient[i]); } - FIMS_mgc_value = maxgc; + } + FIMS_mgc_value = maxgc; - for (size_t i = 0; i < FIMSRcppInterfaceBase::fims_interface_objects.size(); - i++) { - FIMSRcppInterfaceBase::fims_interface_objects[i]->finalize(); - } + for (size_t i = 0; i < FIMSRcppInterfaceBase::fims_interface_objects.size(); + i++) { + FIMSRcppInterfaceBase::fims_interface_objects[i]->finalize(); + } } /** @@ -160,17 +160,16 @@ void finalize_objects(Rcpp::NumericVector p) { * TODO: Remove the ability to take a single list. * @param opt A list containing \"par\". */ -void finalize_fims(Rcpp::Nullable< Rcpp::List> obj = R_NilValue, - Rcpp::Nullable< Rcpp::List> opt = R_NilValue) { - +void finalize_fims(Rcpp::Nullable obj = R_NilValue, + Rcpp::Nullable opt = R_NilValue) { bool valid_list = true; Rcpp::NumericVector parameters; - //check and handle the first argument. + // check and handle the first argument. if (!Rf_isNull(obj.get())) { Rcpp::List input_list = Rcpp::as(obj); - if (input_list.containsElementNamed("obj") - && input_list.containsElementNamed("opt")) { + if (input_list.containsElementNamed("obj") && + input_list.containsElementNamed("opt")) { Rcpp::List obj_list = input_list["obj"]; Rcpp::List opt_list = input_list["opt"]; @@ -195,8 +194,8 @@ void finalize_fims(Rcpp::Nullable< Rcpp::List> obj = R_NilValue, FIMS_ERROR_LOG("Invalid call, \"par\" not found in argument list."); } - //if we are here, a single argument was used. if it contains the - //expected elements, the list is valid and objects can be finalize. + // if we are here, a single argument was used. if it contains the + // expected elements, the list is valid and objects can be finalize. if (valid_list) { finalize_objects(parameters); FIMS_finalized = true; @@ -205,7 +204,7 @@ void finalize_fims(Rcpp::Nullable< Rcpp::List> obj = R_NilValue, return; } - } else {//two arguments? + } else { // two arguments? if (input_list.containsElementNamed("fn")) { FIMS_objective_function = input_list["fn"]; } else { @@ -222,24 +221,22 @@ void finalize_fims(Rcpp::Nullable< Rcpp::List> obj = R_NilValue, } } - //check second argument. + // check second argument. if (!Rf_isNull(opt.get())) { + Rcpp::List input_list = Rcpp::as(opt); - Rcpp::List input_list = Rcpp::as(opt); - - if (input_list.containsElementNamed("par")) { - parameters = Rcpp::as(input_list["par"]); - } else { - valid_list = false; - FIMS_ERROR_LOG("Invalid call, \"par\" not found in argument list."); - - } - } else { + if (input_list.containsElementNamed("par")) { + parameters = Rcpp::as(input_list["par"]); + } else { valid_list = false; + FIMS_ERROR_LOG("Invalid call, \"par\" not found in argument list."); + } + } else { + valid_list = false; } - //if we're here, two arguments were given. If they contain the expected - //elements, the lists are valid and objects can be finalized. + // if we're here, two arguments were given. If they contain the expected + // elements, the lists are valid and objects can be finalized. if (valid_list) { finalize_objects(parameters); FIMS_finalized = true; @@ -255,8 +252,8 @@ std::string get_output() { auto now = std::chrono::system_clock::now(); std::time_t now_time = std::chrono::system_clock::to_time_t(now); std::string ctime_no_newline = strtok(ctime(&now_time), "\n"); - std::shared_ptr> info = - fims_info::Information::GetInstance(); + std::shared_ptr> info = + fims_info::Information::GetInstance(); std::stringstream ss; ss << "{\n"; ss << "\"timestamp\": \"" << ctime_no_newline << "\",\n"; @@ -277,14 +274,17 @@ std::string get_output() { } size_t length = FIMSRcppInterfaceBase::fims_interface_objects.size(); for (size_t i = 0; i < length - 1; i++) { - ss << FIMSRcppInterfaceBase::fims_interface_objects[i]->to_json() << ",\n"; + ss << FIMSRcppInterfaceBase::fims_interface_objects[i]->to_json() + << ",\n"; } - ss << FIMSRcppInterfaceBase::fims_interface_objects[length - 1]->to_json() << "\n}"; + ss << FIMSRcppInterfaceBase::fims_interface_objects[length - 1]->to_json() + << "\n}"; ret = fims::JsonParser::PrettyFormatJSON(ss.str()); } else { - Rcpp::Rcout << "Invalid request to \"get_output()\". Please call finalize() first."; + Rcpp::Rcout + << "Invalid request to \"get_output()\". Please call finalize() first."; } return ret; } @@ -296,8 +296,8 @@ std::string get_output() { */ Rcpp::NumericVector get_fixed_parameters_vector() { // base model - std::shared_ptr> d0 = - fims_info::Information::GetInstance(); + std::shared_ptr> d0 = + fims_info::Information::GetInstance(); Rcpp::NumericVector p; @@ -315,8 +315,8 @@ Rcpp::NumericVector get_fixed_parameters_vector() { */ Rcpp::NumericVector get_random_parameters_vector() { // base model - std::shared_ptr> d0 = - fims_info::Information::GetInstance(); + std::shared_ptr> d0 = + fims_info::Information::GetInstance(); Rcpp::NumericVector p; @@ -335,8 +335,8 @@ Rcpp::NumericVector get_random_parameters_vector() { */ Rcpp::List get_parameter_names(Rcpp::List pars) { // base model - std::shared_ptr> d0 = - fims_info::Information::GetInstance(); + std::shared_ptr> d0 = + fims_info::Information::GetInstance(); pars.attr("names") = d0->parameter_names; @@ -350,8 +350,8 @@ Rcpp::List get_parameter_names(Rcpp::List pars) { */ template void clear_internal() { - std::shared_ptr> d0 = - fims_info::Information::GetInstance(); + std::shared_ptr> d0 = + fims_info::Information::GetInstance(); d0->Clear(); } @@ -362,7 +362,7 @@ void clear() { // rcpp_interface_base.hpp FIMSRcppInterfaceBase::fims_interface_objects.clear(); - //Parameter and ParameterVector + // Parameter and ParameterVector Parameter::id_g = 1; ParameterVector::id_g = 1; // rcpp_data.hpp @@ -449,30 +449,24 @@ void clear() { /** * @brief Gets the log entries as a string in JSON format. */ -std::string get_log() { - return fims::FIMSLog::fims_log->get_log(); -} +std::string get_log() { return fims::FIMSLog::fims_log->get_log(); } /** * @brief Gets the error entries from the log as a string in JSON format. */ -std::string get_log_errors() { - return fims::FIMSLog::fims_log->get_errors(); -} +std::string get_log_errors() { return fims::FIMSLog::fims_log->get_errors(); } /** * @brief Gets the warning entries from the log as a string in JSON format. */ std::string get_log_warnings() { - return fims::FIMSLog::fims_log->get_warnings(); + return fims::FIMSLog::fims_log->get_warnings(); } /** * @brief Gets the info entries from the log as a string in JSON format. */ -std::string get_log_info() { - return fims::FIMSLog::fims_log->get_info(); -} +std::string get_log_info() { return fims::FIMSLog::fims_log->get_info(); } /** * @brief Gets log entries by module as a string in JSON format. @@ -508,14 +502,16 @@ void set_log_throw_on_error(bool throw_on_error) { * @brief Adds an info entry to the log from the R environment. */ void log_info(std::string log_entry) { - fims::FIMSLog::fims_log->info_message(log_entry, -1, "R_env", "R_script_entry"); + fims::FIMSLog::fims_log->info_message(log_entry, -1, "R_env", + "R_script_entry"); } /** * @brief Adds a warning entry to the log from the R environment. */ void log_warning(std::string log_entry) { - fims::FIMSLog::fims_log->warning_message(log_entry, -1, "R_env", "R_script_entry"); + fims::FIMSLog::fims_log->warning_message(log_entry, -1, "R_env", + "R_script_entry"); } /** @@ -533,7 +529,8 @@ std::string escapeQuotes(const std::string& input) { size_t pos = result.find(search); while (pos != std::string::npos) { result.replace(pos, search.size(), replace); - pos = result.find(search, pos + replace.size()); // Move past the replaced position + pos = result.find(search, + pos + replace.size()); // Move past the replaced position } return result; } @@ -547,7 +544,8 @@ void log_error(std::string log_entry) { SEXP expression, result; ParseStatus status; - PROTECT(expression = R_ParseVector(Rf_mkString(ss.str().c_str()), 1, &status, R_NilValue)); + PROTECT(expression = R_ParseVector(Rf_mkString(ss.str().c_str()), 1, &status, + R_NilValue)); if (status != PARSE_OK) { Rcpp::Rcout << "Error parsing expression" << std::endl; UNPROTECT(1); @@ -563,7 +561,8 @@ void log_error(std::string log_entry) { ss_ret << escapeQuotes(str) << "\\n"; } - std::string ret = ss_ret.str(); //"find error";//Rcpp::as(result); + std::string ret = + ss_ret.str(); //"find error";//Rcpp::as(result); fims::FIMSLog::fims_log->error_message(log_entry, -1, "R_env", ret.c_str()); } @@ -588,127 +587,113 @@ RCPP_EXPOSED_CLASS(ParameterVector) * */ RCPP_MODULE(fims) { - Rcpp::function( - "CreateTMBModel", &CreateTMBModel, - "Creates the TMB model object and adds interface objects to it."); - Rcpp::function( - "finalize", &finalize_fims, - "Extracts the derived quantities from `Information` to the Rcpp object."); - Rcpp::function( - "get_output", &get_output, - "Extracts the derived quantities from model objects."); - Rcpp::function( - "get_fixed", &get_fixed_parameters_vector, - "Gets the fixed parameters vector object."); - Rcpp::function( - "get_random", &get_random_parameters_vector, - "Gets the random parameters vector object."); - Rcpp::function( - "get_parameter_names", &get_parameter_names, - "Gets the parameter names object."); - Rcpp::function( - "clear", clear, - "Clears all pointers/references of a FIMS model"); - Rcpp::function( - "get_log", get_log, - "Gets the log entries as a string in JSON format."); - Rcpp::function( - "get_log_errors", get_log_errors, - "Gets the error entries from the log as a string in JSON format."); - Rcpp::function( - "get_log_warnings", get_log_warnings, - "Gets the warning entries from the log as a string in JSON format."); - Rcpp::function( - "get_log_info", get_log_info, - "Gets the info entries from the log as a string in JSON format."); - Rcpp::function( - "get_log_module", get_log_module, - "Gets log entries by module as a string in JSON format."); - Rcpp::function( - "write_log", write_log, - "If true, writes the log on exit."); - Rcpp::function( - "set_log_path", set_log_path, - "Sets the path for the log file to be written to."); - Rcpp::function( - "init_logging", init_logging, - "Initializes the logging system, setting all signal handling."); - Rcpp::function( - "set_log_throw_on_error", set_log_throw_on_error, - "If true, throws a runtime exception when an error is logged."); - Rcpp::function( - "log_info", log_info, - "Adds an info entry to the log from the R environment."); - Rcpp::function( - "log_warning", log_warning, - "Adds a warning entry to the log from the R environment."); - Rcpp::function( - "log_error", log_error, - "Adds a error entry to the log from the R environment."); - Rcpp::class_( - "Parameter", - "An RcppInterface class that defines the Parameter class.") - .constructor() - .constructor() - .constructor() - .field( - "value", &Parameter::initial_value_m, - "A numeric value specifying the initial value of the parameter.") - .field( - "value", &Parameter::final_value_m, - "A numeric value specifying the final value of the parameter.") - .field( - "min", &Parameter::min_m, - "A numeric value specifying the minimum possible parameter value, where the default is negative infinity.") - .field( - "max", &Parameter::max_m, - "A numeric value specifying the maximum possible parameter value, where the default is positive infinity.") - .field( - "id", &Parameter::id_m, - "unique id for parameter class") - .field( - "is_random_effect", &Parameter::is_random_effect_m, - "A boolean indicating whether or not the parameter is a random effect; the default is FALSE.") - .field( - "estimated", &Parameter::estimated_m, - "A boolean indicating whether or not the parameter is estimated; the default is FALSE."); - - Rcpp::class_( + Rcpp::function( + "CreateTMBModel", &CreateTMBModel, + "Creates the TMB model object and adds interface objects to it."); + Rcpp::function( + "finalize", &finalize_fims, + "Extracts the derived quantities from `Information` to the Rcpp object."); + Rcpp::function("get_output", &get_output, + "Extracts the derived quantities from model objects."); + Rcpp::function("get_fixed", &get_fixed_parameters_vector, + "Gets the fixed parameters vector object."); + Rcpp::function("get_random", &get_random_parameters_vector, + "Gets the random parameters vector object."); + Rcpp::function("get_parameter_names", &get_parameter_names, + "Gets the parameter names object."); + Rcpp::function("clear", clear, + "Clears all pointers/references of a FIMS model"); + Rcpp::function("get_log", get_log, + "Gets the log entries as a string in JSON format."); + Rcpp::function( + "get_log_errors", get_log_errors, + "Gets the error entries from the log as a string in JSON format."); + Rcpp::function( + "get_log_warnings", get_log_warnings, + "Gets the warning entries from the log as a string in JSON format."); + Rcpp::function( + "get_log_info", get_log_info, + "Gets the info entries from the log as a string in JSON format."); + Rcpp::function("get_log_module", get_log_module, + "Gets log entries by module as a string in JSON format."); + Rcpp::function("write_log", write_log, "If true, writes the log on exit."); + Rcpp::function("set_log_path", set_log_path, + "Sets the path for the log file to be written to."); + Rcpp::function( + "init_logging", init_logging, + "Initializes the logging system, setting all signal handling."); + Rcpp::function( + "set_log_throw_on_error", set_log_throw_on_error, + "If true, throws a runtime exception when an error is logged."); + Rcpp::function("log_info", log_info, + "Adds an info entry to the log from the R environment."); + Rcpp::function("log_warning", log_warning, + "Adds a warning entry to the log from the R environment."); + Rcpp::function("log_error", log_error, + "Adds a error entry to the log from the R environment."); + Rcpp::class_( + "Parameter", "An RcppInterface class that defines the Parameter class.") + .constructor() + .constructor() + .constructor() + .field("value", &Parameter::initial_value_m, + "A numeric value specifying the initial value of the parameter.") + .field("value", &Parameter::final_value_m, + "A numeric value specifying the final value of the parameter.") + .field("min", &Parameter::min_m, + "A numeric value specifying the minimum possible parameter value, " + "where the default is negative infinity.") + .field("max", &Parameter::max_m, + "A numeric value specifying the maximum possible parameter value, " + "where the default is positive infinity.") + .field("id", &Parameter::id_m, "unique id for parameter class") + .field("is_random_effect", &Parameter::is_random_effect_m, + "A boolean indicating whether or not the parameter is a random " + "effect; the default is FALSE.") + .field("estimated", &Parameter::estimated_m, + "A boolean indicating whether or not the parameter is estimated; " + "the default is FALSE."); + + Rcpp::class_( "ParameterVector", "An RcppInterface class that defines the ParameterVector class.") - .constructor() - .constructor() - .constructor() - .method("get", &ParameterVector::get, - "An internal accessor for calling a position of a ParameterVector from R.") - .method("set", &ParameterVector::set, - "An internal setter for setting a position of a ParameterVector from R.") - .method("show", &ParameterVector::show, - "The printing methods for a ParameterVector.") - .method("at", &ParameterVector::at, - "Returns a Parameter at the indicated position given the index argument.") - .method("size", &ParameterVector::size, - "Returns the size of a ParameterVector.") - .method("resize", &ParameterVector::resize, - "Resizes a ParameterVector to the desired length.") - .method("set_all_estimable", &ParameterVector::set_all_estimable, - "Sets all Parameters within a ParameterVector as estimable.") - .method("set_all_random", &ParameterVector::set_all_random, - "Sets all Parameters within a ParameterVector as random effects.") - .method("fill", &ParameterVector::fill, - "Sets the value of all Parameters in the ParameterVector to the provided value.") - .method("get_id", &ParameterVector::get_id, - "Gets the ID of the ParameterVector object."); - - Rcpp::class_("BevertonHoltRecruitment") - .constructor() - .field("logit_steep", &BevertonHoltRecruitmentInterface::logit_steep) - .field("log_rzero", &BevertonHoltRecruitmentInterface::log_rzero) - .field("log_devs", &BevertonHoltRecruitmentInterface::log_devs) - .field("estimate_log_devs", - &BevertonHoltRecruitmentInterface::estimate_log_devs) - .method("get_id", &BevertonHoltRecruitmentInterface::get_id) - .method("evaluate", &BevertonHoltRecruitmentInterface::evaluate); + .constructor() + .constructor() + .constructor() + .method("get", &ParameterVector::get, + "An internal accessor for calling a position of a " + "ParameterVector from R.") + .method("set", &ParameterVector::set, + "An internal setter for setting a position of a ParameterVector " + "from R.") + .method("show", &ParameterVector::show, + "The printing methods for a ParameterVector.") + .method("at", &ParameterVector::at, + "Returns a Parameter at the indicated position given the index " + "argument.") + .method("size", &ParameterVector::size, + "Returns the size of a ParameterVector.") + .method("resize", &ParameterVector::resize, + "Resizes a ParameterVector to the desired length.") + .method("set_all_estimable", &ParameterVector::set_all_estimable, + "Sets all Parameters within a ParameterVector as estimable.") + .method("set_all_random", &ParameterVector::set_all_random, + "Sets all Parameters within a ParameterVector as random effects.") + .method("fill", &ParameterVector::fill, + "Sets the value of all Parameters in the ParameterVector to the " + "provided value.") + .method("get_id", &ParameterVector::get_id, + "Gets the ID of the ParameterVector object."); + + Rcpp::class_("BevertonHoltRecruitment") + .constructor() + .field("logit_steep", &BevertonHoltRecruitmentInterface::logit_steep) + .field("log_rzero", &BevertonHoltRecruitmentInterface::log_rzero) + .field("log_devs", &BevertonHoltRecruitmentInterface::log_devs) + .field("estimate_log_devs", + &BevertonHoltRecruitmentInterface::estimate_log_devs) + .method("get_id", &BevertonHoltRecruitmentInterface::get_id) + .method("evaluate", &BevertonHoltRecruitmentInterface::evaluate); Rcpp::class_("Fleet") .constructor() @@ -721,127 +706,184 @@ RCPP_MODULE(fims) { .field("estimate_q", &FleetInterface::estimate_q) .field("random_q", &FleetInterface::random_q) .field("log_expected_index", &FleetInterface::log_expected_index) - .field("proportion_catch_numbers_at_age", &FleetInterface::proportion_catch_numbers_at_age) - .field("proportion_catch_numbers_at_length", &FleetInterface::proportion_catch_numbers_at_length) - .field("age_length_conversion_matrix", &FleetInterface::age_length_conversion_matrix) + .field("proportion_catch_numbers_at_age", + &FleetInterface::proportion_catch_numbers_at_age) + .field("proportion_catch_numbers_at_length", + &FleetInterface::proportion_catch_numbers_at_length) + .field("age_length_conversion_matrix", + &FleetInterface::age_length_conversion_matrix) .method("SetObservedAgeCompData", &FleetInterface::SetObservedAgeCompData) - .method("GetObservedAgeCompDataID", &FleetInterface::GetObservedAgeCompDataID) - .method("SetObservedLengthCompData", &FleetInterface::SetObservedLengthCompData) - .method("GetObservedLengthCompDataID", &FleetInterface::GetObservedLengthCompDataID) + .method("GetObservedAgeCompDataID", + &FleetInterface::GetObservedAgeCompDataID) + .method("SetObservedLengthCompData", + &FleetInterface::SetObservedLengthCompData) + .method("GetObservedLengthCompDataID", + &FleetInterface::GetObservedLengthCompDataID) .method("SetObservedIndexData", &FleetInterface::SetObservedIndexData) .method("GetObservedIndexDataID", &FleetInterface::GetObservedIndexDataID) .method("SetSelectivity", &FleetInterface::SetSelectivity); - Rcpp::class_("AgeComp") - .constructor() - .field("age_comp_data", &AgeCompDataInterface::age_comp_data) - .method("get_id", &AgeCompDataInterface::get_id); - - Rcpp::class_("LengthComp") - .constructor() - .field("length_comp_data", &LengthCompDataInterface::length_comp_data) - .method("get_id", &LengthCompDataInterface::get_id); - - Rcpp::class_("Index") - .constructor() - .field("index_data", &IndexDataInterface::index_data) - .method("get_id", &IndexDataInterface::get_id); - - Rcpp::class_("Population") - .constructor() - .method("get_id", &PopulationInterface::get_id, "get population ID") - .field("nages", &PopulationInterface::nages, "number of ages") - .field("nfleets", &PopulationInterface::nfleets, "number of fleets") - .field("nseasons", &PopulationInterface::nseasons, "number of seasons") - .field("nyears", &PopulationInterface::nyears, "number of years") - .field("nlengths", &PopulationInterface::nlengths, "number of lengths") - .field("log_M", &PopulationInterface::log_M, "natural log of the natural mortality of the population") - .field("log_init_naa", &PopulationInterface::log_init_naa, "natural log of the initial numbers at age") - .field("ages", &PopulationInterface::ages, "vector of ages in the population; length nages") - .method("evaluate", &PopulationInterface::evaluate, "evaluate the population function") - .method("SetMaturity", &PopulationInterface::SetMaturity, "Set the unique id for the Maturity object") - .method("SetGrowth", &PopulationInterface::SetGrowth, "Set the unique id for the growth object") - .method("SetRecruitment", &PopulationInterface::SetRecruitment, "Set the unique id for the Recruitment object") - .method("evaluate", &PopulationInterface::evaluate, "evaluate the population function"); - - Rcpp::class_("LogisticMaturity") - .constructor() - .field("inflection_point", &LogisticMaturityInterface::inflection_point) - .field("slope", &LogisticMaturityInterface::slope) - .method("get_id", &LogisticMaturityInterface::get_id) - .method("evaluate", &LogisticMaturityInterface::evaluate); - - Rcpp::class_("LogisticSelectivity") - .constructor() - .field("inflection_point", - &LogisticSelectivityInterface::inflection_point) - .field("slope", &LogisticSelectivityInterface::slope) - .method("get_id", &LogisticSelectivityInterface::get_id) - .method("evaluate", &LogisticSelectivityInterface::evaluate); - - Rcpp::class_("DoubleLogisticSelectivity") - .constructor() - .field( - "inflection_point_asc", - &DoubleLogisticSelectivityInterface::inflection_point_asc, - "50 percent quantile of the value of the quantity of interest (x) on the ascending limb of the double logistic curve; e.g., age at which 50 percent of the fish are selected.") - .field( - "slope_asc", - &DoubleLogisticSelectivityInterface::slope_asc, - "Scalar multiplier of difference between quantity of interest value (x) and inflection_point on the ascending limb of the double logistic curve.") - .field( - "inflection_point_desc", - &DoubleLogisticSelectivityInterface::inflection_point_desc, - "50 percent quantile of the value of the quantity of interest (x) on the descending limb of the double logistic curve; e.g. age at which 50 percent of the fish are selected.") - .field( - "slope_desc", - &DoubleLogisticSelectivityInterface::slope_desc, - "Scalar multiplier of difference between quantity of interest value (x) and inflection_point on the descending limb of the double logistic curve.") - .method( - "get_id", - &DoubleLogisticSelectivityInterface::get_id, - "Returns a unique ID for the selectivity class.") - .method( - "evaluate", - &DoubleLogisticSelectivityInterface::evaluate, - "Evaluates the double logistic selectivity given input value (e.g., age or size in selectivity)."); - - Rcpp::class_("EWAAgrowth") - .constructor() - .field("ages", &EWAAGrowthInterface::ages, "Ages for each age class.") - .field("weights", &EWAAGrowthInterface::weights, "Weights for each age class.") - .method("get_id", &EWAAGrowthInterface::get_id) - .method("evaluate", &EWAAGrowthInterface::evaluate); - - Rcpp::class_("DnormDistribution") - .constructor() - .method("get_id", &DnormDistributionsInterface::get_id, "Returns a unique ID for the Dnorm distribution class.") - .method("evaluate", &DnormDistributionsInterface::evaluate, "Evaluates the normal distribution given input data and parameter values.") - .method("set_observed_data", &DnormDistributionsInterface::set_observed_data, "Accepts a unique ID for a given Data Object class to link the data with the distribution.") - .method("set_distribution_links", &DnormDistributionsInterface::set_distribution_links, "Accepts a unique ID for a given parameter to link the parameter with the distribution.") - .field("x", &DnormDistributionsInterface::x, "Input for distribution when not observations, e.g., prior or random effect.") - .field("expected_values", &DnormDistributionsInterface::expected_values, "Mean of the distribution.") - .field("log_sd", &DnormDistributionsInterface::log_sd, "The natural log of the standard deviation."); - - Rcpp::class_("DlnormDistribution") - .constructor() - .method("get_id", &DlnormDistributionsInterface::get_id, "Returns a unique ID for the Dnorm distribution class.") - .method("evaluate", &DlnormDistributionsInterface::evaluate, "Evaluates the normal distribution given input data and parameter values.") - .method("set_observed_data", &DlnormDistributionsInterface::set_observed_data, "Accepts a unique ID for a given Data Object class to link the data with the distribution.") - .method("set_distribution_links", &DlnormDistributionsInterface::set_distribution_links, "Accepts a unique ID for a given parameter to link the parameter with the distribution.") - .field("x", &DlnormDistributionsInterface::x, "Input for distribution when not observations, e.g., prior or random effect.") - .field("expected_values", &DlnormDistributionsInterface::expected_values, "Mean of the distribution on the natural log scale.") - .field("log_sd", &DlnormDistributionsInterface::log_sd, "The natural log of the standard deviation of the distribution on the natural log scale."); - - Rcpp::class_("DmultinomDistribution") - .constructor() - .method("get_id", &DmultinomDistributionsInterface::get_id, "Returns a unique ID for the Dnorm distribution class.") - .method("evaluate", &DmultinomDistributionsInterface::evaluate, "Evaluates the normal distribution given input data and parameter values.") - .method("set_observed_data", &DmultinomDistributionsInterface::set_observed_data, "Accepts a unique ID for a given Data Object class to link the data with the distribution.") - .method("set_distribution_links", &DmultinomDistributionsInterface::set_distribution_links, "Accepts a unique ID for a given parameter to link the parameter with the distribution.") - .field("x", &DmultinomDistributionsInterface::x, "Input for distribution when not observations, e.g., prior or random effect.") - .field("expected_values", &DmultinomDistributionsInterface::expected_values, "numeric non-negative vector of length K, specifying the probability for the K classes.") - .field("dims", &DmultinomDistributionsInterface::dims, "dimension of the multivariate input, e.g., c(num rows, num cols)."); + Rcpp::class_("AgeComp") + .constructor() + .field("age_comp_data", &AgeCompDataInterface::age_comp_data) + .method("get_id", &AgeCompDataInterface::get_id); + + Rcpp::class_("LengthComp") + .constructor() + .field("length_comp_data", &LengthCompDataInterface::length_comp_data) + .method("get_id", &LengthCompDataInterface::get_id); + + Rcpp::class_("Index") + .constructor() + .field("index_data", &IndexDataInterface::index_data) + .method("get_id", &IndexDataInterface::get_id); + + Rcpp::class_("Population") + .constructor() + .method("get_id", &PopulationInterface::get_id, "get population ID") + .field("nages", &PopulationInterface::nages, "number of ages") + .field("nfleets", &PopulationInterface::nfleets, "number of fleets") + .field("nseasons", &PopulationInterface::nseasons, "number of seasons") + .field("nyears", &PopulationInterface::nyears, "number of years") + .field("nlengths", &PopulationInterface::nlengths, "number of lengths") + .field("log_M", &PopulationInterface::log_M, + "natural log of the natural mortality of the population") + .field("log_init_naa", &PopulationInterface::log_init_naa, + "natural log of the initial numbers at age") + .field("ages", &PopulationInterface::ages, + "vector of ages in the population; length nages") + .method("evaluate", &PopulationInterface::evaluate, + "evaluate the population function") + .method("SetMaturity", &PopulationInterface::SetMaturity, + "Set the unique id for the Maturity object") + .method("SetGrowth", &PopulationInterface::SetGrowth, + "Set the unique id for the growth object") + .method("SetRecruitment", &PopulationInterface::SetRecruitment, + "Set the unique id for the Recruitment object") + .method("evaluate", &PopulationInterface::evaluate, + "evaluate the population function"); + + Rcpp::class_("LogisticMaturity") + .constructor() + .field("inflection_point", &LogisticMaturityInterface::inflection_point) + .field("slope", &LogisticMaturityInterface::slope) + .method("get_id", &LogisticMaturityInterface::get_id) + .method("evaluate", &LogisticMaturityInterface::evaluate); + + Rcpp::class_("LogisticSelectivity") + .constructor() + .field("inflection_point", + &LogisticSelectivityInterface::inflection_point) + .field("slope", &LogisticSelectivityInterface::slope) + .method("get_id", &LogisticSelectivityInterface::get_id) + .method("evaluate", &LogisticSelectivityInterface::evaluate); + + Rcpp::class_("DoubleLogisticSelectivity") + .constructor() + .field("inflection_point_asc", + &DoubleLogisticSelectivityInterface::inflection_point_asc, + "50 percent quantile of the value of the quantity of interest (x) " + " on the ascending limb of the double logistic curve; e.g., age " + "at which 50 percent of the fish are selected.") + .field("slope_asc", &DoubleLogisticSelectivityInterface::slope_asc, + "Scalar multiplier of difference between quantity of interest " + "value (x) and inflection_point on the ascending limb of the " + "double logistic curve.") + .field("inflection_point_desc", + &DoubleLogisticSelectivityInterface::inflection_point_desc, + "50 percent quantile of the value of the quantity of interest (x) " + "on the descending limb of the double logistic curve; e.g. age at " + "which 50 percent of the fish are selected.") + .field("slope_desc", &DoubleLogisticSelectivityInterface::slope_desc, + "Scalar multiplier of difference between quantity of interest " + "value (x) and inflection_point on the descending limb of the " + "double logistic curve.") + .method("get_id", &DoubleLogisticSelectivityInterface::get_id, + "Returns a unique ID for the selectivity class.") + .method("evaluate", &DoubleLogisticSelectivityInterface::evaluate, + "Evaluates the double logistic selectivity given input value " + "(e.g., age or size in selectivity)."); + + Rcpp::class_("EWAAgrowth") + .constructor() + .field("ages", &EWAAGrowthInterface::ages, "Ages for each age class.") + .field("weights", &EWAAGrowthInterface::weights, + "Weights for each age class.") + .method("get_id", &EWAAGrowthInterface::get_id) + .method("evaluate", &EWAAGrowthInterface::evaluate); + + Rcpp::class_("DnormDistribution") + .constructor() + .method("get_id", &DnormDistributionsInterface::get_id, + "Returns a unique ID for the Dnorm distribution class.") + .method("evaluate", &DnormDistributionsInterface::evaluate, + "Evaluates the normal distribution given input data and " + "parameter values.") + .method("set_observed_data", + &DnormDistributionsInterface::set_observed_data, + "Accepts a unique ID for a given Data Object class to link the " + "data with the distribution.") + .method("set_distribution_links", + &DnormDistributionsInterface::set_distribution_links, + "Accepts a unique ID for a given parameter to link the parameter " + "with the distribution.") + .field("x", &DnormDistributionsInterface::x, + "Input for distribution when not observations, e.g., prior or " + "random effect.") + .field("expected_values", &DnormDistributionsInterface::expected_values, + "Mean of the distribution.") + .field("log_sd", &DnormDistributionsInterface::log_sd, + "The natural log of the standard deviation."); + + Rcpp::class_("DlnormDistribution") + .constructor() + .method("get_id", &DlnormDistributionsInterface::get_id, + "Returns a unique ID for the Dnorm distribution class.") + .method("evaluate", &DlnormDistributionsInterface::evaluate, + "Evaluates the normal distribution given input data and " + "parameter values.") + .method("set_observed_data", + &DlnormDistributionsInterface::set_observed_data, + "Accepts a unique ID for a given Data Object class to link the " + "data with the distribution.") + .method("set_distribution_links", + &DlnormDistributionsInterface::set_distribution_links, + "Accepts a unique ID for a given parameter to link the parameter " + "with the distribution.") + .field("x", &DlnormDistributionsInterface::x, + "Input for distribution when not observations, e.g., prior or " + "random effect.") + .field("expected_values", &DlnormDistributionsInterface::expected_values, + "Mean of the distribution on the natural log scale.") + .field("log_sd", &DlnormDistributionsInterface::log_sd, + "The natural log of the standard deviation of the distribution on " + "the natural log scale."); + + Rcpp::class_("DmultinomDistribution") + .constructor() + .method("get_id", &DmultinomDistributionsInterface::get_id, + "Returns a unique ID for the Dnorm distribution class.") + .method("evaluate", &DmultinomDistributionsInterface::evaluate, + "Evaluates the normal distribution given input data and " + "parameter values.") + .method("set_observed_data", + &DmultinomDistributionsInterface::set_observed_data, + "Accepts a unique ID for a given Data Object class to link the " + "data with the distribution.") + .method("set_distribution_links", + &DmultinomDistributionsInterface::set_distribution_links, + "Accepts a unique ID for a given parameter to link the parameter " + "with the distribution.") + .field("x", &DmultinomDistributionsInterface::x, + "Input for distribution when not observations, e.g., prior or " + "random effect.") + .field("expected_values", + &DmultinomDistributionsInterface::expected_values, + "numeric non-negative vector of length K, specifying the " + "probability for the K classes.") + .field( + "dims", &DmultinomDistributionsInterface::dims, + "dimension of the multivariate input, e.g., c(num rows, num cols)."); } #endif /* RCPP_INTERFACE_HPP */ diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp index fc86efd5..6efab03d 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_data.hpp @@ -28,7 +28,7 @@ class DataInterfaceBase : public FIMSRcppInterfaceBase { static uint32_t id_g; /** * @brief The local id of the DataInterfaceBase object. - * + * */ uint32_t id; /** @@ -109,7 +109,7 @@ class AgeCompDataInterface : public DataInterfaceBase { * @return The ID. */ virtual uint32_t get_id() { return this->id; } - + /** * @brief Converts the data to json representation for the output. * @return A string is returned specifying that the module relates to the @@ -119,7 +119,7 @@ class AgeCompDataInterface : public DataInterfaceBase { */ virtual std::string to_json() { std::stringstream ss; - + ss << "\"module\" : {\n"; ss << " \"name\": \"data\",\n"; ss << " \"type\" : \"AgeComp\",\n"; @@ -134,7 +134,6 @@ class AgeCompDataInterface : public DataInterfaceBase { ss << "}"; return ss.str(); } - #ifdef TMB_MODEL @@ -215,7 +214,7 @@ class LengthCompDataInterface : public DataInterfaceBase { * @return The ID. */ virtual uint32_t get_id() { return this->id; } - + /** * @brief Converts the data to json representation for the output. * @return A string is returned specifying that the module relates to the @@ -225,7 +224,7 @@ class LengthCompDataInterface : public DataInterfaceBase { */ virtual std::string to_json() { std::stringstream ss; - + ss << "\"module\" : {\n"; ss << " \"name\": \"data\",\n"; ss << " \"type\" : \"LengthComp\",\n"; @@ -240,7 +239,7 @@ class LengthCompDataInterface : public DataInterfaceBase { ss << "}"; return ss.str(); } - + #ifdef TMB_MODEL template bool add_to_fims_tmb_internal() { @@ -304,17 +303,17 @@ class IndexDataInterface : public DataInterfaceBase { * @return The ID. */ virtual uint32_t get_id() { return this->id; } - + /** * @brief Converts the data to json representation for the output. * @return A string is returned specifying that the module relates to the * data interface with index data. It also returns the ID, the rank of 1, the * dimensions by printing ymax, followed by the data values themselves. This * string is formatted for a json file. - */ + */ virtual std::string to_json() { std::stringstream ss; - + ss << "\"module\" : {\n"; ss << " \"name\": \"data\",\n"; ss << " \"type\": \"Index\",\n"; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp index 37c5b2cf..30d92dd1 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_distribution.hpp @@ -70,11 +70,13 @@ class DistributionsInterfaceBase : public FIMSRcppInterfaceBase { /** * @brief Sets pointers for data observations, random effects, or priors. * - * @param input_type String that sets whether the distribution type is for priors, random effects, or data. + * @param input_type String that sets whether the distribution type is for + * priors, random effects, or data. * @param ids Vector of unique ids for each linked parameter(s), derived * value(s), or observed data vector. */ - virtual bool set_distribution_links(std::string input_type, Rcpp::IntegerVector ids){ + virtual bool set_distribution_links(std::string input_type, + Rcpp::IntegerVector ids) { return false; } @@ -84,9 +86,7 @@ class DistributionsInterfaceBase : public FIMSRcppInterfaceBase { * @param observed_data_id Unique ID for the Observed Age Comp Data * object */ - virtual bool set_observed_data(int observed_data_id){ - return false; - } + virtual bool set_observed_data(int observed_data_id) { return false; } /** * @brief A method for each child distribution interface object to inherit so @@ -98,8 +98,8 @@ class DistributionsInterfaceBase : public FIMSRcppInterfaceBase { uint32_t DistributionsInterfaceBase::id_g = 1; // local id of the DistributionsInterfaceBase object map relating the ID of the // DistributionsInterfaceBase to the DistributionsInterfaceBase objects -std::map DistributionsInterfaceBase::live_objects; +std::map + DistributionsInterfaceBase::live_objects; /** * @brief The Rcpp interface for Dnorm to instantiate from R: @@ -154,14 +154,16 @@ class DnormDistributionsInterface : public DistributionsInterfaceBase { /** * @brief Sets pointers for data observations, random effects, or priors. * - * @param input_type String that sets whether the distribution type is for priors, random effects, or data. + * @param input_type String that sets whether the distribution type is for + * priors, random effects, or data. * @param ids Vector of unique ids for each linked parameter(s), derived * value(s), or observed data vector. */ - virtual bool set_distribution_links(std::string input_type, Rcpp::IntegerVector ids){ + virtual bool set_distribution_links(std::string input_type, + Rcpp::IntegerVector ids) { this->input_type_m = input_type; this->key_m.resize(ids.size()); - for(int i=0; ikey_m[i] = ids[i]; } return true; @@ -178,13 +180,13 @@ class DnormDistributionsInterface : public DistributionsInterfaceBase { dnorm.x.resize(this->x.size()); dnorm.expected_values.resize(this->expected_values.size()); dnorm.log_sd.resize(this->log_sd.size()); - for(size_t i=0; ix[i].initial_value_m; } - for(size_t i=0; iexpected_values[i].initial_value_m; } - for(size_t i=0; ilog_sd[i].initial_value_m; } return dnorm.evaluate(); @@ -196,29 +198,32 @@ class DnormDistributionsInterface : public DistributionsInterfaceBase { */ virtual void finalize() { if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("DnormDistribution " + fims::to_string(this->id_m) + " has been finalized already."); + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("DnormDistribution " + fims::to_string(this->id_m) + + " has been finalized already."); } - this->finalized = true; //indicate this has been called already + this->finalized = true; // indicate this has been called already - std::shared_ptr > info = + std::shared_ptr> info = fims_info::Information::GetInstance(); fims_info::Information::density_components_iterator it; - //search for density component in Information + // search for density component in Information it = info->density_components.find(this->id_m); - //if not found, just return + // if not found, just return if (it == info->density_components.end()) { - FIMS_WARNING_LOG("DnormDistribution " + fims::to_string(this->id_m) + " not found in Information."); + FIMS_WARNING_LOG("DnormDistribution " + fims::to_string(this->id_m) + + " not found in Information."); return; } else { - std::shared_ptr > dnorm = - std::dynamic_pointer_cast >(it->second); + std::shared_ptr> dnorm = + std::dynamic_pointer_cast>( + it->second); this->lpdf_vec = Rcpp::NumericVector(dnorm->lpdf_vec.size()); - for(R_xlen_t i=0; i < this->lpdf_vec.size(); i++) { - this->lpdf_vec[i] = dnorm->lpdf_vec[i]; + for (R_xlen_t i = 0; i < this->lpdf_vec.size(); i++) { + this->lpdf_vec[i] = dnorm->lpdf_vec[i]; } } } @@ -244,7 +249,7 @@ class DnormDistributionsInterface : public DistributionsInterfaceBase { if (this->lpdf_vec.size() == 0) { ss << "]\n"; } else { - for(R_xlen_t i=0; i < this->lpdf_vec.size() - 1; i++) { + for (R_xlen_t i = 0; i < this->lpdf_vec.size() - 1; i++) { ss << this->lpdf_vec[i] << ", "; } ss << this->lpdf_vec[this->lpdf_vec.size() - 1] << "]\n"; @@ -254,40 +259,39 @@ class DnormDistributionsInterface : public DistributionsInterfaceBase { return ss.str(); } - #ifdef TMB_MODEL template bool add_to_fims_tmb_internal() { std::shared_ptr> info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); std::shared_ptr> distribution = - std::make_shared>(); + std::make_shared>(); // interface to data/parameter value - distribution->observed_data_id_m = - interface_observed_data_id_m; + distribution->observed_data_id_m = interface_observed_data_id_m; distribution->input_type = this->input_type_m; distribution->key.resize(this->key_m.size()); - for(size_t i=0; ikey_m.size(); i++){ + for (size_t i = 0; i < this->key_m.size(); i++) { distribution->key[i] = this->key_m[i]; } distribution->id = this->id_m; distribution->x.resize(this->x.size()); - for(size_t i=0; ix.size(); i++){ + for (size_t i = 0; i < this->x.size(); i++) { distribution->x[i] = this->x[i].initial_value_m; } // set relative info distribution->expected_values.resize(this->expected_values.size()); - for(size_t i=0; iexpected_values.size(); i++) { - distribution->expected_values[i] = this->expected_values[i].initial_value_m; + for (size_t i = 0; i < this->expected_values.size(); i++) { + distribution->expected_values[i] = + this->expected_values[i].initial_value_m; } distribution->log_sd.resize(this->log_sd.size()); - for(size_t i=0; ilog_sd.size(); i++){ + for (size_t i = 0; i < this->log_sd.size(); i++) { distribution->log_sd[i] = this->log_sd[i].initial_value_m; - if(this->log_sd[i].estimated_m){ + if (this->log_sd[i].estimated_m) { info->RegisterParameterName("normal log_sd"); info->RegisterParameter(distribution->log_sd[i]); } @@ -374,14 +378,16 @@ class DlnormDistributionsInterface : public DistributionsInterfaceBase { /** * @brief Sets pointers for data observations, random effects, or priors. * - * @param input_type String that sets whether the distribution type is for priors, random effects, or data. + * @param input_type String that sets whether the distribution type is for + * priors, random effects, or data. * @param ids Vector of unique ids for each linked parameter(s), derived * value(s), or observed data vector. */ - virtual bool set_distribution_links(std::string input_type, Rcpp::IntegerVector ids){ + virtual bool set_distribution_links(std::string input_type, + Rcpp::IntegerVector ids) { this->input_type_m = input_type; this->key_m.resize(ids.size()); - for(int i=0; ikey_m[i] = ids[i]; } return true; @@ -398,13 +404,13 @@ class DlnormDistributionsInterface : public DistributionsInterfaceBase { dlnorm.x.resize(this->x.size()); dlnorm.expected_values.resize(this->expected_values.size()); dlnorm.log_sd.resize(this->log_sd.size()); - for(size_t i=0; ix[i].initial_value_m; } - for(size_t i=0; iexpected_values[i].initial_value_m; } - for(size_t i=0; ilog_sd[i].initial_value_m; } return dlnorm.evaluate(); @@ -416,28 +422,31 @@ class DlnormDistributionsInterface : public DistributionsInterfaceBase { */ virtual void finalize() { if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("LogNormalLPDF " + fims::to_string(this->id_m) + " has been finalized already."); + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("LogNormalLPDF " + fims::to_string(this->id_m) + + " has been finalized already."); } - this->finalized = true; //indicate this has been called already + this->finalized = true; // indicate this has been called already - std::shared_ptr > info = + std::shared_ptr> info = fims_info::Information::GetInstance(); fims_info::Information::density_components_iterator it; - //search for density component in Information + // search for density component in Information it = info->density_components.find(this->id_m); - //if not found, just return + // if not found, just return if (it == info->density_components.end()) { - FIMS_WARNING_LOG("LogNormalLPDF " + fims::to_string(this->id_m) + " not found in Information."); + FIMS_WARNING_LOG("LogNormalLPDF " + fims::to_string(this->id_m) + + " not found in Information."); return; } else { - std::shared_ptr > dlnorm = - std::dynamic_pointer_cast >(it->second); + std::shared_ptr> dlnorm = + std::dynamic_pointer_cast>( + it->second); this->lpdf_vec = Rcpp::NumericVector(dlnorm->lpdf_vec.size()); - for(R_xlen_t i=0; i < this->lpdf_vec.size(); i++) { + for (R_xlen_t i = 0; i < this->lpdf_vec.size(); i++) { this->lpdf_vec[i] = dlnorm->lpdf_vec[i]; } } @@ -462,20 +471,18 @@ class DlnormDistributionsInterface : public DistributionsInterfaceBase { ss << " \"name\": \"lpdf_vec\",\n"; ss << " \"values\":["; if (this->lpdf_vec.size() == 0) { - ss << "]\n"; + ss << "]\n"; } else { - for(R_xlen_t i=0; i < this->lpdf_vec.size() - 1; i++) { - ss << this->lpdf_vec[i] << ", "; - } - ss << this->lpdf_vec[this->lpdf_vec.size() - 1] << "]\n"; + for (R_xlen_t i = 0; i < this->lpdf_vec.size() - 1; i++) { + ss << this->lpdf_vec[i] << ", "; + } + ss << this->lpdf_vec[this->lpdf_vec.size() - 1] << "]\n"; } ss << " }\n]"; return ss.str(); } - - #ifdef TMB_MODEL template @@ -488,26 +495,26 @@ class DlnormDistributionsInterface : public DistributionsInterfaceBase { // set relative info distribution->id = this->id_m; - distribution->observed_data_id_m = - interface_observed_data_id_m; + distribution->observed_data_id_m = interface_observed_data_id_m; distribution->input_type = this->input_type_m; distribution->key.resize(this->key_m.size()); - for(size_t i=0; ikey_m.size(); i++){ + for (size_t i = 0; i < this->key_m.size(); i++) { distribution->key[i] = this->key_m[i]; } distribution->x.resize(this->x.size()); - for(size_t i=0; ix.size(); i++){ + for (size_t i = 0; i < this->x.size(); i++) { distribution->x[i] = this->x[i].initial_value_m; } // set relative info distribution->expected_values.resize(this->expected_values.size()); - for(size_t i=0; iexpected_values.size(); i++){ - distribution->expected_values[i] = this->expected_values[i].initial_value_m; + for (size_t i = 0; i < this->expected_values.size(); i++) { + distribution->expected_values[i] = + this->expected_values[i].initial_value_m; } distribution->log_sd.resize(this->log_sd.size()); - for(size_t i=0; ilog_sd.size(); i++){ + for (size_t i = 0; i < this->log_sd.size(); i++) { distribution->log_sd[i] = this->log_sd[i].initial_value_m; - if(this->log_sd[i].estimated_m){ + if (this->log_sd[i].estimated_m) { info->RegisterParameterName("lognormal log_sd"); info->RegisterParameter(distribution->log_sd[i]); } @@ -591,14 +598,16 @@ class DmultinomDistributionsInterface : public DistributionsInterfaceBase { /** * @brief Sets pointers for data observations, random effects, or priors. * - * @param input_type String that sets whether the distribution type is for priors, random effects, or data. + * @param input_type String that sets whether the distribution type is for + * priors, random effects, or data. * @param ids Vector of unique ids for each linked parameter(s), derived * value(s), or observed data vector. */ - virtual bool set_distribution_links(std::string input_type, Rcpp::IntegerVector ids){ + virtual bool set_distribution_links(std::string input_type, + Rcpp::IntegerVector ids) { this->input_type_m = input_type; this->key_m.resize(ids.size()); - for(int i=0; ikey_m[i] = ids[i]; } return true; @@ -615,10 +624,10 @@ class DmultinomDistributionsInterface : public DistributionsInterfaceBase { // Declare TMBVector in this scope dmultinom.x.resize(this->x.size()); dmultinom.expected_values.resize(this->expected_values.size()); - for(size_t i=0; ix[i].initial_value_m; } - for(size_t i=0; iexpected_values[i].initial_value_m; } dmultinom.dims.resize(2); @@ -638,23 +647,23 @@ class DmultinomDistributionsInterface : public DistributionsInterfaceBase { std::make_shared>(); distribution->id = this->id_m; - distribution->observed_data_id_m = - interface_observed_data_id_m; + distribution->observed_data_id_m = interface_observed_data_id_m; distribution->input_type = this->input_type_m; distribution->key.resize(this->key_m.size()); - for(size_t i=0; ikey_m.size(); i++){ + for (size_t i = 0; i < this->key_m.size(); i++) { distribution->key[i] = this->key_m[i]; } distribution->x.resize(this->x.size()); - for(size_t i=0; ix.size(); i++){ + for (size_t i = 0; i < this->x.size(); i++) { distribution->x[i] = this->x[i].initial_value_m; } // set relative info distribution->expected_values.resize(this->expected_values.size()); - for(size_t i=0; iexpected_values.size(); i++){ - distribution->expected_values[i] = this->expected_values[i].initial_value_m; + for (size_t i = 0; i < this->expected_values.size(); i++) { + distribution->expected_values[i] = + this->expected_values[i].initial_value_m; } - if(this->dims.size()>0){ + if (this->dims.size() > 0) { distribution->dims.resize(2); distribution->dims[0] = this->dims[0]; distribution->dims[1] = this->dims[1]; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp index 54330712..ad3136b3 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_fleet.hpp @@ -83,7 +83,7 @@ class FleetInterface : public FleetInterfaceBase { */ int interface_selectivity_id_m = -999; -public: + public: /** * @brief The name of the fleet. */ @@ -118,7 +118,8 @@ class FleetInterface : public FleetInterfaceBase { */ ParameterVector log_Fmort; /** - * @brief The vector of natural log of the expected index of abundance for the fleet. + * @brief The vector of natural log of the expected index of abundance for the + * fleet. */ ParameterVector log_expected_index; /** @@ -130,7 +131,8 @@ class FleetInterface : public FleetInterfaceBase { */ ParameterVector proportion_catch_numbers_at_length; /** - * @brief The vector of conversions to go from age to length, i.e., the age-to-length-conversion matrix. + * @brief The vector of conversions to go from age to length, i.e., the + * age-to-length-conversion matrix. */ ParameterVector age_length_conversion_matrix; /** @@ -216,16 +218,16 @@ class FleetInterface : public FleetInterfaceBase { } /** - * @brief Get the unique ID for the observed age-composition data object. - */ + * @brief Get the unique ID for the observed age-composition data object. + */ int GetObservedAgeCompDataID() { return interface_observed_agecomp_data_id_m; } /** - * @brief Get the unique ID for the observed length-composition data - * object. - */ + * @brief Get the unique ID for the observed length-composition data + * object. + */ int GetObservedLengthCompDataID() { return interface_observed_lengthcomp_data_id_m; } @@ -233,37 +235,35 @@ class FleetInterface : public FleetInterfaceBase { /** * @brief Get the unique id for the observed index data object. */ - int GetObservedIndexDataID() { - return interface_observed_index_data_id_m; - } + int GetObservedIndexDataID() { return interface_observed_index_data_id_m; } - /** + /** * @brief Extracts the derived quantities from `Information` to the Rcpp - * object. + * object. */ virtual void finalize() { if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("Fleet " + fims::to_string(this->id) + " has been finalized already."); + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("Fleet " + fims::to_string(this->id) + + " has been finalized already."); } - this->finalized = true; //indicate this has been called already + this->finalized = true; // indicate this has been called already std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); fims_info::Information::fleet_iterator it; it = info->fleets.find(this->id); if (it == info->fleets.end()) { - FIMS_WARNING_LOG("Fleet " + fims::to_string(this->id) + " not found in Information."); + FIMS_WARNING_LOG("Fleet " + fims::to_string(this->id) + + " not found in Information."); return; } else { - std::shared_ptr > fleet = - std::dynamic_pointer_cast >(it->second); - + std::dynamic_pointer_cast >(it->second); for (size_t i = 0; i < this->log_Fmort.size(); i++) { if (this->log_Fmort[i].estimated_m) { @@ -281,38 +281,43 @@ class FleetInterface : public FleetInterfaceBase { } } - this->derived_cnaa = Rcpp::NumericVector(fleet->catch_numbers_at_age.size()); + this->derived_cnaa = + Rcpp::NumericVector(fleet->catch_numbers_at_age.size()); for (R_xlen_t i = 0; i < this->derived_cnaa.size(); i++) { this->derived_cnaa[i] = fleet->catch_numbers_at_age[i]; } - this->derived_cnal = Rcpp::NumericVector(fleet->catch_numbers_at_length.size()); + this->derived_cnal = + Rcpp::NumericVector(fleet->catch_numbers_at_length.size()); for (R_xlen_t i = 0; i < this->derived_cnal.size(); i++) { this->derived_cnal[i] = fleet->catch_numbers_at_length[i]; } - this->derived_cwaa = Rcpp::NumericVector(fleet->catch_weight_at_age.size()); + this->derived_cwaa = + Rcpp::NumericVector(fleet->catch_weight_at_age.size()); for (R_xlen_t i = 0; i < this->derived_cwaa.size(); i++) { this->derived_cwaa[i] = fleet->catch_weight_at_age[i]; } - this->derived_age_composition = Rcpp::NumericVector(fleet->proportion_catch_numbers_at_age.size()); + this->derived_age_composition = + Rcpp::NumericVector(fleet->proportion_catch_numbers_at_age.size()); for (R_xlen_t i = 0; i < this->derived_age_composition.size(); i++) { - this->derived_age_composition[i] = fleet->proportion_catch_numbers_at_age[i]; + this->derived_age_composition[i] = + fleet->proportion_catch_numbers_at_age[i]; } - this->derived_length_composition = Rcpp::NumericVector(fleet->proportion_catch_numbers_at_length.size()); + this->derived_length_composition = + Rcpp::NumericVector(fleet->proportion_catch_numbers_at_length.size()); for (R_xlen_t i = 0; i < this->derived_length_composition.size(); i++) { - this->derived_length_composition[i] = fleet->proportion_catch_numbers_at_length[i]; + this->derived_length_composition[i] = + fleet->proportion_catch_numbers_at_length[i]; } this->derived_index = Rcpp::NumericVector(fleet->expected_index.size()); for (R_xlen_t i = 0; i < this->derived_index.size(); i++) { this->derived_index[i] = fleet->expected_index[i]; } - } - } /** @@ -383,7 +388,6 @@ class FleetInterface : public FleetInterfaceBase { } ss << " },\n"; - ss << " \"derived_quantity\": {\n"; ss << " \"name\": \"age_composition \",\n"; ss << " \"values\":["; @@ -393,7 +397,9 @@ class FleetInterface : public FleetInterfaceBase { for (R_xlen_t i = 0; i < this->derived_age_composition.size() - 1; i++) { ss << this->derived_age_composition[i] << ", "; } - ss << this->derived_age_composition[this->derived_age_composition.size() - 1] << "]\n"; + ss << this->derived_age_composition[this->derived_age_composition.size() - + 1] + << "]\n"; } ss << " },\n"; @@ -403,10 +409,13 @@ class FleetInterface : public FleetInterfaceBase { if (this->derived_length_composition.size() == 0) { ss << "]\n"; } else { - for (R_xlen_t i = 0; i < this->derived_length_composition.size() - 1; i++) { + for (R_xlen_t i = 0; i < this->derived_length_composition.size() - 1; + i++) { ss << this->derived_length_composition[i] << ", "; } - ss << this->derived_length_composition[this->derived_length_composition.size() - 1] << "]\n"; + ss << this->derived_length_composition + [this->derived_length_composition.size() - 1] + << "]\n"; } ss << " },\n"; @@ -424,20 +433,17 @@ class FleetInterface : public FleetInterfaceBase { ss << " },\n"; return ss.str(); - } - - #ifdef TMB_MODEL template bool add_to_fims_tmb_internal() { std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); std::shared_ptr > fleet = - std::make_shared >(); + std::make_shared >(); // set relative info fleet->id = this->id; @@ -446,9 +452,9 @@ class FleetInterface : public FleetInterfaceBase { fleet->nlengths = this->nlengths; fleet->nyears = this->nyears; fleet->fleet_observed_agecomp_data_id_m = - interface_observed_agecomp_data_id_m; + interface_observed_agecomp_data_id_m; fleet->fleet_observed_lengthcomp_data_id_m = - interface_observed_lengthcomp_data_id_m; + interface_observed_lengthcomp_data_id_m; fleet->fleet_observed_index_data_id_m = interface_observed_index_data_id_m; fleet->fleet_selectivity_id_m = interface_selectivity_id_m; @@ -458,15 +464,14 @@ class FleetInterface : public FleetInterfaceBase { if (this->log_q[i].estimated_m) { info->RegisterParameterName("log_q"); - if (this->log_q[i].is_random_effect_m) { - info->RegisterRandomEffect(fleet->log_q[i]); - } else { - info->RegisterParameter(fleet->log_q[i]); - } + if (this->log_q[i].is_random_effect_m) { + info->RegisterRandomEffect(fleet->log_q[i]); + } else { + info->RegisterParameter(fleet->log_q[i]); + } } } - fleet->log_Fmort.resize(this->log_Fmort.size()); for (size_t i = 0; i < log_Fmort.size(); i++) { fleet->log_Fmort[i] = this->log_Fmort[i].initial_value_m; @@ -480,21 +485,24 @@ class FleetInterface : public FleetInterfaceBase { } } } - //add to variable_map + // add to variable_map info->variable_map[this->log_Fmort.id_m] = &(fleet)->log_Fmort; - //exp_catch + // exp_catch fleet->log_expected_index.resize(nyears); // assume index is for all ages. - info->variable_map[this->log_expected_index.id_m] = &(fleet)->log_expected_index; + info->variable_map[this->log_expected_index.id_m] = + &(fleet)->log_expected_index; fleet->proportion_catch_numbers_at_age.resize(nyears * nages); - info->variable_map[this->proportion_catch_numbers_at_age.id_m] = &(fleet)->proportion_catch_numbers_at_age; + info->variable_map[this->proportion_catch_numbers_at_age.id_m] = + &(fleet)->proportion_catch_numbers_at_age; - if(this->nlengths > 0){ + if (this->nlengths > 0) { fleet->proportion_catch_numbers_at_length.resize(nyears * nlengths); fleet->age_length_conversion_matrix.resize(nages * nlengths); - for (size_t i = 0; i < fleet->age_length_conversion_matrix.size(); i++){ - fleet->age_length_conversion_matrix[i] = this->age_length_conversion_matrix[i].initial_value_m; - + for (size_t i = 0; i < fleet->age_length_conversion_matrix.size(); i++) { + fleet->age_length_conversion_matrix[i] = + this->age_length_conversion_matrix[i].initial_value_m; + if (this->age_length_conversion_matrix[i].estimated_m) { info->RegisterParameterName("age_length_conversion_matrix"); if (this->age_length_conversion_matrix[i].is_random_effect_m) { @@ -504,8 +512,10 @@ class FleetInterface : public FleetInterfaceBase { } } } - info->variable_map[this->age_length_conversion_matrix.id_m] = &(fleet)->age_length_conversion_matrix; - info->variable_map[this->proportion_catch_numbers_at_length.id_m] = &(fleet)->proportion_catch_numbers_at_length; + info->variable_map[this->age_length_conversion_matrix.id_m] = + &(fleet)->age_length_conversion_matrix; + info->variable_map[this->proportion_catch_numbers_at_length.id_m] = + &(fleet)->proportion_catch_numbers_at_length; } // add to Information diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_growth.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_growth.hpp index 37220a77..eb7cf082 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_growth.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_growth.hpp @@ -143,14 +143,14 @@ class EWAAGrowthInterface : public GrowthInterfaceBase { EWAAGrowth.ewaa = this->ewaa; return EWAAGrowth.evaluate(age); } - + /** * @brief Converts the data to json representation for the output. * @return A string is returned specifying that the module relates to the * growth interface with empirical weight at age. It also returns the ID, the * rank of 1, the dimensions, age bins, and the calculated values themselves. * This string is formatted for a json file. - */ + */ virtual std::string to_json() { std::stringstream ss; ss << "\"module\" : {\n"; @@ -162,28 +162,28 @@ class EWAAGrowthInterface : public GrowthInterfaceBase { ss << " \"ages\": ["; for (size_t i = 0; i < ages.size() - 1; i++) { - ss << ages[i] << ", "; + ss << ages[i] << ", "; } ss << ages[ages.size() - 1] << "],\n"; ss << " \"values\": ["; for (size_t i = 0; i < weights.size() - 1; i++) { - ss << weights[i] << ", "; + ss << weights[i] << ", "; } ss << weights[weights.size() - 1] << "]\n"; ss << "}"; return ss.str(); } - + #ifdef TMB_MODEL template bool add_to_fims_tmb_internal() { std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); std::shared_ptr > ewaa_growth = - std::make_shared >(); + std::make_shared >(); // set relative info ewaa_growth->id = this->id; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp index b10a6645..e6f6ed1f 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_interface_base.hpp @@ -10,6 +10,7 @@ #define FIMS_INTERFACE_RCPP_RCPP_OBJECTS_RCPP_INTERFACE_BASE_HPP #include + #include #include @@ -67,25 +68,31 @@ class Parameter { * @brief The constructor for initializing a parameter. */ Parameter(double value, double min, double max, bool estimated) - : id_m(Parameter::id_g++), initial_value_m(value), min_m(min), max_m(max), estimated_m(estimated) {} + : id_m(Parameter::id_g++), + initial_value_m(value), + min_m(min), + max_m(max), + estimated_m(estimated) {} /** * @brief The constructor for initializing a parameter. */ - Parameter(const Parameter& other) : - id_m(other.id_m), initial_value_m(other.initial_value_m), - final_value_m(other.final_value_m), - min_m(other.min_m), max_m(other.max_m), - is_random_effect_m(other.is_random_effect_m), - estimated_m(other.estimated_m) {} + Parameter(const Parameter& other) + : id_m(other.id_m), + initial_value_m(other.initial_value_m), + final_value_m(other.final_value_m), + min_m(other.min_m), + max_m(other.max_m), + is_random_effect_m(other.is_random_effect_m), + estimated_m(other.estimated_m) {} /** * @brief The constructor for initializing a parameter. */ Parameter& operator=(const Parameter& right) { // Check for self-assignment! - if (this == &right) // Same object? - return *this; // Yes, so skip assignment, and just return *this. + if (this == &right) // Same object? + return *this; // Yes, so skip assignment, and just return *this. this->id_m = right.id_m; this->initial_value_m = right.initial_value_m; this->estimated_m = right.estimated_m; @@ -95,8 +102,6 @@ class Parameter { return *this; } - - /** * @brief The constructor for initializing a parameter. */ @@ -111,24 +116,25 @@ class Parameter { */ Parameter() { initial_value_m = 0; - id_m = Parameter::id_g++;} + id_m = Parameter::id_g++; + } }; - /** - * @brief The unique ID for the variable map that points to a fims::Vector. - */ - uint32_t Parameter::id_g = 0; +/** + * @brief The unique ID for the variable map that points to a fims::Vector. + */ +uint32_t Parameter::id_g = 0; /** * @brief Output for std::ostream& for a parameter. * * @param out The stream. * @param p A parameter. - * @return std::ostream& + * @return std::ostream& */ std::ostream& operator<<(std::ostream& out, const Parameter& p) { out << "{id:" << p.id_m << ",\nvalue:" << p.initial_value_m - << ",\nestimated_value:" << p.final_value_m << ",\nmin:" - << p.min_m << ",\nmax:" << p.max_m << ",\nestimated:" << p.estimated_m << "\n}"; + << ",\nestimated_value:" << p.final_value_m << ",\nmin:" << p.min_m + << ",\nmax:" << p.max_m << ",\nestimated:" << p.estimated_m << "\n}"; return out; } @@ -138,8 +144,8 @@ std::ostream& operator<<(std::ostream& out, const Parameter& p) { * @details An Rcpp interface class that defines the interface between R and * C++ for a parameter vector type. */ -class ParameterVector{ -public: +class ParameterVector { + public: /** * @brief The static ID of the Parameter object. */ @@ -156,27 +162,27 @@ class ParameterVector{ /** * @brief The constructor. */ - ParameterVector(){ + ParameterVector() { this->id_m = ParameterVector::id_g++; this->storage_m = std::make_shared >(); - this->storage_m->resize(1); //push_back(Rcpp::wrap(p)); + this->storage_m->resize(1); // push_back(Rcpp::wrap(p)); } /** * @brief The constructor. */ - ParameterVector(const ParameterVector& other) : - storage_m(other.storage_m), id_m(other.id_m) {} + ParameterVector(const ParameterVector& other) + : storage_m(other.storage_m), id_m(other.id_m) {} /** * @brief The constructor. */ - ParameterVector(size_t size ){ + ParameterVector(size_t size) { this->id_m = ParameterVector::id_g++; this->storage_m = std::make_shared >(); this->storage_m->resize(size); for (size_t i = 0; i < size; i++) { - storage_m->at(i) = Parameter(); + storage_m->at(i) = Parameter(); } } @@ -185,7 +191,7 @@ class ParameterVector{ * @param x A numeric vector. * @param size The number of elements to copy over. */ - ParameterVector(Rcpp::NumericVector x, size_t size){ + ParameterVector(Rcpp::NumericVector x, size_t size) { this->id_m = ParameterVector::id_g++; this->storage_m = std::make_shared >(); this->resize(size); @@ -209,9 +215,9 @@ class ParameterVector{ /** * @brief Destroy the Parameter Vector object. - * + * */ - virtual ~ParameterVector(){} + virtual ~ParameterVector() {} /** * @brief Gets the ID of the ParameterVector object. @@ -222,20 +228,19 @@ class ParameterVector{ * @brief The accessor where the first index starts is zero. * @param pos The position of the ParameterVector that you want returned. */ - inline Parameter& operator[](size_t pos) { - return this->storage_m->at(pos); - } + inline Parameter& operator[](size_t pos) { return this->storage_m->at(pos); } /** * @brief The accessor where the first index starts at one. This function is * for calling accessing from R. * @param pos The position of the ParameterVector that you want returned. */ - SEXP at(R_xlen_t pos){ + SEXP at(R_xlen_t pos) { if (static_cast(pos) == 0 || - static_cast(pos) > this->storage_m->size()) { + static_cast(pos) > this->storage_m->size()) { Rcpp::Rcout << "ParameterVector: Index out of range.\n"; - FIMS_ERROR_LOG(fims::to_string(pos) + "!<" + fims::to_string(this->size())); + FIMS_ERROR_LOG(fims::to_string(pos) + "!<" + + fims::to_string(this->size())); return NULL; } return Rcpp::wrap(this->storage_m->at(pos - 1)); @@ -265,25 +270,19 @@ class ParameterVector{ * @param p A numeric value specifying the value to set position `pos` to * in the ParameterVector. */ - void set(size_t pos, const Parameter& p) { - this->storage_m->at(pos) = p; - } + void set(size_t pos, const Parameter& p) { this->storage_m->at(pos) = p; } /** * @brief Returns the size of a ParameterVector. */ - size_t size() { - return this->storage_m->size(); - } + size_t size() { return this->storage_m->size(); } /** * @brief Resizes a ParameterVector to the desired length. * @param size An integer specifying the desired length for the * ParameterVector to be resized to. */ - void resize(size_t size) { - this->storage_m->resize(size); - } + void resize(size_t size) { this->storage_m->resize(size); } /** * @brief Sets all Parameters within a ParameterVector as estimable. @@ -292,7 +291,7 @@ class ParameterVector{ * ParameterVector should be estimated within the model. A value of true * leads to all Parameters being estimated. */ - void set_all_estimable(bool estimable){ + void set_all_estimable(bool estimable) { for (size_t i = 0; i < this->storage_m->size(); i++) { storage_m->at(i).estimated_m = estimable; } @@ -305,7 +304,7 @@ class ParameterVector{ * ParameterVector should be designated as random effects. A value of true * leads to all Parameters being random effects. */ - void set_all_random(bool random){ + void set_all_random(bool random) { for (size_t i = 0; i < this->storage_m->size(); i++) { storage_m->at(i).is_random_effect_m = random; } @@ -318,7 +317,7 @@ class ParameterVector{ * @param value A double specifying the value to set all Parameters to * within the ParameterVector. */ - void fill(double value){ + void fill(double value) { for (size_t i = 0; i < this->storage_m->size(); i++) { storage_m->at(i).initial_value_m = value; } @@ -330,7 +329,7 @@ class ParameterVector{ * * @param value The value to be assigned. */ - void fill_min(double value){ + void fill_min(double value) { for (size_t i = 0; i < this->storage_m->size(); i++) { storage_m->at(i).min_m = value; } @@ -342,7 +341,7 @@ class ParameterVector{ * * @param value The value to be assigned. */ - void fill_max(double value){ + void fill_max(double value) { for (size_t i = 0; i < this->storage_m->size(); i++) { storage_m->at(i).max_m = value; } @@ -359,7 +358,6 @@ class ParameterVector{ Rcpp::Rcout << storage_m->at(i) << " "; } } - }; uint32_t ParameterVector::id_g = 0; @@ -368,7 +366,7 @@ uint32_t ParameterVector::id_g = 0; * * @param out The stream. * @param v A ParameterVector. - * @return std::ostream& + * @return std::ostream& */ std::ostream& operator<<(std::ostream& out, ParameterVector& v) { out << "["; @@ -384,7 +382,7 @@ std::ostream& operator<<(std::ostream& out, ParameterVector& v) { *@brief Base class for all interface objects. */ class FIMSRcppInterfaceBase { -public: + public: /** * @brief Is the object already finalized? The default is false. */ @@ -392,31 +390,28 @@ class FIMSRcppInterfaceBase { /** * @brief FIMS interface object vectors. */ - static std::vector fims_interface_objects; + static std::vector fims_interface_objects; /** * @brief A virtual method to inherit to add objects to the TMB model. */ virtual bool add_to_fims_tmb() { Rcpp::Rcout << "fims_rcpp_interface_base::add_to_fims_tmb(): Not yet " - "implemented.\n"; + "implemented.\n"; return false; } - /** + /** * @brief Extracts derived quantities back to the Rcpp interface object from - * the Information object. + * the Information object. */ - virtual void finalize() { - } + virtual void finalize() {} /** * @brief Convert the data to json representation for the output. */ - virtual std::string to_json() { - return ""; - } + virtual std::string to_json() { return ""; } }; -std::vector - FIMSRcppInterfaceBase::fims_interface_objects; +std::vector + FIMSRcppInterfaceBase::fims_interface_objects; #endif diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_lpdf.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_lpdf.hpp index 2e6a999d..822c0b64 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_lpdf.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_lpdf.hpp @@ -25,7 +25,7 @@ class LPDFInterfaceBase : public FIMSRcppInterfaceBase { /** * @brief The local ID of the LPDFInterfaceBase object. * TODO: think about why this is not id_m like other modules? - */ + */ uint32_t id; /** * @brief The map associating the ID of the LPDFInterfaceBase to the diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp index b3f5d04f..d7615340 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_maturity.hpp @@ -71,9 +71,9 @@ std::map MaturityInterfaceBase::live_objects; * logistic_maturity <- methods::new(logistic_maturity). */ class LogisticMaturityInterface : public MaturityInterfaceBase { -public: + public: /** - * @brief The index value at which the response reaches 0.5. + * @brief The index value at which the response reaches 0.5. */ ParameterVector inflection_point; /** @@ -111,38 +111,42 @@ class LogisticMaturityInterface : public MaturityInterfaceBase { return LogisticMat.evaluate(x); } - /** + /** * @brief Extracts derived quantities back to the Rcpp interface object from * the Information object. */ virtual void finalize() { if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("Logistic Maturity " + fims::to_string(this->id) + " has been finalized already."); + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("Logistic Maturity " + fims::to_string(this->id) + + " has been finalized already."); } - this->finalized = true; //indicate this has been called already + this->finalized = true; // indicate this has been called already std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); fims_info::Information::maturity_models_iterator it; - //search for maturity in Information + // search for maturity in Information it = info->maturity_models.find(this->id); - //if not found, just return + // if not found, just return if (it == info->maturity_models.end()) { - FIMS_WARNING_LOG("Logistic Maturity " + fims::to_string(this->id) + " not found in Information."); + FIMS_WARNING_LOG("Logistic Maturity " + fims::to_string(this->id) + + " not found in Information."); return; } else { std::shared_ptr > mat = - std::dynamic_pointer_cast >(it->second); + std::dynamic_pointer_cast >( + it->second); for (size_t i = 0; i < inflection_point.size(); i++) { if (this->inflection_point[i].estimated_m) { this->inflection_point[i].final_value_m = mat->inflection_point[i]; } else { - this->inflection_point[i].final_value_m = this->inflection_point[i].initial_value_m; + this->inflection_point[i].final_value_m = + this->inflection_point[i].initial_value_m; } } @@ -161,7 +165,7 @@ class LogisticMaturityInterface : public MaturityInterfaceBase { * @return A string is returned specifying that the module relates to the * maturity interface with logistic maturity. It also returns the ID and the * parameters. This string is formatted for a json file. - */ + */ virtual std::string to_json() { std::stringstream ss; ss << "\"module\" : {\n"; @@ -191,10 +195,10 @@ class LogisticMaturityInterface : public MaturityInterfaceBase { template bool add_to_fims_tmb_internal() { std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); std::shared_ptr > maturity = - std::make_shared >(); + std::make_shared >(); // set relative info maturity->id = this->id; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp index 8a1d15c5..823c9d86 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_population.hpp @@ -27,9 +27,9 @@ class PopulationInterfaceBase : public FIMSRcppInterfaceBase { */ uint32_t id; /** - * @brief The map associating the IDs of PopulationInterfaceBase to the objects. - * This is a live object, which is an object that has been created and lives - * in memory. + * @brief The map associating the IDs of PopulationInterfaceBase to the + * objects. This is a live object, which is an object that has been created + * and lives in memory. */ static std::map live_objects; @@ -59,7 +59,7 @@ uint32_t PopulationInterfaceBase::id_g = 1; // local id of the PopulationInterfaceBase object map relating the ID of the // PopulationInterfaceBase to the PopulationInterfaceBase objects std::map - PopulationInterfaceBase::live_objects; + PopulationInterfaceBase::live_objects; /** * @brief Rcpp interface for a new Population to instantiate from R: @@ -193,27 +193,29 @@ class PopulationInterface : public PopulationInterfaceBase { return population.Evaluate(); } - /** + /** * @brief Extracts derived quantities back to the Rcpp interface object from - * the Information object. + * the Information object. */ virtual void finalize() { if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("Population " + fims::to_string(this->id) + " has been finalized already."); + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("Population " + fims::to_string(this->id) + + " has been finalized already."); } - this->finalized = true; //indicate this has been called already + this->finalized = true; // indicate this has been called already std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); this->estimated_log_M = Rcpp::NumericVector(this->log_M.size()); for (size_t i = 0; i < this->log_M.size(); i++) { this->estimated_log_M[i] = this->log_M[i].initial_value_m; } - this->estimated_log_init_naa = Rcpp::NumericVector(this->log_init_naa.size()); + this->estimated_log_init_naa = + Rcpp::NumericVector(this->log_init_naa.size()); for (size_t i = 0; i < this->log_init_naa.size(); i++) { this->estimated_log_init_naa[i] = this->log_init_naa[i].initial_value_m; } @@ -223,10 +225,11 @@ class PopulationInterface : public PopulationInterfaceBase { it = info->populations.find(this->id); std::shared_ptr > pop = - info->populations[this->id]; + info->populations[this->id]; it = info->populations.find(this->id); if (it == info->populations.end()) { - FIMS_WARNING_LOG("Population " + fims::to_string(this->id) + " not found in Information."); + FIMS_WARNING_LOG("Population " + fims::to_string(this->id) + + " not found in Information."); return; } else { if (this->estimated_log_M) { @@ -244,30 +247,29 @@ class PopulationInterface : public PopulationInterfaceBase { this->derived_naa = Rcpp::NumericVector(pop->numbers_at_age.size()); this->derived_ssb = Rcpp::NumericVector(pop->spawning_biomass.size()); this->derived_biomass = Rcpp::NumericVector(pop->biomass.size()); - this->derived_recruitment = Rcpp::NumericVector(pop->expected_recruitment.size()); + this->derived_recruitment = + Rcpp::NumericVector(pop->expected_recruitment.size()); - //set naa from Information/ + // set naa from Information/ for (R_xlen_t i = 0; i < this->derived_naa.size(); i++) { this->derived_naa[i] = pop->numbers_at_age[i]; } - //set ssb from Information/ + // set ssb from Information/ for (R_xlen_t i = 0; i < this->derived_ssb.size(); i++) { this->derived_ssb[i] = pop->spawning_biomass[i]; } - //set biomass from Information + // set biomass from Information for (R_xlen_t i = 0; i < this->derived_biomass.size(); i++) { this->derived_biomass[i] = pop->biomass[i]; } - //set recruitment from Information/ + // set recruitment from Information/ for (R_xlen_t i = 0; i < this->derived_recruitment.size(); i++) { this->derived_recruitment[i] = pop->expected_recruitment[i]; } - } - } /** @@ -276,7 +278,7 @@ class PopulationInterface : public PopulationInterfaceBase { * population interface. It also returns the ID for each associated module * and the values associated with that module. Then it returns several * derived quantities. This string is formatted for a json file. - */ + */ virtual std::string to_json() { std::stringstream ss; @@ -350,7 +352,8 @@ class PopulationInterface : public PopulationInterfaceBase { for (R_xlen_t i = 0; i < this->derived_recruitment.size() - 1; i++) { ss << this->derived_recruitment[i] << ", "; } - ss << this->derived_recruitment[this->derived_recruitment.size() - 1] << "]\n"; + ss << this->derived_recruitment[this->derived_recruitment.size() - 1] + << "]\n"; } ss << " }\n"; @@ -359,7 +362,6 @@ class PopulationInterface : public PopulationInterfaceBase { return ss.str(); } - #ifdef TMB_MODEL template @@ -390,8 +392,8 @@ class PopulationInterface : public PopulationInterfaceBase { for (size_t i = 0; i < log_M.size(); i++) { population->log_M[i] = this->log_M[i].initial_value_m; if (this->log_M[i].estimated_m) { - info->RegisterParameterName("log_M"); - info->RegisterParameter(population->log_M[i]); + info->RegisterParameterName("log_M"); + info->RegisterParameter(population->log_M[i]); } } info->variable_map[this->log_M.id_m] = &(population)->log_M; @@ -409,7 +411,8 @@ class PopulationInterface : public PopulationInterfaceBase { } population->numbers_at_age.resize((nyears + 1) * nages); - info->variable_map[this->numbers_at_age.id_m] = &(population)->numbers_at_age; + info->variable_map[this->numbers_at_age.id_m] = + &(population)->numbers_at_age; // add to Information info->populations[population->id] = population; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp index e75e2ffc..545505c1 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_recruitment.hpp @@ -135,9 +135,8 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { BevHolt.logit_steep[0] = this->logit_steep[0].initial_value_m; if (this->logit_steep[0].initial_value_m == 1.0) { warning( - "Steepness is subject to a logit transformation. " - "Fixing it at 1.0 is not currently possible." - ); + "Steepness is subject to a logit transformation. " + "Fixing it at 1.0 is not currently possible."); } BevHolt.log_rzero.resize(1); BevHolt.log_rzero[0] = this->log_rzero[0].initial_value_m; @@ -145,37 +144,43 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { return BevHolt.evaluate(spawners, ssbzero); } - /** + /** * @brief Extracts derived quantities back to the Rcpp interface object from - * the Information object. + * the Information object. */ virtual void finalize() { if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("Beverton-Holt Recruitment " + fims::to_string(this->id) + " has been finalized already."); + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("Beverton-Holt Recruitment " + + fims::to_string(this->id) + + " has been finalized already."); } - this->finalized = true; //indicate this has been called already + this->finalized = true; // indicate this has been called already std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); fims_info::Information::recruitment_models_iterator it; it = info->recruitment_models.find(this->id); if (it == info->recruitment_models.end()) { - FIMS_WARNING_LOG("Beverton-Holt Recruitment " + fims::to_string(this->id) + " not found in Information."); + FIMS_WARNING_LOG("Beverton-Holt Recruitment " + + fims::to_string(this->id) + + " not found in Information."); return; } else { std::shared_ptr > recr = - std::dynamic_pointer_cast >(it->second); + std::dynamic_pointer_cast >( + it->second); for (size_t i = 0; i < this->logit_steep.size(); i++) { if (this->logit_steep[i].estimated_m) { this->logit_steep[i].final_value_m = recr->logit_steep[i]; } else { - this->logit_steep[i].final_value_m = this->logit_steep[i].initial_value_m; + this->logit_steep[i].final_value_m = + this->logit_steep[i].initial_value_m; } } @@ -203,9 +208,9 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { * recruitment interface with Beverton--Holt stock--recruitment relationship. * It also returns the ID and the parameters. This string is formatted for a * json file. - */ + */ virtual std::string to_json() { - std::stringstream ss; + std::stringstream ss; ss << "\"module\" : {\n"; ss << " \"name\": \"recruitment\",\n"; @@ -238,14 +243,14 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { template bool add_to_fims_tmb_internal() { std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); std::shared_ptr > recruitment = - std::make_shared >(); + std::make_shared >(); // set relative info recruitment->id = this->id; - //set logit_steep + // set logit_steep recruitment->logit_steep.resize(this->logit_steep.size()); for (size_t i = 0; i < this->logit_steep.size(); i++) { recruitment->logit_steep[i] = this->logit_steep[i].initial_value_m; @@ -258,12 +263,11 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { info->RegisterParameter(recruitment->logit_steep[i]); } } - } info->variable_map[this->logit_steep.id_m] = &(recruitment)->logit_steep; - //set log_rzero + // set log_rzero recruitment->log_rzero.resize(this->log_rzero.size()); for (size_t i = 0; i < this->log_rzero.size(); i++) { recruitment->log_rzero[i] = this->log_rzero[i].initial_value_m; @@ -280,7 +284,7 @@ class BevertonHoltRecruitmentInterface : public RecruitmentInterfaceBase { info->variable_map[this->log_rzero.id_m] = &(recruitment)->log_rzero; - //set log_recruit_devs + // set log_recruit_devs recruitment->log_recruit_devs.resize(this->log_devs.size()); for (size_t i = 0; i < this->log_devs.size(); i++) { recruitment->log_recruit_devs[i] = this->log_devs[i].initial_value_m; diff --git a/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp b/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp index 1ea8a327..c8c8656a 100644 --- a/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp +++ b/inst/include/interface/rcpp/rcpp_objects/rcpp_selectivity.hpp @@ -65,7 +65,7 @@ uint32_t SelectivityInterfaceBase::id_g = 1; // local id of the SelectivityInterfaceBase object map relating the ID of the // SelectivityInterfaceBase to the SelectivityInterfaceBase objects std::map - SelectivityInterfaceBase::live_objects; + SelectivityInterfaceBase::live_objects; /** * @brief Rcpp interface for logistic selectivity to instantiate the object @@ -75,7 +75,7 @@ std::map class LogisticSelectivityInterface : public SelectivityInterfaceBase { public: /** - * @brief The index value at which the response reaches 0.5. + * @brief The index value at which the response reaches 0.5. */ ParameterVector inflection_point; /** @@ -113,38 +113,42 @@ class LogisticSelectivityInterface : public SelectivityInterfaceBase { return LogisticSel.evaluate(x); } - /** + /** * @brief Extracts derived quantities back to the Rcpp interface object from * the Information object. */ virtual void finalize() { if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("Logistic Selectivity " + fims::to_string(this->id) + " has been finalized already."); + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("Logistic Selectivity " + fims::to_string(this->id) + + " has been finalized already."); } - this->finalized = true; //indicate this has been called already + this->finalized = true; // indicate this has been called already std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); fims_info::Information::selectivity_models_iterator it; - //search for maturity in Information + // search for maturity in Information it = info->selectivity_models.find(this->id); - //if not found, just return + // if not found, just return if (it == info->selectivity_models.end()) { - FIMS_WARNING_LOG("Logistic Selectivity " + fims::to_string(this->id) + " not found in Information."); + FIMS_WARNING_LOG("Logistic Selectivity " + fims::to_string(this->id) + + " not found in Information."); return; } else { std::shared_ptr > sel = - std::dynamic_pointer_cast >(it->second); + std::dynamic_pointer_cast >( + it->second); for (size_t i = 0; i < inflection_point.size(); i++) { if (this->inflection_point[i].estimated_m) { this->inflection_point[i].final_value_m = sel->inflection_point[i]; } else { - this->inflection_point[i].final_value_m = this->inflection_point[i].initial_value_m; + this->inflection_point[i].final_value_m = + this->inflection_point[i].initial_value_m; } } @@ -163,7 +167,7 @@ class LogisticSelectivityInterface : public SelectivityInterfaceBase { * @return A string is returned specifying that the module relates to the * selectivity interface with logistic selectivity. It also returns the ID * and the parameters. This string is formatted for a json file. - */ + */ virtual std::string to_json() { std::stringstream ss; @@ -189,49 +193,50 @@ class LogisticSelectivityInterface : public SelectivityInterfaceBase { return ss.str(); } - #ifdef TMB_MODEL template bool add_to_fims_tmb_internal() { std::shared_ptr > info = - fims_info::Information::GetInstance(); + fims_info::Information::GetInstance(); std::shared_ptr > selectivity = - std::make_shared >(); + std::make_shared >(); std::stringstream ss; // set relative info selectivity->id = this->id; - selectivity->inflection_point.resize(this->inflection_point.size()); - for (size_t i = 0; i < this->inflection_point.size(); i++) { - selectivity->inflection_point[i] = this->inflection_point[i].initial_value_m; - if (this->inflection_point[i].estimated_m) { - ss.str(""); - ss << "selectivity.inflection_point." << this->id << "." << i; - info->RegisterParameterName(ss.str()); - if (this->inflection_point[i].is_random_effect_m) { - info->RegisterRandomEffect(selectivity->inflection_point[i]); - } else { - info->RegisterParameter(selectivity->inflection_point[i]); - } + selectivity->inflection_point.resize(this->inflection_point.size()); + for (size_t i = 0; i < this->inflection_point.size(); i++) { + selectivity->inflection_point[i] = + this->inflection_point[i].initial_value_m; + if (this->inflection_point[i].estimated_m) { + ss.str(""); + ss << "selectivity.inflection_point." << this->id << "." << i; + info->RegisterParameterName(ss.str()); + if (this->inflection_point[i].is_random_effect_m) { + info->RegisterRandomEffect(selectivity->inflection_point[i]); + } else { + info->RegisterParameter(selectivity->inflection_point[i]); } } + } - info->variable_map[this->inflection_point.id_m] = &(selectivity)->inflection_point; - selectivity->slope.resize(this->slope.size()); - for (size_t i = 0; i < this->slope.size(); i++) { - selectivity->slope[i] = this->slope[i].initial_value_m; - if (this->slope[i].estimated_m) { - ss.str(""); - ss << "selectivity.slope." << this->id << "." << i; - info->RegisterParameterName(ss.str()); - if (this->slope[i].is_random_effect_m) { - info->RegisterRandomEffect(selectivity->slope[i]); - } else { - info->RegisterParameter(selectivity->slope[i]); - } + info->variable_map[this->inflection_point.id_m] = + &(selectivity)->inflection_point; + selectivity->slope.resize(this->slope.size()); + for (size_t i = 0; i < this->slope.size(); i++) { + selectivity->slope[i] = this->slope[i].initial_value_m; + if (this->slope[i].estimated_m) { + ss.str(""); + ss << "selectivity.slope." << this->id << "." << i; + info->RegisterParameterName(ss.str()); + if (this->slope[i].is_random_effect_m) { + info->RegisterRandomEffect(selectivity->slope[i]); + } else { + info->RegisterParameter(selectivity->slope[i]); } } + } info->variable_map[this->slope.id_m] = &(selectivity)->slope; // add to Information @@ -259,17 +264,19 @@ class LogisticSelectivityInterface : public SelectivityInterfaceBase { /** * @brief Rcpp interface for logistic selectivity as an S4 object. To - * instantiate from R: logistic_selectivity <- methods::new(logistic_selectivity) + * instantiate from R: logistic_selectivity <- + * methods::new(logistic_selectivity) */ class DoubleLogisticSelectivityInterface : public SelectivityInterfaceBase { public: - ParameterVector inflection_point_asc; /**< the index value at which the response - reaches .5 */ - ParameterVector slope_asc; /**< the width of the curve at the inflection_point */ - ParameterVector inflection_point_desc; /**< the index value at which the response - reaches .5 */ - ParameterVector slope_desc; /**< the width of the curve at the inflection_point */ - + ParameterVector inflection_point_asc; /**< the index value at which the + response reaches .5 */ + ParameterVector + slope_asc; /**< the width of the curve at the inflection_point */ + ParameterVector inflection_point_desc; /**< the index value at which the + response reaches .5 */ + ParameterVector + slope_desc; /**< the width of the curve at the inflection_point */ DoubleLogisticSelectivityInterface() : SelectivityInterfaceBase() {} @@ -285,7 +292,8 @@ class DoubleLogisticSelectivityInterface : public SelectivityInterfaceBase { virtual double evaluate(double x) { fims_popdy::DoubleLogisticSelectivity DoubleLogisticSel; DoubleLogisticSel.inflection_point_asc.resize(1); - DoubleLogisticSel.inflection_point_asc[0] = this->inflection_point_asc[0].initial_value_m; + DoubleLogisticSel.inflection_point_asc[0] = + this->inflection_point_asc[0].initial_value_m; DoubleLogisticSel.slope_asc.resize(1); DoubleLogisticSel.slope_asc[0] = this->slope_asc[0].initial_value_m; DoubleLogisticSel.inflection_point_desc.resize(1); @@ -295,119 +303,116 @@ class DoubleLogisticSelectivityInterface : public SelectivityInterfaceBase { DoubleLogisticSel.slope_desc[0] = this->slope_desc[0].initial_value_m; return DoubleLogisticSel.evaluate(x); } - /** - * @brief finalize function. Extracts derived quantities back to - * the Rcpp interface object from the Information object. - */ - virtual void finalize() { - - if (this->finalized) { - //log warning that finalize has been called more than once. - FIMS_WARNING_LOG("Double Logistic Selectivity " + fims::to_string(this->id) + " has been finalized already."); - } - - this->finalized = true; //indicate this has been called already - - std::shared_ptr > info = - fims_info::Information::GetInstance(); + /** + * @brief finalize function. Extracts derived quantities back to + * the Rcpp interface object from the Information object. + */ + virtual void finalize() { + if (this->finalized) { + // log warning that finalize has been called more than once. + FIMS_WARNING_LOG("Double Logistic Selectivity " + + fims::to_string(this->id) + + " has been finalized already."); + } + this->finalized = true; // indicate this has been called already + std::shared_ptr > info = + fims_info::Information::GetInstance(); - fims_info::Information::selectivity_models_iterator it; + fims_info::Information::selectivity_models_iterator it; - //search for maturity in Information - it = info->selectivity_models.find(this->id); - //if not found, just return - if (it == info->selectivity_models.end()) { - FIMS_WARNING_LOG("Double Logistic Selectivity " + fims::to_string(this->id) + " not found in Information."); - return; + // search for maturity in Information + it = info->selectivity_models.find(this->id); + // if not found, just return + if (it == info->selectivity_models.end()) { + FIMS_WARNING_LOG("Double Logistic Selectivity " + + fims::to_string(this->id) + + " not found in Information."); + return; + } else { + std::shared_ptr > sel = + std::dynamic_pointer_cast< + fims_popdy::DoubleLogisticSelectivity >(it->second); + + for (size_t i = 0; i < inflection_point_asc.size(); i++) { + if (this->inflection_point_asc[i].estimated_m) { + this->inflection_point_asc[i].final_value_m = + sel->inflection_point_asc[i]; } else { - std::shared_ptr > sel = - std::dynamic_pointer_cast >(it->second); - - - for (size_t i = 0; i < inflection_point_asc.size(); i++) { - if (this->inflection_point_asc[i].estimated_m) { - this->inflection_point_asc[i].final_value_m = sel->inflection_point_asc[i]; - } else { - this->inflection_point_asc[i].final_value_m = this->inflection_point_asc[i].initial_value_m; - } - - } + this->inflection_point_asc[i].final_value_m = + this->inflection_point_asc[i].initial_value_m; + } + } - for (size_t i = 0; i < slope_asc.size(); i++) { - if (this->slope_asc[i].estimated_m) { - this->slope_asc[i].final_value_m = sel->slope_asc[i]; - } else { - this->slope_asc[i].final_value_m = this->slope_asc[i].initial_value_m; - } + for (size_t i = 0; i < slope_asc.size(); i++) { + if (this->slope_asc[i].estimated_m) { + this->slope_asc[i].final_value_m = sel->slope_asc[i]; + } else { + this->slope_asc[i].final_value_m = this->slope_asc[i].initial_value_m; + } + } - } + for (size_t i = 0; i < inflection_point_desc.size(); i++) { + if (this->inflection_point_desc[i].estimated_m) { + this->inflection_point_desc[i].final_value_m = + sel->inflection_point_desc[i]; + } else { + this->inflection_point_desc[i].final_value_m = + this->inflection_point_desc[i].initial_value_m; + } + } - for (size_t i = 0; i < inflection_point_desc.size(); i++) { - if (this->inflection_point_desc[i].estimated_m) { - this->inflection_point_desc[i].final_value_m = sel->inflection_point_desc[i]; - } else { - this->inflection_point_desc[i].final_value_m = this->inflection_point_desc[i].initial_value_m; - } + for (size_t i = 0; i < slope_desc.size(); i++) { + if (this->slope_desc[i].estimated_m) { + this->slope_desc[i].final_value_m = sel->slope_desc[i]; + } else { + this->slope_desc[i].final_value_m = + this->slope_desc[i].initial_value_m; + } + } + } + } - } + /** + * @brief Convert the data to json representation for the output. + */ + virtual std::string to_json() { + std::stringstream ss; - for (size_t i = 0; i < slope_desc.size(); i++) { - if (this->slope_desc[i].estimated_m) { - this->slope_desc[i].final_value_m = sel->slope_desc[i]; - } else { - this->slope_desc[i].final_value_m = this->slope_desc[i].initial_value_m; - } + ss << "\"module\" : {\n"; + ss << " \"name\": \"selectivity\",\n"; + ss << " \"type\": \"DoubleLogistic\",\n"; + ss << " \"id\": " << this->id << ",\n"; - } + ss << " \"parameter\": {\n"; + ss << " \"name\": \"inflection_point_asc\",\n"; + ss << " \"id\":" << this->inflection_point_asc.id_m << ",\n"; + ss << " \"type\": \"vector\",\n"; + ss << " \"values\":" << this->inflection_point_asc << ",\n},\n"; + ss << " \"parameter\": {\n"; + ss << " \"name\": \"slope_asc\",\n"; + ss << " \"id\":" << this->slope_asc.id_m << ",\n"; + ss << " \"type\": \"vector\",\n"; + ss << " \"values\":" << this->slope_asc << ",\n},\n"; + ss << " \"parameter\": {\n"; + ss << " \"name\": \"inflection_point_desc\",\n"; + ss << " \"id\":" << this->inflection_point_desc.id_m << ",\n"; + ss << " \"type\": \"vector\",\n"; + ss << " \"values\":" << this->inflection_point_desc << ",\n},\n"; - } - } + ss << " \"parameter\": {\n"; + ss << " \"name\": \"slope_desc\",\n"; + ss << " \"id\":" << this->slope_desc.id_m << ",\n"; + ss << " \"type\": \"vector\",\n"; + ss << " \"values\":" << this->slope_desc << ",\n}\n"; - /** - * @brief Convert the data to json representation for the output. - */ - virtual std::string to_json() { - std::stringstream ss; - - ss << "\"module\" : {\n"; - ss << " \"name\": \"selectivity\",\n"; - ss << " \"type\": \"DoubleLogistic\",\n"; - ss << " \"id\": " << this->id << ",\n"; - - ss << " \"parameter\": {\n"; - ss << " \"name\": \"inflection_point_asc\",\n"; - ss << " \"id\":" << this->inflection_point_asc.id_m << ",\n"; - ss << " \"type\": \"vector\",\n"; - ss << " \"values\":" << this->inflection_point_asc << ",\n},\n"; - - ss << " \"parameter\": {\n"; - ss << " \"name\": \"slope_asc\",\n"; - ss << " \"id\":" << this->slope_asc.id_m << ",\n"; - ss << " \"type\": \"vector\",\n"; - ss << " \"values\":" << this->slope_asc << ",\n},\n"; - - ss << " \"parameter\": {\n"; - ss << " \"name\": \"inflection_point_desc\",\n"; - ss << " \"id\":" << this->inflection_point_desc.id_m << ",\n"; - ss << " \"type\": \"vector\",\n"; - ss << " \"values\":" << this->inflection_point_desc << ",\n},\n"; - - ss << " \"parameter\": {\n"; - ss << " \"name\": \"slope_desc\",\n"; - ss << " \"id\":" << this->slope_desc.id_m << ",\n"; - ss << " \"type\": \"vector\",\n"; - ss << " \"values\":" << this->slope_desc << ",\n}\n"; - - - ss << "}"; - - return ss.str(); - } + ss << "}"; + return ss.str(); + } #ifdef TMB_MODEL @@ -419,74 +424,77 @@ class DoubleLogisticSelectivityInterface : public SelectivityInterfaceBase { std::shared_ptr > selectivity = std::make_shared >(); - std::stringstream ss; - // set relative info - selectivity->id = this->id; - selectivity->inflection_point_asc.resize(this->inflection_point_asc.size()); - for (size_t i = 0; i < this->inflection_point_asc.size(); i++) { - selectivity->inflection_point_asc[i] = this->inflection_point_asc[i].initial_value_m; - if (this->inflection_point_asc[i].estimated_m) { - ss.str(""); - ss << "selectivity.inflection_point_asc." << this->id << "." << i; - info->RegisterParameterName(ss.str()); - if (this->inflection_point_asc[i].is_random_effect_m) { - info->RegisterRandomEffect(selectivity->inflection_point_asc[i]); - } else { - info->RegisterParameter(selectivity->inflection_point_asc[i]); - } - } + std::stringstream ss; + // set relative info + selectivity->id = this->id; + selectivity->inflection_point_asc.resize(this->inflection_point_asc.size()); + for (size_t i = 0; i < this->inflection_point_asc.size(); i++) { + selectivity->inflection_point_asc[i] = + this->inflection_point_asc[i].initial_value_m; + if (this->inflection_point_asc[i].estimated_m) { + ss.str(""); + ss << "selectivity.inflection_point_asc." << this->id << "." << i; + info->RegisterParameterName(ss.str()); + if (this->inflection_point_asc[i].is_random_effect_m) { + info->RegisterRandomEffect(selectivity->inflection_point_asc[i]); + } else { + info->RegisterParameter(selectivity->inflection_point_asc[i]); } + } + } - info->variable_map[this->inflection_point_asc.id_m] = &(selectivity)->inflection_point_asc; - - - selectivity->slope_asc.resize(this->slope_asc.size()); - for (size_t i = 0; i < this->slope_asc.size(); i++) { - selectivity->slope_asc[i] = this->slope_asc[i].initial_value_m; - if (this->slope_asc[i].estimated_m) { - ss.str(""); - ss << "selectivity.slope_asc." << this->id << "." << i; - info->RegisterParameterName(ss.str()); - if (this->slope_asc[i].is_random_effect_m) { - info->RegisterRandomEffect(selectivity->slope_asc[i]); - } else { - info->RegisterParameter(selectivity->slope_asc[i]); - } - } + info->variable_map[this->inflection_point_asc.id_m] = + &(selectivity)->inflection_point_asc; + + selectivity->slope_asc.resize(this->slope_asc.size()); + for (size_t i = 0; i < this->slope_asc.size(); i++) { + selectivity->slope_asc[i] = this->slope_asc[i].initial_value_m; + if (this->slope_asc[i].estimated_m) { + ss.str(""); + ss << "selectivity.slope_asc." << this->id << "." << i; + info->RegisterParameterName(ss.str()); + if (this->slope_asc[i].is_random_effect_m) { + info->RegisterRandomEffect(selectivity->slope_asc[i]); + } else { + info->RegisterParameter(selectivity->slope_asc[i]); } + } + } info->variable_map[this->slope_asc.id_m] = &(selectivity)->slope_asc; - selectivity->inflection_point_desc.resize(this->inflection_point_desc.size()); - for (size_t i = 0; i < this->inflection_point_desc.size(); i++) { - selectivity->inflection_point_desc[i] = this->inflection_point_desc[i].initial_value_m; - if (this->inflection_point_desc[i].estimated_m) { - ss.str(""); - ss << "selectivity.inflection_point_desc." << this->id << "." << i; - info->RegisterParameterName(ss.str()); - if (this->inflection_point_desc[i].is_random_effect_m) { - info->RegisterRandomEffect(selectivity->inflection_point_desc[i]); - } else { - info->RegisterParameter(selectivity->inflection_point_desc[i]); - } - } + selectivity->inflection_point_desc.resize( + this->inflection_point_desc.size()); + for (size_t i = 0; i < this->inflection_point_desc.size(); i++) { + selectivity->inflection_point_desc[i] = + this->inflection_point_desc[i].initial_value_m; + if (this->inflection_point_desc[i].estimated_m) { + ss.str(""); + ss << "selectivity.inflection_point_desc." << this->id << "." << i; + info->RegisterParameterName(ss.str()); + if (this->inflection_point_desc[i].is_random_effect_m) { + info->RegisterRandomEffect(selectivity->inflection_point_desc[i]); + } else { + info->RegisterParameter(selectivity->inflection_point_desc[i]); } + } + } - info->variable_map[this->inflection_point_desc.id_m] = &(selectivity)->inflection_point_desc; - selectivity->slope_desc.resize(this->slope_desc.size()); - for (size_t i = 0; i < this->slope_desc.size(); i++) { - selectivity->slope_desc[i] = this->slope_desc[i].initial_value_m; - if (this->slope_desc[i].estimated_m) { - ss.str(""); - ss << "selectivity.slope_desc." << this->id << "." << i; - info->RegisterParameterName(ss.str()); - if (this->slope_desc[i].is_random_effect_m) { - info->RegisterRandomEffect(selectivity->slope_desc[i]); - } else { - info->RegisterParameter(selectivity->slope_desc[i]); - } - } + info->variable_map[this->inflection_point_desc.id_m] = + &(selectivity)->inflection_point_desc; + selectivity->slope_desc.resize(this->slope_desc.size()); + for (size_t i = 0; i < this->slope_desc.size(); i++) { + selectivity->slope_desc[i] = this->slope_desc[i].initial_value_m; + if (this->slope_desc[i].estimated_m) { + ss.str(""); + ss << "selectivity.slope_desc." << this->id << "." << i; + info->RegisterParameterName(ss.str()); + if (this->slope_desc[i].is_random_effect_m) { + info->RegisterRandomEffect(selectivity->slope_desc[i]); + } else { + info->RegisterParameter(selectivity->slope_desc[i]); } - + } + } info->variable_map[this->slope_desc.id_m] = &(selectivity)->slope_desc; diff --git a/inst/include/population_dynamics/fleet/fleet.hpp b/inst/include/population_dynamics/fleet/fleet.hpp index d9de028a..ec51b362 100644 --- a/inst/include/population_dynamics/fleet/fleet.hpp +++ b/inst/include/population_dynamics/fleet/fleet.hpp @@ -17,225 +17,232 @@ namespace fims_popdy { - /** @brief Base class for all fleets. - * - * @tparam Type The type of the fleet object. - */ - template - struct Fleet : public fims_model_object::FIMSObject { - static uint32_t id_g; /*!< reference id for fleet object*/ - size_t nyears; /*!< the number of years in the model*/ - size_t nages; /*!< the number of ages in the model*/ - size_t nlengths; /*!< the number of lengths in the model*/ - - // selectivity - int fleet_selectivity_id_m = -999; /*!< id of selectivity component*/ - std::shared_ptr> - selectivity; /*!< selectivity component*/ +/** @brief Base class for all fleets. + * + * @tparam Type The type of the fleet object. + */ +template +struct Fleet : public fims_model_object::FIMSObject { + static uint32_t id_g; /*!< reference id for fleet object*/ + size_t nyears; /*!< the number of years in the model*/ + size_t nages; /*!< the number of ages in the model*/ + size_t nlengths; /*!< the number of lengths in the model*/ + + // selectivity + int fleet_selectivity_id_m = -999; /*!< id of selectivity component*/ + std::shared_ptr> + selectivity; /*!< selectivity component*/ // index data int fleet_observed_index_data_id_m = -999; /*!< id of index data */ std::shared_ptr> - observed_index_data; /*!< observed index data*/ + observed_index_data; /*!< observed index data*/ // age comp data int fleet_observed_agecomp_data_id_m = -999; /*!< id of age comp data */ std::shared_ptr> - observed_agecomp_data; /*!< observed agecomp data*/ + observed_agecomp_data; /*!< observed agecomp data*/ // length comp data int fleet_observed_lengthcomp_data_id_m = -999; /*!< id of length comp data */ std::shared_ptr> - observed_lengthcomp_data; /*!< observed lengthcomp data*/ + observed_lengthcomp_data; /*!< observed lengthcomp data*/ // Mortality and catchability fims::Vector log_Fmort; /*!< estimated parameter: log Fishing mortality*/ - fims::Vector log_q; /*!< estimated parameter: catchability of the fleet */ - - fims::Vector Fmort; /*!< transformed parameter: Fishing mortality*/ - fims::Vector q; /*!< transformed parameter: the catchability of the fleet */ - - // derived quantities - fims::Vector catch_at_age; /*! catch_index; /*! age_composition; /*! length_composition; /*! age_length_conversion_matrix; /*! observed_catch_lpdf; /*! observed_index_lpdf; /*! expected_catch; /*! expected_index; /*! log_expected_index; /*! expected_catch_lpdf; /*! expected_index_lpdf; /*! catch_numbers_at_age; /*! catch_numbers_at_length; /*! proportion_catch_numbers_at_age; /*! proportion_catch_numbers_at_length; /*! catch_weight_at_age; /*! *of; -#endif - - /** - * @brief Constructor. - */ - Fleet() { - this->id = Fleet::id_g++; - } - - /** - * @brief Destructor. - */ - virtual ~Fleet() { - } + fims::Vector + log_q; /*!< estimated parameter: catchability of the fleet */ - /** - * @brief Intialize Fleet Class - * @param nyears The number of years in the model. - * @param nages The number of ages in the model. - * @param nlengths The number of lengths in the model. - */ - void Initialize(int nyears, int nages, int nlengths = 0) { - if (this->log_q.size() == 0) { - this->log_q.resize(1); - this->log_q[0] = 0.0; - } - this->nyears = nyears; - this->nages = nages; - this->nlengths = nlengths; - - catch_at_age.resize(nyears * nages); - catch_numbers_at_age.resize(nyears * nages); - catch_numbers_at_length.resize(nyears * nlengths); - proportion_catch_numbers_at_age.resize(nyears * nages); - proportion_catch_numbers_at_length.resize(nyears * nlengths); - age_length_conversion_matrix.resize(nages * nlengths); - catch_weight_at_age.resize(nyears * nages); - catch_index.resize(nyears); // assume index is for all ages. - expected_catch.resize(nyears); - expected_index.resize(nyears); - log_expected_index.resize(nyears); - age_composition.resize(nyears * nages); - length_composition.resize(nyears * nlengths); - q.resize(this->log_q.size()); - log_Fmort.resize(nyears); - Fmort.resize(nyears); - } + fims::Vector Fmort; /*!< transformed parameter: Fishing mortality*/ + fims::Vector + q; /*!< transformed parameter: the catchability of the fleet */ - /** - * @brief Prepare to run the fleet module. Called at each model - * iteration, and used to exponentiate the natural log of q and Fmort - * parameters prior to evaluation. - * - */ - void Prepare() { - // for(size_t fleet_ = 0; fleet_ <= this->nfleets; fleet_++) { - // this -> Fmort[fleet_] = fims_math::exp(this -> log_Fmort[fleet_]); - - // derived quantities - std::fill(catch_at_age.begin(), catch_at_age.end(), - 0); /**log_q.size(); i++) { - this->q[i] = fims_math::exp(this->log_q[i]); - } - - for (size_t year = 0; year < this->nyears; year++) { - this->Fmort[year] = fims_math::exp(this->log_Fmort[year]); - } - } + // derived quantities + fims::Vector catch_at_age; /*! catch_index; /*! age_composition; /*! + length_composition; /*! + age_length_conversion_matrix; /*! observed_catch_lpdf; /*! observed_index_lpdf; /*! expected_catch; /*! expected_index; /*! log_expected_index; /*! expected_catch_lpdf; /*! expected_index_lpdf; /*! catch_numbers_at_age; /*! + catch_numbers_at_length; /*! + proportion_catch_numbers_at_age; /*! + proportion_catch_numbers_at_length; /*! catch_weight_at_age; /*!nyears; y++) { - Type sum = 0.0; - for (size_t a = 0; a < this->nages; a++) { - size_t i_age_year = y * this->nages + a; - sum += this->catch_numbers_at_age[i_age_year]; - } - for (size_t a = 0; a < this->nages; a++) { - size_t i_age_year = y * this->nages + a; - this->proportion_catch_numbers_at_age[i_age_year] = this->catch_numbers_at_age[i_age_year] / sum; - - } - } - } +#ifdef TMB_MODEL + ::objective_function *of; +#endif - /** - * Evaluate the proportion of catch numbers at length. - */ - void evaluate_length_comp() { - if (this->nlengths > 0) { - for (size_t y = 0; y < this->nyears; y++) { - Type sum = 0.0; - for (size_t l = 0; l < this->nlengths; l++) { - size_t i_length_year = y * this->nlengths + l; - for(size_t a = 0; a < this->nages; a++) { - size_t i_age_year = y * this->nages + a; - size_t i_length_age = a * this->nlengths + l; - this->catch_numbers_at_length[i_length_year] += - this->catch_numbers_at_age[i_age_year] * - this->age_length_conversion_matrix[i_length_age]; - } - sum += this->catch_numbers_at_length[i_length_year]; - } - for (size_t l = 0; l < this->nlengths; l++) { - size_t i_length_year = y * this->nlengths + l; - this->proportion_catch_numbers_at_length[i_length_year] = - this->catch_numbers_at_length[i_length_year] / sum; - } - } - } + /** + * @brief Constructor. + */ + Fleet() { this->id = Fleet::id_g++; } + + /** + * @brief Destructor. + */ + virtual ~Fleet() {} + + /** + * @brief Intialize Fleet Class + * @param nyears The number of years in the model. + * @param nages The number of ages in the model. + * @param nlengths The number of lengths in the model. + */ + void Initialize(int nyears, int nages, int nlengths = 0) { + if (this->log_q.size() == 0) { + this->log_q.resize(1); + this->log_q[0] = 0.0; + } + this->nyears = nyears; + this->nages = nages; + this->nlengths = nlengths; + + catch_at_age.resize(nyears * nages); + catch_numbers_at_age.resize(nyears * nages); + catch_numbers_at_length.resize(nyears * nlengths); + proportion_catch_numbers_at_age.resize(nyears * nages); + proportion_catch_numbers_at_length.resize(nyears * nlengths); + age_length_conversion_matrix.resize(nages * nlengths); + catch_weight_at_age.resize(nyears * nages); + catch_index.resize(nyears); // assume index is for all ages. + expected_catch.resize(nyears); + expected_index.resize(nyears); + log_expected_index.resize(nyears); + age_composition.resize(nyears * nages); + length_composition.resize(nyears * nlengths); + q.resize(this->log_q.size()); + log_Fmort.resize(nyears); + Fmort.resize(nyears); + } + + /** + * @brief Prepare to run the fleet module. Called at each model + * iteration, and used to exponentiate the natural log of q and Fmort + * parameters prior to evaluation. + * + */ + void Prepare() { + // for(size_t fleet_ = 0; fleet_ <= this->nfleets; fleet_++) { + // this -> Fmort[fleet_] = fims_math::exp(this -> log_Fmort[fleet_]); + + // derived quantities + std::fill(catch_at_age.begin(), catch_at_age.end(), + 0); /**log_q.size(); i++) { + this->q[i] = fims_math::exp(this->log_q[i]); + } + + for (size_t year = 0; year < this->nyears; year++) { + this->Fmort[year] = fims_math::exp(this->log_Fmort[year]); + } + } + + /** + * Evaluate the proportion of catch numbers at age. + */ + void evaluate_age_comp() { + for (size_t y = 0; y < this->nyears; y++) { + Type sum = 0.0; + for (size_t a = 0; a < this->nages; a++) { + size_t i_age_year = y * this->nages + a; + sum += this->catch_numbers_at_age[i_age_year]; + } + for (size_t a = 0; a < this->nages; a++) { + size_t i_age_year = y * this->nages + a; + this->proportion_catch_numbers_at_age[i_age_year] = + this->catch_numbers_at_age[i_age_year] / sum; + } + } + } + + /** + * Evaluate the proportion of catch numbers at length. + */ + void evaluate_length_comp() { + if (this->nlengths > 0) { + for (size_t y = 0; y < this->nyears; y++) { + Type sum = 0.0; + for (size_t l = 0; l < this->nlengths; l++) { + size_t i_length_year = y * this->nlengths + l; + for (size_t a = 0; a < this->nages; a++) { + size_t i_age_year = y * this->nages + a; + size_t i_length_age = a * this->nlengths + l; + this->catch_numbers_at_length[i_length_year] += + this->catch_numbers_at_age[i_age_year] * + this->age_length_conversion_matrix[i_length_age]; } - - /** - * Evaluate the natural log of the expected index. - */ - void evaluate_index() { - for (size_t i = 0; iexpected_index.size(); i++) { - log_expected_index[i] = log(this->expected_index[i]); - } + sum += this->catch_numbers_at_length[i_length_year]; } - }; - - // default id of the singleton fleet class - template - uint32_t Fleet::id_g = 0; - -} // end namespace fims_popdy + for (size_t l = 0; l < this->nlengths; l++) { + size_t i_length_year = y * this->nlengths + l; + this->proportion_catch_numbers_at_length[i_length_year] = + this->catch_numbers_at_length[i_length_year] / sum; + } + } + } + } + + /** + * Evaluate the natural log of the expected index. + */ + void evaluate_index() { + for (size_t i = 0; i < this->expected_index.size(); i++) { + log_expected_index[i] = log(this->expected_index[i]); + } + } +}; + +// default id of the singleton fleet class +template +uint32_t Fleet::id_g = 0; + +} // end namespace fims_popdy #endif /* FIMS_POPULATION_DYNAMICS_FLEET_HPP */ diff --git a/inst/include/population_dynamics/growth/functors/ewaa.hpp b/inst/include/population_dynamics/growth/functors/ewaa.hpp index b32d853e..496d2986 100644 --- a/inst/include/population_dynamics/growth/functors/ewaa.hpp +++ b/inst/include/population_dynamics/growth/functors/ewaa.hpp @@ -28,7 +28,8 @@ struct EWAAgrowth : public GrowthBase { // the value is the weight at that age (second double) std::map ewaa; /** */ - typedef typename std::map::iterator weight_iterator; /**< Iterator for ewaa map object > */ + typedef typename std::map::iterator + weight_iterator; /**< Iterator for ewaa map object > */ EWAAgrowth() : GrowthBase() {} @@ -40,11 +41,11 @@ struct EWAAgrowth : public GrowthBase { * @param a age of the fish, the age vector must start at zero */ virtual const Type evaluate(const double& a) { - weight_iterator it = this->ewaa.find(a); - if(it == this->ewaa.end() ){ - return 0.0; - } - Type ret = (*it).second;//itewaa[a]; + weight_iterator it = this->ewaa.find(a); + if (it == this->ewaa.end()) { + return 0.0; + } + Type ret = (*it).second; // itewaa[a]; return ret; } }; diff --git a/inst/include/population_dynamics/maturity/functors/logistic.hpp b/inst/include/population_dynamics/maturity/functors/logistic.hpp index fd353aa9..a58b3552 100644 --- a/inst/include/population_dynamics/maturity/functors/logistic.hpp +++ b/inst/include/population_dynamics/maturity/functors/logistic.hpp @@ -22,46 +22,44 @@ namespace fims_popdy { */ template struct LogisticMaturity : public MaturityBase { - fims::Vector inflection_point; /**< 50 percent quantile of the value of the quantity of - interest (x); e.g. age at which 50 percent of the fish are mature */ - fims::Vector slope; /** + inflection_point; /**< 50 percent quantile of the value of the quantity of +interest (x); e.g. age at which 50 percent of the fish are mature */ + fims::Vector slope; /**() - { - } + LogisticMaturity() : MaturityBase() {} - /** - * @brief Method of the logistic maturity class that implements the - * logistic function from FIMS math. - * - * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope (x - inflection_point))} \f] - * - * @param x The independent variable in the logistic function (e.g., age or - * size at maturity). - */ + /** + * @brief Method of the logistic maturity class that implements the + * logistic function from FIMS math. + * + * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope (x - inflection_point))} \f] + * + * @param x The independent variable in the logistic function (e.g., age or + * size at maturity). + */ - virtual const Type evaluate(const Type& x) - { - return fims_math::logistic(inflection_point[0], slope[0], x); - } + virtual const Type evaluate(const Type& x) { + return fims_math::logistic(inflection_point[0], slope[0], x); + } - /** - * @brief Method of the logistic maturity class that implements the - * logistic function from FIMS math. - * - * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope_t (x - {inflection\_point}_t))} \f] - * - * @param x The independent variable in the logistic function (e.g., age or - * size in selectivity). - * @param pos Position index, e.g., which year. - */ - virtual const Type evaluate(const Type& x, size_t pos) - { - return fims_math::logistic(inflection_point.get_force_scalar(pos), slope.get_force_scalar(pos), x); - } + /** + * @brief Method of the logistic maturity class that implements the + * logistic function from FIMS math. + * + * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope_t (x - {inflection\_point}_t))} \f] + * + * @param x The independent variable in the logistic function (e.g., age or + * size in selectivity). + * @param pos Position index, e.g., which year. + */ + virtual const Type evaluate(const Type& x, size_t pos) { + return fims_math::logistic(inflection_point.get_force_scalar(pos), + slope.get_force_scalar(pos), x); + } }; -} // namespace fims_popdy +} // namespace fims_popdy #endif /* POPULATION_DYNAMICS_MATURITY_LOGISTIC_HPP */ diff --git a/inst/include/population_dynamics/maturity/functors/maturity_base.hpp b/inst/include/population_dynamics/maturity/functors/maturity_base.hpp index 1ee6d308..2050bb5c 100644 --- a/inst/include/population_dynamics/maturity/functors/maturity_base.hpp +++ b/inst/include/population_dynamics/maturity/functors/maturity_base.hpp @@ -22,39 +22,38 @@ namespace fims_popdy { template struct MaturityBase : public fims_model_object::FIMSObject { - // id_g is the ID of the instance of the MaturityBase class. - // this is like a memory tracker. - // Assigning each one its own ID is a way to keep track of - // all the instances of the MaturityBase class. - static uint32_t id_g; /**< The ID of the instance of the MaturityBase class */ - - /** @brief Constructor. - */ - MaturityBase() - { - // increment id of the singleton maturity class - this->id = MaturityBase::id_g++; - } - - /** - * @brief Calculates the maturity. - * @param x The independent variable in the maturity function (e.g., logistic - * maturity at age or size). - */ - virtual const Type evaluate(const Type& x) = 0; - /** - * @brief Calculates the selectivity. - * @param x The independent variable in the logistic function (e.g., age or - * size in selectivity). - * @param pos Position index, e.g., which year. - */ - virtual const Type evaluate(const Type& x, size_t pos) = 0; + // id_g is the ID of the instance of the MaturityBase class. + // this is like a memory tracker. + // Assigning each one its own ID is a way to keep track of + // all the instances of the MaturityBase class. + static uint32_t id_g; /**< The ID of the instance of the MaturityBase class */ + + /** @brief Constructor. + */ + MaturityBase() { + // increment id of the singleton maturity class + this->id = MaturityBase::id_g++; + } + + /** + * @brief Calculates the maturity. + * @param x The independent variable in the maturity function (e.g., logistic + * maturity at age or size). + */ + virtual const Type evaluate(const Type& x) = 0; + /** + * @brief Calculates the selectivity. + * @param x The independent variable in the logistic function (e.g., age or + * size in selectivity). + * @param pos Position index, e.g., which year. + */ + virtual const Type evaluate(const Type& x, size_t pos) = 0; }; // default id of the singleton maturity class template uint32_t MaturityBase::id_g = 0; -} // namespace fims_popdy +} // namespace fims_popdy #endif /* POPULATION_DYNAMICS_MATURITY_BASE_HPP */ diff --git a/inst/include/population_dynamics/population/population.hpp b/inst/include/population_dynamics/population/population.hpp index e3a87568..425df254 100644 --- a/inst/include/population_dynamics/population/population.hpp +++ b/inst/include/population_dynamics/population/population.hpp @@ -9,615 +9,608 @@ #define FIMS_POPULATION_DYNAMICS_POPULATION_HPP #include "../../common/model_object.hpp" +#include "../../interface/interface.hpp" #include "../fleet/fleet.hpp" #include "../growth/growth.hpp" -#include "../recruitment/recruitment.hpp" -#include "../../interface/interface.hpp" #include "../maturity/maturity.hpp" +#include "../recruitment/recruitment.hpp" namespace fims_popdy { - /*TODO: - Review, add functions to evaluate, push vectors back to fleet (or point to - fleet directly?) - */ +/*TODO: + Review, add functions to evaluate, push vectors back to fleet (or point to + fleet directly?) + */ - /** - * @brief Population class. Contains subpopulations - * that are divided into generic partitions (eg. sex, area). - */ - template - struct Population : public fims_model_object::FIMSObject { - static uint32_t id_g; /*!< reference id for population object*/ - size_t nyears; /*!< total number of years in the fishery*/ - size_t nseasons; /*!< total number of seasons in the fishery*/ - size_t nages; /*!< total number of ages in the population*/ - size_t nfleets; /*!< total number of fleets in the fishery*/ - - // parameters are estimated; after initialize in create_model, push_back to - // parameter list - in information.hpp (same for initial F in fleet) - fims::Vector - log_init_naa; /*!< estimated parameter: natural log of numbers at age*/ - fims::Vector log_M; /*!< estimated parameter: natural log of Natural Mortality*/ - fims::Vectorproportion_female = fims::Vector(1, Type(0.5)); /*!< proportion female by age */ - - // Transformed values - fims::Vector M; /*!< transformed parameter: natural mortality*/ - - fims::Vector ages; /*!< vector of the ages for referencing*/ - fims::Vector years; /*!< vector of years for referencing*/ - fims::Vector mortality_F; /*!< vector of fishing mortality summed across - fleet by year and age*/ - fims::Vector - mortality_Z; /*!< vector of total mortality by year and age*/ - - // derived quantities - fims::Vector - weight_at_age; /*!< Derived quantity: expected weight at age */ - // fecundity removed because we don't need it yet - fims::Vector numbers_at_age; /*!< Derived quantity: population expected - numbers at age in each year*/ - fims::Vector - unfished_numbers_at_age; /*!< Derived quantity: population expected - unfished numbers at age in each year*/ - fims::Vector - biomass; /*!< Derived quantity: total population biomass in each year*/ - fims::Vector spawning_biomass; /*!< Derived quantity: Spawning_biomass*/ - fims::Vector unfished_biomass; /*!< Derived quanity - biomass assuming unfished*/ - fims::Vector unfished_spawning_biomass; /*!< Derived quanity Spawning - biomass assuming unfished*/ - fims::Vector proportion_mature_at_age; /*!< Derived quantity: Proportion - mature at age */ - fims::Vector expected_numbers_at_age; /*!< Expected values: Numbers at - age (thousands?? millions??) */ - fims::Vector expected_catch; /*!< Expected values: Catch*/ - fims::Vector expected_recruitment; /*!< Expected recruitment */ - /// recruitment - int recruitment_id = -999; /*!< id of recruitment model object*/ - std::shared_ptr> - recruitment; /*!< shared pointer to recruitment module */ - - // growth - int growth_id = -999; /*!< id of growth model object*/ - std::shared_ptr> - growth; /*!< shared pointer to growth module */ - - // maturity - int maturity_id = -999; /*!< id of maturity model object*/ - std::shared_ptr> - maturity; /*!< shared pointer to maturity module */ - - // fleet - int fleet_id = -999; /*!< id of fleet model object*/ - std::vector>> - fleets; /*!< shared pointer to fleet module */ - - // Define objective function object to be able to REPORT and ADREPORT +/** + * @brief Population class. Contains subpopulations + * that are divided into generic partitions (eg. sex, area). + */ +template +struct Population : public fims_model_object::FIMSObject { + static uint32_t id_g; /*!< reference id for population object*/ + size_t nyears; /*!< total number of years in the fishery*/ + size_t nseasons; /*!< total number of seasons in the fishery*/ + size_t nages; /*!< total number of ages in the population*/ + size_t nfleets; /*!< total number of fleets in the fishery*/ + + // parameters are estimated; after initialize in create_model, push_back to + // parameter list - in information.hpp (same for initial F in fleet) + fims::Vector + log_init_naa; /*!< estimated parameter: natural log of numbers at age*/ + fims::Vector + log_M; /*!< estimated parameter: natural log of Natural Mortality*/ + fims::Vector proportion_female = + fims::Vector(1, Type(0.5)); /*!< proportion female by age */ + + // Transformed values + fims::Vector M; /*!< transformed parameter: natural mortality*/ + + fims::Vector ages; /*!< vector of the ages for referencing*/ + fims::Vector years; /*!< vector of years for referencing*/ + fims::Vector mortality_F; /*!< vector of fishing mortality summed across + fleet by year and age*/ + fims::Vector + mortality_Z; /*!< vector of total mortality by year and age*/ + + // derived quantities + fims::Vector + weight_at_age; /*!< Derived quantity: expected weight at age */ + // fecundity removed because we don't need it yet + fims::Vector numbers_at_age; /*!< Derived quantity: population expected + numbers at age in each year*/ + fims::Vector + unfished_numbers_at_age; /*!< Derived quantity: population expected + unfished numbers at age in each year*/ + fims::Vector + biomass; /*!< Derived quantity: total population biomass in each year*/ + fims::Vector spawning_biomass; /*!< Derived quantity: Spawning_biomass*/ + fims::Vector unfished_biomass; /*!< Derived quanity + biomass assuming unfished*/ + fims::Vector unfished_spawning_biomass; /*!< Derived quanity Spawning + biomass assuming unfished*/ + fims::Vector proportion_mature_at_age; /*!< Derived quantity: Proportion + mature at age */ + fims::Vector expected_numbers_at_age; /*!< Expected values: Numbers at + age (thousands?? millions??) */ + fims::Vector expected_catch; /*!< Expected values: Catch*/ + fims::Vector expected_recruitment; /*!< Expected recruitment */ + /// recruitment + int recruitment_id = -999; /*!< id of recruitment model object*/ + std::shared_ptr> + recruitment; /*!< shared pointer to recruitment module */ + + // growth + int growth_id = -999; /*!< id of growth model object*/ + std::shared_ptr> + growth; /*!< shared pointer to growth module */ + + // maturity + int maturity_id = -999; /*!< id of maturity model object*/ + std::shared_ptr> + maturity; /*!< shared pointer to maturity module */ + + // fleet + int fleet_id = -999; /*!< id of fleet model object*/ + std::vector>> + fleets; /*!< shared pointer to fleet module */ + + // Define objective function object to be able to REPORT and ADREPORT #ifdef TMB_MODEL - ::objective_function - *of; // :: references global namespace, defined in src/FIMS.cpp, - // available anywhere in the R package + ::objective_function + *of; // :: references global namespace, defined in src/FIMS.cpp, + // available anywhere in the R package #endif - // this -> means you're referring to a class member (member of self) - - Population() { - this->id = Population::id_g++; - } - - /** - * @brief Initialize values. Called once at the start of model run. - * - * @param nyears number of years in the population - * @param nseasons number of seasons in the population - * @param nages number of ages in the population - */ - void Initialize(int nyears, int nseasons, int nages) { - this->nyears = nyears; - this->nseasons = nseasons; - this->nages = nages; - - // size all the vectors to length of nages - nfleets = fleets.size(); - expected_catch.resize(nyears * nfleets); - years.resize(nyears); - mortality_F.resize(nyears * nages); - mortality_Z.resize(nyears * nages); - proportion_mature_at_age.resize((nyears + 1) * nages); - proportion_female.resize(nages); - weight_at_age.resize(nages); - unfished_numbers_at_age.resize((nyears + 1) * nages); - biomass.resize((nyears + 1)); - unfished_biomass.resize((nyears + 1)); - unfished_spawning_biomass.resize((nyears + 1)); - spawning_biomass.resize((nyears + 1)); - expected_recruitment.resize((nyears + 1)); - M.resize(nyears * nages); - ages.resize(nages); - log_init_naa.resize(nages); - log_M.resize(nyears * nages); - } - - /** - * @brief Prepare to run the population loop. Called at each model iteration, - * and used to zero out derived quantities, values that were summed, etc. - * - */ - void Prepare() { - - for (size_t fleet = 0; fleet < this->fleets.size(); fleet++) { - this->fleets[fleet]->Prepare(); - } - - std::fill(biomass.begin(), biomass.end(), 0.0); - std::fill(unfished_spawning_biomass.begin(), - unfished_spawning_biomass.end(), 0.0); - std::fill(spawning_biomass.begin(), spawning_biomass.end(), 0.0); - std::fill(expected_catch.begin(), expected_catch.end(), 0.0); - std::fill(expected_recruitment.begin(), expected_recruitment.end(), 0.0); - std::fill(proportion_mature_at_age.begin(), proportion_mature_at_age.end(), - 0.0); - std::fill(mortality_Z.begin(), mortality_Z.end(), 0.0); - std::fill(proportion_female.begin(), proportion_female.end(), 0.5); - - // Transformation Section - for (size_t age = 0; age < this->nages; age++) { - this->weight_at_age[age] = growth->evaluate(ages[age]); - for (size_t year = 0; year < this->nyears; year++) { - size_t i_age_year = age * this->nyears + year; - this->M[i_age_year] = fims_math::exp(this->log_M[i_age_year]); - // mortality_F is a fims::Vector and therefore needs to be filled - // within a loop - this->mortality_F[i_age_year] = 0.0; - } - } - } - - /** - * life history calculations + // this -> means you're referring to a class member (member of self) + + Population() { this->id = Population::id_g++; } + + /** + * @brief Initialize values. Called once at the start of model run. + * + * @param nyears number of years in the population + * @param nseasons number of seasons in the population + * @param nages number of ages in the population + */ + void Initialize(int nyears, int nseasons, int nages) { + this->nyears = nyears; + this->nseasons = nseasons; + this->nages = nages; + + // size all the vectors to length of nages + nfleets = fleets.size(); + expected_catch.resize(nyears * nfleets); + years.resize(nyears); + mortality_F.resize(nyears * nages); + mortality_Z.resize(nyears * nages); + proportion_mature_at_age.resize((nyears + 1) * nages); + proportion_female.resize(nages); + weight_at_age.resize(nages); + unfished_numbers_at_age.resize((nyears + 1) * nages); + biomass.resize((nyears + 1)); + unfished_biomass.resize((nyears + 1)); + unfished_spawning_biomass.resize((nyears + 1)); + spawning_biomass.resize((nyears + 1)); + expected_recruitment.resize((nyears + 1)); + M.resize(nyears * nages); + ages.resize(nages); + log_init_naa.resize(nages); + log_M.resize(nyears * nages); + } + + /** + * @brief Prepare to run the population loop. Called at each model iteration, + * and used to zero out derived quantities, values that were summed, etc. + * + */ + void Prepare() { + for (size_t fleet = 0; fleet < this->fleets.size(); fleet++) { + this->fleets[fleet]->Prepare(); + } + + std::fill(biomass.begin(), biomass.end(), 0.0); + std::fill(unfished_spawning_biomass.begin(), + unfished_spawning_biomass.end(), 0.0); + std::fill(spawning_biomass.begin(), spawning_biomass.end(), 0.0); + std::fill(expected_catch.begin(), expected_catch.end(), 0.0); + std::fill(expected_recruitment.begin(), expected_recruitment.end(), 0.0); + std::fill(proportion_mature_at_age.begin(), proportion_mature_at_age.end(), + 0.0); + std::fill(mortality_Z.begin(), mortality_Z.end(), 0.0); + std::fill(proportion_female.begin(), proportion_female.end(), 0.5); + + // Transformation Section + for (size_t age = 0; age < this->nages; age++) { + this->weight_at_age[age] = growth->evaluate(ages[age]); + for (size_t year = 0; year < this->nyears; year++) { + size_t i_age_year = age * this->nyears + year; + this->M[i_age_year] = fims_math::exp(this->log_M[i_age_year]); + // mortality_F is a fims::Vector and therefore needs to be filled + // within a loop + this->mortality_F[i_age_year] = 0.0; + } + } + } + + /** + * life history calculations + */ + + /** + * @brief Calculates initial numbers at age for index and age + * + * @param i_age_year dimension folded index for age and year + * @param a age index + */ + inline void CalculateInitialNumbersAA( + size_t i_age_year, size_t a) { // inline all function unless complicated + this->numbers_at_age[i_age_year] = fims_math::exp(this->log_init_naa[a]); + } + + /** + * @brief Calculates total mortality at an index, year, and age + * + * @param i_age_year dimension folded index for age and year + * @param year year index + * @param age age index + */ + void CalculateMortality(size_t i_age_year, size_t year, size_t age) { + for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { + if (this->fleets[fleet_]->is_survey == false) { + this->mortality_F[i_age_year] += + this->fleets[fleet_]->Fmort[year] * + // evaluate is a member function of the selectivity class + this->fleets[fleet_]->selectivity->evaluate(ages[age]); + } + } + + this->mortality_Z[i_age_year] = + this->M[i_age_year] + this->mortality_F[i_age_year]; + } + + /** + * @brief Calculates numbers at age at year and age specific indices + * + * @param i_age_year dimension folded index for age and year + * @param i_agem1_yearm1 dimension folded index for age-1 and year-1 + * @param age age index + */ + inline void CalculateNumbersAA(size_t i_age_year, size_t i_agem1_yearm1, + size_t age) { + // using Z from previous age/year + this->numbers_at_age[i_age_year] = + this->numbers_at_age[i_agem1_yearm1] * + (fims_math::exp(-this->mortality_Z[i_agem1_yearm1])); + + // Plus group calculation + if (age == (this->nages - 1)) { + this->numbers_at_age[i_age_year] = + this->numbers_at_age[i_age_year] + + this->numbers_at_age[i_agem1_yearm1 + 1] * + (fims_math::exp(-this->mortality_Z[i_agem1_yearm1 + 1])); + } + } + + /** + * @brief Calculates unfished numbers at age at year and age specific indices + * + * @param i_age_year dimension folded index for age and year + * @param i_agem1_yearm1 dimension folded index for age-1 and year-1 + * @param age age index + */ + inline void CalculateUnfishedNumbersAA(size_t i_age_year, + size_t i_agem1_yearm1, size_t age) { + // using M from previous age/year + this->unfished_numbers_at_age[i_age_year] = + this->unfished_numbers_at_age[i_agem1_yearm1] * + + (fims_math::exp(-this->M[i_agem1_yearm1])); + + // Plus group calculation + if (age == (this->nages - 1)) { + this->unfished_numbers_at_age[i_age_year] = + this->unfished_numbers_at_age[i_age_year] + + this->unfished_numbers_at_age[i_agem1_yearm1 + 1] * + (fims_math::exp(-this->M[i_agem1_yearm1 + 1])); + } + } + + /** + * @brief Calculates biomass + * + * @param i_age_year dimension folded index for age and year + * @param year the year biomass is being aggregated for + * @param age the age who's biomass is being added into total biomass + */ + void CalculateBiomass(size_t i_age_year, size_t year, size_t age) { + this->biomass[year] += + this->numbers_at_age[i_age_year] * this->weight_at_age[age]; + } + + /** + * @brief Adds to existing yearly unfished biomass estimates the + * biomass for a specified year and age + * + * @param i_age_year dimension folded index for age and year + * @param year the year of unfished biomass to add + * @param age the age of unfished biomass to add + */ + void CalculateUnfishedBiomass(size_t i_age_year, size_t year, size_t age) { + this->unfished_biomass[year] += + this->unfished_numbers_at_age[i_age_year] * this->weight_at_age[age]; + } + + /** + * @brief Calculates spawning biomass + * + * @param i_age_year dimension folded index for age and year + * @param year the year spawning biomass is being aggregated for + * @param age the age who's biomass is being added into total spawning biomass + */ + void CalculateSpawningBiomass(size_t i_age_year, size_t year, size_t age) { + this->spawning_biomass[year] += + this->proportion_female[age] * this->numbers_at_age[i_age_year] * + this->proportion_mature_at_age[i_age_year] * this->weight_at_age[age]; + } + + /** + * @brief Adds to existing yearly unfished spawning biomass estimates the + * biomass for a specified year and age + * + * @param i_age_year dimension folded index for age and year + * @param year the year of unfished spawning biomass to add + * @param age the age of unfished spawning biomass to add + */ + void CalculateUnfishedSpawningBiomass(size_t i_age_year, size_t year, + size_t age) { + this->unfished_spawning_biomass[year] += + this->proportion_female[age] * + this->unfished_numbers_at_age[i_age_year] * + this->proportion_mature_at_age[i_age_year] * this->weight_at_age[age]; + } + + /** + * @brief Calculates equilibrium spawning biomass per recruit + * + * @return Type + */ + Type CalculateSBPR0() { + std::vector numbers_spr(this->nages, 1.0); + Type phi_0 = 0.0; + phi_0 += numbers_spr[0] * this->proportion_female[0] * + this->proportion_mature_at_age[0] * + this->growth->evaluate(ages[0]); + for (size_t a = 1; a < (this->nages - 1); a++) { + numbers_spr[a] = numbers_spr[a - 1] * fims_math::exp(-this->M[a]); + phi_0 += numbers_spr[a] * this->proportion_female[a] * + this->proportion_mature_at_age[a] * + this->growth->evaluate(ages[a]); + } + + numbers_spr[this->nages - 1] = + (numbers_spr[nages - 2] * fims_math::exp(-this->M[nages - 2])) / + (1 - fims_math::exp(-this->M[this->nages - 1])); + phi_0 += numbers_spr[this->nages - 1] * + this->proportion_female[this->nages - 1] * + this->proportion_mature_at_age[this->nages - 1] * + this->growth->evaluate(ages[this->nages - 1]); + return phi_0; + } + + /** + * @brief Calculates expected recruitment for a given year + * + * @param i_age_year dimension folded index for age and year + * @param year the year recruitment is being calculated for + * @param i_dev index to log_recruit_dev of vector length nyears-1 + */ + void CalculateRecruitment(size_t i_age_year, size_t year, size_t i_dev) { + Type phi0 = CalculateSBPR0(); + + if (i_dev == this->nyears) { + this->numbers_at_age[i_age_year] = + this->recruitment->evaluate(this->spawning_biomass[year - 1], phi0); + /*the final year of the time series has no data to inform recruitment + devs, so this value is set to the mean recruitment.*/ + } else { + this->numbers_at_age[i_age_year] = + this->recruitment->evaluate(this->spawning_biomass[year - 1], phi0) * + /*the log_recruit_dev vector does not include a value for year == 0 + and is of length nyears - 1 where the first position of the vector + corresponds to the second year of the time series.*/ + fims_math::exp(this->recruitment->log_recruit_devs[i_dev - 1]); + this->expected_recruitment[year] = this->numbers_at_age[i_age_year]; + } + } + + /** + * @brief Adds to exiting expected total catch by fleet in weight + * + * @param year the year of expected total catch + * @param age the age of catch that is being added into total catch + */ + void CalculateCatch(size_t year, size_t age) { + for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { + if (this->fleets[fleet_]->is_survey == false) { + size_t index_yf = year * this->nfleets + + fleet_; // index by fleet and years to dimension fold + size_t i_age_year = year * this->nages + age; + + this->expected_catch[index_yf] += + this->fleets[fleet_]->catch_weight_at_age[i_age_year]; + + fleets[fleet_]->expected_catch[year] += + this->fleets[fleet_]->catch_weight_at_age[i_age_year]; + } + } + } + + /** + * @brief Adds to the expected population indices by fleet + * + * @param i_age_year dimension folded index for age and year + * @param year the year of the population index + * @param age the age of the index that is added into population index + */ + void CalculateIndex(size_t i_age_year, size_t year, size_t age) { + for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { + Type index_; + // I = qN (N is total numbers), I is an index in numbers + if (this->fleets[fleet_]->is_survey == false) { + index_ = this->fleets[fleet_]->catch_numbers_at_age[i_age_year] * + this->weight_at_age[age]; + } else { + index_ = this->fleets[fleet_]->q.get_force_scalar(year) * + this->fleets[fleet_]->selectivity->evaluate(ages[age]) * + this->numbers_at_age[i_age_year] * + this->weight_at_age[age]; // this->weight_at_age[age]; + } + fleets[fleet_]->expected_index[year] += index_; + } + } + + /** + * @brief Calculates catch in numbers at age for each fleet for a given year + * and age, then adds the value to the expected catch in numbers at age for + * each fleet + * + * @param i_age_year dimension folded index for age and year + * @param year the year of expected catch composition is being calculated for + * @param age the age composition is being calculated for + */ + void CalculateCatchNumbersAA(size_t i_age_year, size_t year, size_t age) { + for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { + // make an intermediate value in order to set multiple members (of + // current and fleet objects) to that value. + Type catch_; // catch_ is used to avoid using the c++ keyword catch + // Baranov Catch Equation + if (this->fleets[fleet_]->is_survey == false) { + catch_ = (this->fleets[fleet_]->Fmort[year] * + this->fleets[fleet_]->selectivity->evaluate(ages[age])) / + this->mortality_Z[i_age_year] * + this->numbers_at_age[i_age_year] * + (1 - fims_math::exp(-(this->mortality_Z[i_age_year]))); + } else { + catch_ = (this->fleets[fleet_]->selectivity->evaluate(ages[age])) * + this->numbers_at_age[i_age_year]; + } + + // this->catch_numbers_at_age[i_age_yearf] += catch_; + // catch_numbers_at_age for the fleet module has different + // dimensions (year/age, not year/fleet/age) + this->fleets[fleet_]->catch_numbers_at_age[i_age_year] += catch_; + } + } + + /** + * @brief Calculates expected catch weight at age for each fleet for a given + * year and age + * + * @param year the year of expected catch weight at age + * @param age the age of expected catch weight at age + */ + void CalculateCatchWeightAA(size_t year, size_t age) { + int i_age_year = year * this->nages + age; + for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { + this->fleets[fleet_]->catch_weight_at_age[i_age_year] = + this->fleets[fleet_]->catch_numbers_at_age[i_age_year] * + this->weight_at_age[age]; + } + } + + /** + * @brief Calculates expected proportion of individuals mature at a selected + * ageage + * + * @param i_age_year dimension folded index for age and year + * @param age the age of maturity + */ + void CalculateMaturityAA(size_t i_age_year, size_t age) { + // this->maturity is pointing to the maturity module, which has + // an evaluate function. -> can be nested. + + this->proportion_mature_at_age[i_age_year] = + this->maturity->evaluate(ages[age]); + } + + /** + * @brief Executes the population loop + * + */ + void Evaluate() { + /* + Sets derived vectors to zero + Performs parameters transformations + Sets recruitment deviations to mean 0. + */ + Prepare(); + /* + start at year=0, age=0; + here year 0 is the estimated initial population structure and age 0 are + recruits loops start at zero with if statements inside to specify unique + code for initial structure and recruitment 0 loops. Could also have started + loops at 1 with initial structure and recruitment setup outside the loops. + + year loop is extended to <= nyears because SSB is calculted as the start of + the year value and by extending one extra year we get estimates of the + population structure at the end of the final year. An alternative approach + would be to keep initial numbers at age in it's own vector and each year to + include the population structure at the end of the year. This is likely a + null point given that we are planning to modify to an event/stanza based + structure in later milestones which will elimitate this confusion by + explicity referencing the exact date (or period of averaging) at which any + calculation or output is being made. + */ + for (size_t y = 0; y <= this->nyears; y++) { + for (size_t a = 0; a < this->nages; a++) { + /* + index naming defines the dimensional folding structure + i.e. i_age_year is referencing folding over years and ages. */ - - /** - * @brief Calculates initial numbers at age for index and age - * - * @param i_age_year dimension folded index for age and year - * @param a age index + size_t i_age_year = y * this->nages + a; + /* + Mortality rates are not estimated in the final year which is + used to show expected population structure at the end of the model + period. This is because biomass in year i represents biomass at the + start of the year. Should we add complexity to track more values such + as start, mid, and end biomass in all years where, start biomass=end + biomass of the previous year? Referenced above, this is probably not + worth exploring as later milestone changes will eliminate this + confusion. */ - inline void CalculateInitialNumbersAA( - size_t i_age_year, size_t a) { // inline all function unless complicated - this->numbers_at_age[i_age_year] = fims_math::exp(this->log_init_naa[a]); + if (y < this->nyears) { + /* + First thing we need is total mortality aggregated across all fleets + to inform the subsequent catch and change in numbers at age + calculations. This is only calculated for years < nyears as these are + the model estimated years with data. The year loop extends to + y=nyears so that population numbers at age and SSB can be calculated + at the end of the last year of the model + */ + CalculateMortality(i_age_year, y, a); } - - /** - * @brief Calculates total mortality at an index, year, and age - * - * @param i_age_year dimension folded index for age and year - * @param year year index - * @param age age index + CalculateMaturityAA(i_age_year, a); + /* if statements needed because some quantities are only needed + for the first year and/or age, so these steps are included here. */ - void CalculateMortality(size_t i_age_year, size_t year, size_t age) { - for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { - if (this->fleets[fleet_]->is_survey == false) { - this->mortality_F[i_age_year] += - this->fleets[fleet_]->Fmort[year] * - // evaluate is a member function of the selectivity class - this->fleets[fleet_]->selectivity->evaluate(ages[age]); - - } - } - - this->mortality_Z[i_age_year] = - this->M[i_age_year] + this->mortality_F[i_age_year]; - } + if (y == 0) { + // Initial numbers at age is a user input or estimated parameter + // vector. + CalculateInitialNumbersAA(i_age_year, a); - /** - * @brief Calculates numbers at age at year and age specific indices - * - * @param i_age_year dimension folded index for age and year - * @param i_agem1_yearm1 dimension folded index for age-1 and year-1 - * @param age age index - */ - inline void CalculateNumbersAA(size_t i_age_year, size_t i_agem1_yearm1, - size_t age) { - // using Z from previous age/year - this->numbers_at_age[i_age_year] = - this->numbers_at_age[i_agem1_yearm1] * - (fims_math::exp(-this->mortality_Z[i_agem1_yearm1])); - - // Plus group calculation - if (age == (this->nages - 1)) { - this->numbers_at_age[i_age_year] = - this->numbers_at_age[i_age_year] + - this->numbers_at_age[i_agem1_yearm1 + 1] * - (fims_math::exp(-this->mortality_Z[i_agem1_yearm1 + 1])); - } - } - - /** - * @brief Calculates unfished numbers at age at year and age specific indices - * - * @param i_age_year dimension folded index for age and year - * @param i_agem1_yearm1 dimension folded index for age-1 and year-1 - * @param age age index - */ - inline void CalculateUnfishedNumbersAA(size_t i_age_year, - size_t i_agem1_yearm1, size_t age) { - // using M from previous age/year + if (a == 0) { this->unfished_numbers_at_age[i_age_year] = - this->unfished_numbers_at_age[i_agem1_yearm1] * - - (fims_math::exp(-this->M[i_agem1_yearm1])); - - // Plus group calculation - if (age == (this->nages - 1)) { - this->unfished_numbers_at_age[i_age_year] = - this->unfished_numbers_at_age[i_age_year] + - this->unfished_numbers_at_age[i_agem1_yearm1 + 1] * - (fims_math::exp(-this->M[i_agem1_yearm1 + 1])); - } - } + fims_math::exp(this->recruitment->log_rzero[0]); + } else { + CalculateUnfishedNumbersAA(i_age_year, a - 1, a); + } - /** - * @brief Calculates biomass - * - * @param i_age_year dimension folded index for age and year - * @param year the year biomass is being aggregated for - * @param age the age who's biomass is being added into total biomass - */ - void CalculateBiomass(size_t i_age_year, size_t year, size_t age) { - this->biomass[year] += - this->numbers_at_age[i_age_year] * this->weight_at_age[age]; - } - - /** - * @brief Adds to existing yearly unfished biomass estimates the - * biomass for a specified year and age - * - * @param i_age_year dimension folded index for age and year - * @param year the year of unfished biomass to add - * @param age the age of unfished biomass to add - */ - void CalculateUnfishedBiomass(size_t i_age_year, size_t year, size_t age) { - this->unfished_biomass[year] += - this->unfished_numbers_at_age[i_age_year] * this->weight_at_age[age]; - } - - /** - * @brief Calculates spawning biomass - * - * @param i_age_year dimension folded index for age and year - * @param year the year spawning biomass is being aggregated for - * @param age the age who's biomass is being added into total spawning biomass - */ - void CalculateSpawningBiomass(size_t i_age_year, size_t year, size_t age) { - this->spawning_biomass[year] += - this->proportion_female[age] * this->numbers_at_age[i_age_year] * - this->proportion_mature_at_age[i_age_year] * this->weight_at_age[age]; - } - - /** - * @brief Adds to existing yearly unfished spawning biomass estimates the - * biomass for a specified year and age - * - * @param i_age_year dimension folded index for age and year - * @param year the year of unfished spawning biomass to add - * @param age the age of unfished spawning biomass to add - */ - void CalculateUnfishedSpawningBiomass(size_t i_age_year, size_t year, - size_t age) { - this->unfished_spawning_biomass[year] += - this->proportion_female[age] * - this->unfished_numbers_at_age[i_age_year] * - this->proportion_mature_at_age[i_age_year] * this->weight_at_age[age]; - } - - /** - * @brief Calculates equilibrium spawning biomass per recruit - * - * @return Type - */ - Type CalculateSBPR0() { - std::vector numbers_spr(this->nages, 1.0); - Type phi_0 = 0.0; - phi_0 += numbers_spr[0] * this->proportion_female[0] * - this->proportion_mature_at_age[0] * - this->growth->evaluate(ages[0]); - for (size_t a = 1; a < (this->nages - 1); a++) { - numbers_spr[a] = numbers_spr[a - 1] * fims_math::exp(-this->M[a]); - phi_0 += numbers_spr[a] * this->proportion_female[a] * - this->proportion_mature_at_age[a] * - this->growth->evaluate(ages[a]); - } - - numbers_spr[this->nages - 1] = - (numbers_spr[nages - 2] * fims_math::exp(-this->M[nages - 2])) / - (1 - fims_math::exp(-this->M[this->nages - 1])); - phi_0 += numbers_spr[this->nages - 1] * - this->proportion_female[this->nages - 1] * - this->proportion_mature_at_age[this->nages - 1] * - this->growth->evaluate(ages[this->nages - 1]); - return phi_0; - } - - /** - * @brief Calculates expected recruitment for a given year - * - * @param i_age_year dimension folded index for age and year - * @param year the year recruitment is being calculated for - * @param i_dev index to log_recruit_dev of vector length nyears-1 - */ - void CalculateRecruitment(size_t i_age_year, size_t year, size_t i_dev) { - Type phi0 = CalculateSBPR0(); - - if (i_dev == this->nyears) { - this->numbers_at_age[i_age_year] = - this->recruitment->evaluate(this->spawning_biomass[year - 1], phi0); - /*the final year of the time series has no data to inform recruitment - devs, so this value is set to the mean recruitment.*/ - } else { - this->numbers_at_age[i_age_year] = - this->recruitment->evaluate(this->spawning_biomass[year - 1], phi0) * - /*the log_recruit_dev vector does not include a value for year == 0 - and is of length nyears - 1 where the first position of the vector - corresponds to the second year of the time series.*/ - fims_math::exp(this->recruitment->log_recruit_devs[i_dev - 1]); - this->expected_recruitment[year] = this->numbers_at_age[i_age_year]; - } + /* + Fished and unfished biomass vectors are summing biomass at + age across ages. + */ - } + CalculateBiomass(i_age_year, y, a); - /** - * @brief Adds to exiting expected total catch by fleet in weight - * - * @param year the year of expected total catch - * @param age the age of catch that is being added into total catch - */ - void CalculateCatch(size_t year, size_t age) { - for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { - if (this->fleets[fleet_]->is_survey == false) { - size_t index_yf = year * this->nfleets + - fleet_; // index by fleet and years to dimension fold - size_t i_age_year = year * this->nages + age; - - this->expected_catch[index_yf] += - this->fleets[fleet_]->catch_weight_at_age[i_age_year]; - - fleets[fleet_]->expected_catch[year] += - this->fleets[fleet_]->catch_weight_at_age[i_age_year]; - } - } - } + CalculateUnfishedBiomass(i_age_year, y, a); - /** - * @brief Adds to the expected population indices by fleet - * - * @param i_age_year dimension folded index for age and year - * @param year the year of the population index - * @param age the age of the index that is added into population index - */ - void CalculateIndex(size_t i_age_year, size_t year, size_t age) { - for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { - Type index_; - // I = qN (N is total numbers), I is an index in numbers - if (this->fleets[fleet_]->is_survey == false) { - index_ = this->fleets[fleet_]->catch_numbers_at_age[i_age_year] * - this->weight_at_age[age]; - } else { - index_ = this->fleets[fleet_]->q.get_force_scalar(year) * - this->fleets[fleet_]->selectivity->evaluate(ages[age]) * - this->numbers_at_age[i_age_year] * - this->weight_at_age[age]; // this->weight_at_age[age]; - } - fleets[fleet_]->expected_index[year] += index_; - } - } + /* + Fished and unfished spawning biomass vectors are summing biomass at + age across ages to allow calculation of recruitment in the next year. + */ - /** - * @brief Calculates catch in numbers at age for each fleet for a given year - * and age, then adds the value to the expected catch in numbers at age for - * each fleet - * - * @param i_age_year dimension folded index for age and year - * @param year the year of expected catch composition is being calculated for - * @param age the age composition is being calculated for - */ - void CalculateCatchNumbersAA(size_t i_age_year, size_t year, size_t age) { - for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { - // make an intermediate value in order to set multiple members (of - // current and fleet objects) to that value. - Type catch_; // catch_ is used to avoid using the c++ keyword catch - // Baranov Catch Equation - if (this->fleets[fleet_]->is_survey == false) { - catch_ = (this->fleets[fleet_]->Fmort[year] * - this->fleets[fleet_]->selectivity->evaluate(ages[age])) / - this->mortality_Z[i_age_year] * - this->numbers_at_age[i_age_year] * - (1 - fims_math::exp(-(this->mortality_Z[i_age_year]))); - } else { - catch_ = (this->fleets[fleet_]->selectivity->evaluate(ages[age])) * - this->numbers_at_age[i_age_year]; - } - - // this->catch_numbers_at_age[i_age_yearf] += catch_; - // catch_numbers_at_age for the fleet module has different - // dimensions (year/age, not year/fleet/age) - this->fleets[fleet_]->catch_numbers_at_age[i_age_year] += catch_; - } - } + CalculateSpawningBiomass(i_age_year, y, a); - /** - * @brief Calculates expected catch weight at age for each fleet for a given - * year and age - * - * @param year the year of expected catch weight at age - * @param age the age of expected catch weight at age - */ - void CalculateCatchWeightAA(size_t year, size_t age) { - int i_age_year = year * this->nages + age; - for (size_t fleet_ = 0; fleet_ < this->nfleets; fleet_++) { - - this->fleets[fleet_]->catch_weight_at_age[i_age_year] = - this->fleets[fleet_]->catch_numbers_at_age[i_age_year] * - this->weight_at_age[age]; + CalculateUnfishedSpawningBiomass(i_age_year, y, a); - } - } + /* + Expected recruitment in year 0 is numbers at age 0 in year 0. + */ - /** - * @brief Calculates expected proportion of individuals mature at a selected - * ageage - * - * @param i_age_year dimension folded index for age and year - * @param age the age of maturity - */ - void CalculateMaturityAA(size_t i_age_year, size_t age) { - // this->maturity is pointing to the maturity module, which has - // an evaluate function. -> can be nested. - - this->proportion_mature_at_age[i_age_year] = - this->maturity->evaluate(ages[age]); + this->expected_recruitment[i_age_year] = + this->numbers_at_age[i_age_year]; + } else { + if (a == 0) { + // Set the nrecruits for age a=0 year y (use pointers instead of + // functional returns) assuming fecundity = 1 and 50:50 sex ratio + CalculateRecruitment(i_age_year, y, y); + this->unfished_numbers_at_age[i_age_year] = + fims_math::exp(this->recruitment->log_rzero[0]); + + } else { + size_t i_agem1_yearm1 = (y - 1) * nages + (a - 1); + CalculateNumbersAA(i_age_year, i_agem1_yearm1, a); + CalculateUnfishedNumbersAA(i_age_year, i_agem1_yearm1, a); + } + CalculateBiomass(i_age_year, y, a); + CalculateSpawningBiomass(i_age_year, y, a); + + CalculateUnfishedBiomass(i_age_year, y, a); + CalculateUnfishedSpawningBiomass(i_age_year, y, a); } - /** - * @brief Executes the population loop - * + /* + Here composition, total catch, and index values are calculated for all + years with reference data. They are not calculated for y=nyears as there + is this is just to get final population structure at the end of the + terminal year. */ - void Evaluate() { - /* - Sets derived vectors to zero - Performs parameters transformations - Sets recruitment deviations to mean 0. - */ - Prepare(); - /* - start at year=0, age=0; - here year 0 is the estimated initial population structure and age 0 are recruits - loops start at zero with if statements inside to specify unique code for - initial structure and recruitment 0 loops. Could also have started loops at - 1 with initial structure and recruitment setup outside the loops. - - year loop is extended to <= nyears because SSB is calculted as the start of - the year value and by extending one extra year we get estimates of the - population structure at the end of the final year. An alternative approach - would be to keep initial numbers at age in it's own vector and each year to - include the population structure at the end of the year. This is likely a - null point given that we are planning to modify to an event/stanza based - structure in later milestones which will elimitate this confusion by - explicity referencing the exact date (or period of averaging) at which any - calculation or output is being made. - */ - for (size_t y = 0; y <= this->nyears; y++) { - for (size_t a = 0; a < this->nages; a++) { - /* - index naming defines the dimensional folding structure - i.e. i_age_year is referencing folding over years and ages. - */ - size_t i_age_year = y * this->nages + a; - /* - Mortality rates are not estimated in the final year which is - used to show expected population structure at the end of the model period. - This is because biomass in year i represents biomass at the start of - the year. - Should we add complexity to track more values such as start, - mid, and end biomass in all years where, start biomass=end biomass of - the previous year? Referenced above, this is probably not worth - exploring as later milestone changes will eliminate this confusion. - */ - if (y < this->nyears) { - /* - First thing we need is total mortality aggregated across all fleets - to inform the subsequent catch and change in numbers at age - calculations. This is only calculated for years < nyears as these are - the model estimated years with data. The year loop extends to - y=nyears so that population numbers at age and SSB can be calculated - at the end of the last year of the model - */ - CalculateMortality(i_age_year, y, a); - } - CalculateMaturityAA(i_age_year, a); - /* if statements needed because some quantities are only needed - for the first year and/or age, so these steps are included here. - */ - if (y == 0) { - // Initial numbers at age is a user input or estimated parameter - // vector. - CalculateInitialNumbersAA(i_age_year, a); - - if (a == 0) { - this->unfished_numbers_at_age[i_age_year] = - fims_math::exp(this->recruitment->log_rzero[0]); - } else { - CalculateUnfishedNumbersAA(i_age_year, a - 1, a); - } - - /* - Fished and unfished biomass vectors are summing biomass at - age across ages. - */ - - CalculateBiomass(i_age_year, y, a); - - CalculateUnfishedBiomass(i_age_year, y, a); - - /* - Fished and unfished spawning biomass vectors are summing biomass at - age across ages to allow calculation of recruitment in the next year. - */ - - CalculateSpawningBiomass(i_age_year, y, a); - - CalculateUnfishedSpawningBiomass(i_age_year, y, a); - - /* - Expected recruitment in year 0 is numbers at age 0 in year 0. - */ - - this->expected_recruitment[i_age_year] = - this->numbers_at_age[i_age_year]; - - } else { - if (a == 0) { - // Set the nrecruits for age a=0 year y (use pointers instead of - // functional returns) assuming fecundity = 1 and 50:50 sex ratio - CalculateRecruitment(i_age_year, y, y); - this->unfished_numbers_at_age[i_age_year] = - fims_math::exp(this->recruitment->log_rzero[0]); - - } else { - size_t i_agem1_yearm1 = (y - 1) * nages + (a - 1); - CalculateNumbersAA(i_age_year, i_agem1_yearm1, a); - CalculateUnfishedNumbersAA(i_age_year, i_agem1_yearm1, a); - } - CalculateBiomass(i_age_year, y, a); - CalculateSpawningBiomass(i_age_year, y, a); - - CalculateUnfishedBiomass(i_age_year, y, a); - CalculateUnfishedSpawningBiomass(i_age_year, y, a); - } - - /* - Here composition, total catch, and index values are calculated for all - years with reference data. They are not calculated for y=nyears as there - is this is just to get final population structure at the end of the - terminal year. - */ - if (y < this->nyears) { - CalculateCatchNumbersAA(i_age_year, y, a); - - CalculateCatchWeightAA(y, a); - CalculateCatch(y, a); - CalculateIndex(i_age_year, y, a); - } - } - } + if (y < this->nyears) { + CalculateCatchNumbersAA(i_age_year, y, a); + CalculateCatchWeightAA(y, a); + CalculateCatch(y, a); + CalculateIndex(i_age_year, y, a); } - }; - template - uint32_t Population::id_g = 0; - -} // namespace fims_popdy + } + } + } +}; +template +uint32_t Population::id_g = 0; + +} // namespace fims_popdy #endif /* FIMS_POPULATION_DYNAMICS_POPULATION_HPP */ diff --git a/inst/include/population_dynamics/recruitment/functors/recruitment_base.hpp b/inst/include/population_dynamics/recruitment/functors/recruitment_base.hpp index 3a6f65a8..3472e5cb 100644 --- a/inst/include/population_dynamics/recruitment/functors/recruitment_base.hpp +++ b/inst/include/population_dynamics/recruitment/functors/recruitment_base.hpp @@ -1,4 +1,4 @@ -/** +/** * @file recruitment_base.hpp * @brief Serves as the parent class where recruitment functions are called. * @details Defines guards for recruitment base outline to define the @@ -28,12 +28,12 @@ template struct RecruitmentBase : public fims_model_object::FIMSObject { static uint32_t id_g; /**< reference id for recruitment object*/ - fims::Vector - log_recruit_devs; /*!< A vector of the natural log of recruitment deviations */ - bool constrain_deviations = false; /*!< A flag to indicate if recruitment - deviations are summing to zero or not */ + fims::Vector log_recruit_devs; /*!< A vector of the natural log of + recruitment deviations */ + bool constrain_deviations = false; /*!< A flag to indicate if recruitment + deviations are summing to zero or not */ - fims::Vector log_rzero; /**< Natural log of unexploited recruitment.*/ + fims::Vector log_rzero; /**< Natural log of unexploited recruitment.*/ bool estimate_log_recruit_devs = true; /*!< A flag to indicate if recruitment deviations are estimated or not */ @@ -60,7 +60,6 @@ struct RecruitmentBase : public fims_model_object::FIMSObject { const Type &spawners, const Type &ssbzero) = 0; // need to add input parameter values - /** @brief Prepare constrained recruitment deviations. * Based on ADMB sum-to-zero constraint implementation. We still * need to adde an additional penalty to the PrepareConstrainedDeviations diff --git a/inst/include/population_dynamics/recruitment/functors/sr_beverton_holt.hpp b/inst/include/population_dynamics/recruitment/functors/sr_beverton_holt.hpp index 66407d10..12d45886 100644 --- a/inst/include/population_dynamics/recruitment/functors/sr_beverton_holt.hpp +++ b/inst/include/population_dynamics/recruitment/functors/sr_beverton_holt.hpp @@ -10,8 +10,8 @@ #ifndef FIMS_POPULATION_DYNAMICS_RECRUITMENT_SR_BEVERTON_HOLT_HPP #define FIMS_POPULATION_DYNAMICS_RECRUITMENT_SR_BEVERTON_HOLT_HPP -#include "recruitment_base.hpp" #include "../../../common/fims_vector.hpp" +#include "recruitment_base.hpp" namespace fims_popdy { @@ -28,7 +28,7 @@ struct SRBevertonHolt : public RecruitmentBase { // stock--recruitment function. These members are needed by the Beverton--Holt // stock--recruitment function but will not be common to all recruitment // functions like spawners is below. - fims::Vector logit_steep; /**< Transformed value of recruitment + fims::Vector logit_steep; /**< Transformed value of recruitment relative to unfished recruitment at 20 percent of unfished spawning biomass.*/ diff --git a/inst/include/population_dynamics/selectivity/functors/double_logistic.hpp b/inst/include/population_dynamics/selectivity/functors/double_logistic.hpp index 0a65f47f..12c20856 100644 --- a/inst/include/population_dynamics/selectivity/functors/double_logistic.hpp +++ b/inst/include/population_dynamics/selectivity/functors/double_logistic.hpp @@ -22,64 +22,61 @@ namespace fims_popdy { */ template struct DoubleLogisticSelectivity : public SelectivityBase { - fims::Vector inflection_point_asc; /**< 50% quantile of the value of the quantity of - interest (x) on the ascending limb of the double logistic curve; - e.g. age at which 50% of the fish are selected */ - fims::Vector slope_asc; /** inflection_point_desc; /**< 50% quantile of the value of the quantity of - interest (x) on the descending limb of the double logistic curve; - e.g. age at which 50% of the fish are selected */ - fims::Vector slope_desc; /** inflection_point_asc; /**< 50% quantile of the value of the + quantity of interest (x) on the ascending limb of the double + logistic curve; e.g. age at which 50% of the fish are selected */ + fims::Vector slope_asc; /** inflection_point_desc; /**< 50% quantile of the value of + the quantity of interest (x) on the descending limb of the double + logistic curve; e.g. age at which 50% of the fish are selected */ + fims::Vector slope_desc; /**() - { - } + DoubleLogisticSelectivity() : SelectivityBase() {} - virtual ~DoubleLogisticSelectivity() - { - } + virtual ~DoubleLogisticSelectivity() {} - /** - * @brief Method of the double logistic selectivity class that implements the - * double logistic function from FIMS math. - * - * \f$ \frac{1.0}{ 1.0 + exp(-1.0 * slope\_asc (x - inflection_point\_asc))} - * \left(1.0-\frac{1.0}{ 1.0 + exp(-1.0 * slope\_desc (x - - * inflection_point\_desc))} \right)\f$ - * - * @param x The independent variable in the double logistic function (e.g., - * age or size in selectivity). - */ - virtual const Type evaluate(const Type &x) - { - return fims_math::double_logistic( - inflection_point_asc[0], slope_asc[0], inflection_point_desc[0], slope_desc[0], x); - } + /** + * @brief Method of the double logistic selectivity class that implements the + * double logistic function from FIMS math. + * + * \f$ \frac{1.0}{ 1.0 + exp(-1.0 * slope\_asc (x - inflection_point\_asc))} + * \left(1.0-\frac{1.0}{ 1.0 + exp(-1.0 * slope\_desc (x - + * inflection_point\_desc))} \right)\f$ + * + * @param x The independent variable in the double logistic function (e.g., + * age or size in selectivity). + */ + virtual const Type evaluate(const Type &x) { + return fims_math::double_logistic( + inflection_point_asc[0], slope_asc[0], inflection_point_desc[0], + slope_desc[0], x); + } - /** - * @brief Method of the double logistic selectivity class that implements the - * double logistic function from FIMS math. - * - * \f$ \frac{1.0}{ 1.0 + exp(-1.0 * slope\_asc_t (x - inflection_point\_asc_t))} - * \left(1.0-\frac{1.0}{ 1.0 + exp(-1.0 * slope\_desc_t (x - - * inflection_point\_desc_t))} \right)\f$ - * - * @param x The independent variable in the double logistic function (e.g., - * age or size in selectivity). - * @param pos Position index, e.g., which year. - */ - virtual const Type evaluate(const Type &x, size_t pos) - { - return fims_math::double_logistic( - inflection_point_asc.get_force_scalar(pos), slope_asc.get_force_scalar(pos), - inflection_point_desc.get_force_scalar(pos), slope_desc.get_force_scalar(pos), x); - } + /** + * @brief Method of the double logistic selectivity class that implements the + * double logistic function from FIMS math. + * + * \f$ \frac{1.0}{ 1.0 + exp(-1.0 * slope\_asc_t (x - + * inflection_point\_asc_t))} \left(1.0-\frac{1.0}{ 1.0 + exp(-1.0 * + * slope\_desc_t (x - inflection_point\_desc_t))} \right)\f$ + * + * @param x The independent variable in the double logistic function (e.g., + * age or size in selectivity). + * @param pos Position index, e.g., which year. + */ + virtual const Type evaluate(const Type &x, size_t pos) { + return fims_math::double_logistic( + inflection_point_asc.get_force_scalar(pos), + slope_asc.get_force_scalar(pos), + inflection_point_desc.get_force_scalar(pos), + slope_desc.get_force_scalar(pos), x); + } }; -} // namespace fims_popdy +} // namespace fims_popdy #endif /* POPULATION_DYNAMICS_SELECTIVITY_DOUBLE_LOGISTIC_HPP */ diff --git a/inst/include/population_dynamics/selectivity/functors/logistic.hpp b/inst/include/population_dynamics/selectivity/functors/logistic.hpp index 27090521..52e13254 100644 --- a/inst/include/population_dynamics/selectivity/functors/logistic.hpp +++ b/inst/include/population_dynamics/selectivity/functors/logistic.hpp @@ -22,49 +22,45 @@ namespace fims_popdy { */ template struct LogisticSelectivity : public SelectivityBase { - fims::Vector inflection_point; /**< 50% quantile of the value of the quantity of - interest (x); e.g. age at which 50% of the fish are selected */ - fims::Vector slope; /** + inflection_point; /**< 50% quantile of the value of the quantity of + interest (x); e.g. age at which 50% of the fish are selected */ + fims::Vector slope; /**() - { - } + LogisticSelectivity() : SelectivityBase() {} - virtual ~LogisticSelectivity() - { - } + virtual ~LogisticSelectivity() {} - /** - * @brief Method of the logistic selectivity class that implements the - * logistic function from FIMS math. - * - * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope (x - inflection\_point))} \f] - * - * @param x The independent variable in the logistic function (e.g., age or - * size in selectivity). - */ - virtual const Type evaluate(const Type& x) - { - return fims_math::logistic(inflection_point[0], slope[0], x); - } + /** + * @brief Method of the logistic selectivity class that implements the + * logistic function from FIMS math. + * + * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope (x - inflection\_point))} \f] + * + * @param x The independent variable in the logistic function (e.g., age or + * size in selectivity). + */ + virtual const Type evaluate(const Type& x) { + return fims_math::logistic(inflection_point[0], slope[0], x); + } - /** - * @brief Method of the logistic selectivity class that implements the - * logistic function from FIMS math. - * - * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope_t (x - {inflection\_point}_t))} \f] - * - * @param x The independent variable in the logistic function (e.g., age or - * size in selectivity). - * @param pos Position index, e.g., which year. - */ - virtual const Type evaluate(const Type& x, size_t pos) - { - return fims_math::logistic(inflection_point.get_force_scalar(pos), slope.get_force_scalar(pos), x); - } + /** + * @brief Method of the logistic selectivity class that implements the + * logistic function from FIMS math. + * + * \f[ \frac{1.0}{ 1.0 + exp(-1.0 * slope_t (x - {inflection\_point}_t))} \f] + * + * @param x The independent variable in the logistic function (e.g., age or + * size in selectivity). + * @param pos Position index, e.g., which year. + */ + virtual const Type evaluate(const Type& x, size_t pos) { + return fims_math::logistic(inflection_point.get_force_scalar(pos), + slope.get_force_scalar(pos), x); + } }; -} // namespace fims_popdy +} // namespace fims_popdy #endif /* POPULATION_DYNAMICS_SELECTIVITY_LOGISTIC_HPP */ diff --git a/inst/include/population_dynamics/selectivity/functors/selectivity_base.hpp b/inst/include/population_dynamics/selectivity/functors/selectivity_base.hpp index c4906981..1d7cc4d0 100644 --- a/inst/include/population_dynamics/selectivity/functors/selectivity_base.hpp +++ b/inst/include/population_dynamics/selectivity/functors/selectivity_base.hpp @@ -44,8 +44,8 @@ struct SelectivityBase : public fims_model_object::FIMSObject { * size in selectivity). */ virtual const Type evaluate(const Type& x) = 0; - - /** + + /** * @brief Calculates the selectivity. * @param x The independent variable in the logistic function (e.g., age or * size in selectivity). diff --git a/inst/include/utilities/fims_json.hpp b/inst/include/utilities/fims_json.hpp index 205aa104..793f39f2 100644 --- a/inst/include/utilities/fims_json.hpp +++ b/inst/include/utilities/fims_json.hpp @@ -7,530 +7,500 @@ * Fisheries Integrated Modeling System project. See LICENSE in the source * folder for reuse information. */ +#include #include #include #include #include #include -#include #include - namespace fims { - class JsonValue; - - /** - * Alias for a JSON object, mapping strings to JSON values. - */ - using JsonObject = std::map; - - /** - * Alias for a JSON array, containing a sequence of JSON values. - */ - using JsonArray = std::vector; - - /** - * Represents different types of JSON values. - */ - enum JsonValueType { - Null = 0, /**< Null JSON value. */ - Number, /**< Numeric JSON value. */ - String, /**< String JSON value. */ - Bool, /**< Boolean JSON value. */ - Object, /**< JSON object. */ - JArray /**< JSON array. */ - }; - - /** - * Represents a JSON value. - */ - class JsonValue { - public: - - /** Default constructor, initializes to Null value. */ - JsonValue() : type(JsonValueType::Null) { - } +class JsonValue; - /** Constructor for numeric JSON value (i.e., integer). */ - JsonValue(int num) : type(JsonValueType::Number), number(num) { - } +/** + * Alias for a JSON object, mapping strings to JSON values. + */ +using JsonObject = std::map; - /** Constructor for numeric JSON value (i.e., double). */ - JsonValue(double num) : type(JsonValueType::Number), number(num) { - } +/** + * Alias for a JSON array, containing a sequence of JSON values. + */ +using JsonArray = std::vector; - /** Constructor for string JSON value. */ - JsonValue(const std::string& str) : type(JsonValueType::String), str(str) { - } +/** + * Represents different types of JSON values. + */ +enum JsonValueType { + Null = 0, /**< Null JSON value. */ + Number, /**< Numeric JSON value. */ + String, /**< String JSON value. */ + Bool, /**< Boolean JSON value. */ + Object, /**< JSON object. */ + JArray /**< JSON array. */ +}; - /** Constructor for boolean JSON value. */ - JsonValue(bool b) : type(JsonValueType::Bool), boolean(b) { - } +/** + * Represents a JSON value. + */ +class JsonValue { + public: + /** Default constructor, initializes to Null value. */ + JsonValue() : type(JsonValueType::Null) {} - /** Constructor for JSON object value. */ - JsonValue(const JsonObject& obj) : type(JsonValueType::Object), object(obj) { - } + /** Constructor for numeric JSON value (i.e., integer). */ + JsonValue(int num) : type(JsonValueType::Number), number(num) {} - /** Constructor for JSON array value. */ - JsonValue(const JsonArray& arr) : type(JsonValueType::JArray), array(arr) { - } + /** Constructor for numeric JSON value (i.e., double). */ + JsonValue(double num) : type(JsonValueType::Number), number(num) {} - /** Get the type of the JSON value. */ - JsonValueType GetType() const { - return type; - } + /** Constructor for string JSON value. */ + JsonValue(const std::string& str) : type(JsonValueType::String), str(str) {} - /** Get the numeric value as an integer. */ - int GetInt() const { - return static_cast (number); - } + /** Constructor for boolean JSON value. */ + JsonValue(bool b) : type(JsonValueType::Bool), boolean(b) {} - /** Get the numeric value as a double. */ - double GetDouble() const { - return number; - } + /** Constructor for JSON object value. */ + JsonValue(const JsonObject& obj) : type(JsonValueType::Object), object(obj) {} - /** Get the string value. */ - const std::string& GetString() const { - return str; - } + /** Constructor for JSON array value. */ + JsonValue(const JsonArray& arr) : type(JsonValueType::JArray), array(arr) {} - /** Get the boolean value. */ - bool GetBool() const { - return boolean; - } + /** Get the type of the JSON value. */ + JsonValueType GetType() const { return type; } - /** Get the JSON object. */ - JsonObject& GetObject() { - return object; - } + /** Get the numeric value as an integer. */ + int GetInt() const { return static_cast(number); } - /** Get the JSON array. */ - JsonArray& GetArray() { - return array; - } + /** Get the numeric value as a double. */ + double GetDouble() const { return number; } - private: - JsonValueType type; /**< Type of the JSON value. */ - double number; /**< Numeric value. */ - std::string str; /**< String value. */ - bool boolean; /**< Boolean value. */ - JsonObject object; /**< JSON object. */ - JsonArray array; /**< JSON array. */ - }; - - /** - * Parses JSON strings and generates JSON values. - */ - class JsonParser { - public: - /** Parse a JSON string and return the corresponding JSON value. */ - JsonValue Parse(const std::string& json); - /** Write a JSON value to a file. */ - void WriteToFile(const std::string& filename, JsonValue jsonValue); - /** Display a JSON value to the standard output. */ - void Show(JsonValue jsonValue); - - /** Remove whitespace in JSON. */ - static std::string removeWhitespace(const std::string& input) { - std::string result = input; - result.erase(std::remove_if(result.begin(), result.end(), ::isspace), result.end()); - return result; - } + /** Get the string value. */ + const std::string& GetString() const { return str; } - /** - * @brief Formats a JSON string. - * @param json - * @return - */ - static std::string PrettyFormatJSON(const std::string& json) { - std::string result; - std::string input = JsonParser::removeWhitespace(json); - int indentLevel = 0; - bool inQuotes = false; - - for (size_t i = 0; i < input.size(); ++i) { - char current = input[i]; - - switch (current) { - case '{': - case '[': - result += current; - if (!inQuotes) { - result += '\n'; - indentLevel++; - result += std::string(indentLevel * 4, ' '); - } - break; - - case '}': - case ']': - if (!inQuotes) { - result += '\n'; - indentLevel--; - result += std::string(indentLevel * 4, ' '); - } - result += current; - break; - - case ',': - result += current; - if (!inQuotes) { - result += '\n'; - result += std::string(indentLevel * 4, ' '); - } - break; - - case ':': - result += current; - if (!inQuotes) result += " "; - break; - - case '"': - result += current; - // Toggle inQuotes when we encounter a double-quote - if (i == 0 || input[i - 1] != '\\') { - inQuotes = !inQuotes; - } - break; - - default: - result += current; - break; - } - } - return result; - } + /** Get the boolean value. */ + bool GetBool() const { return boolean; } - private: - /** Skip whitespace characters in the input string. */ - void SkipWhitespace(); - /** Parse a JSON value. */ - JsonValue ParseValue(); - /** Parse a numeric JSON value. */ - JsonValue ParseNumber(); - /** Parse a string JSON value. */ - JsonValue ParseString(); - /** Parse a boolean JSON value. */ - JsonValue ParseBool(); - /** Parse a null JSON value. */ - JsonValue ParseNull(); - /** Parse a JSON object. */ - JsonValue ParseObject(); - /** Parse a JSON array. */ - JsonValue ParseArray(); - /** Write a JSON value to an output file stream. */ - void WriteJsonValue(std::ofstream& outputFile, JsonValue jsonValue); - /** Display a JSON value to an output stream. */ - void PrintJsonValue(std::ostream& outputFile, JsonValue jsonValue); - /** Indentation helper for printing JSON values in an output file stream. */ - void Indent(std::ostream& outputFile, int level); - /** Indentation helper for printing JSON values in an output stream. */ - void Indent(std::ofstream& outputFile, int level); - - std::string data; /**< Input JSON data. */ - size_t position; /**< Current position in the data. */ - }; - - /** - * Parse a JSON string and return the corresponding JSON value. - * @param json The JSON string to parse. - * @return The parsed JSON value. - */ - JsonValue JsonParser::Parse(const std::string& json) { - data = json; - position = 0; - return ParseValue(); - } + /** Get the JSON object. */ + JsonObject& GetObject() { return object; } - /** - * @brief Skip the white space. - * - */ - void JsonParser::SkipWhitespace() { - while (position < data.size() && std::isspace(data[position])) { - position++; - } - } + /** Get the JSON array. */ + JsonArray& GetArray() { return array; } - /** - * Parse a JSON value. - * @return The parsed JSON value. - */ - JsonValue JsonParser::ParseValue() { - /** Skip whitespace characters in the input string. */ - SkipWhitespace(); - char current = data[position]; - if (current == '{') { - return ParseObject(); - } else if (current == '[') { - return ParseArray(); - } else if (current == '"') { - return ParseString(); - } else if (current == 't' || current == 'f') { - return ParseBool(); - } else if (current == 'n') { - return ParseNull(); - } else { - return ParseNumber(); - } + private: + JsonValueType type; /**< Type of the JSON value. */ + double number; /**< Numeric value. */ + std::string str; /**< String value. */ + bool boolean; /**< Boolean value. */ + JsonObject object; /**< JSON object. */ + JsonArray array; /**< JSON array. */ +}; + +/** + * Parses JSON strings and generates JSON values. + */ +class JsonParser { + public: + /** Parse a JSON string and return the corresponding JSON value. */ + JsonValue Parse(const std::string& json); + /** Write a JSON value to a file. */ + void WriteToFile(const std::string& filename, JsonValue jsonValue); + /** Display a JSON value to the standard output. */ + void Show(JsonValue jsonValue); + + /** Remove whitespace in JSON. */ + static std::string removeWhitespace(const std::string& input) { + std::string result = input; + result.erase(std::remove_if(result.begin(), result.end(), ::isspace), + result.end()); + return result; + } + + /** + * @brief Formats a JSON string. + * @param json + * @return + */ + static std::string PrettyFormatJSON(const std::string& json) { + std::string result; + std::string input = JsonParser::removeWhitespace(json); + int indentLevel = 0; + bool inQuotes = false; + + for (size_t i = 0; i < input.size(); ++i) { + char current = input[i]; + + switch (current) { + case '{': + case '[': + result += current; + if (!inQuotes) { + result += '\n'; + indentLevel++; + result += std::string(indentLevel * 4, ' '); + } + break; + + case '}': + case ']': + if (!inQuotes) { + result += '\n'; + indentLevel--; + result += std::string(indentLevel * 4, ' '); + } + result += current; + break; + + case ',': + result += current; + if (!inQuotes) { + result += '\n'; + result += std::string(indentLevel * 4, ' '); + } + break; + + case ':': + result += current; + if (!inQuotes) result += " "; + break; + + case '"': + result += current; + // Toggle inQuotes when we encounter a double-quote + if (i == 0 || input[i - 1] != '\\') { + inQuotes = !inQuotes; + } + break; + + default: + result += current; + break; + } } + return result; + } + + private: + /** Skip whitespace characters in the input string. */ + void SkipWhitespace(); + /** Parse a JSON value. */ + JsonValue ParseValue(); + /** Parse a numeric JSON value. */ + JsonValue ParseNumber(); + /** Parse a string JSON value. */ + JsonValue ParseString(); + /** Parse a boolean JSON value. */ + JsonValue ParseBool(); + /** Parse a null JSON value. */ + JsonValue ParseNull(); + /** Parse a JSON object. */ + JsonValue ParseObject(); + /** Parse a JSON array. */ + JsonValue ParseArray(); + /** Write a JSON value to an output file stream. */ + void WriteJsonValue(std::ofstream& outputFile, JsonValue jsonValue); + /** Display a JSON value to an output stream. */ + void PrintJsonValue(std::ostream& outputFile, JsonValue jsonValue); + /** Indentation helper for printing JSON values in an output file stream. */ + void Indent(std::ostream& outputFile, int level); + /** Indentation helper for printing JSON values in an output stream. */ + void Indent(std::ofstream& outputFile, int level); + + std::string data; /**< Input JSON data. */ + size_t position; /**< Current position in the data. */ +}; - /** - * Parse a numeric JSON value. - * @return The parsed JSON value. - */ - JsonValue JsonParser::ParseNumber() { - size_t end_pos = position; - bool is_float = false; - while (end_pos < data.size() && - (std::isdigit(data[end_pos]) || data[end_pos] == '.' || - data[end_pos] == '-' || data[end_pos] == 'e' || - data[end_pos] == 'E')) { - if (data[end_pos] == '.' || data[end_pos] == 'e' || data[end_pos] == 'E') { - is_float = true; - } - end_pos++; - } +/** + * Parse a JSON string and return the corresponding JSON value. + * @param json The JSON string to parse. + * @return The parsed JSON value. + */ +JsonValue JsonParser::Parse(const std::string& json) { + data = json; + position = 0; + return ParseValue(); +} - std::string num_str = data.substr(position, end_pos - position); - position = end_pos; - - if (is_float) { - double num; - std::istringstream(num_str) >> num; - return JsonValue(num); - } else { - int num; - std::istringstream(num_str) >> num; - return JsonValue(num); - } - } +/** + * @brief Skip the white space. + * + */ +void JsonParser::SkipWhitespace() { + while (position < data.size() && std::isspace(data[position])) { + position++; + } +} - /** - * Parse a string JSON value. - * @return The parsed JSON value. - */ - JsonValue JsonParser::ParseString() { - position++; // Skip the initial '"' - size_t end_pos = data.find('"', position); - std::string str = data.substr(position, end_pos - position); - position = end_pos + 1; - return JsonValue(str); - } +/** + * Parse a JSON value. + * @return The parsed JSON value. + */ +JsonValue JsonParser::ParseValue() { + /** Skip whitespace characters in the input string. */ + SkipWhitespace(); + char current = data[position]; + if (current == '{') { + return ParseObject(); + } else if (current == '[') { + return ParseArray(); + } else if (current == '"') { + return ParseString(); + } else if (current == 't' || current == 'f') { + return ParseBool(); + } else if (current == 'n') { + return ParseNull(); + } else { + return ParseNumber(); + } +} - /** - * Parse a boolean JSON value. - * @return The parsed JSON value. - */ - JsonValue JsonParser::ParseBool() { - if (data.compare(position, 4, "true") == 0) { - position += 4; - return JsonValue(true); - } else if (data.compare(position, 5, "false") == 0) { - position += 5; - return JsonValue(false); - } else { - // Invalid boolean value - return JsonValue(); - } +/** + * Parse a numeric JSON value. + * @return The parsed JSON value. + */ +JsonValue JsonParser::ParseNumber() { + size_t end_pos = position; + bool is_float = false; + while (end_pos < data.size() && + (std::isdigit(data[end_pos]) || data[end_pos] == '.' || + data[end_pos] == '-' || data[end_pos] == 'e' || + data[end_pos] == 'E')) { + if (data[end_pos] == '.' || data[end_pos] == 'e' || data[end_pos] == 'E') { + is_float = true; } + end_pos++; + } + + std::string num_str = data.substr(position, end_pos - position); + position = end_pos; + + if (is_float) { + double num; + std::istringstream(num_str) >> num; + return JsonValue(num); + } else { + int num; + std::istringstream(num_str) >> num; + return JsonValue(num); + } +} - /** - * Parse a null JSON value. - * @return The parsed JSON value. - */ - JsonValue JsonParser::ParseNull() { - if (data.compare(position, 4, "null") == 0) { - position += 4; - return JsonValue(); - } else { - // Invalid null value - return JsonValue(); - } - } +/** + * Parse a string JSON value. + * @return The parsed JSON value. + */ +JsonValue JsonParser::ParseString() { + position++; // Skip the initial '"' + size_t end_pos = data.find('"', position); + std::string str = data.substr(position, end_pos - position); + position = end_pos + 1; + return JsonValue(str); +} - /** - * Parse a JSON object. - * @return The parsed JSON value representing the object. - */ - JsonValue JsonParser::ParseObject() { - JsonObject obj; - position++; // Skip the initial '{' - - while (data[position] != '}') { - SkipWhitespace(); - std::string key = ParseString().GetString(); - - position++; // Skip the ':' - SkipWhitespace(); - JsonValue value = ParseValue(); - obj[key] = value; - - SkipWhitespace(); - if (data[position] == ',') { - position++; - } - } +/** + * Parse a boolean JSON value. + * @return The parsed JSON value. + */ +JsonValue JsonParser::ParseBool() { + if (data.compare(position, 4, "true") == 0) { + position += 4; + return JsonValue(true); + } else if (data.compare(position, 5, "false") == 0) { + position += 5; + return JsonValue(false); + } else { + // Invalid boolean value + return JsonValue(); + } +} - position++; // Skip the trailing '}' - return JsonValue(obj); +/** + * Parse a null JSON value. + * @return The parsed JSON value. + */ +JsonValue JsonParser::ParseNull() { + if (data.compare(position, 4, "null") == 0) { + position += 4; + return JsonValue(); + } else { + // Invalid null value + return JsonValue(); + } +} + +/** + * Parse a JSON object. + * @return The parsed JSON value representing the object. + */ +JsonValue JsonParser::ParseObject() { + JsonObject obj; + position++; // Skip the initial '{' + + while (data[position] != '}') { + SkipWhitespace(); + std::string key = ParseString().GetString(); + + position++; // Skip the ':' + SkipWhitespace(); + JsonValue value = ParseValue(); + obj[key] = value; + + SkipWhitespace(); + if (data[position] == ',') { + position++; } + } - /** - * Parse a JSON array. - * @return The parsed JSON value representing the array. - */ - JsonValue JsonParser::ParseArray() { - JsonArray arr; - position++; // Skip the initial '[' - - while (data[position] != ']') { - SkipWhitespace(); - JsonValue value = ParseValue(); - arr.push_back(value); - - SkipWhitespace(); - if (data[position] == ',') { - position++; - } - } + position++; // Skip the trailing '}' + return JsonValue(obj); +} - position++; // Skip the trailing ']' - return JsonValue(arr); +/** + * Parse a JSON array. + * @return The parsed JSON value representing the array. + */ +JsonValue JsonParser::ParseArray() { + JsonArray arr; + position++; // Skip the initial '[' + + while (data[position] != ']') { + SkipWhitespace(); + JsonValue value = ParseValue(); + arr.push_back(value); + + SkipWhitespace(); + if (data[position] == ',') { + position++; } + } - /** - * Write a JSON value to an output file. - * @param filename The name of the output file. - * @param jsonValue The JSON value to write. - */ - void JsonParser::WriteToFile(const std::string& filename, JsonValue jsonValue) { - std::ofstream outputFile(filename); - if (!outputFile) { - std::cerr << "Error: Unable to open file " << filename << " for writing." - << std::endl; - return; - } + position++; // Skip the trailing ']' + return JsonValue(arr); +} - /** Call a private helper function to write JSON values recursively */ - WriteJsonValue(outputFile, jsonValue); - } +/** + * Write a JSON value to an output file. + * @param filename The name of the output file. + * @param jsonValue The JSON value to write. + */ +void JsonParser::WriteToFile(const std::string& filename, JsonValue jsonValue) { + std::ofstream outputFile(filename); + if (!outputFile) { + std::cerr << "Error: Unable to open file " << filename << " for writing." + << std::endl; + return; + } + + /** Call a private helper function to write JSON values recursively */ + WriteJsonValue(outputFile, jsonValue); +} - /** - * Write a JSON value to an output file. - * Private helper function to write JSON values recursively - * @param outputFile The output file stream. - * @param jsonValue The JSON value to write. - */ - void JsonParser::WriteJsonValue(std::ofstream& outputFile, - JsonValue jsonValue) { - switch (jsonValue.GetType()) { - case JsonValueType::Null: - outputFile << "null"; - break; - case JsonValueType::Number: - outputFile << jsonValue.GetDouble(); - break; - case JsonValueType::String: - outputFile << "\"" << jsonValue.GetString() << "\""; - break; - case JsonValueType::Bool: - outputFile << (jsonValue.GetBool() ? "true" : "false"); - break; - case JsonValueType::Object: - { - JsonObject& obj = jsonValue.GetObject(); - outputFile << "{"; - bool first = true; - for (const auto& pair : obj) { - if (!first) { - outputFile << ","; - } - first = false; - outputFile << "\"" << pair.first << "\":"; - WriteJsonValue(outputFile, pair.second); - } - outputFile << "}"; - } - break; - case JsonValueType::JArray: - { - JsonArray& arr = jsonValue.GetArray(); - outputFile << "["; - bool first = true; - for (const auto& value : arr) { - if (!first) { - outputFile << ","; - } - first = false; - WriteJsonValue(outputFile, value); - } - outputFile << "]"; - } - break; +/** + * Write a JSON value to an output file. + * Private helper function to write JSON values recursively + * @param outputFile The output file stream. + * @param jsonValue The JSON value to write. + */ +void JsonParser::WriteJsonValue(std::ofstream& outputFile, + JsonValue jsonValue) { + switch (jsonValue.GetType()) { + case JsonValueType::Null: + outputFile << "null"; + break; + case JsonValueType::Number: + outputFile << jsonValue.GetDouble(); + break; + case JsonValueType::String: + outputFile << "\"" << jsonValue.GetString() << "\""; + break; + case JsonValueType::Bool: + outputFile << (jsonValue.GetBool() ? "true" : "false"); + break; + case JsonValueType::Object: { + JsonObject& obj = jsonValue.GetObject(); + outputFile << "{"; + bool first = true; + for (const auto& pair : obj) { + if (!first) { + outputFile << ","; } - } + first = false; + outputFile << "\"" << pair.first << "\":"; + WriteJsonValue(outputFile, pair.second); + } + outputFile << "}"; + } break; + case JsonValueType::JArray: { + JsonArray& arr = jsonValue.GetArray(); + outputFile << "["; + bool first = true; + for (const auto& value : arr) { + if (!first) { + outputFile << ","; + } + first = false; + WriteJsonValue(outputFile, value); + } + outputFile << "]"; + } break; + } +} - /** - * Display a JSON value to the standard output. - * @param jsonValue The JSON value to display. - */ - void JsonParser::Show(JsonValue jsonValue) { - this->PrintJsonValue(std::cout, jsonValue); - std::cout << std::endl; - } +/** + * Display a JSON value to the standard output. + * @param jsonValue The JSON value to display. + */ +void JsonParser::Show(JsonValue jsonValue) { + this->PrintJsonValue(std::cout, jsonValue); + std::cout << std::endl; +} - /** - * Display a JSON value to an output stream. - * @param output The output stream. - * @param jsonValue The JSON value to display. - */ - void JsonParser::PrintJsonValue(std::ostream& output, JsonValue jsonValue) { - switch (jsonValue.GetType()) { - case JsonValueType::Null: - output << "null"; - break; - case JsonValueType::Number: - output << jsonValue.GetDouble(); - break; - case JsonValueType::String: - output << "\"" << jsonValue.GetString() << "\""; - break; - case JsonValueType::Bool: - output << (jsonValue.GetBool() ? "true" : "false"); - break; - case JsonValueType::Object: - { - JsonObject& obj = jsonValue.GetObject(); - output << "{"; - bool first = true; - for (const auto& pair : obj) { - if (!first) { - output << ","; - } - first = false; - output << "\"" << pair.first << "\":"; - PrintJsonValue(output, pair.second); - } - output << "}"; - } - break; - case JsonValueType::JArray: - { - JsonArray& arr = jsonValue.GetArray(); - output << "["; - bool first = true; - for (const auto& value : arr) { - if (!first) { - output << ","; - } - first = false; - PrintJsonValue(output, value); - } - output << "]"; - } - break; +/** + * Display a JSON value to an output stream. + * @param output The output stream. + * @param jsonValue The JSON value to display. + */ +void JsonParser::PrintJsonValue(std::ostream& output, JsonValue jsonValue) { + switch (jsonValue.GetType()) { + case JsonValueType::Null: + output << "null"; + break; + case JsonValueType::Number: + output << jsonValue.GetDouble(); + break; + case JsonValueType::String: + output << "\"" << jsonValue.GetString() << "\""; + break; + case JsonValueType::Bool: + output << (jsonValue.GetBool() ? "true" : "false"); + break; + case JsonValueType::Object: { + JsonObject& obj = jsonValue.GetObject(); + output << "{"; + bool first = true; + for (const auto& pair : obj) { + if (!first) { + output << ","; } - } -} \ No newline at end of file + first = false; + output << "\"" << pair.first << "\":"; + PrintJsonValue(output, pair.second); + } + output << "}"; + } break; + case JsonValueType::JArray: { + JsonArray& arr = jsonValue.GetArray(); + output << "["; + bool first = true; + for (const auto& value : arr) { + if (!first) { + output << ","; + } + first = false; + PrintJsonValue(output, value); + } + output << "]"; + } break; + } +} +} // namespace fims \ No newline at end of file diff --git a/tests/gtest/test_population_test_fixture.hpp b/tests/gtest/test_population_test_fixture.hpp index 3dcfd453..0250d792 100644 --- a/tests/gtest/test_population_test_fixture.hpp +++ b/tests/gtest/test_population_test_fixture.hpp @@ -2,9 +2,6 @@ #include "population_dynamics/population/population.hpp" - - - namespace { // Use test fixture to reuse the same configuration of objects for @@ -89,7 +86,7 @@ class PopulationEvaluateTestFixture : public testing::Test { selectivity->slope[0] = 0.5; fleet->expected_catch.resize(nyears); - fleet->expected_index.resize(nyears); + fleet->expected_index.resize(nyears); fleet->catch_numbers_at_age.resize(nyears * nages); fleet->log_q.resize(1); fleet->Initialize(nyears, nages); @@ -106,9 +103,9 @@ class PopulationEvaluateTestFixture : public testing::Test { } population.numbers_at_age.resize((nyears + 1) * nages); try { - population.Initialize(nyears, nseasons, nages); + population.Initialize(nyears, nseasons, nages); } catch (std::exception& e) { - std::cout << e.what() << "\n"; + std::cout << e.what() << "\n"; } for (int i = 0; i < nages; i++) { @@ -251,9 +248,9 @@ class PopulationPrepareTestFixture : public testing::Test { selectivity->slope.resize(1); selectivity->inflection_point[0] = 7; selectivity->slope[0] = 0.5; - + fleet->expected_catch.resize(nyears); - fleet->expected_index.resize(nyears); + fleet->expected_index.resize(nyears); fleet->catch_numbers_at_age.resize(nyears * nages); fleet->log_q.resize(1); fleet->Initialize(nyears, nages);