diff --git a/include/amici/model.h b/include/amici/model.h index de0abe4eb9..4e41f94778 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -11,6 +11,8 @@ #include "amici/sundials_matrix_wrapper.h" #include +#include +#include #include namespace amici { @@ -618,7 +620,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return The parameter names */ - virtual std::vector get_free_parameter_names() const; + virtual std::span get_free_parameter_names() const; /** * @brief Report whether the model has state names set. @@ -633,14 +635,14 @@ class Model : public AbstractModel, public ModelDimensions { * * @return State names */ - virtual std::vector get_state_names() const; + virtual std::span get_state_names() const; /** * @brief Get names of the solver states. * * @return State names */ - virtual std::vector get_state_names_solver() const; + virtual std::span get_state_names_solver() const; /** * @brief Report whether the model has fixed parameter names set. @@ -655,7 +657,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return Fixed parameter names */ - virtual std::vector get_fixed_parameter_names() const; + virtual std::span get_fixed_parameter_names() const; /** * @brief Report whether the model has observable names set. @@ -670,7 +672,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return Observable names */ - virtual std::vector get_observable_names() const; + virtual std::span get_observable_names() const; /** * @brief Report whether the model has expression names set. @@ -685,7 +687,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return Expression names */ - virtual std::vector get_expression_names() const; + virtual std::span get_expression_names() const; /** * @brief Report whether the model has parameter IDs set. @@ -700,7 +702,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return Parameter IDs */ - virtual std::vector get_free_parameter_ids() const; + virtual std::span get_free_parameter_ids() const; /** * @brief Report whether the model has state IDs set. @@ -715,14 +717,14 @@ class Model : public AbstractModel, public ModelDimensions { * * @return State IDs */ - virtual std::vector get_state_ids() const; + virtual std::span get_state_ids() const; /** * @brief Get IDs of the solver states. * * @return State IDs */ - virtual std::vector get_state_ids_solver() const; + virtual std::span get_state_ids_solver() const; /** * @brief Report whether the model has fixed parameter IDs set. @@ -737,7 +739,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return Fixed parameter IDs */ - virtual std::vector get_fixed_parameter_ids() const; + virtual std::span get_fixed_parameter_ids() const; /** * @brief Report whether the model has observable IDs set. @@ -752,7 +754,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return Observable IDs */ - virtual std::vector get_observable_ids() const; + virtual std::span get_observable_ids() const; /** * @brief Report whether the model has expression IDs set. @@ -767,7 +769,7 @@ class Model : public AbstractModel, public ModelDimensions { * * @return Expression IDs */ - virtual std::vector get_expression_ids() const; + virtual std::span get_expression_ids() const; /** * @brief Checks whether the defined noise model is Gaussian, i.e., the nllh diff --git a/models/model_calvetti_py/CMakeLists.txt b/models/model_calvetti_py/CMakeLists.txt index d7ad2f5ada..c60c49c92c 100644 --- a/models/model_calvetti_py/CMakeLists.txt +++ b/models/model_calvetti_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_calvetti_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_calvetti_py/model_calvetti_py.cpp b/models/model_calvetti_py/model_calvetti_py.cpp index 7ddbedab18..b3a69ae302 100644 --- a/models/model_calvetti_py/model_calvetti_py.cpp +++ b/models/model_calvetti_py/model_calvetti_py.cpp @@ -1,15 +1,16 @@ #include #include +#include namespace amici::model_model_calvetti_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { "V1ss", // k[0] "R1ss", // k[1] "V2ss", // k[2] @@ -18,7 +19,7 @@ std::array fixed_parameter_names = { "R3ss", // k[5] }; -std::array state_names = { +extern const std::array state_names = { "V1", // x_rdata[0] "V2", // x_rdata[1] "V3", // x_rdata[2] @@ -27,7 +28,16 @@ std::array state_names = { "f3", // x_rdata[5] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "V1", // x_solver[0] +"V2", // x_solver[1] +"V3", // x_solver[2] +"f1", // x_solver[3] +"f2", // x_solver[4] +"f3", // x_solver[5] +}; + +extern const std::array observable_names = { "y0", // y[0] "y1", // y[1] "y2", // y[2] @@ -45,7 +55,7 @@ ObservableScaling::lin, // y[4] ObservableScaling::lin, // y[5] }; -std::array expression_names = { +extern const std::array expression_names = { "C1ss", // w[0] "C2ss", // w[1] "C3ss", // w[2] @@ -64,11 +74,11 @@ std::array expression_names = { "rate_of_V3", // w[15] }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { "V1ss", // k[0] "R1ss", // k[1] "V2ss", // k[2] @@ -77,7 +87,7 @@ std::array fixed_parameter_ids = { "R3ss", // k[5] }; -std::array state_ids = { +extern const std::array state_ids = { "V1", // x_rdata[0] "V2", // x_rdata[1] "V3", // x_rdata[2] @@ -86,7 +96,16 @@ std::array state_ids = { "f3", // x_rdata[5] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "V1", // x_solver[0] +"V2", // x_solver[1] +"V3", // x_solver[2] +"f1", // x_solver[3] +"f2", // x_solver[4] +"f3", // x_solver[5] +}; + +extern const std::array observable_ids = { "obs_V1", // y[0] "obs_V2", // y[1] "obs_V3", // y[2] @@ -95,7 +114,7 @@ std::array observable_ids = { "obs_f2", // y[5] }; -std::array expression_ids = { +extern const std::array expression_ids = { "C1ss", // w[0] "C2ss", // w[1] "C3ss", // w[2] diff --git a/models/model_calvetti_py/model_calvetti_py.h b/models/model_calvetti_py/model_calvetti_py.h index a683b6010e..641b17963a 100644 --- a/models/model_calvetti_py/model_calvetti_py.h +++ b/models/model_calvetti_py/model_calvetti_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_calvetti_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_calvetti_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -424,114 +426,96 @@ class Model_model_calvetti_py : public amici::Model_DAE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -557,7 +541,7 @@ class Model_model_calvetti_py : public amici::Model_DAE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/models/model_dirac_py/CMakeLists.txt b/models/model_dirac_py/CMakeLists.txt index e5b80c5342..015fbe4cc4 100644 --- a/models/model_dirac_py/CMakeLists.txt +++ b/models/model_dirac_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_dirac_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_dirac_py/model_dirac_py.cpp b/models/model_dirac_py/model_dirac_py.cpp index e52ab31800..073c842703 100644 --- a/models/model_dirac_py/model_dirac_py.cpp +++ b/models/model_dirac_py/model_dirac_py.cpp @@ -1,27 +1,33 @@ #include #include +#include namespace amici::model_model_dirac_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { "p1", // p[0] "p2", // p[1] "p3", // p[2] "p4", // p[3] }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { }; -std::array state_names = { +extern const std::array state_names = { "x1", // x_rdata[0] "x2", // x_rdata[1] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +}; + +extern const std::array observable_names = { "y0", // y[0] }; @@ -29,31 +35,36 @@ std::array observable_scalings = { ObservableScaling::lin, // y[0] }; -std::array expression_names = { +extern const std::array expression_names = { }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { "p1", // p[0] "p2", // p[1] "p3", // p[2] "p4", // p[3] }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { }; -std::array state_ids = { +extern const std::array state_ids = { "x1", // x_rdata[0] "x2", // x_rdata[1] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +}; + +extern const std::array observable_ids = { "obs_x2", // y[0] }; -std::array expression_ids = { +extern const std::array expression_ids = { }; diff --git a/models/model_dirac_py/model_dirac_py.h b/models/model_dirac_py/model_dirac_py.h index 1d4e41430d..4952a901d1 100644 --- a/models/model_dirac_py/model_dirac_py.h +++ b/models/model_dirac_py/model_dirac_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_dirac_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_dirac_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -411,114 +413,96 @@ class Model_model_dirac_py : public amici::Model_ODE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -544,7 +528,7 @@ class Model_model_dirac_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/models/model_events_py/CMakeLists.txt b/models/model_events_py/CMakeLists.txt index 5b4c57907c..2d628c888e 100644 --- a/models/model_events_py/CMakeLists.txt +++ b/models/model_events_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_events_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_events_py/model_events_py.cpp b/models/model_events_py/model_events_py.cpp index 2f5da7d8a7..89c13088b5 100644 --- a/models/model_events_py/model_events_py.cpp +++ b/models/model_events_py/model_events_py.cpp @@ -1,31 +1,38 @@ #include #include +#include namespace amici::model_model_events_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { "p1", // p[0] "p2", // p[1] "p3", // p[2] "p4", // p[3] }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { "k1", // k[0] "k2", // k[1] "k3", // k[2] "k4", // k[3] }; -std::array state_names = { +extern const std::array state_names = { "x1", // x_rdata[0] "x2", // x_rdata[1] "x3", // x_rdata[2] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +"x3", // x_solver[2] +}; + +extern const std::array observable_names = { "y1", // y[0] }; @@ -33,35 +40,41 @@ std::array observable_scalings = { ObservableScaling::lin, // y[0] }; -std::array expression_names = { +extern const std::array expression_names = { }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { "p1", // p[0] "p2", // p[1] "p3", // p[2] "p4", // p[3] }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { "k1", // k[0] "k2", // k[1] "k3", // k[2] "k4", // k[3] }; -std::array state_ids = { +extern const std::array state_ids = { "x1", // x_rdata[0] "x2", // x_rdata[1] "x3", // x_rdata[2] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +"x3", // x_solver[2] +}; + +extern const std::array observable_ids = { "y1", // y[0] }; -std::array expression_ids = { +extern const std::array expression_ids = { }; diff --git a/models/model_events_py/model_events_py.h b/models/model_events_py/model_events_py.h index 5c2d058a6a..ffa1da8fc7 100644 --- a/models/model_events_py/model_events_py.h +++ b/models/model_events_py/model_events_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_events_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_events_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -446,114 +448,96 @@ class Model_model_events_py : public amici::Model_ODE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -579,7 +563,7 @@ class Model_model_events_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/models/model_jakstat_adjoint_py/CMakeLists.txt b/models/model_jakstat_adjoint_py/CMakeLists.txt index d3a16024cb..ba0095a279 100644 --- a/models/model_jakstat_adjoint_py/CMakeLists.txt +++ b/models/model_jakstat_adjoint_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_jakstat_adjoint_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.cpp b/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.cpp index 85d326e72d..0409a90c61 100644 --- a/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.cpp +++ b/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.cpp @@ -1,11 +1,12 @@ #include #include +#include namespace amici::model_model_jakstat_adjoint_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { "p1", // p[0] "p2", // p[1] "p3", // p[2] @@ -25,12 +26,12 @@ std::array free_parameter_names = { "sigma_pEpoR", // p[16] }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { "Omega_cyt", // k[0] "Omega_nuc", // k[1] }; -std::array state_names = { +extern const std::array state_names = { "STAT", // x_rdata[0] "pSTAT", // x_rdata[1] "pSTAT_pSTAT", // x_rdata[2] @@ -42,7 +43,19 @@ std::array state_names = { "nSTAT5", // x_rdata[8] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "STAT", // x_solver[0] +"pSTAT", // x_solver[1] +"pSTAT_pSTAT", // x_solver[2] +"npSTAT_npSTAT", // x_solver[3] +"nSTAT1", // x_solver[4] +"nSTAT2", // x_solver[5] +"nSTAT3", // x_solver[6] +"nSTAT4", // x_solver[7] +"nSTAT5", // x_solver[8] +}; + +extern const std::array observable_names = { "y0", // y[0] "y1", // y[1] "y2", // y[2] @@ -54,11 +67,11 @@ ObservableScaling::lin, // y[1] ObservableScaling::lin, // y[2] }; -std::array expression_names = { +extern const std::array expression_names = { "u", // w[0] }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { "p1", // p[0] "p2", // p[1] "p3", // p[2] @@ -78,12 +91,12 @@ std::array free_parameter_ids = { "sigma_pEpoR", // p[16] }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { "Omega_cyt", // k[0] "Omega_nuc", // k[1] }; -std::array state_ids = { +extern const std::array state_ids = { "STAT", // x_rdata[0] "pSTAT", // x_rdata[1] "pSTAT_pSTAT", // x_rdata[2] @@ -95,13 +108,25 @@ std::array state_ids = { "nSTAT5", // x_rdata[8] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "STAT", // x_solver[0] +"pSTAT", // x_solver[1] +"pSTAT_pSTAT", // x_solver[2] +"npSTAT_npSTAT", // x_solver[3] +"nSTAT1", // x_solver[4] +"nSTAT2", // x_solver[5] +"nSTAT3", // x_solver[6] +"nSTAT4", // x_solver[7] +"nSTAT5", // x_solver[8] +}; + +extern const std::array observable_ids = { "obs_pSTAT", // y[0] "obs_tSTAT", // y[1] "obs_spline", // y[2] }; -std::array expression_ids = { +extern const std::array expression_ids = { "u", // w[0] }; diff --git a/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.h b/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.h index 076cd143f0..5cc9be9063 100644 --- a/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.h +++ b/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_jakstat_adjoint_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_jakstat_adjoint_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -419,114 +421,96 @@ class Model_model_jakstat_adjoint_py : public amici::Model_ODE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -552,7 +536,7 @@ class Model_model_jakstat_adjoint_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/models/model_nested_events_py/CMakeLists.txt b/models/model_nested_events_py/CMakeLists.txt index faf49f9b21..f1edd47182 100644 --- a/models/model_nested_events_py/CMakeLists.txt +++ b/models/model_nested_events_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_nested_events_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_nested_events_py/model_nested_events_py.cpp b/models/model_nested_events_py/model_nested_events_py.cpp index 15df7aa91a..fbada254fb 100644 --- a/models/model_nested_events_py/model_nested_events_py.cpp +++ b/models/model_nested_events_py/model_nested_events_py.cpp @@ -1,11 +1,12 @@ #include #include +#include namespace amici::model_model_nested_events_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { "V_0", // p[0] "V_0_inject", // p[1] "t_0", // p[2] @@ -13,15 +14,19 @@ std::array free_parameter_names = { "delta_V", // p[4] }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { }; -std::array state_names = { +extern const std::array state_names = { "Virus", // x_rdata[0] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "Virus", // x_solver[0] +}; + +extern const std::array observable_names = { "y0", // y[0] }; @@ -29,11 +34,11 @@ std::array observable_scalings = { ObservableScaling::lin, // y[0] }; -std::array expression_names = { +extern const std::array expression_names = { }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { "V_0", // p[0] "V_0_inject", // p[1] "t_0", // p[2] @@ -41,19 +46,23 @@ std::array free_parameter_ids = { "delta_V", // p[4] }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { }; -std::array state_ids = { +extern const std::array state_ids = { "Virus", // x_rdata[0] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "Virus", // x_solver[0] +}; + +extern const std::array observable_ids = { "obs_Virus", // y[0] }; -std::array expression_ids = { +extern const std::array expression_ids = { }; diff --git a/models/model_nested_events_py/model_nested_events_py.h b/models/model_nested_events_py/model_nested_events_py.h index 18a8727846..ae97183ea4 100644 --- a/models/model_nested_events_py/model_nested_events_py.h +++ b/models/model_nested_events_py/model_nested_events_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_nested_events_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_nested_events_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -419,114 +421,96 @@ class Model_model_nested_events_py : public amici::Model_ODE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -552,7 +536,7 @@ class Model_model_nested_events_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/models/model_neuron_py/CMakeLists.txt b/models/model_neuron_py/CMakeLists.txt index 440bc4fdd4..5792978baa 100644 --- a/models/model_neuron_py/CMakeLists.txt +++ b/models/model_neuron_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_neuron_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_neuron_py/model_neuron_py.cpp b/models/model_neuron_py/model_neuron_py.cpp index c9ba737562..9afa8a4d5c 100644 --- a/models/model_neuron_py/model_neuron_py.cpp +++ b/models/model_neuron_py/model_neuron_py.cpp @@ -1,28 +1,34 @@ #include #include +#include namespace amici::model_model_neuron_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { "a", // p[0] "b", // p[1] "c", // p[2] "d", // p[3] }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { "v0", // k[0] "I0", // k[1] }; -std::array state_names = { +extern const std::array state_names = { "v", // x_rdata[0] "u", // x_rdata[1] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "v", // x_solver[0] +"u", // x_solver[1] +}; + +extern const std::array observable_names = { "v", // y[0] }; @@ -30,32 +36,37 @@ std::array observable_scalings = { ObservableScaling::lin, // y[0] }; -std::array expression_names = { +extern const std::array expression_names = { }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { "a", // p[0] "b", // p[1] "c", // p[2] "d", // p[3] }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { "v0", // k[0] "I0", // k[1] }; -std::array state_ids = { +extern const std::array state_ids = { "v", // x_rdata[0] "u", // x_rdata[1] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "v", // x_solver[0] +"u", // x_solver[1] +}; + +extern const std::array observable_ids = { "y1", // y[0] }; -std::array expression_ids = { +extern const std::array expression_ids = { }; diff --git a/models/model_neuron_py/model_neuron_py.h b/models/model_neuron_py/model_neuron_py.h index c56016dc5e..84c40c6758 100644 --- a/models/model_neuron_py/model_neuron_py.h +++ b/models/model_neuron_py/model_neuron_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_neuron_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_neuron_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -441,114 +443,96 @@ class Model_model_neuron_py : public amici::Model_ODE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -574,7 +558,7 @@ class Model_model_neuron_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/models/model_robertson_py/CMakeLists.txt b/models/model_robertson_py/CMakeLists.txt index 6442492172..e0b561a15b 100644 --- a/models/model_robertson_py/CMakeLists.txt +++ b/models/model_robertson_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_robertson_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_robertson_py/model_robertson_py.cpp b/models/model_robertson_py/model_robertson_py.cpp index fa7e441dfb..6f31088c96 100644 --- a/models/model_robertson_py/model_robertson_py.cpp +++ b/models/model_robertson_py/model_robertson_py.cpp @@ -1,27 +1,34 @@ #include #include +#include namespace amici::model_model_robertson_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { "p1", // p[0] "p2", // p[1] "p3", // p[2] }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { "k1", // k[0] }; -std::array state_names = { +extern const std::array state_names = { "x1", // x_rdata[0] "x2", // x_rdata[1] "x3", // x_rdata[2] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +"x3", // x_solver[2] +}; + +extern const std::array observable_names = { "y0", // y[0] "y1", // y[1] "y2", // y[2] @@ -33,33 +40,39 @@ ObservableScaling::lin, // y[1] ObservableScaling::lin, // y[2] }; -std::array expression_names = { +extern const std::array expression_names = { }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { "p1", // p[0] "p2", // p[1] "p3", // p[2] }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { "k1", // k[0] }; -std::array state_ids = { +extern const std::array state_ids = { "x1", // x_rdata[0] "x2", // x_rdata[1] "x3", // x_rdata[2] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +"x3", // x_solver[2] +}; + +extern const std::array observable_ids = { "obs_x1", // y[0] "obs_x2", // y[1] "obs_x3", // y[2] }; -std::array expression_ids = { +extern const std::array expression_ids = { }; diff --git a/models/model_robertson_py/model_robertson_py.h b/models/model_robertson_py/model_robertson_py.h index 84cbfa524b..aabaabf30f 100644 --- a/models/model_robertson_py/model_robertson_py.h +++ b/models/model_robertson_py/model_robertson_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_robertson_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_robertson_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -403,114 +405,96 @@ class Model_model_robertson_py : public amici::Model_DAE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -536,7 +520,7 @@ class Model_model_robertson_py : public amici::Model_DAE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/models/model_steadystate_py/CMakeLists.txt b/models/model_steadystate_py/CMakeLists.txt index 69cb4d4bf4..4d2a75c76d 100644 --- a/models/model_steadystate_py/CMakeLists.txt +++ b/models/model_steadystate_py/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.22) cmake_policy(VERSION 3.22...3.31) +# We aren't using C++20 modules, so disable scanning for them to avoid +# clang-scan-deps-notfound errors. +# See also https://discourse.cmake.org/t/cmake-3-28-cmake-cxx-compiler-clang-scan-deps-notfound-not-found/9244/3 +set(CMAKE_CXX_SCAN_FOR_MODULES OFF) + project(model_steadystate_py) message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/models/model_steadystate_py/model_steadystate_py.cpp b/models/model_steadystate_py/model_steadystate_py.cpp index 65de9fee33..51717fba30 100644 --- a/models/model_steadystate_py/model_steadystate_py.cpp +++ b/models/model_steadystate_py/model_steadystate_py.cpp @@ -1,11 +1,12 @@ #include #include +#include namespace amici::model_model_steadystate_py { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { "p1", // p[0] "p2", // p[1] "p3", // p[2] @@ -13,20 +14,26 @@ std::array free_parameter_names = { "p5", // p[4] }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { "k1", // k[0] "k2", // k[1] "k3", // k[2] "k4", // k[3] }; -std::array state_names = { +extern const std::array state_names = { "x1", // x_rdata[0] "x2", // x_rdata[1] "x3", // x_rdata[2] }; -std::array observable_names = { +extern const std::array state_names_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +"x3", // x_solver[2] +}; + +extern const std::array observable_names = { "y0", // y[0] "y1", // y[1] "y2", // y[2] @@ -38,11 +45,11 @@ ObservableScaling::lin, // y[1] ObservableScaling::lin, // y[2] }; -std::array expression_names = { +extern const std::array expression_names = { }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { "p1", // p[0] "p2", // p[1] "p3", // p[2] @@ -50,26 +57,32 @@ std::array free_parameter_ids = { "p5", // p[4] }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { "k1", // k[0] "k2", // k[1] "k3", // k[2] "k4", // k[3] }; -std::array state_ids = { +extern const std::array state_ids = { "x1", // x_rdata[0] "x2", // x_rdata[1] "x3", // x_rdata[2] }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + "x1", // x_solver[0] +"x2", // x_solver[1] +"x3", // x_solver[2] +}; + +extern const std::array observable_ids = { "obs_x1", // y[0] "obs_x2", // y[1] "obs_x3", // y[2] }; -std::array expression_ids = { +extern const std::array expression_ids = { }; diff --git a/models/model_steadystate_py/model_steadystate_py.h b/models/model_steadystate_py/model_steadystate_py.h index cbe88ddd70..1548d01f9f 100644 --- a/models/model_steadystate_py/model_steadystate_py.h +++ b/models/model_steadystate_py/model_steadystate_py.h @@ -14,17 +14,19 @@ class Solver; namespace model_model_steadystate_py { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; extern void Jy_model_steadystate_py(realtype *Jy, const int iy, const realtype *p, const realtype *k, const realtype *y, const realtype *sigmay, const realtype *my); @@ -403,114 +405,96 @@ class Model_model_steadystate_py : public amici::Model_ODE { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** @@ -536,7 +520,7 @@ class Model_model_steadystate_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string get_amici_commit() const override { - return "a8dfd6e0963f32c1ce4647a652e93a271b14a053"; + return "2b036e909775bc4645c617839fb23d3ed5f07421"; } bool has_quadratic_llh() const override { diff --git a/python/sdist/amici/_installation/swig.py b/python/sdist/amici/_installation/swig.py index 90fde75265..70bff6b7a6 100644 --- a/python/sdist/amici/_installation/swig.py +++ b/python/sdist/amici/_installation/swig.py @@ -54,6 +54,7 @@ class TypeHintFixer(ast.NodeTransformer): "std::allocator< amici::ParameterScaling > > const &": ast.Name( "ParameterScalingVector" ), + "std::span< std::string_view const >": ast.Name("Sequence[str]"), } def __init__(self): diff --git a/python/sdist/amici/exporters/sundials/de_export.py b/python/sdist/amici/exporters/sundials/de_export.py index c4a1e5807b..38042ae72d 100644 --- a/python/sdist/amici/exporters/sundials/de_export.py +++ b/python/sdist/amici/exporters/sundials/de_export.py @@ -1040,6 +1040,9 @@ def event_initializer_list() -> str: "STATE_NAMES_INITIALIZER_LIST": self._get_symbol_name_initializer_list( "x_rdata" ), + "STATE_NAMES_SOLVER_INITIALIZER_LIST": self._get_symbol_name_initializer_list( + "x_solver" + ), "FIXED_PARAMETER_NAMES_INITIALIZER_LIST": self._get_symbol_name_initializer_list( "k" ), @@ -1061,6 +1064,9 @@ def event_initializer_list() -> str: "STATE_IDS_INITIALIZER_LIST": self._get_symbol_id_initializer_list( "x_rdata" ), + "STATE_IDS_SOLVER_INITIALIZER_LIST": self._get_symbol_id_initializer_list( + "x_solver" + ), "FIXED_PARAMETER_IDS_INITIALIZER_LIST": self._get_symbol_id_initializer_list( "k" ), @@ -1198,9 +1204,19 @@ def _get_symbol_name_initializer_list(self, name: str) -> str: :return: Template initializer list of names """ + if name == "x_solver": + # The current x_solver symbols are different from the names we + # want here + names = [ + state.get_name() + for state in self.model.states() + if not state.has_conservation_law() + ] + else: + names = self.model.name(name) + return "\n".join( - f'"{symbol}", // {name}[{idx}]' - for idx, symbol in enumerate(self.model.name(name)) + f'"{symbol}", // {name}[{idx}]' for idx, symbol in enumerate(names) ) def _get_symbol_id_initializer_list(self, name: str) -> str: @@ -1214,9 +1230,20 @@ def _get_symbol_id_initializer_list(self, name: str) -> str: :return: Template initializer list of ids """ + if name == "x_solver": + # The current x_solver symbols are different from the ones we + # want here + syms = [ + state.get_sym() + for state in self.model.states() + if not state.has_conservation_law() + ] + else: + syms = self.model.sym(name) + return "\n".join( f'"{self._code_printer.doprint(symbol)}", // {name}[{idx}]' - for idx, symbol in enumerate(self.model.sym(name)) + for idx, symbol in enumerate(syms) ) def _write_c_make_file(self): diff --git a/python/sdist/amici/exporters/sundials/templates/model.template.cpp b/python/sdist/amici/exporters/sundials/templates/model.template.cpp index 5bee191c3d..3104ed1f03 100644 --- a/python/sdist/amici/exporters/sundials/templates/model.template.cpp +++ b/python/sdist/amici/exporters/sundials/templates/model.template.cpp @@ -1,23 +1,28 @@ #include #include +#include namespace amici::model_TPL_MODELNAME { // clang-format off -std::array free_parameter_names = { +extern const std::array free_parameter_names = { TPL_FREE_PARAMETER_NAMES_INITIALIZER_LIST }; -std::array fixed_parameter_names = { +extern const std::array fixed_parameter_names = { TPL_FIXED_PARAMETER_NAMES_INITIALIZER_LIST }; -std::array state_names = { +extern const std::array state_names = { TPL_STATE_NAMES_INITIALIZER_LIST }; -std::array observable_names = { +extern const std::array state_names_solver = { + TPL_STATE_NAMES_SOLVER_INITIALIZER_LIST +}; + +extern const std::array observable_names = { TPL_OBSERVABLE_NAMES_INITIALIZER_LIST }; @@ -25,27 +30,31 @@ std::array observable_scalings = { TPL_OBSERVABLE_TRAFO_INITIALIZER_LIST }; -std::array expression_names = { +extern const std::array expression_names = { TPL_EXPRESSION_NAMES_INITIALIZER_LIST }; -std::array free_parameter_ids = { +extern const std::array free_parameter_ids = { TPL_FREE_PARAMETER_IDS_INITIALIZER_LIST }; -std::array fixed_parameter_ids = { +extern const std::array fixed_parameter_ids = { TPL_FIXED_PARAMETER_IDS_INITIALIZER_LIST }; -std::array state_ids = { +extern const std::array state_ids = { TPL_STATE_IDS_INITIALIZER_LIST }; -std::array observable_ids = { +extern const std::array state_ids_solver = { + TPL_STATE_IDS_SOLVER_INITIALIZER_LIST +}; + +extern const std::array observable_ids = { TPL_OBSERVABLE_IDS_INITIALIZER_LIST }; -std::array expression_ids = { +extern const std::array expression_ids = { TPL_EXPRESSION_IDS_INITIALIZER_LIST }; diff --git a/python/sdist/amici/exporters/sundials/templates/model_header.template.h b/python/sdist/amici/exporters/sundials/templates/model_header.template.h index e71b556f36..115bc878ea 100644 --- a/python/sdist/amici/exporters/sundials/templates/model_header.template.h +++ b/python/sdist/amici/exporters/sundials/templates/model_header.template.h @@ -14,17 +14,19 @@ class Solver; namespace model_TPL_MODELNAME { -extern std::array free_parameter_names; -extern std::array fixed_parameter_names; -extern std::array state_names; -extern std::array observable_names; +extern const std::array free_parameter_names; +extern const std::array fixed_parameter_names; +extern const std::array state_names; +extern const std::array state_names_solver; +extern const std::array observable_names; extern std::array observable_scalings; -extern std::array expression_names; -extern std::array free_parameter_ids; -extern std::array fixed_parameter_ids; -extern std::array state_ids; -extern std::array observable_ids; -extern std::array expression_ids; +extern const std::array expression_names; +extern const std::array free_parameter_ids; +extern const std::array fixed_parameter_ids; +extern const std::array state_ids; +extern const std::array state_ids_solver; +extern const std::array observable_ids; +extern const std::array expression_ids; extern std::array state_idxs_solver; TPL_JY_DEF @@ -291,114 +293,96 @@ class Model_TPL_MODELNAME : public amici::Model_TPL_MODEL_TYPE_UPPER { * @brief Get names of the free model parameters * @return the names */ - std::vector get_free_parameter_names() const override { - return std::vector(free_parameter_names.begin(), - free_parameter_names.end()); + std::span get_free_parameter_names() const override { + return free_parameter_names; } /** * @brief Get names of the model states * @return the names */ - std::vector get_state_names() const override { - return std::vector(state_names.begin(), state_names.end()); + std::span get_state_names() const override { + return state_names; } /** * @brief Get names of the solver states * @return the names */ - std::vector get_state_names_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto const idx: state_idxs_solver) { - result.push_back(state_names[idx]); - } - return result; + std::span get_state_names_solver() const override { + return state_names_solver; } /** * @brief Get names of the fixed model parameters * @return the names */ - std::vector get_fixed_parameter_names() const override { - return std::vector(fixed_parameter_names.begin(), - fixed_parameter_names.end()); + std::span get_fixed_parameter_names() const override { + return fixed_parameter_names; } /** * @brief Get names of the observables * @return the names */ - std::vector get_observable_names() const override { - return std::vector(observable_names.begin(), - observable_names.end()); + std::span get_observable_names() const override { + return observable_names; } /** * @brief Get names of model expressions * @return Expression names */ - std::vector get_expression_names() const override { - return std::vector(expression_names.begin(), - expression_names.end()); + std::span get_expression_names() const override { + return expression_names; } /** * @brief Get ids of the free model parameters * @return the ids */ - std::vector get_free_parameter_ids() const override { - return std::vector(free_parameter_ids.begin(), - free_parameter_ids.end()); + std::span get_free_parameter_ids() const override { + return free_parameter_ids; } /** * @brief Get ids of the model states * @return the ids */ - std::vector get_state_ids() const override { - return std::vector(state_ids.begin(), state_ids.end()); + std::span get_state_ids() const override { + return state_ids; } /** * @brief Get ids of the solver states * @return the ids */ - std::vector get_state_ids_solver() const override { - std::vector result; - result.reserve(state_idxs_solver.size()); - for(auto idx: state_idxs_solver) { - result.push_back(state_ids[idx]); - } - return result; + std::span get_state_ids_solver() const override { + return state_ids_solver; } /** * @brief Get ids of the fixed model parameters * @return the ids */ - std::vector get_fixed_parameter_ids() const override { - return std::vector(fixed_parameter_ids.begin(), - fixed_parameter_ids.end()); + std::span get_fixed_parameter_ids() const override { + return fixed_parameter_ids; } /** * @brief Get ids of the observables * @return the ids */ - std::vector get_observable_ids() const override { - return std::vector(observable_ids.begin(), - observable_ids.end()); + std::span get_observable_ids() const override { + return observable_ids; } /** * @brief Get IDs of model expressions * @return Expression IDs */ - std::vector get_expression_ids() const override { - return std::vector(expression_ids.begin(), - expression_ids.end()); + std::span get_expression_ids() const override { + return expression_ids; } /** diff --git a/python/sdist/amici/testing/models.py b/python/sdist/amici/testing/models.py index 6aca290947..adf48f2176 100644 --- a/python/sdist/amici/testing/models.py +++ b/python/sdist/amici/testing/models.py @@ -165,7 +165,7 @@ def import_model_calvetti(output_dir: Path = None) -> Model: "R2ss", "V3ss", "R3ss", - ) + ), model.get_fixed_parameter_ids() return model diff --git a/src/model.cpp b/src/model.cpp index bf56f966dc..375556fec8 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -86,7 +86,7 @@ static void set_nan_to_zero(std::vector& vec) { /** * @brief local helper function to get parameters - * @param ids vector of name/ids of (fixed)Parameters + * @param ids span of name/ids of (fixed)Parameters * @param values values of the (fixed)Parameters * @param id name/id to look for in the vector * @param variable_name string indicating what variable we are looking at @@ -94,8 +94,9 @@ static void set_nan_to_zero(std::vector& vec) { * @return value of the selected parameter */ static realtype get_value_by_id( - std::vector const& ids, std::vector const& values, - std::string const& id, char const* variable_name, char const* id_name + std::span const& ids, + std::vector const& values, std::string const& id, + char const* variable_name, char const* id_name ) { auto it = std::ranges::find(ids, id); if (it != ids.end()) @@ -108,7 +109,7 @@ static realtype get_value_by_id( /** * @brief local helper function to set parameters - * @param ids vector of names/ids of (fixed)Parameters + * @param ids span of names/ids of (fixed)Parameters * @param values values of the (fixed)Parameters * @param value for the selected parameter * @param id name/id to look for in the vector @@ -116,7 +117,7 @@ static realtype get_value_by_id( * @param id_name string indicating whether name or id was specified */ static void set_value_by_id( - std::vector const& ids, std::vector& values, + std::span const& ids, std::vector& values, realtype const value, std::string const& id, char const* variable_name, char const* id_name ) { @@ -131,7 +132,7 @@ static void set_value_by_id( /** * @brief local helper function to set parameters via regex - * @param ids vector of names/ids of (fixed)Parameters + * @param ids span of names/ids of (fixed)Parameters * @param values values of the (fixed)Parameters * @param value for the selected parameter * @param regex string according to which names/ids are to be matched @@ -141,15 +142,16 @@ static void set_value_by_id( */ static int set_value_by_id_regex( - std::vector const& ids, std::vector& values, + std::span const& ids, std::vector& values, realtype value, std::string const& regex, char const* variable_name, char const* id_name ) { try { std::regex pattern(regex); int n_found = 0; + std::match_results m; for (auto const& id : ids) { - if (std::regex_match(id, pattern)) { + if (std::regex_match(id.begin(), id.end(), m, pattern)) { values.at(&id - &ids[0]) = value; ++n_found; } @@ -769,65 +771,85 @@ bool Model::has_free_parameter_names() const { return np() == 0 || !get_free_parameter_names().empty(); } -std::vector Model::get_free_parameter_names() const { return {}; } +std::span Model::get_free_parameter_names() const { + return {}; +} bool Model::has_state_names() const { return nx_rdata == 0 || !get_state_names().empty(); } -std::vector Model::get_state_names() const { return {}; } +std::span Model::get_state_names() const { return {}; } -std::vector Model::get_state_names_solver() const { return {}; } +std::span Model::get_state_names_solver() const { + return {}; +} bool Model::has_fixed_parameter_names() const { return nk() == 0 || !get_fixed_parameter_names().empty(); } -std::vector Model::get_fixed_parameter_names() const { return {}; } +std::span Model::get_fixed_parameter_names() const { + return {}; +} bool Model::has_observable_names() const { return ny == 0 || !get_observable_names().empty(); } -std::vector Model::get_observable_names() const { return {}; } +std::span Model::get_observable_names() const { + return {}; +} bool Model::has_expression_names() const { return ny == 0 || !get_expression_names().empty(); } -std::vector Model::get_expression_names() const { return {}; } +std::span Model::get_expression_names() const { + return {}; +} bool Model::has_free_parameter_ids() const { return np() == 0 || !get_free_parameter_ids().empty(); } -std::vector Model::get_free_parameter_ids() const { return {}; } +std::span Model::get_free_parameter_ids() const { + return {}; +} bool Model::has_state_ids() const { return nx_rdata == 0 || !get_state_ids().empty(); } -std::vector Model::get_state_ids() const { return {}; } +std::span Model::get_state_ids() const { return {}; } -std::vector Model::get_state_ids_solver() const { return {}; } +std::span Model::get_state_ids_solver() const { + return {}; +} bool Model::has_fixed_parameter_ids() const { return nk() == 0 || !get_fixed_parameter_ids().empty(); } -std::vector Model::get_fixed_parameter_ids() const { return {}; } +std::span Model::get_fixed_parameter_ids() const { + return {}; +} bool Model::has_observable_ids() const { return ny == 0 || !get_observable_ids().empty(); } -std::vector Model::get_observable_ids() const { return {}; } +std::span Model::get_observable_ids() const { + return {}; +} bool Model::has_expression_ids() const { return ny == 0 || !get_expression_ids().empty(); } -std::vector Model::get_expression_ids() const { return {}; } +std::span Model::get_expression_ids() const { + return {}; +} bool Model::has_quadratic_llh() const { return true; } @@ -1700,28 +1722,30 @@ int Model::check_finite( case ModelQuantity::dydp: case ModelQuantity::dsigmaydp: if (has_observable_ids()) - row_id += " " + get_observable_ids()[row]; + row_id.append(" ").append(get_observable_ids()[row]); if (has_free_parameter_ids()) - col_id - += " " + get_free_parameter_ids()[plist(gsl::narrow(col))]; + col_id.append(" ").append( + get_free_parameter_ids()[plist(gsl::narrow(col))] + ); break; case ModelQuantity::dydx: if (has_observable_ids()) - row_id += " " + get_observable_ids()[row]; + row_id.append(" ").append(get_observable_ids()[row]); if (has_state_ids()) - col_id += " " + get_state_ids_solver()[col]; + col_id.append(" ").append(get_state_ids_solver()[col]); break; case ModelQuantity::deltasx: if (has_state_ids()) - row_id += " " + get_state_ids_solver()[row]; + row_id.append(" ").append(get_state_ids_solver()[row]); if (has_free_parameter_ids()) - col_id - += " " + get_free_parameter_ids()[plist(gsl::narrow(col))]; + col_id.append(" ").append( + get_free_parameter_ids()[plist(gsl::narrow(col))] + ); break; case ModelQuantity::dJydy: case ModelQuantity::dJydsigma: if (has_observable_ids()) - col_id += " " + get_observable_ids()[col]; + col_id.append(" ").append(get_observable_ids()[col]); break; case ModelQuantity::dJydx: case ModelQuantity::dJzdx: @@ -1729,7 +1753,7 @@ int Model::check_finite( case ModelQuantity::dzdx: case ModelQuantity::drzdx: if (has_state_ids()) - col_id += " " + get_state_ids_solver()[col]; + col_id.append(" ").append(get_state_ids_solver()[col]); break; case ModelQuantity::deltaqB: case ModelQuantity::sz: @@ -1737,14 +1761,15 @@ int Model::check_finite( case ModelQuantity::drzdp: case ModelQuantity::dsigmazdp: if (has_free_parameter_ids()) - col_id - += " " + get_free_parameter_ids()[plist(gsl::narrow(col))]; + col_id.append(" ").append( + get_free_parameter_ids()[plist(gsl::narrow(col))] + ); break; case ModelQuantity::dsigmaydy: if (has_observable_ids()) { auto obs_ids = get_observable_ids(); - row_id += " " + obs_ids[row]; - col_id += " " + obs_ids[col]; + row_id.append(" ").append(obs_ids[row]); + col_id.append(" ").append(obs_ids[col]); } break; default: @@ -1820,28 +1845,28 @@ int Model::check_finite( case ModelQuantity::JB: if (has_state_ids()) { auto state_ids = get_state_ids_solver(); - row_id += " " + state_ids[row]; - col_id += " " + state_ids[col]; + row_id.append(" ").append(state_ids[row]); + col_id.append(" ").append(state_ids[col]); } break; case ModelQuantity::dwdx: if (has_expression_ids()) - row_id += " " + get_expression_ids()[row]; + row_id.append(" ").append(get_expression_ids()[row]); if (has_state_ids()) - col_id += " " + get_state_ids_solver()[col]; + col_id.append(" ").append(get_state_ids_solver()[col]); break; case ModelQuantity::dwdw: if (has_expression_ids()) { auto expr_ids = get_expression_ids(); - row_id += " " + expr_ids[row]; - col_id += " " + expr_ids[col]; + row_id.append(" ").append(expr_ids[row]); + col_id.append(" ").append(expr_ids[col]); } break; case ModelQuantity::dwdp: if (has_expression_ids()) - row_id += " " + get_expression_ids()[row]; + row_id.append(" ").append(get_expression_ids()[row]); if (has_free_parameter_ids()) - col_id += " " + get_free_parameter_ids()[col]; + col_id.append(" ").append(get_free_parameter_ids()[col]); break; default: break; @@ -2142,9 +2167,10 @@ void Model::fsigmay(int const it, ExpData const* edata) { derived_state_.sigmay_.at(iytrue + iJ * nytrue) = 0; if (edata->is_set_measurement(it, iytrue)) { - std::string obs_id = has_observable_ids() - ? get_observable_ids().at(iytrue) - : std::to_string(iytrue); + std::string obs_id + = has_observable_ids() + ? std::string(get_observable_ids()[iytrue]) + : std::to_string(iytrue); std::stringstream ss; ss << "sigmay (" << obs_id << ", ExpData::id=" << edata->id << ", t=" << get_timepoint(it) << ")"; diff --git a/swig/amici.i b/swig/amici.i index cadd5efa44..0e36b51607 100644 --- a/swig/amici.i +++ b/swig/amici.i @@ -53,6 +53,32 @@ nonstandard type conversions. %typemap(doctype) size_t "int"; +// Typemap to support returning std::span +// as Python tuple +// Currently, the strings are copied; if performance becomes an issue, +// we can see if we can return views into existing memory. +// At least for the model entity IDs/names, there is no risk of dangling +// pointers as long as the shared object is not unloaded. +%include + +%typemap(out) std::span { + PyObject *tuple = PyTuple_New((Py_ssize_t)$1.size()); + if (!tuple) { + SWIG_exception_fail(SWIG_RuntimeError, "could not allocate tuple"); + } + for (size_t i = 0; i < $1.size(); ++i) { + const std::string_view &sv = $1.data()[i]; + PyObject *sobj = PyUnicode_DecodeUTF8(sv.data(), (Py_ssize_t)sv.size(), "strict"); + if (!sobj) { + Py_DECREF(tuple); + SWIG_exception_fail(SWIG_RuntimeError, "failed to decode string_view as UTF-8"); + } + PyTuple_SET_ITEM(tuple, (Py_ssize_t)i, sobj); // takes ownership of sobj + } + $result = tuple; +} + + %include %exception { try { diff --git a/tests/cpp/testfunctions.cpp b/tests/cpp/testfunctions.cpp index 86a41aedc5..f683f2b6a5 100644 --- a/tests/cpp/testfunctions.cpp +++ b/tests/cpp/testfunctions.cpp @@ -9,7 +9,10 @@ #include #include #include - +#include +#include +#include +#include #include "gtest/gtest.h" namespace amici { @@ -20,13 +23,30 @@ extern std::unique_ptr get_model(); } // namespace generic_model -std::vector getVariableNames(std::string const& name, int length) { - std::vector names; - names.reserve(length); - for (int i = 0; i < length; ++i) { - names.push_back(name + std::to_string(i)); +std::map> var_names { + {"p", {"p0", "p1", "p2", "p3", "p4"}}, + {"k", {"k0", "k1", "k2"}}, + {"x", {"x0", "x1", "x2", "x3", "x4", "x5"}}, + {"y", {"y0", "y1", "y2"}} +}; + +std::span getVariableNames(std::string const& name, int length) { + auto it = var_names.find(name); + if(it != var_names.end()) { + if((int)it->second.size() >= length) { + return std::span(it->second.data(), length); + } else { + // need to add more names to var_names above. + // this is a bit ugly, but we can't generate this dynamically, as + // we are only passing around references. + throw std::runtime_error( + "Variable names for " + name + " with length " + + std::to_string(length) + + " not available. Update tests/cpp/testfunctions.cpp:var_names." + ); + } } - return names; + throw std::runtime_error("Variable names for " + name + " with length " + std::to_string(length) + " not found."); } void simulateVerifyWrite(const std::string& path) diff --git a/tests/cpp/testfunctions.h b/tests/cpp/testfunctions.h index a1557a0877..83699a7433 100644 --- a/tests/cpp/testfunctions.h +++ b/tests/cpp/testfunctions.h @@ -6,8 +6,10 @@ #include +#include #include #include +#include namespace amici { @@ -27,7 +29,8 @@ class ExpData; * @param length number of variables * @return default names/ids */ -std::vector getVariableNames(std::string const& name, int length); +std::span +getVariableNames(std::string const& name, int length); /** * @brief The Model_Test class is a model-unspecific implementation @@ -147,35 +150,37 @@ class Model_Test : public Model { throw AmiException("not implemented"); } - std::vector get_free_parameter_names() const override { + std::span + get_free_parameter_names() const override { return getVariableNames("p", np()); } - std::vector get_state_names() const override { + std::span get_state_names() const override { return getVariableNames("x", nx_rdata); } - std::vector get_fixed_parameter_names() const override { + std::span + get_fixed_parameter_names() const override { return getVariableNames("k", nk()); } - std::vector get_observable_names() const override { + std::span get_observable_names() const override { return getVariableNames("y", ny); } - std::vector get_free_parameter_ids() const override { + std::span get_free_parameter_ids() const override { return getVariableNames("p", np()); } - std::vector get_state_ids() const override { + std::span get_state_ids() const override { return getVariableNames("x", nx_rdata); } - std::vector get_fixed_parameter_ids() const override { + std::span get_fixed_parameter_ids() const override { return getVariableNames("k", nk()); } - std::vector get_observable_ids() const override { + std::span get_observable_ids() const override { return getVariableNames("y", ny); } };