]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Multiple varied parameters to sensitivity analysis. (refs #4238)
authormiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 27 Jun 2013 10:27:35 +0000 (10:27 +0000)
committermiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 27 Jun 2013 10:27:35 +0000 (10:27 +0000)
Now the parameters are defined outside of the distributions. This allows firstly to randomize the parameter values for each run so that no parameter values repeat between individual runs. Secondly this enables using more sophisticated techniques of selecting the sequence of parameter sets (not yet implemented).

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@27664 ac1ea38d-2e2b-0410-8846-a27921b304fc

13 files changed:
org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java
org.simantics.sysdyn.ontology/graph.tg
org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph
org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityAnalysisExperimentNodeHandler.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SensitivityAnalysisExperimentTab.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterLabelRule.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/IDistribution.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/Interval.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/NormalDistribution.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/distribution/UniformDistribution.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/RandomGenerator.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynSensitivityAnalysisExperiment.java

index 369a28140039b70623cd52a9356541e0a0721d1f..d4091285cff0b0c490d6f69cb3bdf4f84c1c9317 100644 (file)
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.io.InputStream;\r
 import java.io.LineNumberReader;\r
 import java.util.ArrayList;\r
+import java.util.ConcurrentModificationException;\r
 import java.util.HashMap;\r
 import java.util.List;\r
 import java.util.regex.Matcher;\r
@@ -458,12 +459,17 @@ public class SimulationResult {
             if(resArray.length == 2 && timesArray.length > 2)\r
                 timesArray = new double[] {timesArray[0], timesArray[timesArray.length - 1]};\r
             ds = new DataSet(variable, timesArray, resArray);\r
-            for (DataSet tempds : variables){\r
-                if (tempds.name.equals(variable))\r
-                    // We should never need to go there unless some change in\r
-                    // the logic of reading variables are made.\r
-                    // Also helps in seeking memory leaks.\r
-                    return null;\r
+            try {\r
+                   for (DataSet tempds : variables){\r
+                       if (tempds.name.equals(variable))\r
+                           // We should never need to go there unless some change in\r
+                           // the logic of reading variables are made.\r
+                           // Also helps in seeking memory leaks.\r
+                               System.err.println("Find me and add a comment that I was printed, please.");\r
+                               // If it seems that in no case we need to go here, comment this try catch.\r
+                           return null;\r
+                   }\r
+            } catch (ConcurrentModificationException e) {\r
             }\r
             variables.add(ds);\r
             return ds;\r
index d11b9bca82449ddc1bd62f62bd97c5f1b0ed9d64..a01167bedf29b956211c931238a9e095601749ea 100644 (file)
Binary files a/org.simantics.sysdyn.ontology/graph.tg and b/org.simantics.sysdyn.ontology/graph.tg differ
index cfce20a5bf221de5af4f5cd75338583f5f00b326..9b8873121f0bb86c902c4c378a9ca9a4a40d1206 100644 (file)
@@ -23,8 +23,8 @@ SYSDYN.ImportedOntologies : PROJ.NamespaceRequirement
         "http://www.simantics.org/Sysdyn-1.1" : L0.URI
         "http://www.simantics.org/Layer0-1.1" : L0.URI
         "http://www.simantics.org/SelectionView-1.2" : L0.URI
-        "http://www.simantics.org/Documentation-1.1" : L0.URI // Experimental documentation tool
-        "http://www.simantics.org/DocumentWorkbench-1.0" : L0.URI // Experimental documentation tool
+//        "http://www.simantics.org/Documentation-1.1" : L0.URI // Experimental documentation tool
+//        "http://www.simantics.org/DocumentWorkbench-1.0" : L0.URI // Experimental documentation tool
                 
 SYSDYN.SharedFunctionOntology <T L0.Ontology
 SYSDYN.SharedModuleOntology <T L0.Ontology      
@@ -352,15 +352,15 @@ SYSDYN.SensitivityAnalysisExperiment <T SYSDYN.Experiment
     >-- SYSDYN.SensitivityAnalysisExperiment.parameterList --> L0.List <R L0.IsComposedOf : L0.FunctionalRelation
     >-- SYSDYN.SensitivityAnalysisExperiment.randomSeed --> L0.Integer <R L0.HasProperty : L0.FunctionalRelation
     >-- SYSDYN.SensitivityAnalysisExperiment.resultRefreshRate --> L0.Integer <R L0.HasProperty : L0.FunctionalRelation
+    >-- SYSDYN.SensitivityAnalysisExperiment.numberOfValues --> L0.Integer <R L0.HasProperty : L0.FunctionalRelation
     @L0.assert SYSDYN.SensitivityAnalysisExperiment.randomSeed 123
+    @L0.assert SYSDYN.SensitivityAnalysisExperiment.numberOfValues 10
 
 SYSDYN.SensitivityAnalysisExperiment.Parameter <T L0.Entity
     >-- SYSDYN.SensitivityAnalysisExperiment.Parameter.propabilityDistribution --> SYSDYN.ProbabilityDistribution <R L0.HasProperty : L0.FunctionalRelation
     >-- SYSDYN.SensitivityAnalysisExperiment.Parameter.variable --> L0.String <R L0.HasProperty : L0.FunctionalRelation
     >-- SYSDYN.SensitivityAnalysisExperiment.Parameter.indexes --> L0.StringArray <R L0.HasProperty : L0.FunctionalRelation
-    >-- SYSDYN.SensitivityAnalysisExperiment.Parameter.numberOfValues --> L0.Integer <R L0.HasProperty : L0.FunctionalRelation
-    
-    
+        
 SYSDYN.ProbabilityDistribution <T L0.Entity
 SYSDYN.UniformDistribution <T SYSDYN.ProbabilityDistribution
     >-- SYSDYN.UniformDistribution.minValue --> L0.Double <R L0.HasProperty : L0.FunctionalRelation
index 97525b65a01d7acb39365c2ea40a22affd83542e..5d086c8921c1ce00c5cd072d46b12c908cdaeadd 100644 (file)
@@ -556,12 +556,12 @@ public class SysdynResource {
     public final Resource SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule;\r
     public final Resource SensitivityAnalysisExperiment_Parameter_indexes;\r
     public final Resource SensitivityAnalysisExperiment_Parameter_indexes_Inverse;\r
-    public final Resource SensitivityAnalysisExperiment_Parameter_numberOfValues;\r
-    public final Resource SensitivityAnalysisExperiment_Parameter_numberOfValues_Inverse;\r
     public final Resource SensitivityAnalysisExperiment_Parameter_propabilityDistribution;\r
     public final Resource SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse;\r
     public final Resource SensitivityAnalysisExperiment_Parameter_variable;\r
     public final Resource SensitivityAnalysisExperiment_Parameter_variable_Inverse;\r
+    public final Resource SensitivityAnalysisExperiment_numberOfValues;\r
+    public final Resource SensitivityAnalysisExperiment_numberOfValues_Inverse;\r
     public final Resource SensitivityAnalysisExperiment_parameterList;\r
     public final Resource SensitivityAnalysisExperiment_parameterList_Inverse;\r
     public final Resource SensitivityAnalysisExperiment_randomSeed;\r
@@ -1284,12 +1284,12 @@ public class SysdynResource {
         public static final String SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/ParameterBrowseContext/ParameterLabelRule";\r
         public static final String SensitivityAnalysisExperiment_Parameter_indexes = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/indexes";\r
         public static final String SensitivityAnalysisExperiment_Parameter_indexes_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/indexes/Inverse";\r
-        public static final String SensitivityAnalysisExperiment_Parameter_numberOfValues = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/numberOfValues";\r
-        public static final String SensitivityAnalysisExperiment_Parameter_numberOfValues_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/numberOfValues/Inverse";\r
         public static final String SensitivityAnalysisExperiment_Parameter_propabilityDistribution = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/propabilityDistribution";\r
         public static final String SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/propabilityDistribution/Inverse";\r
         public static final String SensitivityAnalysisExperiment_Parameter_variable = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/variable";\r
         public static final String SensitivityAnalysisExperiment_Parameter_variable_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/Parameter/variable/Inverse";\r
+        public static final String SensitivityAnalysisExperiment_numberOfValues = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/numberOfValues";\r
+        public static final String SensitivityAnalysisExperiment_numberOfValues_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/numberOfValues/Inverse";\r
         public static final String SensitivityAnalysisExperiment_parameterList = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/parameterList";\r
         public static final String SensitivityAnalysisExperiment_parameterList_Inverse = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/parameterList/Inverse";\r
         public static final String SensitivityAnalysisExperiment_randomSeed = "http://www.simantics.org/Sysdyn-1.1/SensitivityAnalysisExperiment/randomSeed";\r
@@ -2022,12 +2022,12 @@ public class SysdynResource {
         SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_ParameterBrowseContext_ParameterLabelRule);\r
         SensitivityAnalysisExperiment_Parameter_indexes = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_indexes);\r
         SensitivityAnalysisExperiment_Parameter_indexes_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_indexes_Inverse);\r
-        SensitivityAnalysisExperiment_Parameter_numberOfValues = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_numberOfValues);\r
-        SensitivityAnalysisExperiment_Parameter_numberOfValues_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_numberOfValues_Inverse);\r
         SensitivityAnalysisExperiment_Parameter_propabilityDistribution = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_propabilityDistribution);\r
         SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse);\r
         SensitivityAnalysisExperiment_Parameter_variable = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_variable);\r
         SensitivityAnalysisExperiment_Parameter_variable_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_Parameter_variable_Inverse);\r
+        SensitivityAnalysisExperiment_numberOfValues = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_numberOfValues);\r
+        SensitivityAnalysisExperiment_numberOfValues_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_numberOfValues_Inverse);\r
         SensitivityAnalysisExperiment_parameterList = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_parameterList);\r
         SensitivityAnalysisExperiment_parameterList_Inverse = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_parameterList_Inverse);\r
         SensitivityAnalysisExperiment_randomSeed = getResourceOrNull(graph, URIs.SensitivityAnalysisExperiment_randomSeed);\r
index 7b48a779ec2ce2d678ddcb6705e4ba159a0565e1..ac823f5b73180eac831121520402c56c9e5d7c1b 100644 (file)
@@ -42,7 +42,6 @@ public class NewSensitivityAnalysisExperimentNodeHandler extends NewExperimentNo
         Resource parameter = GraphUtils.create2(graph, sr.SensitivityAnalysisExperiment_Parameter,\r
                 sr.SensitivityAnalysisExperiment_Parameter_propabilityDistribution, distribution,\r
                 sr.SensitivityAnalysisExperiment_Parameter_variable, "<Write variable name>",\r
-                sr.SensitivityAnalysisExperiment_Parameter_numberOfValues, 10,\r
                 L0.PartOf, experiment);\r
         \r
         ArrayList<Resource> parameterList = new ArrayList<Resource>();\r
index a88f633f32ca29b8875d8db29ab13c3130d24812..ae039710818a31b2b00aaae5d94b6b8b6846b545 100644 (file)
@@ -1,3 +1,14 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
 package org.simantics.sysdyn.ui.properties;\r
 \r
 import java.util.Collection;\r
@@ -117,7 +128,7 @@ public class SensitivityAnalysisExperimentTab extends LabelPropertyTabContributo
         // Label\r
         Composite labelComposite = new Composite(content, SWT.NONE);\r
         GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(labelComposite);\r
-        GridLayoutFactory.fillDefaults().numColumns(4).applyTo(labelComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(6).applyTo(labelComposite);\r
         Label label = new Label(labelComposite, SWT.NONE);\r
         label.setText("Name");\r
 \r
@@ -128,6 +139,16 @@ public class SensitivityAnalysisExperimentTab extends LabelPropertyTabContributo
         name.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), name.getWidget())));\r
         GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget());\r
         \r
+        label = new Label(labelComposite, SWT.NONE);\r
+        label.setText("Number of runs");\r
+        \r
+        TrackedText n = new TrackedText(labelComposite, support, SWT.BORDER);\r
+        n.setTextFactory(new IntegerPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_numberOfValues));\r
+        n.addModifyListener(new IntegerPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_numberOfValues));\r
+        n.setInputValidator(new IntegerValidator());\r
+        n.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), n.getWidget())));\r
+        GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).applyTo(n.getWidget());\r
+        \r
         label = new Label(labelComposite, SWT.NONE);\r
         label.setText("Seed");\r
         \r
@@ -138,7 +159,6 @@ public class SensitivityAnalysisExperimentTab extends LabelPropertyTabContributo
         seed.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), seed.getWidget())));\r
         GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).applyTo(seed.getWidget());\r
 \r
-\r
         // (Ontology-based) GraphExplorer displaying range axis and variables mapped to those axis\r
         explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys(\r
                 "displaySelectors", "displayFilter", "treeView").values(false, false, true), site, content, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE);\r
@@ -242,18 +262,6 @@ public class SensitivityAnalysisExperimentTab extends LabelPropertyTabContributo
 //        variable.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), variable.getWidget())));\r
 //        GridDataFactory.fillDefaults().grab(true, false).applyTo(variable.getWidget());\r
 \r
-        label = new Label(parameterProperties, SWT.NONE);\r
-        label.setText("Number of values:");\r
-        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
-\r
-\r
-        TrackedText numValues = new TrackedText(parameterProperties, parameterSupport, SWT.BORDER);\r
-        numValues.setTextFactory(new IntegerPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_numberOfValues));\r
-        numValues.addModifyListener(new IntegerPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_numberOfValues));\r
-        numValues.setInputValidator(new IntegerValidator());\r
-        numValues.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), numValues.getWidget())));\r
-        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).hint(80, SWT.DEFAULT).applyTo(numValues.getWidget());\r
-        \r
         label = new Label(parameterProperties, SWT.NONE);\r
         label.setText("Distribution:");\r
         GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
@@ -363,7 +371,6 @@ public class SensitivityAnalysisExperimentTab extends LabelPropertyTabContributo
                 Resource parameter = GraphUtils.create2(graph, sr.SensitivityAnalysisExperiment_Parameter,\r
                         sr.SensitivityAnalysisExperiment_Parameter_propabilityDistribution, distribution,\r
                         sr.SensitivityAnalysisExperiment_Parameter_variable, "<Write variable name>",\r
-                        sr.SensitivityAnalysisExperiment_Parameter_numberOfValues, 10,\r
                         L0.PartOf, input);\r
                 \r
                 Resource parameterList = graph.getPossibleObject(input, sr.SensitivityAnalysisExperiment_parameterList);\r
index 87984f7e13acf99e22deb11c5aea3a1124f1ac77..fd67dc8b340bf86a518cfeab62894ceeeafa19fb 100644 (file)
@@ -8,6 +8,7 @@
  *\r
  * Contributors:\r
  *     Semantum Oy - initial API and implementation\r
+ *     VTT Technical Research Centre of Finland\r
  *******************************************************************************/\r
 package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
 \r
@@ -33,7 +34,6 @@ public class ParameterLabelRule implements LabelRule {
         HashMap<String, String> result = new HashMap<String, String>();\r
         \r
         String variable = graph.getPossibleRelatedValue((Resource)content, SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_variable);\r
-        Integer n = graph.getPossibleRelatedValue((Resource)content, SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_numberOfValues);\r
         \r
         StringBuilder sb = new StringBuilder();\r
         \r
@@ -42,15 +42,6 @@ public class ParameterLabelRule implements LabelRule {
         else\r
             sb.append("No variable");\r
         \r
-        sb.append(" (n=");\r
-        \r
-        if(n != null)\r
-            sb.append(n);\r
-        else\r
-            sb.append("undefined");\r
-        \r
-        sb.append(")");\r
-        \r
         result.put(ColumnKeys.SINGLE, sb.toString()) ;\r
         \r
         return result;\r
index 8a6b8c31888557676d14d89a245461e642f20c62..760ed446bed467c71726ae9047706866a33d58b4 100644 (file)
@@ -8,26 +8,20 @@
  *\r
  * Contributors:\r
  *     Semantum Oy - initial API and implementation\r
+ *     VTT Technical Research Centre of Finland\r
  *******************************************************************************/\r
 package org.simantics.sysdyn.adapter.distribution;\r
 \r
 public interface IDistribution {\r
-    \r
-    /**\r
-     * Return next value of the distribution\r
-     * @return\r
-     */\r
-    public double next();\r
-    \r
+\r
     /**\r
+     * Map a probability to the random variable.\r
+     * When random numbers are used to generate the Monte Carlo simulation parameters, the probability\r
+     * is itself selected randomly (between (0,1); at the domain endpoints the value is undefined).\r
      * \r
-     * @return does the distribution have next value;\r
+     * @param randomVariable\r
+     * @return Inverse cumulative distribution function at probability, i.e. the random variable at the\r
+     * point where the cumulative distribution function yields probability.\r
      */\r
-    public boolean hasNext();\r
-    \r
-    /**\r
-     * Initialize distribution\r
-     */\r
-    public void initialize();\r
-\r
+    public double inverseCDF(double probability);\r
 }\r
index 3def0d33864783d3971db0072778ca98578d4bf9..39fd8760d541ab0bee2ca26ac78fd8649edb0e5b 100644 (file)
@@ -8,11 +8,10 @@
  *\r
  * Contributors:\r
  *     Semantum Oy - initial API and implementation\r
+ *     VTT Technical Research Centre of Finland\r
  *******************************************************************************/\r
 package org.simantics.sysdyn.adapter.distribution;\r
 \r
-import java.util.Random;\r
-\r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
@@ -22,13 +21,10 @@ import org.simantics.sysdyn.SysdynResource;
 \r
 public class Interval implements IDistribution {\r
     \r
-    private Random random;\r
-    \r
     private double min = 0;\r
     private double max = 10;\r
     private double intervalLength = 1;\r
     private int numberOfValues = 10;\r
-    private int seed = 123;\r
     private int index = 0;\r
     \r
     public Interval(ReadGraph graph, Resource distribution) {\r
@@ -43,38 +39,20 @@ public class Interval implements IDistribution {
             Double maxValue = graph.getPossibleRelatedValue(distribution, SR.Interval_maxValue, Bindings.DOUBLE);\r
             if(maxValue != null)\r
                 this.max = maxValue;\r
-            \r
-            \r
+                        \r
             Resource parameter = graph.getPossibleObject(distribution, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse);\r
+           \r
+            Resource experiment = graph.getPossibleObject(parameter, Layer0.getInstance(graph).PartOf);\r
 \r
-            Integer numberOfValues = graph.getPossibleRelatedValue(parameter, SR.SensitivityAnalysisExperiment_Parameter_numberOfValues, Bindings.INTEGER);\r
+            Integer numberOfValues = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_numberOfValues, Bindings.INTEGER);\r
             if(numberOfValues != null)\r
                 this.numberOfValues = numberOfValues;\r
             \r
             intervalLength = (maxValue - minValue) / (this.numberOfValues - 1);\r
             \r
-            Resource experiment = graph.getPossibleObject(parameter, Layer0.getInstance(graph).PartOf);\r
-\r
-            Integer seed =  graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_randomSeed, Bindings.INTEGER);\r
-            if(seed != null)\r
-                this.seed = seed;\r
-            \r
         } catch (DatabaseException e) {\r
 \r
         }\r
-        \r
-        initialize();\r
-    }\r
-    \r
-    @Override\r
-    public double next() {\r
-      double value = min + (intervalLength * index);\r
-      index++;\r
-      return value;\r
-    }\r
-\r
-    public Random getRandom() {\r
-        return random;\r
     }\r
 \r
     public double getMin() {\r
@@ -89,23 +67,18 @@ public class Interval implements IDistribution {
         return numberOfValues;\r
     }\r
 \r
-    public int getSeed() {\r
-        return seed;\r
-    }\r
-    \r
     public double getIntervalLength() {\r
         return intervalLength;\r
     }\r
 \r
-    @Override\r
-    public void initialize() {\r
-        random = new Random(this.seed);\r
-        index = 0;\r
-    }\r
-\r
-    @Override\r
-    public boolean hasNext() {\r
-        return index < numberOfValues;\r
-    }\r
+       @Override\r
+       public double inverseCDF(double probability) {\r
+               // This is a bit awkward...\r
+           double value = min + (intervalLength * index);\r
+           index++;\r
+           if (index >= numberOfValues)\r
+               index = 0;\r
+           return value;\r
+       }\r
     \r
 }\r
index efa2ad1b0f571c0a3b9de7f556191b1be7bfcd7d..7887a62a61e885d533531ecaf412dc1670b62d11 100644 (file)
@@ -8,37 +8,30 @@
  *\r
  * Contributors:\r
  *     Semantum Oy - initial API and implementation\r
+ *     VTT Technical Research Centre of Finland\r
  *******************************************************************************/\r
 package org.simantics.sysdyn.adapter.distribution;\r
 \r
 \r
-import java.util.Random;\r
-\r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.layer0.Layer0;\r
 import org.simantics.sysdyn.SysdynResource;\r
 \r
 public class NormalDistribution implements IDistribution {\r
-    \r
-    private Random random;\r
-    \r
+\r
     private Double min = null;\r
     private Double max = null;\r
+    private double minProbability = 0;\r
+    private double maxProbability = 1;\r
     private double mean;\r
     private double stdDeviation;  \r
-    private int numberOfValues = 10;\r
-    private int seed = 123;\r
-    private int index = 0;\r
-    \r
-    private static int MAX_TRIES = 100;\r
-\r
     \r
     public NormalDistribution(ReadGraph graph, Resource distribution) {\r
 \r
         try {\r
+\r
             SysdynResource SR = SysdynResource.getInstance(graph);\r
 \r
             min = graph.getPossibleRelatedValue(distribution, SR.NormalDistribution_minValue, Bindings.DOUBLE);\r
@@ -46,66 +39,17 @@ public class NormalDistribution implements IDistribution {
             stdDeviation = graph.getPossibleRelatedValue(distribution, SR.NormalDistribution_stdDeviation, Bindings.DOUBLE);\r
             mean = graph.getPossibleRelatedValue(distribution, SR.NormalDistribution_mean, Bindings.DOUBLE);\r
             \r
-            \r
-            Resource parameter = graph.getPossibleObject(distribution, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse);\r
+               // Determine the max and min probabilities.\r
+            if (min != null)\r
+               minProbability = cdf(min, mean, stdDeviation, false);\r
+            if (max != null)\r
+               maxProbability = cdf(max, mean, stdDeviation, false);\r
 \r
-            Integer numberOfValues = graph.getPossibleRelatedValue(parameter, SR.SensitivityAnalysisExperiment_Parameter_numberOfValues, Bindings.INTEGER);\r
-            if(numberOfValues != null)\r
-                this.numberOfValues = numberOfValues;\r
-            \r
-\r
-            \r
-            Resource experiment = graph.getPossibleObject(parameter, Layer0.getInstance(graph).PartOf);\r
-\r
-            Integer seed =  graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_randomSeed, Bindings.INTEGER);\r
-            if(seed != null)\r
-                this.seed = seed;\r
-            \r
-            \r
-            random = new Random(this.seed);\r
-            \r
         } catch (DatabaseException e) {\r
 \r
         }\r
     }\r
     \r
-    @Override\r
-    public double next() {\r
-\r
-        /* Try to find value between min and max, if they are defined.\r
-         * If value cannot be found after MAX_TRIES number of tries,\r
-         * return the last try. \r
-         */\r
-        double value = 0;\r
-        for(int i = 0; i < MAX_TRIES; i++) {\r
-            value = random.nextGaussian() * stdDeviation + mean;\r
-            if(accept(value))\r
-                break;\r
-        }\r
-        \r
-        index++;\r
-        return value;\r
-    }\r
-    \r
-    \r
-    private boolean accept(double value) {\r
-        if(min != null) {\r
-            if(value < min)\r
-                return false;\r
-        }\r
-        \r
-        if(max != null) {\r
-            if(value > max)\r
-                return false;\r
-        }\r
-        \r
-        return true;\r
-    }\r
-    \r
-    public Random getRandom() {\r
-        return random;\r
-    }\r
-\r
     public double getMin() {\r
         return min;\r
     }\r
@@ -113,25 +57,348 @@ public class NormalDistribution implements IDistribution {
     public double getMax() {\r
         return max;\r
     }\r
+    \r
+       @Override\r
+       public double inverseCDF(double probability) {\r
+               // Map probability to [min,max]\r
+               double mappedProbability = minProbability + (maxProbability - minProbability) * probability;\r
+               // Calculate the inverse CDF\r
+               return quantile(mappedProbability, mean, stdDeviation);\r
+       }\r
 \r
-    public int getNumberOfValues() {\r
-        return numberOfValues;\r
-    }\r
-\r
-    public int getSeed() {\r
-        return seed;\r
+    //The following is from BEAST-MCMC (https://code.google.com/p/beast-mcmc/)\r
+    \r
+    /*\r
+     * NormalDistribution.java\r
+     *\r
+     * Copyright (c) 2002-2011 Alexei Drummond, Andrew Rambaut and Marc Suchard\r
+     *\r
+     * This file is part of BEAST.\r
+     * See the NOTICE file distributed with this work for additional\r
+     * information regarding copyright ownership and licensing.\r
+     *\r
+     * BEAST is free software; you can redistribute it and/or modify\r
+     * it under the terms of the GNU Lesser General Public License as\r
+     * published by the Free Software Foundation; either version 2\r
+     * of the License, or (at your option) any later version.\r
+     *\r
+     *  BEAST is distributed in the hope that it will be useful,\r
+     *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+     *  GNU Lesser General Public License for more details.\r
+     *\r
+     * You should have received a copy of the GNU Lesser General Public\r
+     * License along with BEAST; if not, write to the\r
+     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,\r
+     * Boston, MA  02110-1301  USA\r
+     */\r
+    \r
+    /**\r
+     * quantiles (=inverse cumulative density function)\r
+     *\r
+     * @param z  argument\r
+     * @param m  mean\r
+     * @param sd standard deviation\r
+     * @return icdf at z\r
+     */\r
+    public static double quantile(double z, double m, double sd) {\r
+        return m + Math.sqrt(2.0) * sd * inverseErf(2.0 * z - 1.0);\r
     }\r
     \r
+    /** A more accurate and faster implementation of the cdf (taken from function pnorm in the R statistical language)\r
+     * This implementation has discrepancies depending on the programming language and system architecture\r
+     * In Java, returned values become zero once z reaches -37.5193 exactly on the machine tested\r
+     * In the other implementation, the returned value 0 at about z = -8\r
+     * In C, this 0 value is reached approximately z = -37.51938\r
+     *\r
+     * Will later need to be optimised for BEAST\r
+     *\r
+     * @param x     argument\r
+     * @param mu    mean\r
+     * @param sigma standard deviation\r
+     * @param log_p is p logged\r
+     * @return cdf at x\r
+     */\r
+    public static double cdf(double x, double mu, double sigma, boolean log_p) {\r
+        boolean i_tail=false;\r
+        double p, cp = Double.NaN;\r
 \r
-    @Override\r
-    public void initialize() {\r
-        random = new Random(this.seed);\r
-        index = 0;\r
-    }\r
+        if(Double.isNaN(x) || Double.isNaN(mu) || Double.isNaN(sigma)) {\r
+            return Double.NaN;\r
+        }\r
+        if(Double.isInfinite(x) && mu == x) { /* x-mu is NaN */\r
+            return Double.NaN;\r
+        }\r
+        if (sigma <= 0) {\r
+            if(sigma < 0) {\r
+                return Double.NaN;\r
+            }\r
+            return (x < mu) ? 0.0 : 1.0;\r
+        }\r
+        p = (x - mu) / sigma;\r
+        if(Double.isInfinite(p)) {\r
+            return (x < mu) ? 0.0 : 1.0;\r
+        }\r
+        x = p;\r
+        if(Double.isNaN(x)) {\r
+            return Double.NaN;\r
+        }\r
+\r
+        double xden, xnum, temp, del, eps, xsq, y;\r
+        int i;\r
+        boolean lower, upper;\r
+        eps = DBL_EPSILON * 0.5;\r
+        lower = !i_tail;\r
+        upper = i_tail;\r
+\r
+        y = Math.abs(x);\r
+        if (y <= 0.67448975) { /* Normal.quantile(3/4, 1, 0) = 0.67448975 */\r
+            if (y > eps) {\r
+                xsq = x * x;\r
+                xnum = a[4] * xsq;\r
+                xden = xsq;\r
+                for (i = 0; i < 3; i++) {\r
+                    xnum = (xnum + a[i]) * xsq;\r
+                    xden = (xden + b[i]) * xsq;\r
+                }\r
+            }\r
+            else {\r
+                xnum = xden = 0.0;\r
+            }\r
+            temp = x * (xnum + a[3]) / (xden + b[3]);\r
+            if(lower) {\r
+                p = 0.5 + temp;\r
+            }\r
+            if(upper) {\r
+                cp = 0.5 - temp;\r
+            }\r
+            if(log_p) {\r
+                if(lower) {\r
+                    p = Math.log(p);\r
+                }\r
+                if(upper) {\r
+                    cp = Math.log(cp);\r
+                }\r
+            }\r
+        }\r
+\r
+\r
+        else if (y <= M_SQRT_32) {\r
+            /* Evaluate pnorm for 0.67448975 = Normal.quantile(3/4, 1, 0) < |x| <= sqrt(32) ~= 5.657 */\r
+\r
+            xnum = c[8] * y;\r
+            xden = y;\r
+            for (i = 0; i < 7; i++) {\r
+                xnum = (xnum + c[i]) * y;\r
+                xden = (xden + d[i]) * y;\r
+            }\r
+            temp = (xnum + c[7]) / (xden + d[7]);\r
+\r
+            //do_del(y);\r
+            //swap_tail;\r
+            //#define do_del(X)                                                 \\r
+            xsq = ((int) (y * CUTOFF)) * 1.0 / CUTOFF;\r
+            del = (y - xsq) * (y + xsq);\r
+            if(log_p) {\r
+                p = (-xsq * xsq * 0.5) + (-del * 0.5) + Math.log(temp);\r
+                if((lower && x > 0.0) || (upper && x <= 0.0)) {\r
+                    cp = Math.log(1.0-Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp);\r
+                }\r
+            }\r
+            else {\r
+                p = Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp;\r
+                cp = 1.0 - p;\r
+            }\r
+            //#define swap_tail                                         \\r
+            if (x > 0.0) {\r
+                temp = p;\r
+                if(lower) {\r
+                    p = cp;\r
+                }\r
+                cp = temp;\r
+            }\r
+        }\r
+        /* else   |x| > sqrt(32) = 5.657 :\r
+         * the next two case differentiations were really for lower=T, log=F\r
+         * Particularly  *not*  for  log_p !\r
+         * Cody had (-37.5193 < x  &&  x < 8.2924) ; R originally had y < 50\r
+         * Note that we do want symmetry(0), lower/upper -> hence use y\r
+         */\r
+        else if(log_p || (lower && -37.5193 < x  &&  x < 8.2924)\r
+                || (upper && -8.2924  < x  &&  x < 37.5193)) {\r
+\r
+            /* Evaluate pnorm for x in (-37.5, -5.657) union (5.657, 37.5) */\r
+            xsq = 1.0 / (x * x);\r
+            xnum = p_[5] * xsq;\r
+            xden = xsq;\r
+            for (i = 0; i < 4; i++) {\r
+                xnum = (xnum + p_[i]) * xsq;\r
+                xden = (xden + q[i]) * xsq;\r
+            }\r
+            temp = xsq * (xnum + p_[4]) / (xden + q[4]);\r
+            temp = (M_1_SQRT_2PI - temp) / y;\r
+\r
+            //do_del(x);\r
+            xsq = ((int) (x * CUTOFF)) * 1.0 / CUTOFF;\r
+            del = (x - xsq) * (x + xsq);\r
+            if(log_p) {\r
+                p = (-xsq * xsq * 0.5) + (-del * 0.5) + Math.log(temp);\r
+                if((lower && x > 0.0) || (upper && x <= 0.0)) {\r
+                    cp = Math.log(1.0-Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp);\r
+                }\r
+            }\r
+            else {\r
+                p = Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp;\r
+                cp = 1.0 - p;\r
+            }\r
+            //swap_tail;\r
+            if (x > 0.0) {\r
+                temp = p;\r
+                if(lower) {\r
+                    p = cp;\r
+                }\r
+                cp = temp;\r
+            }\r
+        }\r
+        else { /* no log_p , large x such that probs are 0 or 1 */\r
+            if(x > 0) {\r
+                p = 1.0;\r
+                cp = 0.0;\r
+            }\r
+            else {\r
+                p = 0.0;\r
+                cp = 1.0;\r
+            }\r
+        }\r
+        return p;\r
 \r
-    @Override\r
-    public boolean hasNext() {\r
-        return index < numberOfValues;\r
     }\r
 \r
+    // Private\r
+\r
+    protected double m, sd;\r
+\r
+    private static final double[] a = {\r
+            2.2352520354606839287,\r
+            161.02823106855587881,\r
+            1067.6894854603709582,\r
+            18154.981253343561249,\r
+            0.065682337918207449113\r
+    };\r
+    private static final double[] b = {\r
+            47.20258190468824187,\r
+            976.09855173777669322,\r
+            10260.932208618978205,\r
+            45507.789335026729956\r
+    };\r
+    private static final double[] c = {\r
+            0.39894151208813466764,\r
+            8.8831497943883759412,\r
+            93.506656132177855979,\r
+            597.27027639480026226,\r
+            2494.5375852903726711,\r
+            6848.1904505362823326,\r
+            11602.651437647350124,\r
+            9842.7148383839780218,\r
+            1.0765576773720192317e-8\r
+    };\r
+    private static final double[] d = {\r
+            22.266688044328115691,\r
+            235.38790178262499861,\r
+            1519.377599407554805,\r
+            6485.558298266760755,\r
+            18615.571640885098091,\r
+            34900.952721145977266,\r
+            38912.003286093271411,\r
+            19685.429676859990727\r
+    };\r
+    private static final double[] p_ = {\r
+            0.21589853405795699,\r
+            0.1274011611602473639,\r
+            0.022235277870649807,\r
+            0.001421619193227893466,\r
+            2.9112874951168792e-5,\r
+            0.02307344176494017303\r
+    };\r
+    private static final double[] q = {\r
+            1.28426009614491121,\r
+            0.468238212480865118,\r
+            0.0659881378689285515,\r
+            0.00378239633202758244,\r
+            7.29751555083966205e-5\r
+    };\r
+\r
+    private static final int CUTOFF = 16; /* Cutoff allowing exact "*" and "/" */\r
+\r
+    private static final double M_SQRT_32 = 5.656854249492380195206754896838; /* The square root of 32 */\r
+    private static final double M_1_SQRT_2PI =  0.398942280401432677939946059934;\r
+    private static final double DBL_EPSILON = 2.2204460492503131e-016;\r
+    \r
+    /*\r
+     * ErrorFunction.java\r
+     *\r
+     * Copyright (C) 2002-2006 Alexei Drummond and Andrew Rambaut\r
+     *\r
+     * This file is part of BEAST.\r
+     * See the NOTICE file distributed with this work for additional\r
+     * information regarding copyright ownership and licensing.\r
+     *\r
+     * BEAST is free software; you can redistribute it and/or modify\r
+     * it under the terms of the GNU Lesser General Public License as\r
+     * published by the Free Software Foundation; either version 2\r
+     * of the License, or (at your option) any later version.\r
+     *\r
+     *  BEAST is distributed in the hope that it will be useful,\r
+     *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+     *  GNU Lesser General Public License for more details.\r
+     *\r
+     * You should have received a copy of the GNU Lesser General Public\r
+     * License along with BEAST; if not, write to the\r
+     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,\r
+     * Boston, MA  02110-1301  USA\r
+     */\r
+       \r
+       /**\r
+        * inverse error function\r
+        *\r
+        * @param z argument\r
+        *\r
+        * @return function value\r
+        */\r
+       public static double inverseErf(double z)\r
+       {\r
+               return pointNormal(0.5*z+0.5)/Math.sqrt(2.0);\r
+       }\r
+               \r
+       // Private\r
+       \r
+       // Returns z so that Prob{x<z}=prob where x ~ N(0,1) and (1e-12) < prob<1-(1e-12)\r
+       private static double pointNormal(double prob)\r
+       {\r
+               // Odeh RE & Evans JO (1974) The percentage points of the normal distribution.\r
+               // Applied Statistics 22: 96-97 (AS70)\r
+       \r
+               // Newer methods:\r
+               // Wichura MJ (1988) Algorithm AS 241: the percentage points of the\r
+               // normal distribution.  37: 477-484.\r
+               // Beasley JD & Springer SG  (1977).  Algorithm AS 111: the percentage \r
+               // points of the normal distribution.  26: 118-121.\r
+       \r
+               double a0 = -0.322232431088, a1 = -1, a2 = -0.342242088547, a3 = -0.0204231210245;\r
+               double a4 = -0.453642210148e-4, b0 = 0.0993484626060, b1 = 0.588581570495;\r
+               double b2 = 0.531103462366, b3 = 0.103537752850, b4 = 0.0038560700634;\r
+               double y, z = 0, p = prob, p1;\r
+       \r
+               p1 = (p < 0.5 ? p : 1-p);\r
+               if (p1 < 1e-20)\r
+               {\r
+                       new IllegalArgumentException("Argument prob out of range");\r
+               }\r
+       \r
+               y = Math.sqrt(Math.log(1/(p1*p1)));   \r
+               z = y + ((((y*a4+a3)*y+a2)*y+a1)*y+a0)/((((y*b4+b3)*y+b2)*y+b1)*y+b0);\r
+               return (p < 0.5 ? -z : z);\r
+       }\r
+\r
 }\r
index 68c3e5b2e55d1eb8fd635429772a9644367e9655..fe6d4750e828ee176cc881dc07123ea3e53620cc 100644 (file)
@@ -8,28 +8,20 @@
  *\r
  * Contributors:\r
  *     Semantum Oy - initial API and implementation\r
+ *     VTT Technical Research Centre of Finland\r
  *******************************************************************************/\r
 package org.simantics.sysdyn.adapter.distribution;\r
 \r
-import java.util.Random;\r
-\r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.layer0.Layer0;\r
 import org.simantics.sysdyn.SysdynResource;\r
 \r
 public class UniformDistribution implements IDistribution {\r
     \r
-    \r
-    private Random random;\r
-    \r
     private double min;\r
     private double max;\r
-    private int numberOfValues = 10;\r
-    private int seed = 123;\r
-    private int index = 0;\r
     \r
     public UniformDistribution(ReadGraph graph, Resource distribution) {\r
 \r
@@ -44,29 +36,9 @@ public class UniformDistribution implements IDistribution {
             if(maxValue != null)\r
                 this.max = maxValue;\r
             \r
-            \r
-            Resource parameter = graph.getPossibleObject(distribution, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse);\r
-\r
-            Integer numberOfValues = graph.getPossibleRelatedValue(parameter, SR.SensitivityAnalysisExperiment_Parameter_numberOfValues, Bindings.INTEGER);\r
-            if(numberOfValues != null)\r
-                this.numberOfValues = numberOfValues;\r
-            \r
-\r
-            \r
-            Resource experiment = graph.getPossibleObject(parameter, Layer0.getInstance(graph).PartOf);\r
-\r
-            Integer seed =  graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_randomSeed, Bindings.INTEGER);\r
-            if(seed != null)\r
-                this.seed = seed;\r
-            \r
         } catch (DatabaseException e) {\r
 \r
         }\r
-        initialize();\r
-    }\r
-    \r
-    public Random getRandom() {\r
-        return random;\r
     }\r
 \r
     public double getMin() {\r
@@ -77,34 +49,9 @@ public class UniformDistribution implements IDistribution {
         return max;\r
     }\r
 \r
-    public int getNumberOfValues() {\r
-        return numberOfValues;\r
-    }\r
-\r
-    public int getSeed() {\r
-        return seed;\r
-    }\r
-    \r
-    \r
-\r
-    \r
     @Override\r
-    public double next() {\r
-        index++;\r
-        double d = min + ((double)random.nextInt(101) / 100.0) * (max-min); \r
-        return d;\r
-    }\r
-    \r
-\r
-    @Override\r
-    public void initialize() {\r
-        random = new Random(this.seed);\r
-        index = 0;\r
-    }\r
-\r
-    @Override\r
-    public boolean hasNext() {\r
-        return index < numberOfValues;\r
-    }\r
+       public double inverseCDF(double probability) {\r
+               return min + probability * (max - min); \r
+       }\r
 \r
 }\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/RandomGenerator.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/RandomGenerator.java
new file mode 100644 (file)
index 0000000..d58578b
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.manager;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Random;\r
+\r
+/**\r
+ * Random generator that creates ArrayLists of random Doubles between 0 and 1.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ */\r
+\r
+public class RandomGenerator {\r
+       \r
+    private int seed;\r
+    private int dimension;\r
+    private Random random;\r
+    \r
+       public RandomGenerator(int seed, int dimension) {\r
+               this.dimension = dimension;\r
+        this.seed = seed;\r
+               random = new Random(this.seed);\r
+       }\r
+       \r
+       public ArrayList<Double> next() {\r
+               ArrayList<Double> randoms = new ArrayList<Double>();\r
+               for (int i = 0; i < dimension; ++i)\r
+                       randoms.add(random.nextDouble());\r
+               return randoms;\r
+       }\r
+       \r
+    public void initialize() {\r
+       random = new Random(this.seed);\r
+    }\r
+\r
+}\r
index 432ff044a6bbe529656a7c3eb1bcc5f10b1e5b4a..0273ec9fed230ce0ecd904b946ab2be9c095c8dd 100644 (file)
@@ -44,32 +44,57 @@ import org.simantics.sysdyn.adapter.SensitivityExperimentParameter;
  */\r
 public class SysdynSensitivityAnalysisExperiment extends SysdynExperiment {\r
 \r
-    \r
-\r
     private ArrayList<MemoryResult> results = null;\r
-\r
+    private int seed = 124;\r
+       private int numberOfRuns = 0;\r
+       \r
     public SysdynSensitivityAnalysisExperiment(Resource experiment, Resource model) {\r
         super(experiment, model);\r
     }\r
     \r
-    \r
     private void findValuesAndRun(List<SensitivityExperimentParameter> parameters, HashMap<String, String> values, HashMap<String, String> experimentParameters) {\r
-        findValuesAndRun(parameters, 0, values, experimentParameters);\r
-    }\r
-    \r
-    private void findValuesAndRun(List<SensitivityExperimentParameter> parameters, int index, HashMap<String, String> values, HashMap<String, String> experimentParameters) {\r
-        SensitivityExperimentParameter p = parameters.get(index);\r
+       ArrayList<HashMap<String, String>> parameterMaps = new ArrayList<HashMap<String, String>>();\r
+       int parametersSize = parameters.size();\r
+\r
+       // Get seed\r
+        try {\r
+                       session.syncRequest(new ReadRequest() {\r
+                           @Override\r
+                           public void run(ReadGraph graph) throws DatabaseException {\r
+                               SysdynResource SR = SysdynResource.getInstance(graph);\r
+                               seed = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_randomSeed, Bindings.INTEGER);\r
+                               numberOfRuns = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_numberOfValues, Bindings.INTEGER);\r
+                               //refreshRate = numberOfRuns / 20 + 1;\r
+                               refreshRate = 1;\r
+                           }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
         \r
-        while(p.getDistribution().hasNext()) {\r
-            values.put(p.getFullName(), Double.toString(p.getDistribution().next()));\r
-            if((index + 1) < parameters.size()) {\r
-                findValuesAndRun(parameters, index + 1, values, experimentParameters);\r
-            } else {\r
-                // Run with values\r
-                runSensitivityRun(values, experimentParameters);\r
-            }\r
-        }\r
-        p.getDistribution().initialize();\r
+        // Generate values for parameters (randomly)\r
+       RandomGenerator randomGenerator = new RandomGenerator(seed, parametersSize);\r
+       \r
+       // Determine the changed paramters and their values for each individual run\r
+       for (int i = 0; i < numberOfRuns; ++i) {\r
+               ArrayList<Double> randoms = randomGenerator.next();// multi-dimensional random\r
+               HashMap<String, String> parameterMap = new HashMap<String, String>(parametersSize);\r
+               for (int j = 0; j < parametersSize; ++j) {\r
+                       SensitivityExperimentParameter p = parameters.get(j);\r
+                       // Get the random value\r
+                       double value = p.getDistribution().inverseCDF(randoms.get(j));\r
+                       // Add the new parameter-value-pair \r
+                       parameterMap.put(p.getFullName(), Double.toString(value));\r
+               }\r
+               // Add the complete list of one individual run parameter-value-pairs.\r
+               parameterMaps.add(parameterMap);\r
+       }\r
+               \r
+       // Set the parameters for each individual experiment and run them.\r
+       for (HashMap<String, String> parameterSet : parameterMaps) {\r
+               values.putAll(parameterSet);\r
+               runSensitivityRun(values, experimentParameters);\r
+       }\r
     }\r
     \r
     private void runSensitivityRun(HashMap<String, String> values, HashMap<String, String> experimentParameters) {\r
@@ -97,7 +122,8 @@ public class SysdynSensitivityAnalysisExperiment extends SysdynExperiment {
         ModelicaManager.printProcessOutput(process, monitor);\r
 \r
         File resFile = new File(experimentParameters.get(ModelicaManager.RESULT_FILE_NAME));\r
-        Thread resultThread = getResultThread(resFile, experimentParameters, monitor, progressMonitor, currentRun % refreshRate == 0);\r
+        boolean updateMonitors = currentRun % refreshRate == 0 || currentRun == numberOfRuns - 1;\r
+        Thread resultThread = getResultThread(resFile, experimentParameters, monitor, progressMonitor, updateMonitors);\r
         resultThread.run();\r
 \r
         process = null;\r
@@ -111,7 +137,6 @@ public class SysdynSensitivityAnalysisExperiment extends SysdynExperiment {
     private IModelicaMonitor monitor;\r
     private IProgressMonitor progressMonitor;\r
 //    private HashMap<String, String> experimentParameters;\r
-    private int numberOfRuns = 0;\r
     private int currentRun = 0;\r
     private int refreshRate = 1;\r
     private List<SensitivityExperimentParameter> parameters = new ArrayList<SensitivityExperimentParameter>();\r
@@ -293,21 +318,7 @@ public class SysdynSensitivityAnalysisExperiment extends SysdynExperiment {
                 @Override\r
                 public Integer perform(ReadGraph graph) throws DatabaseException {\r
                     SysdynResource SR = SysdynResource.getInstance(graph);\r
-                    \r
-                    Resource parameterListResource = graph.getPossibleObject(experiment, SR.SensitivityAnalysisExperiment_parameterList);\r
-                    List<Resource> parameterResources = ListUtils.toList(graph, parameterListResource);\r
-                    \r
-                    Integer numberOfIterations = null;\r
-                    \r
-                    for(Resource parameter : parameterResources) {\r
-                        Integer n = graph.getPossibleRelatedValue(parameter, SR.SensitivityAnalysisExperiment_Parameter_numberOfValues, Bindings.INTEGER);\r
-                        if(n != null) {\r
-                            if(numberOfIterations == null)\r
-                                numberOfIterations = n;\r
-                            else\r
-                                numberOfIterations = numberOfIterations * n;\r
-                        } \r
-                    }\r
+                    Integer numberOfIterations = graph.getPossibleRelatedValue(experiment, SR.SensitivityAnalysisExperiment_numberOfValues, Bindings.INTEGER);\r
                     \r
                     return numberOfIterations;\r
                 }\r