diff --git a/docs/src/identifiability/identifiability.md b/docs/src/identifiability/identifiability.md index 3aa66d8a9..cb172fd15 100644 --- a/docs/src/identifiability/identifiability.md +++ b/docs/src/identifiability/identifiability.md @@ -12,12 +12,6 @@ assess_identifiability assess_local_identifiability ``` -## Assessing Global Identifiability - -```@docs -assess_global_identifiability -``` - ## Finding Identifiable Functions ```@docs diff --git a/docs/src/tutorials/discrete_time.md b/docs/src/tutorials/discrete_time.md index 4c160a079..22485d502 100644 --- a/docs/src/tutorials/discrete_time.md +++ b/docs/src/tutorials/discrete_time.md @@ -71,6 +71,11 @@ assess_local_identifiability(sir; measured_quantities = [I], funcs_to_check = [ principle it may produce incorrect result but the probability of correctness of the returned result is guaranteed to be at least `p` (in fact, the employed bounds are quite conservative, so in practice incorrect result is almost never produced). +As other main functions in the package, `assess_local_identifiability` accepts an optional parameter `loglevel` (default: `Logging.Info`) +to adjust the verbosity of logging. + + + The implementation is based on a version of the observability rank criterion and will be described in a forthcoming paper. [^1]: > S. Nõmm, C. Moog, [*Identifiability of discrete-time nonlinear systems*](https://doi.org/10.1016/S1474-6670(17)31245-4), IFAC Proceedings Volumes, 2004. diff --git a/docs/src/tutorials/identifiability.md b/docs/src/tutorials/identifiability.md index 242b377c6..1beb767b4 100644 --- a/docs/src/tutorials/identifiability.md +++ b/docs/src/tutorials/identifiability.md @@ -62,9 +62,13 @@ Function `assess_local_identifiability` has several optional parameters - `p` (default $0.99$) is the probability of correctness. The algorithm can, in theory, produce wrong result, but the probability that it is correct is guaranteed to be at least `p`. However, the probability bounds we use are quite conservative, so the actual probability of correctness is likely to be much higher. - - `type` (default `:SE`). By default, the algorithm checks the standard single-experiment identifiability. If one sets `type = :ME`, then the algorithm + + - `type` (default `:SE`). By default, the algorithm checks the standard single-experiment identifiability. If one sets `type = :ME`, then the algorithm checks multi-experiment identifiability, that is, identifiability from several experiments with independent initial conditions (the algorithm from [^2] is used). + - `loglevel` (default `Logging.Info`). The minimal level of logging messages to be displayed. Available options: `Logging.Debug`, + `Logging.Info`, `Logging.Warn`, and `Logging.Error`. + Note that the scaling symmetry given above suggests that $b x_2(t)$ may in fact be identifiable. This can be checked using `funcs_to_check` parameter: ```@example local @@ -108,6 +112,9 @@ Similarly to `assess_local_identifiability`, this function has optional paramete Also, currently, the probability of correctness does not include the probability of correctness of the modular reconstruction for Groebner bases. This probability is ensured by an additional check modulo a large prime, and can be neglected for practical purposes. + - `loglevel` (default `Logging.Info`). The minimal level of logging messages to be displayed. Available options: `Logging.Debug`, + `Logging.Info`, `Logging.Warn`, and `Logging.Error`. + Using `funcs_to_check` parameter, one can further inverstigate the nature of the lack of identifiability in the model at hand. For example, for the Goodwin oscillator, we can check if `beta + delta` and `beta * delta` are identifiable: diff --git a/docs/src/tutorials/identifiable_functions.md b/docs/src/tutorials/identifiable_functions.md index d9f6ef8d2..c7e830dca 100644 --- a/docs/src/tutorials/identifiable_functions.md +++ b/docs/src/tutorials/identifiable_functions.md @@ -40,4 +40,7 @@ By default, `find_identifiable_functions` tries to simplify the output functions the degree of simplification. The default value is `:standard` but one could use `:strong` to try to simplify further (at the expense of heavier computation) or use `:weak` to simplify less (but compute faster). +As `assess_identifiability` and `assess_local_identifiability`, `find_identifiable_functions` accepts an optional parameter `loglevel` (default: `Logging.Info`) +to adjust the verbosity of logging. + [^1]: > Y. Lecourtier, F. Lamnabhi-Lagarrigue, and E. Walter, [*A method to prove that nonlinear models can be unidentifiable*](https://doi.org/10.1109/CDC.1987.272467), Proceedings of the 26th Conference on Decision and Control, December 1987, 2144-2145; diff --git a/src/StructuralIdentifiability.jl b/src/StructuralIdentifiability.jl index 382b4fbc9..227d12164 100644 --- a/src/StructuralIdentifiability.jl +++ b/src/StructuralIdentifiability.jl @@ -82,14 +82,15 @@ function __init__() end """ - assess_identifiability(ode; funcs_to_check = [], p=0.99) + assess_identifiability(ode; funcs_to_check = [], p=0.99, loglevel=Logging.Info) Input: - `ode` - the ODE model - `funcs_to_check` - list of functions to check identifiability for; if empty, all parameters and states are taken - `p` - probability of correctness. - +- `loglevel` - the minimal level of log messages to display (`Logging.Info` by default) + Assesses identifiability of a given ODE model. The result is guaranteed to be correct with the probability at least `p`. The function returns a dictionary from the functions to check to their identifiability properties @@ -166,13 +167,14 @@ function _assess_identifiability( end """ - assess_identifiability(ode::ModelingToolkit.ODESystem; measured_quantities=Array{ModelingToolkit.Equation}[], funcs_to_check=[], p = 0.99) + assess_identifiability(ode::ModelingToolkit.ODESystem; measured_quantities=Array{ModelingToolkit.Equation}[], funcs_to_check=[], p = 0.99, loglevel=Logging.Info) Input: - `ode` - the ModelingToolkit.ODESystem object that defines the model - `measured_quantities` - the output functions of the model - `funcs_to_check` - functions of parameters for which to check the identifiability - `p` - probability of correctness. +- `loglevel` - the minimal level of log messages to display (`Logging.Info` by default) Assesses identifiability (both local and global) of a given ODE model (parameters detected automatically). The result is guaranteed to be correct with the probability at least `p`. diff --git a/src/identifiable_functions.jl b/src/identifiable_functions.jl index 52a6782c7..18cde16c6 100644 --- a/src/identifiable_functions.jl +++ b/src/identifiable_functions.jl @@ -21,6 +21,7 @@ This functions takes the following optional arguments: - `p`: A float in the range from 0 to 1, the probability of correctness. Default is `0.99`. - `seed`: The rng seed. Default value is `42`. +- `loglevel` - the minimal level of log messages to display (`Logging.Info` by default) ## Example diff --git a/src/local_identifiability.jl b/src/local_identifiability.jl index 83a1396fc..df3ef4e04 100644 --- a/src/local_identifiability.jl +++ b/src/local_identifiability.jl @@ -143,7 +143,7 @@ end # ------------------------------------------------------------------------------ """ - function assess_local_identifiability(ode::ModelingToolkit.ODESystem; measured_quantities=Array{ModelingToolkit.Equation}[], funcs_to_check=Array{}[], p::Float64=0.99, type=:SE) + function assess_local_identifiability(ode::ModelingToolkit.ODESystem; measured_quantities=Array{ModelingToolkit.Equation}[], funcs_to_check=Array{}[], p::Float64=0.99, type=:SE, loglevel=Logging.Info) Input: - `ode` - the ODESystem object from ModelingToolkit @@ -151,6 +151,7 @@ Input: - `funcs_to_check` - functions of parameters for which to check identifiability - `p` - probability of correctness - `type` - identifiability type (`:SE` for single-experiment, `:ME` for multi-experiment) +- `loglevel` - the minimal level of log messages to display (`Logging.Info` by default) Output: - for `type=:SE`, the result is a dictionary from each parameter to boolean; @@ -239,7 +240,7 @@ end # ------------------------------------------------------------------------------ """ - assess_local_identifiability(ode::ODE{P}; funcs_to_check::Array{<: Any, 1}, p::Float64=0.99, type=:SE) where P <: MPolyElem{Nemo.fmpq} + assess_local_identifiability(ode::ODE{P}; funcs_to_check::Array{<: Any, 1}, p::Float64=0.99, type=:SE, loglevel=Logging.Info) where P <: MPolyElem{Nemo.fmpq} Checks the local identifiability/observability of the functions in `funcs_to_check`. The result is correct with probability at least `p`.