-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGibsonBruck.m
253 lines (204 loc) · 6.39 KB
/
GibsonBruck.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
% Here is the implementation of Gibson-Bruck algorithm.
%
% I based my implementation upon the implementation of the Gillespie algorithm of Tomas Vejchodsky
% see: www.math.cas.cz/vejchod/gillespiessa.html
%
% Some of my own comments are in French, post back for eventual explanations.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [A,t,prop] = GibsonBruck(knu,c,p,A0,tfin)
%
% Next Reaction Method Stochastic Simulation Algorithm for a system of q
% chemical reactions
% implémenté selon le modèle gillespiessa
% Nchs ... number of chemical species
% q ... number of chemical reactions
%
% i-th reaction with the rate constant knu(i), i=1,2,...,q:
% c(1,i) A(1) + c(2,i) A(2) + ... + c(Nchs,i) A(Nchs)
% --->
% p(1,i) A(1) + p(2,i) A(2) + ... + p(Nchs,i) A(Nchs)
%
% INPUT:
% knu ... 1-by-q row vector; rate constants of the chemical reactions;
% knu = k/nu^(order-1), where nu=volume and order=order of the chemical reaction
% c ... Nchs-by-q; c(j,i) = coeficient at the j-th chemical species at the reactant side of the i-th reaction
% p ... Nchs-by-q; p(j,i) = coeficient at the j-th chemical species at the product side of the i-th reaction
% A0 ... Nchs-by-1 column vector;
% A0(j) = number of molecules of j-th chemical species at the initial time t=0
% tfin ... final time; if the simulation raches tfin it stops
%
% OUTPUT:
% A ... Nchs-by-N; A(j,m) = number of j-molecules in time interval [t(m), t(m+1)]
% A(:,1) == A0(:);
% t ... 1-by-N;
% prop (ajouté par moi) propensity pour chaque état
% NRM SSA
% =============
% cf feuille "Algorithme de Gillespie appliqué au modéle de LV stochastique"
% Initial checks
if (size(A0,2) > 1)
error('The initial numbers of molecules A0 must form a COLUMN vector');
end
Nchs = size(A0,1);
if (size(knu,1) > 1)
error('The rate constants knu must form a ROW vector');
end
q = size(knu,2);
if (size(c) ~= [Nchs,q])
error('The reactant coeficients must be Nchs-by-q but Nchs=%d, q=%d and size(c)=(%d,%d)', Nchs,q,size(c,1),size(c,2));
end
if (size(p) ~= [Nchs,q])
error('The product coeficients must be Nchs-by-q but Nchs=%d, q=%d and size(p)=(%d,%d)', Nchs,q,size(p,1),size(p,2));
end
% assume maximum of Nalloc steps of the algorithm
% allocate memory for Nalloc steps
Nalloc = 10000;
A = zeros(Nchs,Nalloc);
t = zeros(1,Nalloc);
prop = zeros(q,Nalloc);% chaque ligne correpond à une réaction, on y écrit les propensions associées
tau = zeros(q,Nalloc); % putative times (un par réaction)
% queue: vecteur avec q lignes (# reactions chimiques) et 2 colonnes
% (indice de la réaction et moment de la réaction)
queue = zeros(q,2);
% set the initial values
m = 1;
A(:,1) = A0;
t(1) = 0;
% propension (# reactions)
alpha = zeros(1,q);
% vecteur aléatoire uniforme (# reactions)
r = rand(1,q);
%pause
while t(m) <= tfin
if m > 1
%x=x
% espèces touchées par la réaction x
esp_x = find( (c(:,x)>0)|(p(:,x)>0) );%
% quelles sont les reactions où ces espèces apparaissent
react_x = find(sum(c(esp_x,:)>0,1)>0);%
%alpha = zeros(1,q);
% propensions actualisées (propension qui chg => dépend de x)
for i = react_x % react touchées
%i = i
alpha(i) = knu(i);%
for j=1:Nchs % go thru all chemical species
%j=j%
for s=1:c(j,i) % ... alphai=knu*A*(A-1)*(A-2)*...*(A-c(j,i)+1)
alpha(i) = alpha(i) * (A(j,m)-s+1);%
end % for s
end % for j
prop(i,m) = alpha(i);%
%pause
end % for i
% % affichage
% m = m
% propen = alpha
% queue = queue
% temps = t(1:m)
%
% pause
react_x = react_x(logical(react_x ~=x));%
% temps de réactions actualisés
for i = react_x % react touchées
%i = i
%alpha_old_ = alpha_old(i)
%alpha_ = alpha(i)
%tau_i = tau(i)
%t_m = t(m-1)
queue(i,2) = alpha_old(i)/alpha(i)*(queue(i,2)-t(m)) + t(m);%
%pause
end % for i
% temps de réactions pour x
rr = rand(1);
queue(x,2) = -log(rr)/alpha(x) + t(m);%
% sauvegarde propension
alpha_old = alpha;
% % affichage
% m=m
% propen = alpha
% queue = queue
% temps = t(1:m)
%
% pause
else % tp t=1, tirer au hasard pour toutes les propensions
% propensions, tirées de gillespiessa
alpha = zeros(1,q);
for i=1:q % go thru all reactions and compute the propensity function alpha(i)
alpha(i) = knu(i);
for j=1:Nchs % go thru all chemical species
for s=1:c(j,i) % ... alphai=knu*A*(A-1)*(A-2)*...*(A-c(j,i)+1)
alpha(i) = alpha(i) * (A(j,m)-s+1);
end % for s
end % for j
prop(i,m) = alpha(i);
end % for i
% sauvegarde propension
alpha_old = alpha;
% temps de réactions
tau(:,m) = -(log(r)./alpha)';%
% queue
queue = [(1:q)',tau(:,m)];%
% % affichage
% m = m
% r = r
% alpha = alpha
% tau_1 = tau(:,1)
% queue = queue
% temps = t(1:m)
% pause
end
% prochain état
queue_triee = sortrows(queue,2);%
x = queue_triee(1,1);% % l'indice de la reaction qui a lieu est celui pr
% lequel le temps de séjour est minimal
A(:,m+1) = A(:,m) - c(:,x) + p(:,x);%
t(m+1) = queue_triee(1,2);
prop(:,m+1) = prop(:,m);%
% if mod(m+1,1000)==0
% mm = m+1
% tautau = tau(x)
% tt = t(m+1)
% AA = A(:,m+1)
% pause
% end
% % affichage
% m=m
% queue_triee = queue_triee
% A_m = A(:,m)
% A_mp1 = A(:,m+1)
% t_m = t(m)
% t_mp1 = t(m+1)
% prop_m = prop(:,m)
% prop_mp1 = prop(:,m+1)
% temps = t(1:(m+1))
% pause
% incrément
m = m + 1;%
% memory management
if (m >= Nalloc)
%fprintf('Doubling memory for data. (Reallocation.) t(%d)=%f', m, t(m));
%tic
Aaux = zeros(Nchs,2*Nalloc);
taux = zeros(1,2*Nalloc);
Aaux(:,1:Nalloc) = A;
taux(1:Nalloc) = t;
A = Aaux;
t = taux;
clear Aaux taux;
Nalloc = 2*Nalloc;
%fprintf(' done. [%fsec]\n', toc);
end
end
% cutting the zeros at the end of arrays
A = A(:,1:m);
t = t(1:m);
prop = prop(:,1:(m-1));
% postprocessing
if (t(m) > tfin)
t(m) = tfin;
end
for j=1:Nchs
if (A(j,m) < 0)
A(j,m) = 0;
end
end