@@ -282,14 +282,15 @@ function __mtk_to_si(
282
282
end
283
283
# -----------------------------------------------------------------------------
284
284
"""
285
- function assess_local_identifiability(ode ::ModelingToolkit.System; measured_quantities=ModelingToolkit.Equation[], funcs_to_check=Array{}[], prob_threshold::Float64=0.99, type=:SE, loglevel=Logging.Info)
285
+ function assess_local_identifiability(sys ::ModelingToolkit.System; measured_quantities=ModelingToolkit.Equation[], funcs_to_check=Array{}[], prob_threshold::Float64=0.99, type=:SE, loglevel=Logging.Info)
286
286
287
287
Input:
288
- - `ode` - the System object from ModelingToolkit
288
+ - `ode` - the System object from ModelingToolkit (could represent an ODE or a discrete-time dynamical system)
289
289
- `measured_quantities` - the measurable outputs of the model
290
290
- `funcs_to_check` - functions of parameters for which to check identifiability
291
+ - `known_ic` - functions of states (e.g., some of the states) for which initial conditions are assumed to be known (and generic)
291
292
- `prob_threshold` - probability of correctness
292
- - `type` - identifiability type (`:SE` for single-experiment, `:ME` for multi-experiment)
293
+ - `type` - identifiability type (`:SE` for single-experiment, `:ME` for multi-experiment). `:ME` not implemented for discrete-time systems
293
294
- `loglevel` - the minimal level of log messages to display (`Logging.Info` by default)
294
295
295
296
Output:
@@ -299,34 +300,50 @@ Output:
299
300
The function determines local identifiability of parameters in `funcs_to_check` or all possible parameters if `funcs_to_check` is empty
300
301
301
302
The result is correct with probability at least `prob_threshold`.
302
-
303
- `type` can be either `:SE` (single-experiment identifiability) or `:ME` (multi-experiment identifiability).
304
- The return value is a tuple consisting of the array of bools and the number of experiments to be performed.
305
303
"""
306
304
function StructuralIdentifiability. assess_local_identifiability (
307
- ode :: ModelingToolkit.System ;
305
+ sys :: ModelingToolkit.System ;
308
306
measured_quantities = ModelingToolkit. Equation[],
309
307
funcs_to_check = Array{}[],
308
+ known_ic = [],
310
309
prob_threshold:: Float64 = 0.99 ,
311
310
type = :SE ,
312
311
loglevel = Logging. Info,
313
312
)
314
313
restart_logging (loglevel = loglevel)
315
314
with_logger (_si_logger[]) do
316
- return _assess_local_identifiability (
317
- ode,
318
- measured_quantities = measured_quantities,
319
- funcs_to_check = funcs_to_check,
320
- prob_threshold = prob_threshold,
321
- type = type,
322
- )
315
+ if any (ModelingToolkit. hasshift, equations (sys))
316
+ if type == :ME
317
+ throw (
318
+ " Only single-experiment identifiability is implemented in the discrete-time case" ,
319
+ )
320
+ else
321
+ return _assess_local_identifiability_dds (
322
+ sys,
323
+ measured_quantities = measured_quantities,
324
+ funcs_to_check = funcs_to_check,
325
+ known_ic = known_ic,
326
+ prob_threshold = prob_threshold,
327
+ )
328
+ end
329
+ else
330
+ return _assess_local_identifiability_ode (
331
+ sys,
332
+ measured_quantities = measured_quantities,
333
+ funcs_to_check = funcs_to_check,
334
+ known_ic = known_ic,
335
+ prob_threshold = prob_threshold,
336
+ type = type,
337
+ )
338
+ end
323
339
end
324
340
end
325
341
326
- @timeit _to function _assess_local_identifiability (
342
+ @timeit _to function _assess_local_identifiability_ode (
327
343
ode:: ModelingToolkit.System ;
328
344
measured_quantities = Array{ModelingToolkit. Equation}[],
329
345
funcs_to_check = Array{}[],
346
+ known_ic = [],
330
347
prob_threshold:: Float64 = 0.99 ,
331
348
type = :SE ,
332
349
)
@@ -338,19 +355,39 @@ end
338
355
end
339
356
340
357
funcs_to_check_ = [eval_at_nemo (x, conversion) for x in funcs_to_check]
358
+ known_ic_ = [eval_at_nemo (each, conversion) for each in known_ic]
341
359
342
360
if isequal (type, :SE )
343
- result = StructuralIdentifiability. _assess_local_identifiability (
344
- ode,
345
- funcs_to_check = funcs_to_check_,
346
- prob_threshold = prob_threshold,
347
- type = type,
348
- )
361
+ if isempty (known_ic)
362
+ result = StructuralIdentifiability. _assess_local_identifiability (
363
+ ode,
364
+ funcs_to_check = funcs_to_check_,
365
+ prob_threshold = prob_threshold,
366
+ type = type,
367
+ )
368
+ else
369
+ result = StructuralIdentifiability. _assess_local_identifiability_kic (
370
+ ode,
371
+ funcs_to_check = funcs_to_check_,
372
+ prob_threshold = prob_threshold,
373
+ known_ic = known_ic_,
374
+ )
375
+ end
349
376
nemo2mtk = Dict (funcs_to_check_ .=> funcs_to_check)
350
377
out_dict =
351
378
OrderedDict (nemo2mtk[param] => result[param] for param in funcs_to_check_)
379
+ if length (known_ic) > 0
380
+ @warn " Since known initial conditions were provided, identifiability of states (e.g., `x(t)`) is at t = 0 only !"
381
+ t = SymbolicUtils. Sym {Real} (:t )
382
+ out_dict = OrderedDict (substitute (k, Dict (t => 0 )) => v for (k, v) in out_dict)
383
+ end
352
384
return out_dict
353
385
elseif isequal (type, :ME )
386
+ if ! isempty (known_ic)
387
+ throw (
388
+ " Known initail conditions are not well-defined in the multi-experimental regime" ,
389
+ )
390
+ end
354
391
result, bd = StructuralIdentifiability. _assess_local_identifiability (
355
392
ode,
356
393
funcs_to_check = funcs_to_check_,
447
484
448
485
# ------------------------------------------------------------------------------
449
486
450
- """
451
- function assess_local_identifiability(
452
- dds::ModelingToolkit.System;
453
- measured_quantities=Array{ModelingToolkit.Equation}[],
454
- funcs_to_check=Array{}[],
455
- known_ic=Array{}[],
456
- prob_threshold::Float64=0.99)
457
-
458
- Input:
459
- - `dds` - the System object from ModelingToolkit
460
- - `measured_quantities` - the measurable outputs of the model
461
- - `funcs_to_check` - functions of parameters for which to check identifiability (all parameters and states if not specified)
462
- - `known_ic` - functions (of states and parameter) whose initial conditions are assumed to be known
463
- - `prob_threshold` - probability of correctness
464
-
465
- Output:
466
- - the result is an (ordered) dictionary from each function to to boolean;
467
-
468
- The result is correct with probability at least `prob_threshold`.
469
- """
470
- function StructuralIdentifiability. assess_local_identifiability (
471
- dds:: ModelingToolkit.System ;
472
- measured_quantities = Array{ModelingToolkit. Equation}[],
473
- funcs_to_check = Array{}[],
474
- known_ic = Array{}[],
475
- prob_threshold:: Float64 = 0.99 ,
476
- loglevel = Logging. Info,
477
- )
478
- restart_logging (loglevel = loglevel)
479
- with_logger (_si_logger[]) do
480
- return _assess_local_identifiability (
481
- dds,
482
- measured_quantities = measured_quantities,
483
- funcs_to_check = funcs_to_check,
484
- known_ic = known_ic,
485
- prob_threshold = prob_threshold,
486
- )
487
- end
488
- end
489
-
490
- function _assess_local_identifiability (
487
+ function _assess_local_identifiability_dds (
491
488
dds:: ModelingToolkit.System ;
492
489
measured_quantities = Array{ModelingToolkit. Equation}[],
493
490
funcs_to_check = Array{}[],
0 commit comments