Skip to content

Commit a1f916b

Browse files
committed
new inference of D and tests and History file
1 parent 895292c commit a1f916b

File tree

4 files changed

+208
-51
lines changed

4 files changed

+208
-51
lines changed

HISTORY.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@
77
(at the time the release is made). If you need a dependency version increased,
88
please open an issue and we can update it and make a new Catalyst release once
99
testing against the newer dependency version is complete.
10+
- New formula for inferring variables from equations (declared using the `@equations` options) in the DSL. The order of inference of species/variables/parameters is now:
11+
(1) Every symbol explicitly declared using `@species`, `@variables`, and `@parameters` are assigned to the correct category.
12+
(2) Every symbol used as a reaction reactant is inferred as a species.
13+
(3) Every symbol not declared in (1) or (2) that occurs in an expression provided after `@equations` is inferred as a variable.
14+
(4) Every symbol not declared in (1), (2), or (3) that occurs either as a reaction rate or stoichiometric coefficient is inferred to be a parameter.
15+
E.g. in
16+
```julia
17+
@reaction_network begin
18+
@equations V1 + S ~ V2^2
19+
(p + S + V1), S --> 0
20+
end
21+
```
22+
`S` is inferred as a species, `V1` and `V2` as variables, and `p` as a parameter. The previous special cases for the `@observables`, `@compounds`, and `@differentials` options still hold. Finally, the `@require_declaration` options (described in more detail below) can now be used to require everything to be explicitly declared.
23+
- New formula for determining whether the default differentials have been used within an `@equations` option. Right now, if any expression `D(...)` is encountered (where `...`) can be anything, this is inferred as usage of the default differential D. E.g. in the following equations `D` is inferred as a differential with respect to the default independent variable:
24+
```julia
25+
@reaction_network begin
26+
@equations D(V) + V ~ 1
27+
end
28+
@reaction_network begin
29+
@equations D(D(V)) ~ 1
30+
end
31+
```
32+
Please note that this cannot be used at the same time as `D` is used to represent a species, variable, or parameter.
1033
- Array symbolics support is more consistent with ModelingToolkit v9. Parameter
1134
arrays are no longer scalarized by Catalyst, while species and variables
1235
arrays still are (as in ModelingToolkit). As such, parameter arrays should now

src/reactionsystem.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,8 +524,6 @@ function make_ReactionSystem_internal(rxs_and_eqs::Vector, iv, us_in, ps_in;
524524
# Extracts any species, variables, and parameters that occur in (non-reaction) equations.
525525
# Creates the new reactions + equations vector, `fulleqs` (sorted reactions first, equations next).
526526
if !isempty(eqs)
527-
println(eqs)
528-
println(iv)
529527
osys = ODESystem(eqs, iv; name = gensym())
530528
fulleqs = CatalystEqType[rxs; equations(osys)]
531529
union!(us, unknowns(osys))

test/dsl/dsl_options.jl

Lines changed: 184 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,74 @@ let
424424
end
425425
end
426426

427+
# Tests that explicitly declaring a single symbol as several things does not work.
428+
# Several of these are broken, but note sure how to test broken-ness on `@test_throws false Exception @eval`.
429+
# Relevant issue: https://github.com/SciML/Catalyst.jl/issues/1173
430+
let
431+
# Species + parameter.
432+
@test_broken false #@test_throws Exception @eval @reaction_network begin
433+
#@species X(t)
434+
#@parameters X
435+
#end
436+
437+
# Species + variable.
438+
@test_broken false #@test_throws Exception @eval @reaction_network begin
439+
#@species X(t)
440+
#@variables X(t)
441+
#end
442+
443+
# Variable + parameter.
444+
@test_broken false #@test_throws Exception @eval @reaction_network begin
445+
#@variables X(t)
446+
#@parameters X
447+
#end
448+
449+
# Species + differential.
450+
@test_throws false Exception @eval @reaction_network begin
451+
@species X(t)
452+
@differentials X = Differential(t)
453+
end
454+
455+
# Parameter + differential.
456+
@test_throws false Exception @eval @reaction_network begin
457+
@parameters X
458+
@differentials X = Differential(t)
459+
end
460+
461+
# Variable + differential.
462+
@test_throws false Exception @eval @reaction_network begin
463+
@variables X(t)
464+
@differentials X = Differential(t)
465+
end
466+
467+
# Parameter + observable (species/variable + observable is OK, as this e.g. provide additional observables information).
468+
@test_broken false #@test_throws Exception @eval @reaction_network begin
469+
#@species Y(t)
470+
#@parameters X
471+
#@observables X ~ Y
472+
#end
473+
474+
# Species + compound.
475+
@test_broken false #@test_throws Exception @eval @reaction_network begin
476+
#@species X(t) O(t)
477+
#@compounds begin X(t) ~ 2O end
478+
#end
479+
480+
# Parameter + compound.
481+
@test_broken false #@test_throws Exception @eval @reaction_network begin
482+
#@species O(t)
483+
#@parameters X
484+
#@compounds begin X(t) ~ 2O end
485+
#end
486+
487+
# Variable + compound.
488+
@test_broken false #@test_throws Exception @eval @reaction_network begin
489+
#@species O(t)
490+
#@variables X(t)
491+
#@compounds begin X(t) ~ 2O end
492+
#end
493+
end
494+
427495
### Test Independent Variable Designations ###
428496

429497
# Test ivs in DSL.
@@ -450,6 +518,118 @@ let
450518
@test issetequal(Catalyst.get_sivs(rn), [x])
451519
end
452520

521+
### Test Symbolic Variable Inference ###
522+
523+
# Basic checks that that symbolic variables not explicitly declared are correctly inferred.
524+
let
525+
# Case 1 (a reaction only).
526+
rn1 = @reaction_network begin
527+
(p1/(S1+p2) + S2), S1 --> S2
528+
end
529+
@test issetequal(species(rn1), [rn1.S1, rn1.S2])
530+
@test issetequal(parameters(rn1), [rn1.p1, rn1.p2])
531+
532+
# Case 2 (reactions and equations).
533+
rn2 = @reaction_network begin
534+
@equations V1 + log(V2 + S1) ~ V2^2
535+
(p1/V1 + S1 + log(S2 + V2 + p2)), S1 --> S2
536+
end
537+
@test issetequal(species(rn2), [rn2.S1, rn2.S2])
538+
@test issetequal(nonspecies(rn2), [rn2.V1, rn2.V2])
539+
@test issetequal(parameters(rn2), [rn2.p1, rn2.p2])
540+
541+
# Case 3 (reaction and equations with a differential).
542+
rn3 = @reaction_network begin
543+
@equations begin
544+
D(V1) ~ S1 + V1
545+
V2 + S2 ~ V1^2 + V2^2
546+
end
547+
(p1/V1 + S1 + log(S2 + V2 + p2)), S1 --> S2
548+
end
549+
@test issetequal(species(rn3), [rn3.S1, rn3.S2])
550+
@test issetequal(nonspecies(rn3), [rn3.V1, rn3.V2])
551+
@test issetequal(parameters(rn3), [rn3.p1, rn3.p2])
552+
553+
# Case 4 (reactions and equations with a pre-declared parameter).
554+
rn4 = @reaction_network begin
555+
@parameters p1
556+
@equations V1 + sin(p1 + S1) ~ S2*V2
557+
(p1+p2+V1+V2+S1+S2), S1 --> S2
558+
end
559+
@test issetequal(species(rn4), [rn2.S1, rn2.S2])
560+
@test issetequal(nonspecies(rn4), [rn2.V1, rn2.V2])
561+
@test issetequal(parameters(rn4), [rn2.p1, rn2.p2])
562+
563+
# Case 5 (algebraic equation containing D, which is pre-declared as a species).
564+
rn5 = @reaction_network begin
565+
@species D(t)
566+
@equations D * (S1 + V1 + V2) ~ S2
567+
(p1 + p2*(D + V1 + V2 + S2 + S2)), S1 --> S2 + D
568+
end
569+
@test issetequal(species(rn5), [rn5.S1, rn5.S2, rn5.D])
570+
@test issetequal(nonspecies(rn5), [rn5.V1, rn5.V2])
571+
@test issetequal(parameters(rn5), [rn5.p1, rn5.p2])
572+
573+
# Case 6 (algebraic equation containing D, which is pre-declared as a parameter).
574+
rn6 = @reaction_network begin
575+
@parameters D
576+
@equations D * (S1 + V1 + V2) ~ S2
577+
(p1 + p2*(D + V1 + V2 + S2 + S2)), S1 --> S2
578+
end
579+
@test issetequal(species(rn6), [rn6.S1, rn6.S2])
580+
@test issetequal(nonspecies(rn6), [rn6.V1, rn6.V2])
581+
@test issetequal(parameters(rn6), [rn6.p1, rn6.p2, rn6.D])
582+
583+
# Case 7 (algebraic equation containing D, which is pre-declared as a variable).
584+
rn7 = @reaction_network begin
585+
@variables D(t)
586+
@equations D * (S1 + V1 + V2) ~ S2
587+
(p1 + p2*(D + V1 + V2 + S2 + S2)), S1 --> S2
588+
end
589+
@test issetequal(species(rn7), [rn7.S1, rn7.S2])
590+
@test issetequal(nonspecies(rn7), [rn7.V1, rn7.V2, rn7.D])
591+
@test issetequal(parameters(rn7), [rn7.p1, rn7.p2])
592+
593+
# Case 8 (reactions, equations, and a custom differential).
594+
rn8 = @reaction_network begin
595+
@differentials Δ = Differential(t)
596+
@equations Δ(V1) + Δ(V2) + log(V2 + S1) ~ S2
597+
(p1/V1 + S1 + log(S2 + V2 + p2)), S1 --> S2
598+
end
599+
@test issetequal(species(rn8), [rn8.S1, rn8.S2])
600+
@test issetequal(nonspecies(rn8), [rn8.V1, rn8.V2])
601+
@test issetequal(parameters(rn8), [rn8.p1, rn8.p2])
602+
end
603+
604+
# Checks that various cases where symbolic variables cannot (or shouldn't) be inferred generate errors.
605+
let
606+
# Species/variables/parameter named after default differential used as function call.
607+
# In the future, species/variables should be usable this way (designating a time delay).
608+
@test_throws Exception @eval @reaction_network begin
609+
@equations D(V) ~ 1 - V
610+
d, D --> 0
611+
end
612+
@test_throws Exception @eval @reaction_network begin
613+
@variables D(t)
614+
@equations D(V) ~ 1 - V
615+
d, X --> 0
616+
end
617+
@test_throws Exception @eval @reaction_network begin
618+
@parameters D
619+
@equations D(V) ~ 1 - V
620+
d, X --> 0
621+
end
622+
623+
# Symbol only occurring in events.
624+
@test_throws Exception @eval @reaction_network begin
625+
@discrete_event (X > 1.0) => [V => V/2]
626+
d, X --> 0
627+
end
628+
@test_throws Exception @eval @reaction_network begin
629+
@continuous_event [X > 1.0] => [V => V/2]
630+
d, X --> 0
631+
end
632+
end
453633

454634
### Observables ###
455635

@@ -790,7 +970,7 @@ end
790970
# Check that DAE is solved correctly.
791971
let
792972
rn = @reaction_network rn begin
793-
@parameters k
973+
@parameters k d
794974
@variables X(t) Y(t)
795975
@equations begin
796976
X + 5 ~ k*S
@@ -940,10 +1120,10 @@ let
9401120
@test 5*sol[:Y][end] sol[:S][end] + sol[:X][end]
9411121
end
9421122

943-
# Tests that the correct symbolic variables are infered as species, variables, and paraemters.
1123+
# Tests that the correct symbolic variables are inferred as species, variables, and parameters.
9441124
let
9451125
rn = @reaction_network begin
946-
@parameters p1 p2
1126+
@parameters p1 p2 k1 k2 k3 k4
9471127
@species X1(t) X2(t)
9481128
@variables W(t)
9491129
@equations begin
@@ -968,12 +1148,6 @@ let
9681148
@equations X = 1 - S
9691149
(p,d), 0 <--> S
9701150
end
971-
972-
# Equation with component undeclared elsewhere.
973-
@test_throws Exception @eval @reaction_network begin
974-
@equations X ~ p - S
975-
(P,D), 0 <--> S
976-
end
9771151
end
9781152

9791153
# test combinatoric_ratelaws DSL option
@@ -1082,7 +1256,7 @@ let
10821256
@test isequal(Catalyst.expand_registered_functions(equations(rn4)[1]), D(A) ~ v*(A^n))
10831257
end
10841258

1085-
### test that @no_infer properly throws errors when undeclared variables are written
1259+
### test that @no_infer properly throws errors when undeclared variables are written ###
10861260

10871261
import Catalyst: UndeclaredSymbolicError
10881262
let

test/reactionsystem_core/coupled_equation_crn_systems.jl

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -899,38 +899,6 @@ end
899899

900900
# Checks that various misformatted declarations yield errors.
901901
let
902-
# Symbol in equation not appearing elsewhere (1).
903-
@test_throws Exception @eval @reaction_network begin
904-
@equations D(V) ~ -X
905-
end
906-
907-
# Symbol in equation not appearing elsewhere (2).
908-
@test_throws Exception @eval @reaction_network begin
909-
@equations 1 + log(x) ~ 2X
910-
end
911-
912-
# Attempting to infer differential variable not isolated on lhs (1).
913-
@test_throws Exception @eval @reaction_network begin
914-
@equations D(V) + 1 ~ 0
915-
end
916-
917-
# Attempting to infer differential variable not isolated on lhs (2).
918-
@test_throws Exception @eval @reaction_network begin
919-
@equations -1.0 ~ D(V)
920-
end
921-
922-
# Attempting to infer differential operator not isolated on lhs (1).
923-
@test_throws Exception @eval @reaction_network begin
924-
@variables V(t)
925-
@equations D(V) + 1 ~ 0
926-
end
927-
928-
# Attempting to infer a variable when using a non-default differential.
929-
@test_throws Exception @eval @reaction_network begin
930-
@differentials Δ = Differential(t)
931-
@equations Δ(V) ~ -1,0
932-
end
933-
934902
# Attempting to create a new differential from an unknown iv.
935903
@test_throws Exception @eval @reaction_network begin
936904
@differentials D = Differential(τ)
@@ -944,14 +912,8 @@ let
944912

945913
# Several equations without `begin ... end` block.
946914
@test_throws Exception @eval @reaction_network begin
947-
@variables V(t)
948915
@equations D(V) + 1 ~ - 1.0
949-
end
950-
951-
# Undeclared differential.
952-
@test_throws Exception @eval @reaction_network begin
953-
@species V
954-
@equations Δ(V) ~ -1.0
916+
@equations D(W) + 1 ~ - 1.0
955917
end
956918

957919
# System using multiple ivs.

0 commit comments

Comments
 (0)