@@ -7,28 +7,25 @@ function DiffEqBase.DiscreteProblem(lrs::LatticeReactionSystem, u0_in, tspan,
7
7
error (" Currently lattice Jump simulations only supported when all spatial reactions are transport reactions." )
8
8
end
9
9
10
- # Converts potential symmaps to varmaps
11
- # Vertex and edge parameters may be given in a tuple, or in a common vector, making parameter case complicated.
10
+ # Converts potential symmaps to varmaps.
12
11
u0_in = symmap_to_varmap (lrs, u0_in)
13
- p_in = (p_in isa Tuple{<: Any , <: Any }) ?
14
- (symmap_to_varmap (lrs, p_in[1 ]), symmap_to_varmap (lrs, p_in[2 ])) :
15
- symmap_to_varmap (lrs, p_in)
12
+ p_in = symmap_to_varmap (lrs, p_in)
16
13
17
14
# Converts u0 and p to their internal forms.
15
+ # u0 is simply a vector with all the species' initial condition values across all vertices.
18
16
# u0 is [spec 1 at vert 1, spec 2 at vert 1, ..., spec 1 at vert 2, ...].
19
- u0 = lattice_process_u0 (u0_in, species (lrs), num_verts (lrs))
20
- # Both vert_ps and edge_ps becomes vectors of vectors. Each have 1 element for each parameter.
21
- # These elements are length 1 vectors (if the parameter is uniform),
22
- # or length num_verts/nE, with unique values for each vertex/edge (for vert_ps/edge_ps, respectively).
23
- vert_ps, edge_ps = lattice_process_p (p_in, vertex_parameters (lrs),
24
- edge_parameters (lrs), lrs)
25
-
26
- # Returns a DiscreteProblem.
27
- # Previously, a Tuple was used for (vert_ps, edge_ps), but this was converted to a Vector internally.
28
- return DiscreteProblem (u0, tspan, [vert_ps, edge_ps], args... ; kwargs... )
17
+ u0 = lattice_process_u0 (u0_in, species (lrs), lrs)
18
+ # vert_ps and `edge_ps` are vector maps, taking each parameter's Symbolics representation to its value(s).
19
+ # vert_ps values are vectors. Here, index (i) is a parameter's value in vertex i.
20
+ # edge_ps values are sparse matrices. Here, index (i,j) is a parameter's value in the edge from vertex i to vertex j.
21
+ # Uniform vertex/edge parameters store only a single value (a length 1 vector, or size 1x1 sparse matrix).
22
+ vert_ps, edge_ps = lattice_process_p (p_in, vertex_parameters (lrs), edge_parameters (lrs), lrs)
23
+
24
+ # Returns a DiscreteProblem (which basically just stores the processed input).
25
+ return DiscreteProblem (u0, tspan, [vert_ps; edge_ps], args... ; kwargs... )
29
26
end
30
27
31
- # Builds a spatial JumpProblem from a DiscreteProblem containg a Lattice Reaction System .
28
+ # Builds a spatial JumpProblem from a DiscreteProblem containing a `LatticeReactionSystem` .
32
29
function JumpProcesses. JumpProblem (lrs:: LatticeReactionSystem , dprob, aggregator, args... ; name = nameof (reactionsystem (lrs)),
33
30
combinatoric_ratelaws = get_combinatoric_ratelaws (reactionsystem (lrs)), kwargs... )
34
31
# Error checks.
@@ -37,50 +34,53 @@ function JumpProcesses.JumpProblem(lrs::LatticeReactionSystem, dprob, aggregator
37
34
end
38
35
39
36
# Computes hopping constants and mass action jumps (requires some internal juggling).
40
- # Currently, JumpProcesses requires uniform vertex parameters (hence `p=first.(dprob.p[1])`).
41
37
# Currently, the resulting JumpProblem does not depend on parameters (no way to incorporate these).
42
- # Hence the parameters of this one does nto actually matter. If at some point JumpProcess can
38
+ # Hence the parameters of this one does not actually matter. If at some point JumpProcess can
43
39
# handle parameters this can be updated and improved.
44
40
# The non-spatial DiscreteProblem have a u0 matrix with entries for all combinations of species and vertexes.
45
41
hopping_constants = make_hopping_constants (dprob, lrs)
46
42
sma_jumps = make_spatial_majumps (dprob, lrs)
47
43
non_spat_dprob = DiscreteProblem (reshape (dprob. u0, num_species (lrs), num_verts (lrs)), dprob. tspan, first .(dprob. p[1 ]))
48
44
45
+ # Creates and returns a spatial JumpProblem (masked lattices are not supported by these).
46
+ spatial_system = has_masked_lattice (lrs) ? get_lattice_graph (lrs) : lattice (lrs)
49
47
return JumpProblem (non_spat_dprob, aggregator, sma_jumps;
50
- hopping_constants, spatial_system = lattice (lrs) , name, kwargs... )
48
+ hopping_constants, spatial_system , name, kwargs... )
51
49
end
52
50
53
51
# Creates the hopping constants from a discrete problem and a lattice reaction system.
54
52
function make_hopping_constants (dprob:: DiscreteProblem , lrs:: LatticeReactionSystem )
55
53
# Creates the all_diff_rates vector, containing for each species, its transport rate across all edges.
56
54
# If transport rate is uniform for one species, the vector have a single element, else one for each edge.
57
- spatial_rates_dict = Dict (compute_all_transport_rates (dprob. p[ 1 ], dprob . p[ 2 ] , lrs))
55
+ spatial_rates_dict = Dict (compute_all_transport_rates (Dict ( dprob. p) , lrs))
58
56
all_diff_rates = [haskey (spatial_rates_dict, s) ? spatial_rates_dict[s] : [0.0 ]
59
57
for s in species (lrs)]
60
58
61
- # Creates the hopping constant Matrix. It contains one element for each combination of species and vertex.
62
- # Each element is a Vector, containing the outgoing hopping rates for that species, from that vertex, on that edge.
63
- hopping_constants = [Vector {Float64} (undef, length (lattice (lrs). fadjlist[j]))
64
- for i in 1 : (num_species (lrs)), j in 1 : (num_verts (lrs))]
65
-
66
- # For each edge, finds each position in `hopping_constants`.
67
- for (e_idx, e) in enumerate (edges (lattice (lrs)))
68
- dst_idx = findfirst (isequal (e. dst), lattice (lrs). fadjlist[e. src])
69
- # For each species, sets that hopping rate.
70
- for s_idx in 1 : (num_species (lrs))
71
- hopping_constants[s_idx, e. src][dst_idx] = get_component_value (all_diff_rates[s_idx], e_idx)
72
- end
59
+ # Creates an array (of the same size as the hopping constant array) containing all edges.
60
+ # First the array is a NxM matrix (number of species x number of vertices). Each element is a
61
+ # vector containing all edges leading out from that vertex (sorted by destination index).
62
+ edge_array = [Pair{Int64,Int64}[] for _1 in 1 : num_species (lrs), _2 in 1 : num_verts (lrs)]
63
+ for e in edge_iterator (lrs), s_idx in 1 : num_species (lrs)
64
+ push! (edge_array[s_idx, e[1 ]], e)
73
65
end
74
-
66
+ foreach (e_vec -> sort! (e_vec; by = e -> e[2 ]), edge_array)
67
+
68
+ # Creates the hopping constants array. It has the same shape as the edge array, but each
69
+ # element is that species transportation rate along that edge
70
+ hopping_constants = [
71
+ [Catalyst. get_edge_value (all_diff_rates[s_idx], e) for e in edge_array[s_idx, src_idx]]
72
+ for s_idx in 1 : num_species (lrs), src_idx in 1 : num_verts (lrs)
73
+ ]
75
74
return hopping_constants
76
75
end
77
76
78
77
# Creates a SpatialMassActionJump struct from a (spatial) DiscreteProblem and a LatticeReactionSystem.
79
78
# Could implementation a version which, if all reaction's rates are uniform, returns a MassActionJump.
80
- # Not sure if there is any form of performance improvement from that though. Possibly is not the case.
79
+ # Not sure if there is any form of performance improvement from that though. Likely not the case.
81
80
function make_spatial_majumps (dprob, lrs:: LatticeReactionSystem )
82
81
# Creates a vector, storing which reactions have spatial components.
83
- is_spatials = [Catalyst. has_spatial_vertex_component (rx. rate, lrs; vert_ps = dprob. p[1 ]) for rx in reactions (reactionsystem (lrs))]
82
+ is_spatials = [has_spatial_vertex_component (rx. rate, dprob. p)
83
+ for rx in reactions (reactionsystem (lrs))]
84
84
85
85
# Creates templates for the rates (uniform and spatial) and the stoichiometries.
86
86
# We cannot fetch reactant_stoich and net_stoich from a (non-spatial) MassActionJump.
@@ -91,10 +91,10 @@ function make_spatial_majumps(dprob, lrs::LatticeReactionSystem)
91
91
net_stoich = Vector {Vector{Pair{Int64, Int64}}} (undef, length (reactions (reactionsystem (lrs))))
92
92
93
93
# Loops through reactions with non-spatial rates, computes their rates and stoichiometries.
94
- cur_rx = 1 ;
94
+ cur_rx = 1
95
95
for (is_spat, rx) in zip (is_spatials, reactions (reactionsystem (lrs)))
96
96
is_spat && continue
97
- u_rates[cur_rx] = compute_vertex_value (rx. rate, lrs; vert_ps = dprob. p[ 1 ] )[1 ]
97
+ u_rates[cur_rx] = compute_vertex_value (rx. rate, lrs; ps = dprob. p)[1 ]
98
98
substoich_map = Pair .(rx. substrates, rx. substoich)
99
99
reactant_stoich[cur_rx] = int_map (substoich_map, reactionsystem (lrs))
100
100
net_stoich[cur_rx] = int_map (rx. netstoich, reactionsystem (lrs))
@@ -103,8 +103,7 @@ function make_spatial_majumps(dprob, lrs::LatticeReactionSystem)
103
103
# Loops through reactions with spatial rates, computes their rates and stoichiometries.
104
104
for (is_spat, rx) in zip (is_spatials, reactions (reactionsystem (lrs)))
105
105
is_spat || continue
106
- s_rates[cur_rx - length (u_rates), :] = compute_vertex_value (rx. rate, lrs;
107
- vert_ps = dprob. p[1 ])
106
+ s_rates[cur_rx - length (u_rates), :] .= compute_vertex_value (rx. rate, lrs; ps = dprob. p)
108
107
substoich_map = Pair .(rx. substrates, rx. substoich)
109
108
reactant_stoich[cur_rx] = int_map (substoich_map, reactionsystem (lrs))
110
109
net_stoich[cur_rx] = int_map (rx. netstoich, reactionsystem (lrs))
@@ -114,7 +113,7 @@ function make_spatial_majumps(dprob, lrs::LatticeReactionSystem)
114
113
isempty (u_rates) && (u_rates = nothing )
115
114
(count (is_spatials) == 0 ) && (s_rates = nothing )
116
115
117
- return SpatialMassActionJump (u_rates, s_rates, reactant_stoich, net_stoich)
116
+ return SpatialMassActionJump (u_rates, s_rates, reactant_stoich, net_stoich, nothing )
118
117
end
119
118
120
119
# ## Extra ###
0 commit comments