From 2afdf36d195c9e272bc454206ae9aa6251233c6c Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 3 Oct 2025 10:55:00 +0200 Subject: [PATCH] refactor: Use designated initializers for ModelDimensions Improves readability/maintainability. Also fixes the C++ standard for model building which was still lagging behind. --- include/amici/model_dimensions.h | 105 ++-------------- models/model_calvetti_py/CMakeLists.txt | 2 +- models/model_calvetti_py/model_calvetti_py.h | 66 +++++----- models/model_dirac_py/CMakeLists.txt | 2 +- models/model_dirac_py/model_dirac_py.h | 66 +++++----- models/model_events_py/CMakeLists.txt | 2 +- models/model_events_py/model_events_py.h | 66 +++++----- .../model_jakstat_adjoint_py/CMakeLists.txt | 2 +- .../model_jakstat_adjoint_py.h | 66 +++++----- models/model_nested_events_py/CMakeLists.txt | 2 +- .../model_nested_events_py.h | 66 +++++----- models/model_neuron_py/CMakeLists.txt | 2 +- models/model_neuron_py/model_neuron_py.h | 66 +++++----- models/model_robertson_py/CMakeLists.txt | 2 +- .../model_robertson_py/model_robertson_py.h | 66 +++++----- models/model_steadystate_py/CMakeLists.txt | 2 +- .../model_steadystate_py.h | 66 +++++----- src/CMakeLists.template.cmake | 2 +- src/model.cpp | 1 + src/model_header.template.h | 64 +++++----- src/rdata.cpp | 2 + tests/cpp/unittests/testExpData.cpp | 58 ++++----- tests/cpp/unittests/testMisc.cpp | 117 ++++++++--------- tests/cpp/unittests/testSerialization.cpp | 118 +++++++++--------- 24 files changed, 466 insertions(+), 545 deletions(-) diff --git a/include/amici/model_dimensions.h b/include/amici/model_dimensions.h index 0f883343fe..ac0c660a2a 100644 --- a/include/amici/model_dimensions.h +++ b/include/amici/model_dimensions.h @@ -12,94 +12,10 @@ namespace amici { * Holds number of state variables, observables, etc. */ struct ModelDimensions { - /** Default ctor */ - ModelDimensions() = default; - /** - * @brief Constructor with model dimensions - * @param nx_rdata Number of state variables - * @param nxtrue_rdata Number of state variables of the non-augmented model - * @param nx_solver Number of state variables with conservation laws applied - * @param nxtrue_solver Number of state variables of the non-augmented model - * with conservation laws applied - * @param nx_solver_reinit Number of state variables with conservation laws - * subject to reinitialization - * @param np Number of parameters - * @param nk Number of constants - * @param ny Number of observables - * @param nytrue Number of observables of the non-augmented model - * @param nz Number of event observables - * @param nztrue Number of event observables of the non-augmented model - * @param ne Number of events - * @param ne_solver Number of events that require root-finding - * @param nspl Number of splines - * @param nJ Number of objective functions - * @param nw Number of repeating elements - * @param ndwdx Number of nonzero elements in the `x` derivative of the - * repeating elements - * @param ndwdp Number of nonzero elements in the `p` derivative of the - * repeating elements - * @param ndwdw Number of nonzero elements in the `w` derivative of the - * repeating elements - * @param ndxdotdw Number of nonzero elements in the \f$ w\f$ derivative of - * \f$ xdot\f$ - * @param ndJydy Number of nonzero elements in the \f$ y\f$ derivative of - * \f$ dJy\f$ (shape `nytrue`) - * @param ndxrdatadxsolver Number of nonzero elements in the \f$ x\f$ - * derivative of \f$ x_rdata\f$ - * @param ndxrdatadtcl Number of nonzero elements in the \f$ tcl\f$ - * derivative of \f$ x_rdata\f$ - * @param ndtotal_cldx_rdata Number of nonzero elements in the - * \f$ x_rdata \f$ derivative of \f$ total_cl \f$ - * @param nnz Number of nonzero elements in Jacobian - * @param ubw Upper matrix bandwidth in the Jacobian - * @param lbw Lower matrix bandwidth in the Jacobian - * @param ndxdotdp_explicit Number of nonzero elements in `dxdotdp_explicit` - * @param ndxdotdx_explicit Number of nonzero elements in `dxdotdx_explicit` - * @param w_recursion_depth Recursion depth of fw + * @brief Validate dimensions. */ - ModelDimensions( - int const nx_rdata, int const nxtrue_rdata, int const nx_solver, - int const nxtrue_solver, int const nx_solver_reinit, int const np, - int const nk, int const ny, int const nytrue, int const nz, - int const nztrue, int const ne, int const ne_solver, int const nspl, - int const nJ, int const nw, int const ndwdx, int const ndwdp, - int const ndwdw, int const ndxdotdw, std::vector ndJydy, - int const ndxrdatadxsolver, int const ndxrdatadtcl, - int const ndtotal_cldx_rdata, int const nnz, int const ubw, - int const lbw, int ndxdotdp_explicit = 0, int ndxdotdx_explicit = 0, - int w_recursion_depth = 0 - ) - : nx_rdata(nx_rdata) - , nxtrue_rdata(nxtrue_rdata) - , nx_solver(nx_solver) - , nxtrue_solver(nxtrue_solver) - , nx_solver_reinit(nx_solver_reinit) - , np(np) - , nk(nk) - , ny(ny) - , nytrue(nytrue) - , nz(nz) - , nztrue(nztrue) - , ne(ne) - , ne_solver(ne_solver) - , nspl(nspl) - , nw(nw) - , ndwdx(ndwdx) - , ndwdp(ndwdp) - , ndwdw(ndwdw) - , ndxdotdw(ndxdotdw) - , ndJydy(std::move(ndJydy)) - , ndxrdatadxsolver(ndxrdatadxsolver) - , ndxrdatadtcl(ndxrdatadtcl) - , ndtotal_cldx_rdata(ndtotal_cldx_rdata) - , nnz(nnz) - , nJ(nJ) - , ubw(ubw) - , lbw(lbw) - , ndxdotdp_explicit(ndxdotdp_explicit) - , ndxdotdx_explicit(ndxdotdx_explicit) - , w_recursion_depth(w_recursion_depth) { + void validate() const { Expects(nxtrue_rdata >= 0); Expects(nxtrue_rdata <= nx_rdata); Expects(nxtrue_solver >= 0); @@ -139,23 +55,22 @@ struct ModelDimensions { Expects(ndxdotdx_explicit >= 0); Expects(w_recursion_depth >= 0); } - - /** Number of states */ + /** Number of state variables */ int nx_rdata{0}; - /** Number of states in the unaugmented system */ + /** Number of state variables in the unaugmented system */ int nxtrue_rdata{0}; - /** Number of states with conservation laws applied */ + /** Number of state variables with conservation laws applied */ int nx_solver{0}; /** - * Number of states in the unaugmented system with conservation laws - * applied + * Number of state variables in the unaugmented system with conservation + * laws applied */ int nxtrue_solver{0}; - /** Number of solver states subject to reinitialization */ + /** Number of solver state variables subject to reinitialization */ int nx_solver_reinit{0}; /** Number of parameters */ @@ -240,10 +155,10 @@ struct ModelDimensions { /** Lower bandwidth of the Jacobian */ int lbw{0}; - /** Number of nonzero elements in `dxdotdx_explicit` */ + /** Number of nonzero elements in `dxdotdp_explicit` */ int ndxdotdp_explicit = 0; - /** Number of nonzero elements in `dxdotdp_explicit` */ + /** Number of nonzero elements in `dxdotdx_explicit` */ int ndxdotdx_explicit = 0; /** Recursion depth of fw */ diff --git a/models/model_calvetti_py/CMakeLists.txt b/models/model_calvetti_py/CMakeLists.txt index d4e0a7b5ea..8044324d40 100644 --- a/models/model_calvetti_py/CMakeLists.txt +++ b/models/model_calvetti_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_calvetti_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/models/model_calvetti_py/model_calvetti_py.h b/models/model_calvetti_py/model_calvetti_py.h index 846a64e0f9..3b82bcb2aa 100644 --- a/models/model_calvetti_py/model_calvetti_py.h +++ b/models/model_calvetti_py/model_calvetti_py.h @@ -110,38 +110,38 @@ class Model_model_calvetti_py : public amici::Model_DAE { */ Model_model_calvetti_py() : amici::Model_DAE( - amici::ModelDimensions( - 6, // nx_rdata - 6, // nxtrue_rdata - 6, // nx_solver - 6, // nxtrue_solver - 0, // nx_solver_reinit - 0, // np - 6, // nk - 6, // ny - 6, // nytrue - 0, // nz - 0, // nztrue - 4, // nevent - 0, // nevent_solver - 0, // nspl - 1, // nobjective - 17, // nw - 15, // ndwdx - 0, // ndwdp - 16, // ndwdw - 7, // ndxdotdw - std::vector{1, 1, 1, 1, 1, 1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 6, // ubw - 6, // lbw - 0, // ndxdotdp_explicit - 5, // ndxdotdx_explicit - 2 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 6, + .nxtrue_rdata = 6, + .nx_solver = 6, + .nxtrue_solver = 6, + .nx_solver_reinit = 0, + .np = 0, + .nk = 6, + .ny = 6, + .nytrue = 6, + .nz = 0, + .nztrue = 0, + .ne = 4, + .ne_solver = 0, + .nspl = 0, + .nw = 17, + .ndwdx = 15, + .ndwdp = 0, + .ndwdw = 16, + .ndxdotdw = 7, + .ndJydy = std::vector{1, 1, 1, 1, 1, 1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 6, + .lbw = 6, + .ndxdotdp_explicit = 0, + .ndxdotdx_explicit = 5, + .w_recursion_depth = 2, + }, amici::SimulationParameters( std::vector{0.28999999999999998, 0.73999999999999999, 0.44, 0.080000000000000002, 0.27000000000000002, 0.17999999999999999}, // fixedParameters std::vector{} // dynamic parameters @@ -557,7 +557,7 @@ class Model_model_calvetti_py : public amici::Model_DAE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/models/model_dirac_py/CMakeLists.txt b/models/model_dirac_py/CMakeLists.txt index 98212ecd3a..c200d17d5b 100644 --- a/models/model_dirac_py/CMakeLists.txt +++ b/models/model_dirac_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_dirac_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/models/model_dirac_py/model_dirac_py.h b/models/model_dirac_py/model_dirac_py.h index 3858d2625d..9266df8536 100644 --- a/models/model_dirac_py/model_dirac_py.h +++ b/models/model_dirac_py/model_dirac_py.h @@ -110,38 +110,38 @@ class Model_model_dirac_py : public amici::Model_ODE { */ Model_model_dirac_py() : amici::Model_ODE( - amici::ModelDimensions( - 2, // nx_rdata - 2, // nxtrue_rdata - 2, // nx_solver - 2, // nxtrue_solver - 0, // nx_solver_reinit - 4, // np - 0, // nk - 1, // ny - 1, // nytrue - 0, // nz - 0, // nztrue - 1, // nevent - 0, // nevent_solver - 0, // nspl - 1, // nobjective - 1, // nw - 0, // ndwdx - 0, // ndwdp - 0, // ndwdw - 0, // ndxdotdw - std::vector{1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 2, // ubw - 2, // lbw - 3, // ndxdotdp_explicit - 3, // ndxdotdx_explicit - 0 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 2, + .nxtrue_rdata = 2, + .nx_solver = 2, + .nxtrue_solver = 2, + .nx_solver_reinit = 0, + .np = 4, + .nk = 0, + .ny = 1, + .nytrue = 1, + .nz = 0, + .nztrue = 0, + .ne = 1, + .ne_solver = 0, + .nspl = 0, + .nw = 1, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = std::vector{1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 2, + .lbw = 2, + .ndxdotdp_explicit = 3, + .ndxdotdx_explicit = 3, + .w_recursion_depth = 0, + }, amici::SimulationParameters( std::vector{}, // fixedParameters std::vector{1.0, 0.5, 2.0, 3.0} // dynamic parameters @@ -544,7 +544,7 @@ class Model_model_dirac_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/models/model_events_py/CMakeLists.txt b/models/model_events_py/CMakeLists.txt index 5f8dafbecd..ca942eecc5 100644 --- a/models/model_events_py/CMakeLists.txt +++ b/models/model_events_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_events_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/models/model_events_py/model_events_py.h b/models/model_events_py/model_events_py.h index fa7415dcc1..3745c15527 100644 --- a/models/model_events_py/model_events_py.h +++ b/models/model_events_py/model_events_py.h @@ -110,38 +110,38 @@ class Model_model_events_py : public amici::Model_ODE { */ Model_model_events_py() : amici::Model_ODE( - amici::ModelDimensions( - 3, // nx_rdata - 3, // nxtrue_rdata - 3, // nx_solver - 3, // nxtrue_solver - 0, // nx_solver_reinit - 4, // np - 4, // nk - 1, // ny - 1, // nytrue - 2, // nz - 2, // nztrue - 6, // nevent - 2, // nevent_solver - 0, // nspl - 1, // nobjective - 1, // nw - 0, // ndwdx - 0, // ndwdp - 0, // ndwdw - 0, // ndxdotdw - std::vector{1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 3, // ubw - 3, // lbw - 3, // ndxdotdp_explicit - 4, // ndxdotdx_explicit - 0 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 3, + .nxtrue_rdata = 3, + .nx_solver = 3, + .nxtrue_solver = 3, + .nx_solver_reinit = 0, + .np = 4, + .nk = 4, + .ny = 1, + .nytrue = 1, + .nz = 2, + .nztrue = 2, + .ne = 6, + .ne_solver = 2, + .nspl = 0, + .nw = 1, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = std::vector{1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 3, + .lbw = 3, + .ndxdotdp_explicit = 3, + .ndxdotdx_explicit = 4, + .w_recursion_depth = 0, + }, amici::SimulationParameters( std::vector{4.0, 8.0, 10.0, 4.0}, // fixedParameters std::vector{0.5, 2.0, 0.5, 0.5} // dynamic parameters @@ -579,7 +579,7 @@ class Model_model_events_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/models/model_jakstat_adjoint_py/CMakeLists.txt b/models/model_jakstat_adjoint_py/CMakeLists.txt index f5403df754..1a55d59949 100644 --- a/models/model_jakstat_adjoint_py/CMakeLists.txt +++ b/models/model_jakstat_adjoint_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_jakstat_adjoint_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) 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 89bb876f9f..c6d692cbe6 100644 --- a/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.h +++ b/models/model_jakstat_adjoint_py/model_jakstat_adjoint_py.h @@ -110,38 +110,38 @@ class Model_model_jakstat_adjoint_py : public amici::Model_ODE { */ Model_model_jakstat_adjoint_py() : amici::Model_ODE( - amici::ModelDimensions( - 9, // nx_rdata - 9, // nxtrue_rdata - 9, // nx_solver - 9, // nxtrue_solver - 0, // nx_solver_reinit - 17, // np - 2, // nk - 3, // ny - 3, // nytrue - 0, // nz - 0, // nztrue - 0, // nevent - 0, // nevent_solver - 1, // nspl - 1, // nobjective - 2, // nw - 0, // ndwdx - 5, // ndwdp - 0, // ndwdw - 2, // ndxdotdw - std::vector{1, 1, 1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 9, // ubw - 9, // lbw - 13, // ndxdotdp_explicit - 18, // ndxdotdx_explicit - 0 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 9, + .nxtrue_rdata = 9, + .nx_solver = 9, + .nxtrue_solver = 9, + .nx_solver_reinit = 0, + .np = 17, + .nk = 2, + .ny = 3, + .nytrue = 3, + .nz = 0, + .nztrue = 0, + .ne = 0, + .ne_solver = 0, + .nspl = 1, + .nw = 2, + .ndwdx = 0, + .ndwdp = 5, + .ndwdw = 0, + .ndxdotdw = 2, + .ndJydy = std::vector{1, 1, 1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 9, + .lbw = 9, + .ndxdotdp_explicit = 13, + .ndxdotdx_explicit = 18, + .w_recursion_depth = 0, + }, amici::SimulationParameters( std::vector{1.3999999999999999, 0.45000000000000001}, // fixedParameters std::vector{3.9810717055349727, 1000.0, 0.11220184543019635, 0.98287887300003218, 1.0, 0.0015848931924611134, 0.54954087385762451, 0.84139514164519513, 0.38904514499428061, 9.9999999999999991e-6, 0.18197008586099833, 0.22908676527677729, 0.77624711662869172, 1.0641430182243161, 0.31622776601683794, 1.0, 0.31622776601683794} // dynamic parameters @@ -552,7 +552,7 @@ class Model_model_jakstat_adjoint_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/models/model_nested_events_py/CMakeLists.txt b/models/model_nested_events_py/CMakeLists.txt index 0c65a1a636..ef0443001c 100644 --- a/models/model_nested_events_py/CMakeLists.txt +++ b/models/model_nested_events_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_nested_events_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) 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 e56c7c6a92..b3d36776ad 100644 --- a/models/model_nested_events_py/model_nested_events_py.h +++ b/models/model_nested_events_py/model_nested_events_py.h @@ -110,38 +110,38 @@ class Model_model_nested_events_py : public amici::Model_ODE { */ Model_model_nested_events_py() : amici::Model_ODE( - amici::ModelDimensions( - 1, // nx_rdata - 1, // nxtrue_rdata - 1, // nx_solver - 1, // nxtrue_solver - 0, // nx_solver_reinit - 5, // np - 0, // nk - 1, // ny - 1, // nytrue - 0, // nz - 0, // nztrue - 3, // nevent - 2, // nevent_solver - 0, // nspl - 1, // nobjective - 1, // nw - 0, // ndwdx - 0, // ndwdp - 0, // ndwdw - 0, // ndxdotdw - std::vector{1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 1, // ubw - 1, // lbw - 2, // ndxdotdp_explicit - 1, // ndxdotdx_explicit - 0 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 1, + .nxtrue_rdata = 1, + .nx_solver = 1, + .nxtrue_solver = 1, + .nx_solver_reinit = 0, + .np = 5, + .nk = 0, + .ny = 1, + .nytrue = 1, + .nz = 0, + .nztrue = 0, + .ne = 3, + .ne_solver = 2, + .nspl = 0, + .nw = 1, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = std::vector{1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 1, + .lbw = 1, + .ndxdotdp_explicit = 2, + .ndxdotdx_explicit = 1, + .w_recursion_depth = 0, + }, amici::SimulationParameters( std::vector{}, // fixedParameters std::vector{0.10000000000000001, 1000.0, 2.0, 0.80000000000000004, 1.6000000000000001} // dynamic parameters @@ -552,7 +552,7 @@ class Model_model_nested_events_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/models/model_neuron_py/CMakeLists.txt b/models/model_neuron_py/CMakeLists.txt index fa74dafbb9..759fb9bf37 100644 --- a/models/model_neuron_py/CMakeLists.txt +++ b/models/model_neuron_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_neuron_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/models/model_neuron_py/model_neuron_py.h b/models/model_neuron_py/model_neuron_py.h index 26a35fcf97..74db013b12 100644 --- a/models/model_neuron_py/model_neuron_py.h +++ b/models/model_neuron_py/model_neuron_py.h @@ -110,38 +110,38 @@ class Model_model_neuron_py : public amici::Model_ODE { */ Model_model_neuron_py() : amici::Model_ODE( - amici::ModelDimensions( - 2, // nx_rdata - 2, // nxtrue_rdata - 2, // nx_solver - 2, // nxtrue_solver - 0, // nx_solver_reinit - 4, // np - 2, // nk - 1, // ny - 1, // nytrue - 1, // nz - 1, // nztrue - 1, // nevent - 1, // nevent_solver - 0, // nspl - 1, // nobjective - 1, // nw - 0, // ndwdx - 0, // ndwdp - 0, // ndwdw - 0, // ndxdotdw - std::vector{1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 2, // ubw - 2, // lbw - 2, // ndxdotdp_explicit - 4, // ndxdotdx_explicit - 0 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 2, + .nxtrue_rdata = 2, + .nx_solver = 2, + .nxtrue_solver = 2, + .nx_solver_reinit = 0, + .np = 4, + .nk = 2, + .ny = 1, + .nytrue = 1, + .nz = 1, + .nztrue = 1, + .ne = 1, + .ne_solver = 1, + .nspl = 0, + .nw = 1, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = std::vector{1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 2, + .lbw = 2, + .ndxdotdp_explicit = 2, + .ndxdotdx_explicit = 4, + .w_recursion_depth = 0, + }, amici::SimulationParameters( std::vector{-60.0, 10.0}, // fixedParameters std::vector{0.02, 0.29999999999999999, 65.0, 0.90000000000000002} // dynamic parameters @@ -574,7 +574,7 @@ class Model_model_neuron_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/models/model_robertson_py/CMakeLists.txt b/models/model_robertson_py/CMakeLists.txt index f1f97144c3..1f031f29dc 100644 --- a/models/model_robertson_py/CMakeLists.txt +++ b/models/model_robertson_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_robertson_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/models/model_robertson_py/model_robertson_py.h b/models/model_robertson_py/model_robertson_py.h index 6f24fe3ca3..e143342a66 100644 --- a/models/model_robertson_py/model_robertson_py.h +++ b/models/model_robertson_py/model_robertson_py.h @@ -110,38 +110,38 @@ class Model_model_robertson_py : public amici::Model_DAE { */ Model_model_robertson_py() : amici::Model_DAE( - amici::ModelDimensions( - 3, // nx_rdata - 3, // nxtrue_rdata - 3, // nx_solver - 3, // nxtrue_solver - 0, // nx_solver_reinit - 3, // np - 1, // nk - 3, // ny - 3, // nytrue - 0, // nz - 0, // nztrue - 0, // nevent - 0, // nevent_solver - 0, // nspl - 1, // nobjective - 1, // nw - 0, // ndwdx - 0, // ndwdp - 0, // ndwdw - 0, // ndxdotdw - std::vector{1, 1, 1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 3, // ubw - 3, // lbw - 5, // ndxdotdp_explicit - 9, // ndxdotdx_explicit - 0 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 3, + .nxtrue_rdata = 3, + .nx_solver = 3, + .nxtrue_solver = 3, + .nx_solver_reinit = 0, + .np = 3, + .nk = 1, + .ny = 3, + .nytrue = 3, + .nz = 0, + .nztrue = 0, + .ne = 0, + .ne_solver = 0, + .nspl = 0, + .nw = 1, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = std::vector{1, 1, 1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 3, + .lbw = 3, + .ndxdotdp_explicit = 5, + .ndxdotdx_explicit = 9, + .w_recursion_depth = 0, + }, amici::SimulationParameters( std::vector{0.90000000000000002}, // fixedParameters std::vector{0.040000000000000001, 10000.0, 30000000.0} // dynamic parameters @@ -536,7 +536,7 @@ class Model_model_robertson_py : public amici::Model_DAE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/models/model_steadystate_py/CMakeLists.txt b/models/model_steadystate_py/CMakeLists.txt index fbc93d9f04..327933bc76 100644 --- a/models/model_steadystate_py/CMakeLists.txt +++ b/models/model_steadystate_py/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(model_steadystate_py) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/models/model_steadystate_py/model_steadystate_py.h b/models/model_steadystate_py/model_steadystate_py.h index a67c200c1f..d7b25d8994 100644 --- a/models/model_steadystate_py/model_steadystate_py.h +++ b/models/model_steadystate_py/model_steadystate_py.h @@ -110,38 +110,38 @@ class Model_model_steadystate_py : public amici::Model_ODE { */ Model_model_steadystate_py() : amici::Model_ODE( - amici::ModelDimensions( - 3, // nx_rdata - 3, // nxtrue_rdata - 3, // nx_solver - 3, // nxtrue_solver - 0, // nx_solver_reinit - 5, // np - 4, // nk - 3, // ny - 3, // nytrue - 0, // nz - 0, // nztrue - 0, // nevent - 0, // nevent_solver - 0, // nspl - 1, // nobjective - 1, // nw - 0, // ndwdx - 0, // ndwdp - 0, // ndwdw - 0, // ndxdotdw - std::vector{1, 1, 1}, // ndjydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 3, // ubw - 3, // lbw - 11, // ndxdotdp_explicit - 9, // ndxdotdx_explicit - 0 // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = 3, + .nxtrue_rdata = 3, + .nx_solver = 3, + .nxtrue_solver = 3, + .nx_solver_reinit = 0, + .np = 5, + .nk = 4, + .ny = 3, + .nytrue = 3, + .nz = 0, + .nztrue = 0, + .ne = 0, + .ne_solver = 0, + .nspl = 0, + .nw = 1, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = std::vector{1, 1, 1}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 1, + .ubw = 3, + .lbw = 3, + .ndxdotdp_explicit = 11, + .ndxdotdx_explicit = 9, + .w_recursion_depth = 0, + }, amici::SimulationParameters( std::vector{0.10000000000000001, 0.40000000000000002, 0.69999999999999996, 1.0}, // fixedParameters std::vector{1.0, 0.5, 0.40000000000000002, 2.0, 0.10000000000000001} // dynamic parameters @@ -536,7 +536,7 @@ class Model_model_steadystate_py : public amici::Model_ODE { * @return AMICI git commit hash */ std::string getAmiciCommit() const override { - return "dcbbae0f8e9b52afd7ab8b4b7a046da36b907139"; + return "570c71d2a041ed15d548e826df3d97e05d124309"; } bool hasQuadraticLLH() const override { diff --git a/src/CMakeLists.template.cmake b/src/CMakeLists.template.cmake index 74942ebb7d..f01626c164 100644 --- a/src/CMakeLists.template.cmake +++ b/src/CMakeLists.template.cmake @@ -4,7 +4,7 @@ cmake_policy(VERSION 3.22...3.31) project(TPL_MODELNAME) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) diff --git a/src/model.cpp b/src/model.cpp index 671c8c2184..f154d82c60 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -187,6 +187,7 @@ Model::Model( , state_is_non_negative_(nx_solver, false) , simulation_parameters_(std::move(simulation_parameters)) , events_(std::move(events)) { + model_dimensions.validate(); Expects( model_dimensions.np == gsl::narrow(simulation_parameters_.parameters.size()) diff --git a/src/model_header.template.h b/src/model_header.template.h index 2cd1e1c67f..e1b7502181 100644 --- a/src/model_header.template.h +++ b/src/model_header.template.h @@ -110,38 +110,38 @@ class Model_TPL_MODELNAME : public amici::Model_TPL_MODEL_TYPE_UPPER { */ Model_TPL_MODELNAME() : amici::Model_TPL_MODEL_TYPE_UPPER( - amici::ModelDimensions( - TPL_NX_RDATA, // nx_rdata - TPL_NXTRUE_RDATA, // nxtrue_rdata - TPL_NX_SOLVER, // nx_solver - TPL_NXTRUE_SOLVER, // nxtrue_solver - TPL_NX_SOLVER_REINIT, // nx_solver_reinit - TPL_NP, // np - TPL_NK, // nk - TPL_NY, // ny - TPL_NYTRUE, // nytrue - TPL_NZ, // nz - TPL_NZTRUE, // nztrue - TPL_NEVENT, // nevent - TPL_NEVENT_SOLVER, // nevent_solver - TPL_NSPL, // nspl - TPL_NOBJECTIVE, // nobjective - TPL_NW, // nw - TPL_NDWDX, // ndwdx - TPL_NDWDP, // ndwdp - TPL_NDWDW, // ndwdw - TPL_NDXDOTDW, // ndxdotdw - TPL_NDJYDY, // ndjydy - TPL_NDXRDATADXSOLVER, // ndxrdatadxsolver - TPL_NDXRDATADTCL, // ndxrdatadtcl - TPL_NDTOTALCLDXRDATA, // ndtotal_cldx_rdata - 0, // nnz - TPL_UBW, // ubw - TPL_LBW, // lbw - TPL_NDXDOTDP_EXPLICIT, // ndxdotdp_explicit - TPL_NDXDOTDX_EXPLICIT, // ndxdotdx_explicit - TPL_W_RECURSION_DEPTH // w_recursion_depth - ), + amici::ModelDimensions{ + .nx_rdata = TPL_NX_RDATA, + .nxtrue_rdata = TPL_NXTRUE_RDATA, + .nx_solver = TPL_NX_SOLVER, + .nxtrue_solver = TPL_NXTRUE_SOLVER, + .nx_solver_reinit = TPL_NX_SOLVER_REINIT, + .np = TPL_NP, + .nk = TPL_NK, + .ny = TPL_NY, + .nytrue = TPL_NYTRUE, + .nz = TPL_NZ, + .nztrue = TPL_NZTRUE, + .ne = TPL_NEVENT, + .ne_solver = TPL_NEVENT_SOLVER, + .nspl = TPL_NSPL, + .nw = TPL_NW, + .ndwdx = TPL_NDWDX, + .ndwdp = TPL_NDWDP, + .ndwdw = TPL_NDWDW, + .ndxdotdw = TPL_NDXDOTDW, + .ndJydy = TPL_NDJYDY, + .ndxrdatadxsolver = TPL_NDXRDATADXSOLVER, + .ndxrdatadtcl = TPL_NDXRDATADTCL, + .ndtotal_cldx_rdata = TPL_NDTOTALCLDXRDATA, + .nnz = 0, + .nJ = TPL_NOBJECTIVE, + .ubw = TPL_UBW, + .lbw = TPL_LBW, + .ndxdotdp_explicit = TPL_NDXDOTDP_EXPLICIT, + .ndxdotdx_explicit = TPL_NDXDOTDX_EXPLICIT, + .w_recursion_depth = TPL_W_RECURSION_DEPTH, + }, amici::SimulationParameters( std::vector{TPL_FIXED_PARAMETERS}, // fixedParameters std::vector{TPL_PARAMETERS} // dynamic parameters diff --git a/src/rdata.cpp b/src/rdata.cpp index 3e09aede03..86718e7d93 100644 --- a/src/rdata.cpp +++ b/src/rdata.cpp @@ -51,6 +51,8 @@ ReturnData::ReturnData( , plist(plist_) , sigma_offset(sigma_offset_) , nroots_(ne) { + model_dimensions_.validate(); + switch (rdata_reporting) { case RDataReporting::full: initializeFullReporting(quadratic_llh_); diff --git a/tests/cpp/unittests/testExpData.cpp b/tests/cpp/unittests/testExpData.cpp index 721356cdba..373214c9c3 100644 --- a/tests/cpp/unittests/testExpData.cpp +++ b/tests/cpp/unittests/testExpData.cpp @@ -35,35 +35,35 @@ class ExpDataTest : public ::testing::Test { std::unique_ptr model = generic_model::getModel(); Model_Test testModel = Model_Test( - ModelDimensions( - nx, // nx_rdata - nx, // nxtrue_rdata - nx, // nx_solver - nx, // nxtrue_solver - 0, // nx_solver_reinit - 1, // np - 3, // nk - ny, // ny - ny, // nytrue - nz, // nz - nz, // nztrue - nmaxevent, // ne - 0, // ne_solver - 0, // nspl - 0, // nJ - 0, // nw - 0, // ndwdx - 0, // ndwdp - 0, // dwdw - 0, // ndxdotdw - {0, 0}, // ndJydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 0, // ubw - 0 // lbw - ), + ModelDimensions{ + .nx_rdata = nx, + .nxtrue_rdata = nx, + .nx_solver = nx, + .nxtrue_solver = nx, + .nx_solver_reinit = 0, + .np = 1, + .nk = 3, + .ny = ny, + .nytrue = ny, + .nz = nz, + .nztrue = nz, + .ne = nmaxevent, + .ne_solver = 0, + .nspl = 0, + .nw = 0, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = {0, 0}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 0, + .ubw = 0, + .lbw = 0 + }, SimulationParameters( std::vector(3, 0.0), std::vector(1, 0.0), std::vector(2, 1) diff --git a/tests/cpp/unittests/testMisc.cpp b/tests/cpp/unittests/testMisc.cpp index a6f18035a1..6d4e300a22 100644 --- a/tests/cpp/unittests/testMisc.cpp +++ b/tests/cpp/unittests/testMisc.cpp @@ -42,35 +42,35 @@ class ModelTest : public ::testing::Test { std::vector idlist{0}; std::vector z2event{0, 0, 0}; Model_Test model = Model_Test( - ModelDimensions( - nx, // nx_rdata - nx, // nxtrue_rdata - nx, // nx_solver - nx, // nxtrue_solver - 0, // nx_solver_reinit - static_cast(p.size()), // np - static_cast(k.size()), // nk - ny, // ny - ny, // nytrue - nz, // nz - nz, // nztrue - nmaxevent, // ne - 0, // ne_solver - 0, // nspl - 0, // nJ - 0, // nw - 0, // ndwdx - 0, // ndwdp - 0, // dwdw - 0, // ndxdotdw - {0, 0}, // ndJydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 0, // nnz - 0, // ubw - 0 // lbw - ), + ModelDimensions{ + .nx_rdata = nx, + .nxtrue_rdata = nx, + .nx_solver = nx, + .nxtrue_solver = nx, + .nx_solver_reinit = 0, + .np = static_cast(p.size()), + .nk = static_cast(k.size()), + .ny = ny, + .nytrue = ny, + .nz = nz, + .nztrue = nz, + .ne = nmaxevent, + .ne_solver = 0, + .nspl = 0, + .nw = 0, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = {0, 0}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 0, + .nJ = 0, + .ubw = 0, + .lbw = 0 + }, SimulationParameters(k, p, plist), SecondOrderMode::none, idlist, z2event, {} ); @@ -269,35 +269,36 @@ class SolverTest : public ::testing::Test { InterpolationType interp; Model_Test testModel = Model_Test( - ModelDimensions( - nx, // nx_rdata - nx, // nxtrue_rdata - nx, // nx_solver - nx, // nxtrue_solver - 0, // nx_solver_reinit - 1, // np - 3, // nk - ny, // ny - ny, // nytrue - nz, // nz - nz, // nztrue - ne, // ne - 0, // ne_solver - 0, // nspl - 0, // nJ - 0, // nw - 0, // ndwdx - 0, // ndwdp - 0, // dwdw - 0, // ndxdotdw - {0, 0}, // ndJydy - 0, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 1, // nnz - 0, // ubw - 0 // lbw - ), + ModelDimensions{ + .nx_rdata = nx, + .nxtrue_rdata = nx, + .nx_solver = nx, + .nxtrue_solver = nx, + .nx_solver_reinit = 0, + .np = 1, + .nk = 3, + .ny = ny, + .nytrue = ny, + .nz = nz, + .nztrue = nz, + .ne = ne, + .ne_solver = 0, + .nspl = 0, + .nw = 0, + .ndwdx = 0, + .ndwdp = 0, + .ndwdw = 0, + .ndxdotdw = 0, + .ndJydy = {0, 0}, + .ndxrdatadxsolver = 0, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 1, + .nJ = 0, + .ubw = 0, + .lbw = 0 + }, + SimulationParameters( std::vector(3, 0.0), std::vector(1, 0.0), std::vector(2, 1) diff --git a/tests/cpp/unittests/testSerialization.cpp b/tests/cpp/unittests/testSerialization.cpp index 48e77cf625..d44e99611d 100644 --- a/tests/cpp/unittests/testSerialization.cpp +++ b/tests/cpp/unittests/testSerialization.cpp @@ -143,35 +143,36 @@ TEST(ModelSerializationTest, ToFile) { int ne = 6; amici::CVodeSolver solver; amici::Model_Test m = amici::Model_Test( - amici::ModelDimensions( - nx, // nx_rdata - nx, // nxtrue_rdata - nx, // nx_solver - nx, // nxtrue_solver - 0, // nx_solver_reinit - np, // np - nk, // nk - ny, // ny - ny, // nytrue - nz, // nz - nz, // nztrue - ne, // ne - 0, // ne_solver - 0, // nspl - 0, // nJ - 9, // nw - 2, // ndwdx - 2, // ndwdp - 2, // dwdw - 13, // ndxdotdw - {0, 0, 0, 0}, // ndJydy - 9, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 17, // nnz - 18, // ubw - 19 // lbw - ), + amici::ModelDimensions{ + .nx_rdata = nx, + .nxtrue_rdata = nx, + .nx_solver = nx, + .nxtrue_solver = nx, + .nx_solver_reinit = 0, + .np = np, + .nk = nk, + .ny = ny, + .nytrue = ny, + .nz = nz, + .nztrue = nz, + .ne = ne, + .ne_solver = 0, + .nspl = 0, + .nw = 9, + .ndwdx = 2, + .ndwdp = 2, + .ndwdw = 2, + .ndxdotdw = 13, + .ndJydy = {0, 0, 0, 0}, + .ndxrdatadxsolver = 9, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 17, + .nJ = 0, + .ubw = 18, + .lbw = 19 + }, + amici::SimulationParameters( std::vector(nk, 0.0), std::vector(np, 0.0), std::vector(np, 0) @@ -216,35 +217,36 @@ TEST(ReturnDataSerializationTest, ToString) { int ne = 6; amici::CVodeSolver solver; amici::Model_Test m = amici::Model_Test( - amici::ModelDimensions( - nx, // nx_rdata - nx, // nxtrue_rdata - nx, // nx_solver - nx, // nxtrue_solver - 0, // nx_solver_reinit - np, // np - nk, // nk - ny, // ny - ny, // nytrue - nz, // nz - nz, // nztrue - ne, // ne - 0, // ne_solver - 0, // nspl - 0, // nJ - 9, // nw - 10, // ndwdx - 2, // ndwdp - 12, // dwdw - 13, // ndxdotdw - {0, 0, 0, 0}, // ndJydy - 9, // ndxrdatadxsolver - 0, // ndxrdatadtcl - 0, // ndtotal_cldx_rdata - 17, // nnz - 18, // ubw - 19 // lbw - ), + amici::ModelDimensions{ + .nx_rdata = nx, + .nxtrue_rdata = nx, + .nx_solver = nx, + .nxtrue_solver = nx, + .nx_solver_reinit = 0, + .np = np, + .nk = nk, + .ny = ny, + .nytrue = ny, + .nz = nz, + .nztrue = nz, + .ne = ne, + .ne_solver = 0, + .nspl = 0, + .nw = 9, + .ndwdx = 10, + .ndwdp = 2, + .ndwdw = 12, + .ndxdotdw = 13, + .ndJydy = {0, 0, 0, 0}, + .ndxrdatadxsolver = 9, + .ndxrdatadtcl = 0, + .ndtotal_cldx_rdata = 0, + .nnz = 17, + .nJ = 0, + .ubw = 18, + .lbw = 19 + }, + amici::SimulationParameters( std::vector(nk, 0.0), std::vector(np, 0.0), std::vector(np, 0)