### Eclipse Workspace Patch 1.0 #P org.eclipse.stem.core Index: src/org/eclipse/stem/core/graph/IntegrationLabelValue.java =================================================================== --- src/org/eclipse/stem/core/graph/IntegrationLabelValue.java (revision 1861) +++ src/org/eclipse/stem/core/graph/IntegrationLabelValue.java (working copy) @@ -76,8 +76,9 @@ * @param value reference value * @return boolean True if changed */ - public boolean adjustDelta(IntegrationLabelValue value); + public boolean avoidNegative(IntegrationLabelValue value); + public double computeDeltaAdjustment(IntegrationLabelValue value); /** * divide. Divide the input with this value #P org.eclipse.stem.populationmodels Index: src/org/eclipse/stem/populationmodels/standard/provider/PopulationInitializerItemProvider.java =================================================================== --- src/org/eclipse/stem/populationmodels/standard/provider/PopulationInitializerItemProvider.java (revision 1861) +++ src/org/eclipse/stem/populationmodels/standard/provider/PopulationInitializerItemProvider.java (working copy) @@ -18,6 +18,7 @@ import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.ResourceLocator; +import org.eclipse.emf.common.util.URI; import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; import org.eclipse.emf.edit.provider.IEditingDomainItemProvider; import org.eclipse.emf.edit.provider.IItemLabelProvider; Index: src/org/eclipse/stem/populationmodels/standard/impl/StandardPopulationModelLabelValueImpl.java =================================================================== --- src/org/eclipse/stem/populationmodels/standard/impl/StandardPopulationModelLabelValueImpl.java (revision 1861) +++ src/org/eclipse/stem/populationmodels/standard/impl/StandardPopulationModelLabelValueImpl.java (working copy) @@ -249,43 +249,53 @@ * * @generated NOT */ - public boolean adjustDelta(IntegrationLabelValue value) { + public boolean avoidNegative(IntegrationLabelValue value) { StandardPopulationModelLabelValue sval = (StandardPopulationModelLabelValue)value; boolean adjusted = false; double newCount = this.getCount() + sval.getCount(); double newBirths = this.getBirths() + sval.getBirths(); double newDeaths = this.getDeaths() + sval.getDeaths(); - double factor = 1.0; - if(newCount < newBirths && newCount < newDeaths && newCount < 0.0) { - // Scale using S - adjusted = true; - factor = -sval.getCount()/this.getCount(); - } else if(newBirths < newDeaths && newBirths < 0.0) { - // Scale using R - adjusted = true; - factor = -sval.getBirths()/this.getBirths(); - } else if (newDeaths < 0) { - // Scale using R + if(newCount<0.0) { adjusted = true; - factor = -sval.getDeaths()/this.getDeaths(); + this.setCount(-sval.getCount()); } - if(adjusted) this.scale(factor); - // Due to precision limitations it is still possible the number if tiny negative. Adjust if necessary - newCount = this.getCount() + sval.getCount(); - newBirths = this.getBirths() + sval.getBirths(); - newDeaths = this.getDeaths() + sval.getDeaths(); - if(newCount<0) - this.setCount(-sval.getCount()); - if(newBirths<0) + if(newBirths<0.0) { + adjusted = true; this.setBirths(-sval.getBirths()); - if(newDeaths<0) + } + + if(newDeaths<0.0) { + adjusted = true; this.setDeaths(-sval.getDeaths()); + } return adjusted; } + + public double computeDeltaAdjustment(IntegrationLabelValue value) { + StandardPopulationModelLabelValue sval = (StandardPopulationModelLabelValue)value; + double newCount = this.getCount() + sval.getCount(); + double newBirths = this.getBirths() + sval.getBirths(); + double newDeaths = this.getDeaths() + sval.getDeaths(); + double factor = 1.0; + + if(newCount < 0.0) { + factor = Math.min(factor, -sval.getCount()/this.getCount()); + } + + if(newBirths < 0.0) { + factor = Math.min(factor, -sval.getBirths()/this.getBirths()); + } + + if (newDeaths < 0.0) { + factor = Math.min(factor, -sval.getDeaths()/this.getDeaths()); + } + + return factor; + } private EListarrivals; private EListdepartures; Index: src/org/eclipse/stem/populationmodels/standard/impl/PopulationModelImpl.java =================================================================== --- src/org/eclipse/stem/populationmodels/standard/impl/PopulationModelImpl.java (revision 1861) +++ src/org/eclipse/stem/populationmodels/standard/impl/PopulationModelImpl.java (working copy) @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; Index: src/org/eclipse/stem/populationmodels/standard/impl/AgingPopulationModelImpl.java =================================================================== --- src/org/eclipse/stem/populationmodels/standard/impl/AgingPopulationModelImpl.java (revision 1861) +++ src/org/eclipse/stem/populationmodels/standard/impl/AgingPopulationModelImpl.java (working copy) @@ -28,7 +28,7 @@ * Aging Population Model'. *

*

- * + * * @generated */ public class AgingPopulationModelImpl extends DemographicPopulationModelImpl @@ -44,7 +44,6 @@ /** * - * * @generated */ @Override Index: src/org/eclipse/stem/populationmodels/standard/StandardPopulationModelLabelValue.java =================================================================== --- src/org/eclipse/stem/populationmodels/standard/StandardPopulationModelLabelValue.java (revision 1861) +++ src/org/eclipse/stem/populationmodels/standard/StandardPopulationModelLabelValue.java (working copy) @@ -139,12 +139,4 @@ * @generated */ void setDensity(double value); - - /** - * - * - * @model valueType="org.eclipse.stem.populationmodels.standard.IntegrationLabelValue" - * @generated - */ - boolean adjustDelta(IntegrationLabelValue value); } // StandardPopulationModelLabelValue Index: model/standard.ecore =================================================================== --- model/standard.ecore (revision 1861) +++ model/standard.ecore (working copy) @@ -37,9 +37,6 @@ abstract="true" interface="true"/> - - - Index: src/org/eclipse/stem/populationmodels/standard/impl/StandardPackageImpl.java =================================================================== --- src/org/eclipse/stem/populationmodels/standard/impl/StandardPackageImpl.java (revision 1861) +++ src/org/eclipse/stem/populationmodels/standard/impl/StandardPackageImpl.java (working copy) @@ -949,9 +949,6 @@ initEAttribute(getStandardPopulationModelLabelValue_Deaths(), theEcorePackage.getEDouble(), "deaths", null, 0, 1, StandardPopulationModelLabelValue.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEAttribute(getStandardPopulationModelLabelValue_Density(), theEcorePackage.getEDouble(), "density", null, 0, 1, StandardPopulationModelLabelValue.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); - EOperation op = addEOperation(standardPopulationModelLabelValueEClass, theEcorePackage.getEBoolean(), "adjustDelta", 0, 1, IS_UNIQUE, IS_ORDERED); - addEParameter(op, this.getIntegrationLabelValue(), "value", 0, 1, IS_UNIQUE, IS_ORDERED); - initEClass(stochasticStandardPopulationModelEClass, StochasticStandardPopulationModel.class, "StochasticStandardPopulationModel", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getStochasticStandardPopulationModel_Gain(), theEcorePackage.getEDouble(), "gain", "0.01", 0, 1, StochasticStandardPopulationModel.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); #P org.eclipse.stem.diseasemodels.experimental Index: src/org/eclipse/stem/diseasemodels/experimental/impl/TBDiseaseModelLabelValueImpl.java =================================================================== --- src/org/eclipse/stem/diseasemodels/experimental/impl/TBDiseaseModelLabelValueImpl.java (revision 1861) +++ src/org/eclipse/stem/diseasemodels/experimental/impl/TBDiseaseModelLabelValueImpl.java (working copy) @@ -312,9 +312,13 @@ return result.toString(); } - public boolean adjustDelta(IntegrationLabelValue value) { + public boolean avoidNegative(IntegrationLabelValue value) { // TODO Auto-generated method stub return false; } + + public double computeDeltaAdjustment(IntegrationLabelValue value) { + return 1.0; + } } //TBDiseaseModelLabelValueImpl #P org.eclipse.stem.definitions #P org.eclipse.stem.diseasemodels Index: src/org/eclipse/stem/diseasemodels/standard/impl/StandardDiseaseModelImpl.java =================================================================== --- src/org/eclipse/stem/diseasemodels/standard/impl/StandardDiseaseModelImpl.java (revision 1861) +++ src/org/eclipse/stem/diseasemodels/standard/impl/StandardDiseaseModelImpl.java (working copy) @@ -11,6 +11,7 @@ * IBM Corporation - initial API and implementation *******************************************************************************/ +import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; Index: src/org/eclipse/stem/diseasemodels/standard/impl/SIRLabelValueImpl.java =================================================================== --- src/org/eclipse/stem/diseasemodels/standard/impl/SIRLabelValueImpl.java (revision 1861) +++ src/org/eclipse/stem/diseasemodels/standard/impl/SIRLabelValueImpl.java (working copy) @@ -279,7 +279,7 @@ * @return boolean * @override */ - public boolean adjustDelta(IntegrationLabelValue target) { + public boolean avoidNegative(IntegrationLabelValue target) { SIRLabelValue sirValue = (SIRLabelValue)target; boolean adjusted = false; double newS = this.getS() + sirValue.getS(); @@ -287,43 +287,56 @@ double newR = this.getR() + sirValue.getR(); double newDD = this.getDiseaseDeaths() + sirValue.getDiseaseDeaths(); - double factor = 1.0; - if(newS < newI && newS < newR && newS < newDD && newS < 0.0) { - // Scale using S + if(newS<0.0) { adjusted = true; - factor = -sirValue.getS()/this.getS(); - } else if(newI < newR && newI < newDD && newI < 0.0) { - // Scale using I + this.setS(-sirValue.getS()); + } + + if(newI<0.0) { adjusted = true; - factor = -sirValue.getI()/this.getI(); - } else if(newR < newDD && newR < 0.0) { - // Scale using R + this.setI(-sirValue.getI()); + } + + if(newR<0.0) { adjusted = true; - factor = -sirValue.getR()/this.getR(); - } else if(newDD < 0.0) { - // Scale using DD + this.setR(-sirValue.getR()); + } + + if(newDD < 0.0) { adjusted = true; - factor = -sirValue.getDiseaseDeaths()/this.getDiseaseDeaths(); + this.setDiseaseDeaths(-sirValue.getDiseaseDeaths()); } - if(adjusted) this.scale(factor); + return adjusted; + } + + public double computeDeltaAdjustment(IntegrationLabelValue value) { + SIRLabelValue sirValue = (SIRLabelValue)value; + double newS = this.getS() + sirValue.getS(); + double newI = this.getI() + sirValue.getI(); + double newR = this.getR() + sirValue.getR(); + double newDD = this.getDiseaseDeaths() + sirValue.getDiseaseDeaths(); + double factor = 1.0; - // Due to precision limitations it is still possible the number if tiny negative. Adjust if necessary - newS = this.getS() + sirValue.getS(); - newI = this.getI() + sirValue.getI(); - newR = this.getR() + sirValue.getR(); - newDD = this.getDiseaseDeaths() + sirValue.getDiseaseDeaths(); + if(newS < 0.0) { + factor = Math.min(factor, -sirValue.getS()/this.getS()); + } + + if(newI < 0.0) { + factor = Math.min(factor, -sirValue.getI()/this.getI()); + } - if(newS<0) - this.setS(-sirValue.getS()); - if(newI<0) - this.setI(-sirValue.getI()); - if(newR<0) - this.setR(-sirValue.getR()); - if(newDD < 0) - this.setDiseaseDeaths(-sirValue.getDiseaseDeaths()); - return adjusted; + if(newR < 0.0) { + factor = Math.min(factor, -sirValue.getR()/this.getR()); + } + + if(newDD < 0.0) { + factor = Math.min(factor, -sirValue.getDiseaseDeaths()/this.getDiseaseDeaths()); + } + + return factor; } + /** * @see org.eclipse.stem.core.graph.impl.LabelValueImpl#reset() */ Index: src/org/eclipse/stem/diseasemodels/standard/impl/SEIRLabelValueImpl.java =================================================================== --- src/org/eclipse/stem/diseasemodels/standard/impl/SEIRLabelValueImpl.java (revision 1861) +++ src/org/eclipse/stem/diseasemodels/standard/impl/SEIRLabelValueImpl.java (working copy) @@ -266,9 +266,8 @@ * @return boolean * @override */ - public boolean adjustDelta(IntegrationLabelValue target) { - SEIRLabelValue seirValue = (SEIRLabelValue)target; - + public boolean avoidNegative(IntegrationLabelValue target) { + SEIRLabelValue seirValue = (SEIRLabelValue)target; boolean adjusted = false; double newS = this.getS() + seirValue.getS(); double newE = this.getE() + seirValue.getE(); @@ -276,49 +275,65 @@ double newR = this.getR() + seirValue.getR(); double newDD = this.getDiseaseDeaths() +seirValue.getDiseaseDeaths(); - double factor = 1.0; - if(newS < newE && newS < newI && newS < newR && newS < newDD && newS < 0.0) { - // Scale using S + if(newS<0.0) { adjusted = true; - factor = -seirValue.getS()/this.getS(); - } else if(newE < newI && newE < newR && newE < newDD && newE < 0.0) { - // Scale using E - adjusted = true; - factor = -seirValue.getE()/this.getE(); - } else if(newI < newR && newI < newDD && newI < 0.0) { - // Scale using I - adjusted = true; - factor = -seirValue.getI()/this.getI(); - } else if(newR < newDD && newR < 0.0) { - // Scale using R - adjusted = true; - factor = -seirValue.getR()/this.getR(); - } else if(newDD < 0) { - // Scale using R - adjusted = true; - factor = -seirValue.getDiseaseDeaths()/this.getDiseaseDeaths(); + this.setS(-seirValue.getS()); } - if(adjusted) this.scale(factor); - // Due to precision limitations it is still possible the number if tiny negative. Adjust if necessary - newS = this.getS() + seirValue.getS(); - newE = this.getE() + seirValue.getE(); - newI = this.getI() + seirValue.getI(); - newR = this.getR() + seirValue.getR(); - newDD = this.getDiseaseDeaths() + seirValue.getDiseaseDeaths(); - if(newS<0) - this.setS(-seirValue.getS()); - if(newE<0) + if(newE<0.0) { + adjusted = true; this.setE(-seirValue.getE()); - if(newI<0) + } + + if(newI<0.0) { + adjusted = true; this.setI(-seirValue.getI()); - if(newR<0) + } + + if(newR<0.0) { + adjusted = true; this.setR(-seirValue.getR()); - if(newDD < 0) + } + + if(newDD < 0.0) { + adjusted = true; this.setDiseaseDeaths(-seirValue.getDiseaseDeaths()); + } + return adjusted; } + public double computeDeltaAdjustment(IntegrationLabelValue value) { + SEIRLabelValue seirValue = (SEIRLabelValue)value; + double newS = this.getS() + seirValue.getS(); + double newE = this.getE() + seirValue.getE(); + double newI = this.getI() + seirValue.getI(); + double newR = this.getR() + seirValue.getR(); + double newDD = this.getDiseaseDeaths() +seirValue.getDiseaseDeaths(); + double factor = 1.0; + + if(newS < 0.0) { + factor = Math.min(factor, -seirValue.getS()/this.getS()); + } + + if(newE < 0.0) { + factor = Math.min(factor, -seirValue.getE()/this.getE()); + } + + if(newI < 0.0) { + factor = Math.min(factor, -seirValue.getI()/this.getI()); + } + + if(newR < 0.0) { + factor = Math.min(factor, -seirValue.getR()/this.getR()); + } + + if(newDD < 0.0) { + factor = Math.min(factor, -seirValue.getDiseaseDeaths()/this.getDiseaseDeaths()); + } + + return factor; + } /** * @see org.eclipse.stem.diseasemodels.standard.impl.SIRLabelValueImpl#reset() Index: src/org/eclipse/stem/diseasemodels/standard/impl/SILabelValueImpl.java =================================================================== --- src/org/eclipse/stem/diseasemodels/standard/impl/SILabelValueImpl.java (revision 1861) +++ src/org/eclipse/stem/diseasemodels/standard/impl/SILabelValueImpl.java (working copy) @@ -406,41 +406,51 @@ * * @return boolean */ - public boolean adjustDelta(IntegrationLabelValue target) { + public boolean avoidNegative(IntegrationLabelValue target) { SILabelValue siValue = (SILabelValue)target; boolean adjusted = false; double newS = this.getS() + siValue.getS(); double newI = this.getI() + siValue.getI(); double newDD = this.getDiseaseDeaths() + siValue.getDiseaseDeaths(); - double factor = 1.0; - if(newS < newI && newS < newDD && newS < 0.0) { - // Scale using S - adjusted = true; - factor = -siValue.getS()/this.getS(); - } else if(newI < newDD && newI < 0.0) { - // Scale using R - adjusted = true; - factor = -siValue.getI()/this.getI(); - } else if (newDD < 0) { - // Scale using R + if(newS<0.0) { adjusted = true; - factor = -siValue.getDiseaseDeaths()/this.getDiseaseDeaths(); + this.setS(-siValue.getS()); } - if(adjusted) this.scale(factor); - // Due to precision limitations it is still possible the number if tiny negative. Adjust if necessary - newS = this.getS() + siValue.getS(); - newI = this.getI() + siValue.getI(); - newDD = this.getDiseaseDeaths() + siValue.getDiseaseDeaths(); - if(newS<0) - this.setS(-siValue.getS()); - if(newI<0) + if(newI<0.0) { + adjusted = true; this.setI(-siValue.getI()); - if(newDD<0) + } + + if(newDD<0.0) { + adjusted = true; this.setDiseaseDeaths(-siValue.getDiseaseDeaths()); + } return adjusted; } + public double computeDeltaAdjustment(IntegrationLabelValue value) { + SILabelValue siValue = (SILabelValue)value; + double newS = this.getS() + siValue.getS(); + double newI = this.getI() + siValue.getI(); + double newDD = this.getDiseaseDeaths() + siValue.getDiseaseDeaths(); + double factor = 1.0; + + if(newS < 0.0) { + factor = Math.min(factor, -siValue.getS()/this.getS()); + } + + if(newI < 0.0) { + factor = Math.min(factor, -siValue.getI()/this.getI()); + } + + if (newDD < 0) { + factor = Math.min(factor, -siValue.getDiseaseDeaths()/this.getDiseaseDeaths()); + } + + return factor; + } + } // SILabelValueImpl #P org.eclipse.stem.solvers.fd Index: src/org/eclipse/stem/solvers/fd/impl/FdJob.java =================================================================== --- src/org/eclipse/stem/solvers/fd/impl/FdJob.java (revision 1861) +++ src/org/eclipse/stem/solvers/fd/impl/FdJob.java (working copy) @@ -13,6 +13,7 @@ +import org.eclipse.core.internal.runtime.LocalizationUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -30,6 +31,10 @@ this.threadnum = thread; this.solver = s; } + + public static int COMPUTE_DELTAS = 0; + public static int CHECK_DELTAS = 1; + public static int APPLY_DELTAS = 2; protected double progress; protected double t; @@ -39,6 +44,7 @@ long timeDelta; int cycle; short threadnum; + int step; public double getProgress() { return this.progress; @@ -47,8 +53,19 @@ this.progress = p; } protected IStatus run(final IProgressMonitor monitor) { - solver._step(time,timeDelta,cycle,threadnum); + IStatus status = Status.CANCEL_STATUS; - return Status.OK_STATUS; + if (step == COMPUTE_DELTAS) { + solver.computeDeltasStep(time,timeDelta,threadnum); + status = new Status(IStatus.OK, "unknownId", ""); + } else if (step == CHECK_DELTAS) { + double adjustmentFactor = solver.checkDeltasStep(threadnum); + status = new Status(IStatus.OK, "unknownId", adjustmentFactor + ""); + } else if (step == APPLY_DELTAS) { + solver.applyDeltasStep(threadnum); + status = new Status(IStatus.OK, "unknownId", ""); + } + + return status; } } Index: src/org/eclipse/stem/solvers/fd/impl/FiniteDifferenceImpl.java =================================================================== --- src/org/eclipse/stem/solvers/fd/impl/FiniteDifferenceImpl.java (revision 1861) +++ src/org/eclipse/stem/solvers/fd/impl/FiniteDifferenceImpl.java (working copy) @@ -97,7 +97,7 @@ } else currentStateLabelIter.next(); } } - + if(jobs == null || jobs.length != num_threads) { // Initialize the jobs if not done yet or of the number of threads changes jobs = new FdJob[num_threads]; @@ -107,20 +107,39 @@ jobs[i] = new FdJob("Finite Difference Worker "+i, threadnum, this); } // For each job } // If not initialized - - // Initialize + + recursiveStep(time, timeDelta, cycle, 1.0); + + return true; + } + protected void recursiveStep(STEMTime time, long timeDelta, int cycle, double scaling) { + // Compute deltas for(FdJob j:jobs) { j.cycle = cycle; j.time = time; j.timeDelta = timeDelta; + j.step = FdJob.COMPUTE_DELTAS; + j.schedule(); + } + + for(FdJob j : jobs) { + try { + j.join(); + } catch(InterruptedException ie) { + Activator.logError(ie.getMessage(), ie); + } } - // Schedule. Jobs can be rescheduled after finished - for(FdJob j:jobs) + // Scale deltas + scaleAllDeltas(scaling); + + // Check deltas for adjustment + for(FdJob j:jobs) { + j.step = FdJob.CHECK_DELTAS; j.schedule(); + } - // Wait until all jobs completed for(FdJob j : jobs) { try { j.join(); @@ -129,30 +148,63 @@ } } - // Set the common time and step size here and validate everything is right - //double minStep = Double.MAX_VALUE; - //double currentT = jobs[0].t; - //for(SimJob j : jobs) { - // The jobs have calculated new step sizes after they finished. Pick the - // smallest one for the next cycle - // if(j.h < minStep) minStep = j.h; - // if(j.t != currentT) Activator.logError("Error, one thread was in misstep with other threads, its time was "+j.t+" versus "+currentT, new Exception()); - //} + double factor = 1.0; - //this.setCurrentX(currentT); - //this.setStepSize(minStep); // smallest one from above. - return true; + for (FdJob j : jobs) { + factor = Math.min(factor, Double.parseDouble(j.getResult().getMessage())); + } + + if (factor == 1.0) { + // Apply deltas + for(FdJob j:jobs) { + j.step = FdJob.APPLY_DELTAS; + j.schedule(); + } + + for(FdJob j : jobs) { + try { + j.join(); + } catch(InterruptedException ie) { + Activator.logError(ie.getMessage(), ie); + } + } + } else { + // Scale to avoid going negative + scaleAllDeltas(factor); + + // Apply deltas + for(FdJob j:jobs) { + j.step = FdJob.APPLY_DELTAS; + j.schedule(); + } + + for(FdJob j : jobs) { + try { + j.join(); + } catch(InterruptedException ie) { + Activator.logError(ie.getMessage(), ie); + } + } + + // Call this method again for the rest of the time step + for(Decorator decorator:this.getDecorators()) { + EListallLabels = decorator.getLabelsToUpdate(); + for (final Iterator currentStateLabelIter = allLabels + .iterator(); currentStateLabelIter.hasNext();) { + if(decorator instanceof IntegrationDecorator) { + // It's a standard disease model with a standard disease model label + final IntegrationLabel iLabel = (IntegrationLabel) currentStateLabelIter.next(); + ((IntegrationLabelValue)iLabel.getProbeValue()).set((IntegrationLabelValue)iLabel.getNextValue()); + ((IntegrationLabelValue)iLabel.getTempValue()).set((IntegrationLabelValue)iLabel.getNextValue()); + } else currentStateLabelIter.next(); + } + } + + recursiveStep(time, timeDelta, cycle, (1-factor)*scaling); + } } - /** - * _step Do the step for a single thread - * - * @param time - * @param timeDelta - * @param cycle - * @param threadnum - */ - protected void _step(STEMTime time, long timeDelta, int cycle, short threadnum) { + protected void computeDeltasStep(STEMTime time, long timeDelta, short threadnum) { // Now give each decorator a chance to update its dynamic // labels in the canonical graph, but only if it is enabled. A // Decorator might not be enabled if it is the action of a Trigger @@ -169,14 +221,68 @@ imodel.calculateDelta(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); for(IntegrationDecorator imodel:iDecorators) imodel.applyExternalDeltas(time, timeDelta, partitioner.partitionDecoratorLabels((Decorator)imodel, threadnum)); + } + + protected double checkDeltasStep(short threadnum) { + EList iDecorators = new BasicEList(); + for (final Iterator decoratorIter = this + .getDecorators().iterator(); decoratorIter.hasNext();) { + final Decorator decorator = decoratorIter.next(); + // Is the decorator enabled? + if (decorator.isEnabled() && decorator instanceof IntegrationDecorator) iDecorators.add((IntegrationDecorator)decorator); + } + + double factor = 1.0; for(IntegrationDecorator imodel:iDecorators) - updateStandardDiseaseModelLabels((Decorator)imodel, time, timeDelta, cycle, threadnum); + factor = Math.min(factor, getDeltaAdjustment((Decorator)imodel, threadnum)); + return factor; + } + + protected void applyDeltasStep(short threadnum) { + EList iDecorators = new BasicEList(); + for (final Iterator decoratorIter = this + .getDecorators().iterator(); decoratorIter.hasNext();) { + final Decorator decorator = decoratorIter.next(); + // Is the decorator enabled? + if (decorator.isEnabled() && decorator instanceof IntegrationDecorator) iDecorators.add((IntegrationDecorator)decorator); + } + + for(IntegrationDecorator imodel:iDecorators) + updateStandardDiseaseModelLabels((Decorator)imodel, threadnum); + } + + protected void scaleAllDeltas(double scaling) { + for(Decorator decorator:this.getDecorators()) { + EListallLabels = decorator.getLabelsToUpdate(); + for (final Iterator currentStateLabelIter = allLabels + .iterator(); currentStateLabelIter.hasNext();) { + if(decorator instanceof IntegrationDecorator) { + // It's a standard disease model with a standard disease model label + final IntegrationLabel iLabel = (IntegrationLabel) currentStateLabelIter.next(); + ((IntegrationLabelValue)iLabel.getDeltaValue()).scale(scaling); + } else currentStateLabelIter.next(); + } + } } + protected double getDeltaAdjustment(Decorator model, short threadnum) { + EList myLabels = partitioner.partitionDecoratorLabels(model, threadnum); + double factor = 1.0; - protected void updateStandardDiseaseModelLabels(Decorator model, STEMTime time, long timeDelta, int cycle, short threadnum) { + for (final Iterator currentStateLabelIter = myLabels + .iterator(); currentStateLabelIter.hasNext();) { + final IntegrationLabel label = (IntegrationLabel) currentStateLabelIter.next(); + + IntegrationLabelValue delta = (IntegrationLabelValue)label.getDeltaValue(); + factor = Math.min(factor, delta.computeDeltaAdjustment((IntegrationLabelValue)label.getProbeValue())); + } + + return factor; + } + + protected void updateStandardDiseaseModelLabels(Decorator model, short threadnum) { EList myLabels = partitioner.partitionDecoratorLabels(model, threadnum); @@ -189,13 +295,13 @@ // Initialize the next value from the current value and add the delta for (final Iterator currentStateLabelIter = myLabels .iterator(); currentStateLabelIter.hasNext();) { - final DynamicLabel label = (DynamicLabel) currentStateLabelIter.next(); + final IntegrationLabel label = (IntegrationLabel) currentStateLabelIter.next(); LabelValue nextState = label.getNextValue(); LabelValue delta = ((IntegrationLabel)label).getDeltaValue(); // For finite difference, we need to make sure we don't // move too many people from one state to another - ((IntegrationLabelValue)delta).adjustDelta((IntegrationLabelValue)label.getCurrentValue()); + ((IntegrationLabelValue)delta).avoidNegative((IntegrationLabelValue)label.getProbeValue()); nextState.reset(); // Add delta, this will also add the incidence #P org.eclipse.stem.tests.populationmodels Index: src/org/eclipse/stem/populationmodels/standard/tests/StandardPopulationModelLabelValueTest.java =================================================================== --- src/org/eclipse/stem/populationmodels/standard/tests/StandardPopulationModelLabelValueTest.java (revision 1861) +++ src/org/eclipse/stem/populationmodels/standard/tests/StandardPopulationModelLabelValueTest.java (working copy) @@ -15,12 +15,6 @@ * * A test case for the model object 'Population Model Label Value'. * - *

- * The following operations are tested: - *

    - *
  • {@link org.eclipse.stem.populationmodels.standard.StandardPopulationModelLabelValue#adjustDelta(org.eclipse.stem.core.graph.IntegrationLabelValue) Adjust Delta}
  • - *
- *

* @generated */ public class StandardPopulationModelLabelValueTest extends PopulationModelLabelValueTest { @@ -104,10 +98,10 @@ } /** - * Tests the '{@link org.eclipse.stem.populationmodels.standard.StandardPopulationModelLabelValue#adjustDelta(org.eclipse.stem.core.graph.IntegrationLabelValue) Adjust Delta}' operation. + * Tests the '{@link org.eclipse.stem.populationmodels.standard.StandardPopulationModelLabelValue#avoidNegative(org.eclipse.stem.core.graph.IntegrationLabelValue) Adjust Delta}' operation. * * - * @see org.eclipse.stem.populationmodels.standard.StandardPopulationModelLabelValue#adjustDelta(org.eclipse.stem.core.graph.IntegrationLabelValue) + * @see org.eclipse.stem.populationmodels.standard.StandardPopulationModelLabelValue#avoidNegative(org.eclipse.stem.core.graph.IntegrationLabelValue) * @generated NOT */ public void testAdjustDelta__IntegrationLabelValue() {