*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import gnu.trove.list.array.TIntArrayList;\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+\r
import java.util.ArrayList;\r
import java.util.Collection;\r
import java.util.HashMap;\r
+import java.util.HashSet;\r
import java.util.Iterator;\r
import java.util.Map;\r
+import java.util.Set;\r
import java.util.TreeMap;\r
\r
interface Fn {\r
public int size;\r
\r
public Object[] valueTable;\r
+ \r
+ public TObjectIntHashMap<String> keyIndexMap = new TObjectIntHashMap<String>(); \r
\r
HashMap<String,TreeMap<Double,Double>> history = new HashMap<String,TreeMap<Double,Double>>();\r
\r
return;\r
}\r
\r
+ String prefix2 = prefix;\r
+ if(d== 0) prefix2 += "[";\r
+ if(d>0) prefix2 += ",";\r
+\r
for(int i=0;i<dimensions[d];i++) {\r
- String prefix2 = prefix + "[" + i + "]";\r
- addIndexed(dimensions, keys, prefix2, d+1);\r
+ String prefix3 = prefix2 + (i+1);\r
+ if(d+1 == dimensions.length) prefix3 += "]";\r
+ addIndexed(dimensions, keys, prefix3, d+1);\r
}\r
\r
}\r
\r
- public void addVariable(String name, int[] dimensions, ArrayList<String> keys) {\r
+ public int length(int[] dimension) {\r
+ int result = 1;\r
+ for(int d : dimension) result *=d;\r
+ return result;\r
+ }\r
+ \r
+ public void addVariable(String name, int index, int[] dimensions, ArrayList<String> keys, TIntArrayList indices, Set<String> used) {\r
\r
-// int dimensions[] = base.dimensions;\r
+ if(!used.add(name)) return;\r
+ \r
if(dimensions == null) {\r
keys.add(name);\r
+ indices.add(index);\r
} else {\r
addIndexed(dimensions, keys, name, 0);\r
+ for(int i=0;i<length(dimensions);i++)\r
+ indices.add(index+i);\r
}\r
\r
}\r
\r
- public void addVariable(Variable var, ArrayList<String> keys) {\r
- addVariable(var.base.name, var.base.dimensions, keys);\r
+ public void addVariable(Variable var, ArrayList<String> keys, TIntArrayList indices, Set<String> used) {\r
+ addVariable(var.base.name, var.base.index, var.base.dimensions, keys, indices, used);\r
}\r
\r
public String[] getValueKeyArray() {\r
\r
ArrayList<String> keys = new ArrayList<String>();\r
+ TIntArrayList indices = new TIntArrayList();\r
+ Set<String> used = new HashSet<String>();\r
\r
for (int i = 0; i < model.assignmentArray.length; i++) {\r
- addVariable(model.assignmentArray[i].target, keys);\r
+ addVariable(model.assignmentArray[i].target, keys, indices, used);\r
}\r
\r
for (int i = 0; i < model.derivativeArray.length; i++) {\r
- addVariable(model.derivativeArray[i].target, keys);\r
+ addVariable(model.derivativeArray[i].target, keys, indices, used);\r
}\r
\r
// NOTE: there is room for optimization as parameter values that do not\r
// change should only be obtained once (and parameter values that do\r
// change are (possibly) included in assignments or derivatives)\r
for(int i = 0; i < model.parameterArray.length; i++) {\r
- addVariable(model.parameterArray[i].variable, keys);\r
+ addVariable(model.parameterArray[i].variable, keys, indices, used);\r
}\r
\r
for(Map.Entry<String,VariableBase> entry : model.copies.entrySet()) {\r
- addVariable(entry.getKey(), entry.getValue().dimensions, keys);\r
+ addVariable(entry.getKey(), entry.getValue().index, entry.getValue().dimensions, keys, indices, used);\r
}\r
-\r
+ \r
valueArray = new double[keys.size()];\r
\r
+ keyIndexMap.clear();\r
+ for(int i=0;i<keys.size();i++) {\r
+ String key = keys.get(i);\r
+ int index = indices.get(i);\r
+ keyIndexMap.put(key, index);\r
+ }\r
+ \r
return keys.toArray(new String[keys.size()]);\r
\r
}\r
public double[] getValueArray() {\r
\r
int offset = 0;\r
- \r
+\r
+ Set<String> used = new HashSet<String>();\r
+\r
for (int i = 0; i < model.assignmentArray.length; i++) {\r
Variable v = model.assignmentArray[i].target;\r
+ if(!used.add(v.base.name)) continue;\r
for(int index=0;index<v.base.dimension();index++)\r
valueArray[offset++] = (Double)getValue(v.base.index(this, null)+index);\r
}\r
\r
for (int i = 0; i < model.derivativeArray.length; i++) {\r
Variable v = model.derivativeArray[i].target;\r
+ if(!used.add(v.base.name)) continue;\r
for(int index=0;index<v.base.dimension();index++)\r
valueArray[offset++] = (Double)getValue(v.base.index(this, null)+index);\r
}\r
// change are (possibly) included in assignments or derivatives)\r
for(int i = 0; i < model.parameterArray.length; i++) {\r
Variable v = model.parameterArray[i].variable;\r
+ if(!used.add(v.base.name)) continue;\r
for(int index=0;index<v.base.dimension();index++)\r
valueArray[offset++] = (Double)getValue(v.base.index(this, null)+index);\r
}\r
\r
for(Map.Entry<String,VariableBase> entry : model.copies.entrySet()) {\r
VariableBase base = entry.getValue();\r
+ if(!used.add(base.name)) continue;\r
for(int index=0;index<base.dimension();index++)\r
valueArray[offset++] = (Double)getValue(base.index(this, null)+index);\r
}\r
return named.get(key);\r
}\r
\r
+ public void setValue(String key, double value) {\r
+ int index = keyIndexMap.get(key);\r
+ put(index, value);\r
+ }\r
+ \r
}\r
\r
public class Solver {\r
\r
- private static final boolean PRINT_EXCEPTIONS = false; \r
+ private static final boolean PRINT_EXCEPTIONS = true; \r
private static final int STACK_SIZE = 1000;\r
\r
private Model model;\r
}\r
\r
public void setStep(double step) {\r
+ \r
+ new Exception().printStackTrace();\r
+ \r
this.step = step;\r
- ready = false;\r
+ \r
}\r
\r
public void setStart(double start) {\r
+ \r
+ new Exception().printStackTrace();\r
+\r
this.start = start;\r
ready = false;\r
}\r
\r
ready = true;\r
\r
+ System.err.println("prepared " + this);\r
+ \r
long endNanos = System.nanoTime();\r
\r
System.err.println("Prepared model in " + 1e-6*(endNanos-startNanos) + "ms.");\r
return env.getValueArray();\r
}\r
\r
- \r
- \r
public void step() {\r
+ \r
+ printEnvironment();\r
+ \r
+ new Exception().printStackTrace();\r
+\r
// TODO: do something more sensible if the solver is not ready\r
if (!ready) return;\r
\r
// Increment time\r
// should probably be wrapped inside a method or something\r
env.time += env.step;\r
-\r
+ \r
+ VariableBase base = model.names.get("time");\r
+ if(base != null) {\r
+ env.put(base.index, env.time);\r
+ }\r
+ \r
// Next solve algebraic equations\r
for(int i=0;i<assignments.length;i++) {\r
Object value = assignments[i].expression.evaluate(env);\r
}\r
}\r
\r
+ public double getTime() {\r
+ return env.time;\r
+ }\r
+ \r
+ public void setValue(String key, double value) {\r
+ env.setValue(key, value);\r
+ }\r
+ \r
}\r