Lines 97-103
Link Here
|
97 |
} else currentStateLabelIter.next(); |
97 |
} else currentStateLabelIter.next(); |
98 |
} |
98 |
} |
99 |
} |
99 |
} |
100 |
|
100 |
|
101 |
if(jobs == null || jobs.length != num_threads) { |
101 |
if(jobs == null || jobs.length != num_threads) { |
102 |
// Initialize the jobs if not done yet or of the number of threads changes |
102 |
// Initialize the jobs if not done yet or of the number of threads changes |
103 |
jobs = new FdJob[num_threads]; |
103 |
jobs = new FdJob[num_threads]; |
Lines 107-126
Link Here
|
107 |
jobs[i] = new FdJob("Finite Difference Worker "+i, threadnum, this); |
107 |
jobs[i] = new FdJob("Finite Difference Worker "+i, threadnum, this); |
108 |
} // For each job |
108 |
} // For each job |
109 |
} // If not initialized |
109 |
} // If not initialized |
110 |
|
110 |
|
111 |
// Initialize |
111 |
recursiveStep(time, timeDelta, cycle, 1.0); |
|
|
112 |
|
113 |
return true; |
114 |
} |
112 |
|
115 |
|
|
|
116 |
protected void recursiveStep(STEMTime time, long timeDelta, int cycle, double scaling) { |
117 |
// Compute deltas |
113 |
for(FdJob j:jobs) { |
118 |
for(FdJob j:jobs) { |
114 |
j.cycle = cycle; |
119 |
j.cycle = cycle; |
115 |
j.time = time; |
120 |
j.time = time; |
116 |
j.timeDelta = timeDelta; |
121 |
j.timeDelta = timeDelta; |
|
|
122 |
j.step = FdJob.COMPUTE_DELTAS; |
123 |
j.schedule(); |
124 |
} |
125 |
|
126 |
for(FdJob j : jobs) { |
127 |
try { |
128 |
j.join(); |
129 |
} catch(InterruptedException ie) { |
130 |
Activator.logError(ie.getMessage(), ie); |
131 |
} |
117 |
} |
132 |
} |
118 |
|
133 |
|
119 |
// Schedule. Jobs can be rescheduled after finished |
134 |
// Scale deltas |
120 |
for(FdJob j:jobs) |
135 |
scaleAllDeltas(scaling); |
|
|
136 |
|
137 |
// Check deltas for adjustment |
138 |
for(FdJob j:jobs) { |
139 |
j.step = FdJob.CHECK_DELTAS; |
121 |
j.schedule(); |
140 |
j.schedule(); |
|
|
141 |
} |
122 |
|
142 |
|
123 |
// Wait until all jobs completed |
|
|
124 |
for(FdJob j : jobs) { |
143 |
for(FdJob j : jobs) { |
125 |
try { |
144 |
try { |
126 |
j.join(); |
145 |
j.join(); |
Lines 129-158
Link Here
|
129 |
} |
148 |
} |
130 |
} |
149 |
} |
131 |
|
150 |
|
132 |
// Set the common time and step size here and validate everything is right |
151 |
double factor = 1.0; |
133 |
//double minStep = Double.MAX_VALUE; |
|
|
134 |
//double currentT = jobs[0].t; |
135 |
//for(SimJob j : jobs) { |
136 |
// The jobs have calculated new step sizes after they finished. Pick the |
137 |
// smallest one for the next cycle |
138 |
// if(j.h < minStep) minStep = j.h; |
139 |
// if(j.t != currentT) Activator.logError("Error, one thread was in misstep with other threads, its time was "+j.t+" versus "+currentT, new Exception()); |
140 |
//} |
141 |
|
152 |
|
142 |
//this.setCurrentX(currentT); |
153 |
for (FdJob j : jobs) { |
143 |
//this.setStepSize(minStep); // smallest one from above. |
154 |
factor = Math.min(factor, Double.parseDouble(j.getResult().getMessage())); |
144 |
return true; |
155 |
} |
|
|
156 |
|
157 |
if (factor == 1.0) { |
158 |
// Apply deltas |
159 |
for(FdJob j:jobs) { |
160 |
j.step = FdJob.APPLY_DELTAS; |
161 |
j.schedule(); |
162 |
} |
163 |
|
164 |
for(FdJob j : jobs) { |
165 |
try { |
166 |
j.join(); |
167 |
} catch(InterruptedException ie) { |
168 |
Activator.logError(ie.getMessage(), ie); |
169 |
} |
170 |
} |
171 |
} else { |
172 |
// Scale to avoid going negative |
173 |
scaleAllDeltas(factor); |
174 |
|
175 |
// Apply deltas |
176 |
for(FdJob j:jobs) { |
177 |
j.step = FdJob.APPLY_DELTAS; |
178 |
j.schedule(); |
179 |
} |
180 |
|
181 |
for(FdJob j : jobs) { |
182 |
try { |
183 |
j.join(); |
184 |
} catch(InterruptedException ie) { |
185 |
Activator.logError(ie.getMessage(), ie); |
186 |
} |
187 |
} |
188 |
|
189 |
// Call this method again for the rest of the time step |
190 |
for(Decorator decorator:this.getDecorators()) { |
191 |
EList<DynamicLabel>allLabels = decorator.getLabelsToUpdate(); |
192 |
for (final Iterator<DynamicLabel> currentStateLabelIter = allLabels |
193 |
.iterator(); currentStateLabelIter.hasNext();) { |
194 |
if(decorator instanceof IntegrationDecorator) { |
195 |
// It's a standard disease model with a standard disease model label |
196 |
final IntegrationLabel iLabel = (IntegrationLabel) currentStateLabelIter.next(); |
197 |
((IntegrationLabelValue)iLabel.getProbeValue()).set((IntegrationLabelValue)iLabel.getNextValue()); |
198 |
((IntegrationLabelValue)iLabel.getTempValue()).set((IntegrationLabelValue)iLabel.getNextValue()); |
199 |
((IntegrationLabelValue)iLabel.getTempValue()).prepareCycle(); |
200 |
((IntegrationLabelValue)iLabel.getProbeValue()).prepareCycle(); |
201 |
} else currentStateLabelIter.next(); |
202 |
} |
203 |
} |
204 |
|
205 |
recursiveStep(time, timeDelta, cycle, (1-factor)*scaling); |
206 |
} |
145 |
} |
207 |
} |
146 |
|
208 |
|
147 |
/** |
209 |
protected void computeDeltasStep(STEMTime time, long timeDelta, short threadnum) { |
148 |
* _step Do the step for a single thread |
|
|
149 |
* |
150 |
* @param time |
151 |
* @param timeDelta |
152 |
* @param cycle |
153 |
* @param threadnum |
154 |
*/ |
155 |
protected void _step(STEMTime time, long timeDelta, int cycle, short threadnum) { |
156 |
// Now give each decorator a chance to update its dynamic |
210 |
// Now give each decorator a chance to update its dynamic |
157 |
// labels in the canonical graph, but only if it is enabled. A |
211 |
// labels in the canonical graph, but only if it is enabled. A |
158 |
// Decorator might not be enabled if it is the action of a Trigger |
212 |
// Decorator might not be enabled if it is the action of a Trigger |
Lines 169-182
Link Here
|
169 |
imodel.calculateDelta(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); |
223 |
imodel.calculateDelta(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); |
170 |
for(IntegrationDecorator imodel:iDecorators) |
224 |
for(IntegrationDecorator imodel:iDecorators) |
171 |
imodel.applyExternalDeltas(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); |
225 |
imodel.applyExternalDeltas(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); |
|
|
226 |
} |
227 |
|
228 |
protected double checkDeltasStep(short threadnum) { |
229 |
EList<IntegrationDecorator> iDecorators = new BasicEList<IntegrationDecorator>(); |
230 |
for (final Iterator<Decorator> decoratorIter = this |
231 |
.getDecorators().iterator(); decoratorIter.hasNext();) { |
232 |
final Decorator decorator = decoratorIter.next(); |
233 |
// Is the decorator enabled? |
234 |
if (decorator.isEnabled() && decorator instanceof IntegrationDecorator) iDecorators.add((IntegrationDecorator)decorator); |
235 |
} |
236 |
|
237 |
double factor = 1.0; |
172 |
|
238 |
|
173 |
for(IntegrationDecorator imodel:iDecorators) |
239 |
for(IntegrationDecorator imodel:iDecorators) |
174 |
updateStandardDiseaseModelLabels((Decorator)imodel, time, timeDelta, cycle, threadnum); |
240 |
factor = Math.min(factor, getDeltaAdjustment((Decorator)imodel, threadnum)); |
175 |
|
241 |
|
|
|
242 |
return factor; |
243 |
} |
244 |
|
245 |
protected void applyDeltasStep(short threadnum) { |
246 |
EList<IntegrationDecorator> iDecorators = new BasicEList<IntegrationDecorator>(); |
247 |
for (final Iterator<Decorator> decoratorIter = this |
248 |
.getDecorators().iterator(); decoratorIter.hasNext();) { |
249 |
final Decorator decorator = decoratorIter.next(); |
250 |
// Is the decorator enabled? |
251 |
if (decorator.isEnabled() && decorator instanceof IntegrationDecorator) iDecorators.add((IntegrationDecorator)decorator); |
252 |
} |
253 |
|
254 |
for(IntegrationDecorator imodel:iDecorators) |
255 |
updateStandardDiseaseModelLabels((Decorator)imodel, threadnum); |
256 |
} |
257 |
|
258 |
protected void scaleAllDeltas(double scaling) { |
259 |
for(Decorator decorator:this.getDecorators()) { |
260 |
EList<DynamicLabel>allLabels = decorator.getLabelsToUpdate(); |
261 |
for (final Iterator<DynamicLabel> currentStateLabelIter = allLabels |
262 |
.iterator(); currentStateLabelIter.hasNext();) { |
263 |
if(decorator instanceof IntegrationDecorator) { |
264 |
// It's a standard disease model with a standard disease model label |
265 |
final IntegrationLabel iLabel = (IntegrationLabel) currentStateLabelIter.next(); |
266 |
((IntegrationLabelValue)iLabel.getDeltaValue()).scale(scaling); |
267 |
} else currentStateLabelIter.next(); |
268 |
} |
269 |
} |
176 |
} |
270 |
} |
177 |
|
271 |
|
|
|
272 |
protected double getDeltaAdjustment(Decorator model, short threadnum) { |
273 |
EList<DynamicLabel> myLabels = partitioner.partitionDecoratorLabels(model, threadnum); |
274 |
double factor = 1.0; |
178 |
|
275 |
|
179 |
protected void updateStandardDiseaseModelLabels(Decorator model, STEMTime time, long timeDelta, int cycle, short threadnum) { |
276 |
for (final Iterator<DynamicLabel> currentStateLabelIter = myLabels |
|
|
277 |
.iterator(); currentStateLabelIter.hasNext();) { |
278 |
final IntegrationLabel label = (IntegrationLabel) currentStateLabelIter.next(); |
279 |
|
280 |
IntegrationLabelValue delta = (IntegrationLabelValue)label.getDeltaValue(); |
281 |
factor = Math.min(factor, delta.computeDeltaAdjustment((IntegrationLabelValue)label.getProbeValue())); |
282 |
} |
283 |
|
284 |
return factor; |
285 |
} |
286 |
|
287 |
protected void updateStandardDiseaseModelLabels(Decorator model, short threadnum) { |
180 |
|
288 |
|
181 |
EList<DynamicLabel> myLabels = partitioner.partitionDecoratorLabels(model, threadnum); |
289 |
EList<DynamicLabel> myLabels = partitioner.partitionDecoratorLabels(model, threadnum); |
182 |
|
290 |
|
Lines 189-201
Link Here
|
189 |
// Initialize the next value from the current value and add the delta |
297 |
// Initialize the next value from the current value and add the delta |
190 |
for (final Iterator<DynamicLabel> currentStateLabelIter = myLabels |
298 |
for (final Iterator<DynamicLabel> currentStateLabelIter = myLabels |
191 |
.iterator(); currentStateLabelIter.hasNext();) { |
299 |
.iterator(); currentStateLabelIter.hasNext();) { |
192 |
final DynamicLabel label = (DynamicLabel) currentStateLabelIter.next(); |
300 |
final IntegrationLabel label = (IntegrationLabel) currentStateLabelIter.next(); |
193 |
LabelValue nextState = label.getNextValue(); |
301 |
LabelValue nextState = label.getNextValue(); |
194 |
|
302 |
|
195 |
LabelValue delta = ((IntegrationLabel)label).getDeltaValue(); |
303 |
LabelValue delta = ((IntegrationLabel)label).getDeltaValue(); |
196 |
// For finite difference, we need to make sure we don't |
304 |
// For finite difference, we need to make sure we don't |
197 |
// move too many people from one state to another |
305 |
// move too many people from one state to another |
198 |
((IntegrationLabelValue)delta).adjustDelta((IntegrationLabelValue)label.getCurrentValue()); |
306 |
((IntegrationLabelValue)delta).avoidNegative((IntegrationLabelValue)label.getProbeValue()); |
199 |
|
307 |
|
200 |
nextState.reset(); |
308 |
nextState.reset(); |
201 |
// Add delta, this will also add the incidence |
309 |
// Add delta, this will also add the incidence |