Double d2 = (Double)exp2.evaluate(environment);\r
return d1 + d2;\r
}\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Addition(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
\r
}\r
for(IExpression e : exps) \r
if(!(Boolean)e.evaluate(environment)) return false;\r
return true;\r
- } \r
+ }\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ ArrayList<IExpression> ne = new ArrayList<IExpression>();\r
+ for(IExpression e : exps) ne.add(e.withBase(frame, prefix));\r
+ return new And(ne);\r
+ }\r
+\r
+ \r
}\r
return environment.getSystem().evaluateFunction(environment, name, args);\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Application(name, args.withBase(frame, prefix));\r
+ }\r
+ \r
}\r
throw new UnsupportedOperationException();\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Argument(name, modification.withBase(frame, prefix));\r
+ }\r
+ \r
}\r
public class ArgumentList {\r
\r
public ArrayList<Argument> args;\r
+ public String op;\r
\r
public ArgumentList(ArrayList<Argument> args) {\r
this.args = args;\r
+ this.op = "";\r
}\r
\r
- public ArgumentList() {\r
+ public ArgumentList(ArrayList<Argument> args, String op) {\r
+ this.args = args;\r
+ this.op = op;\r
+ }\r
+\r
+ public ArgumentList(String op) {\r
this.args = new ArrayList<Argument>();\r
+ this.op = op;\r
}\r
\r
@Override\r
return b.toString();\r
}\r
\r
+ public ArgumentList withBase(IFrame frame, String prefix) {\r
+ ArrayList<Argument> a2 = new ArrayList<Argument>();\r
+ for(Argument a : args) a2.add((Argument)a.withBase(frame, prefix));\r
+ return new ArgumentList(a2, op);\r
+ }\r
+ \r
}\r
for(int i=0;i<needed;i++) addElement(subArray ? new Array() : null);\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ Array result = new Array();\r
+ for(Object o : elements) {\r
+ if(o instanceof Array) {\r
+ result.addElement(((Array)o).withBase(frame, prefix));\r
+ } else {\r
+ if(o instanceof IExpression) {\r
+ IExpression exp = (IExpression)o;\r
+ result.addElement(exp.withBase(frame, prefix));\r
+ } else {\r
+ result.addElement(o);\r
+ }\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+ \r
}\r
return result;\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new ArraySliceExpression(start.withBase(frame, prefix), end.withBase(frame, prefix));\r
+ }\r
+ \r
}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import org.omg.PortableInterceptor.SUCCESSFUL;\r
+\r
public class Assignment {\r
\r
public Variable target;\r
+ public IExpression[] subscripts;\r
public IExpression expression;\r
public boolean assigned = false;\r
\r
- public Assignment(Variable target, IExpression expression) {\r
+ public Assignment(Variable target, IExpression[] subscripts, IExpression expression) {\r
this.target = target;\r
+ this.subscripts = subscripts;\r
this.expression = expression;\r
}\r
\r
return target + " = " + expression;\r
}\r
\r
+ public Assignment withBase(IFrame frame, String prefix) {\r
+ if(subscripts != null) {\r
+ IExpression[] subscripts2 = new IExpression[subscripts.length];\r
+ for(int i=0;i<subscripts.length;i++)\r
+ subscripts2[i] = subscripts[i].withBase(frame, prefix);\r
+ return new Assignment(target.withBase(frame, prefix), subscripts2, expression.withBase(frame, prefix));\r
+ } else {\r
+ return new Assignment(target.withBase(frame, prefix), null, expression.withBase(frame, prefix));\r
+ }\r
+ }\r
+ \r
}\r
return value;\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return this;\r
+ }\r
+ \r
}\r
+\r
throw new UnsupportedOperationException();\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+ \r
}\r
public class Derivate implements IExpression {\r
\r
private Variable variable;\r
+ private IExpression[] subscripts;\r
private IExpression e;\r
\r
- public Derivate(Variable variable, IExpression e) {\r
+ public Derivate(Variable variable, IExpression[] subscripts, IExpression e) {\r
this.variable = variable;\r
+ this.subscripts = subscripts;\r
this.e = e;\r
}\r
\r
public Object evaluate(IEnvironment _environment) {\r
Environment environment = (Environment)_environment;\r
// Double old = (Double)environment.getValue(variable.name + variable.subscriptKey());\r
- Double old = (Double)environment.getValue(variable.index(_environment));\r
+ Double old = (Double)environment.getValue(variable.index(_environment, subscripts));\r
return old+environment.step*(Double)e.evaluate(environment);\r
}\r
\r
public String toString() {\r
return e.toString();\r
} \r
+\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ if(subscripts != null) {\r
+ IExpression[] subscripts2 = new IExpression[subscripts.length];\r
+ for(int i=0;i<subscripts.length;i++)\r
+ subscripts2[i] = subscripts[i].withBase(frame, prefix);\r
+ return new Derivate((Variable)variable.withBase(frame, prefix), subscripts2, e.withBase(frame, prefix));\r
+ } else {\r
+ return new Derivate((Variable)variable.withBase(frame, prefix), null, e.withBase(frame, prefix));\r
+ }\r
+ }\r
\r
}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
-public class Derivative {\r
+public class Derivative implements IExpression {\r
\r
Variable variable;\r
\r
public String toString() {\r
return "der(" + variable.toString() + ")";\r
}\r
+\r
+ @Override\r
+ public Object evaluate(IEnvironment environment) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
\r
}\r
}\r
\r
private Array arrayDiv(Array a, Double d) {\r
- return a;\r
+ Array result = new Array();\r
+ for(Object o : a.elements()) {\r
+ if(o instanceof Double) {\r
+ result.addElement((Double)o/d);\r
+ } else {\r
+ throw new IllegalStateException();\r
+ }\r
+ }\r
+ return result;\r
}\r
\r
@Override\r
else throw new UnsupportedOperationException();\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Division(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+\r
}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Semantum Oy.\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
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package fi.semantum.sysdyn.solver;\r
+\r
+import java.util.Collection;\r
+import java.util.Iterator;\r
+\r
+public class ElementwiseProduct implements IExpression {\r
+ \r
+ public IExpression exp1;\r
+ public IExpression exp2;\r
+ \r
+ public ElementwiseProduct(IExpression exp1, IExpression exp2) {\r
+ this.exp1 = exp1;\r
+ this.exp2 = exp2;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return exp1 + " * " + exp2;\r
+ }\r
+ \r
+ @Override\r
+ public Object evaluate(IEnvironment environment) {\r
+ Object left = exp1.evaluate(environment);\r
+ Object right = exp2.evaluate(environment);\r
+ if(left instanceof Array && right instanceof Array) {\r
+ Array la = (Array)left;\r
+ Array ra = (Array)right;\r
+ Collection<Object> lae = la.elements();\r
+ Collection<Object> rae = ra.elements();\r
+ if(lae.size() != rae.size()) throw new UnsupportedOperationException();\r
+ Iterator<Object> li = lae.iterator();\r
+ Iterator<Object> ri = rae.iterator();\r
+ Array result = new Array();\r
+ for(int i=0;i<lae.size();i++) {\r
+ double ld = (Double)li.next();\r
+ double rd = (Double)ri.next();\r
+ result.addElement(ld*rd);\r
+ }\r
+ return result;\r
+ } else throw new UnsupportedOperationException();\r
+ }\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new ElementwiseProduct(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+ \r
+}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import java.util.ArrayList;\r
import java.util.HashMap;\r
+import java.util.Map;\r
import java.util.TreeMap;\r
\r
interface Fn {\r
public Object evaluate(IEnvironment environment, int argc);\r
+ public Object evaluateInput(IEnvironment environment, int argPosition);\r
public void setLocals(IEnvironment environment);\r
public int offset();\r
public Variable[] parameters();\r
}\r
\r
abstract class Fn1 implements Fn {\r
+\r
+ Variable[] parameters;\r
\r
- static Variable[] parameters;\r
- \r
- static {\r
- parameters = new Variable[5];\r
- parameters[0] = new Variable(new VariableBase("", 0));\r
- parameters[1] = new Variable(new VariableBase("", 1));\r
- parameters[2] = new Variable(new VariableBase("", 2));\r
- parameters[3] = new Variable(new VariableBase("", 3));\r
- parameters[4] = new Variable(new VariableBase("", 4));\r
+ public Fn1(int pCount) {\r
+ parameters = new Variable[pCount];\r
+ for(int i=0;i<pCount;i++)\r
+ parameters[i] = new Variable(new VariableBase("", i));\r
}\r
\r
public int offset() {\r
public void setLocals(IEnvironment environment) {\r
}\r
\r
+ @Override\r
+ public Object evaluateInput(IEnvironment environment, int argPosition) {\r
+ // Function frame size is constant - this is called when padding is needed\r
+ return null;\r
+ }\r
+ \r
}\r
\r
-public class Environment implements IEnvironment, ISystem {\r
+final public class Environment implements IEnvironment, ISystem {\r
\r
+ final Map<String,Object> named = new HashMap<String,Object>();\r
+\r
public Model model;\r
public final double step;\r
public double time;\r
public boolean initial = true;\r
+ public int size;\r
\r
public Object[] valueTable;\r
\r
this.step = step;\r
this.time = start;\r
\r
- model.functions.put("size", new Fn1() {\r
+ model.functions.put("size", new Fn1(2) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("zidz", new Fn1() {\r
+ model.functions.put("zidz", new Fn1(2) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("xidz", new Fn1() {\r
+ model.functions.put("xidz", new Fn1(3) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("availabilityExternal", new Fn1() {\r
+ model.functions.put("availabilityExternal", new Fn1(4) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("pre", new Fn1() {\r
+ model.functions.put("pre", new Fn1(1) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("fill", new Fn1() {\r
+ model.functions.put("fill", new Fn1(3) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("randomNumber", new Fn1() {\r
+ model.functions.put("randomNumber", new Fn1(2) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("initial", new Fn1() {\r
+ model.functions.put("initial", new Fn1(0) {\r
\r
@Override\r
public Object evaluate(IEnvironment _environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("noEvent", new Fn1() {\r
+ model.functions.put("noEvent", new Fn1(1) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("min", new Fn1() {\r
+ model.functions.put("min", new Fn1(5) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("max", new Fn1() {\r
+ model.functions.put("max", new Fn1(5) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("integer", new Fn1() {\r
+ model.functions.put("integer", new Fn1(1) {\r
\r
@Override\r
public Object evaluate(IEnvironment environment, int argc) {\r
}\r
\r
});\r
- model.functions.put("delay", new Fn1() {\r
+ model.functions.put("sum", new Fn1(1) {\r
+\r
+ @Override\r
+ public Object evaluate(IEnvironment environment, int argc) {\r
+ Object value = environment.getValue(0);\r
+ Array arr = (Array)value;\r
+ double res = 0;\r
+ for(Object o : arr.elements())\r
+ res += (Double)o;\r
+ return res;\r
+ }\r
+ \r
+ });\r
+ model.functions.put("delay", new Fn1(4) {\r
\r
@Override\r
public Object evaluate(IEnvironment _environment, int argc) {\r
valueTable[key] = value;\r
}\r
\r
+ public void put(String key, Object value) {\r
+ named.put(key, value);\r
+ }\r
+\r
+ public void setSize(int size) {\r
+ this.size = size;\r
+ }\r
+ \r
@Override\r
public int offset() {\r
- return model.names.size();\r
+ return size;\r
}\r
\r
@Override\r
public double time() {\r
return time;\r
}\r
+\r
+ double[] valueArray;\r
\r
+ public String[] getValueKeyArray() {\r
+ \r
+ ArrayList<String> keys = new ArrayList<String>();\r
+ \r
+ for (int i = 0; i < model.assignmentArray.length; i++) {\r
+ Variable v = model.assignmentArray[i].target;\r
+ keys.add(v.toString());\r
+ }\r
+ \r
+ for (int i = 0; i < model.derivativeArray.length; i++) {\r
+ Variable v = model.derivativeArray[i].target;\r
+ keys.add(v.toString());\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
+ Variable v = model.parameterArray[i].variable;\r
+ keys.add(v.toString());\r
+ }\r
+\r
+ valueArray = new double[keys.size()];\r
+ \r
+ return keys.toArray(new String[keys.size()]);\r
+ \r
+ }\r
+\r
// TODO: this is probably not smart at all, figure out a better way to obtain results\r
- public HashMap<String, Double> getValueMap() {\r
- HashMap<String, Double> values = new HashMap<String, Double>();\r
+ public double[] getValueArray() {\r
+ \r
+ int offset = 0;\r
\r
for (int i = 0; i < model.assignmentArray.length; i++) {\r
Variable v = model.assignmentArray[i].target;\r
- values.put(v.toString(), (Double)getValue(v.index(this)));\r
+ valueArray[offset++] = (Double)getValue(v.index(this, null));\r
}\r
\r
for (int i = 0; i < model.derivativeArray.length; i++) {\r
Variable v = model.derivativeArray[i].target;\r
- values.put(v.toString(), (Double)getValue(v.index(this)));\r
+ valueArray[offset++] = (Double)getValue(v.index(this, null));\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 (ParameterDeclaration p : model.parameters) {\r
- Variable v = p.variable;\r
- values.put(v.toString(), (Double)getValue(v.index(this)));\r
+ for(int i = 0; i < model.parameterArray.length; i++) {\r
+ Variable v = model.parameterArray[i].variable;\r
+ valueArray[offset++] = (Double)getValue(v.index(this, null));\r
}\r
\r
- return values;\r
+ return valueArray;\r
+ \r
+ }\r
+\r
+ @Override\r
+ public Object getNamedValue(String key) {\r
+ return named.get(key);\r
}\r
\r
}\r
return ((Double)exp1.evaluate(environment)) == ((Double)exp2.evaluate(environment));\r
}\r
\r
- \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Equals(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+\r
}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Semantum Oy.\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
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package fi.semantum.sysdyn.solver;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+public class ForArray implements IExpression {\r
+\r
+ private ArrayList<Object> elements = new ArrayList<Object>();\r
+\r
+ public ForArray() {\r
+ \r
+ }\r
+ \r
+ public void addElement(Object element) {\r
+ if(element instanceof Constant) addElement(((Constant)element).value);\r
+ else elements.add(element);\r
+ }\r
+ \r
+ public void setElement(int index, Object element) {\r
+ elements.set(index, element);\r
+ }\r
+\r
+ @Override\r
+ public Object evaluate(IEnvironment environment) {\r
+ return evaluated(environment);\r
+ }\r
+ \r
+ public Array evaluated(IEnvironment environment) {\r
+ \r
+ Array result = new Array();\r
+ \r
+ IExpression exp = (IExpression)elements.get(0);\r
+ Argument arg = (Argument)elements.get(1);\r
+ \r
+ Array indices = (Array)arg.modification.evaluate(environment);\r
+ for(Object o : indices.elements()) {\r
+ environment.put(arg.name, o);\r
+// Frame f = new Frame(environment, 1);\r
+// f.put(arg.name, o);\r
+ result.addElement(exp.evaluate(environment));\r
+ }\r
+ \r
+ return result;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return elements.toString();\r
+ }\r
+ \r
+ public int size(int col) {\r
+ return elements.size();\r
+ }\r
+ \r
+ public Object element(int index) {\r
+ return elements.get(index);\r
+ }\r
+ \r
+ public Collection<Object> elements() {\r
+ return elements;\r
+ }\r
+ \r
+ public void ensureIndex(int index, boolean subArray) {\r
+ int needed = (index+1-elements.size());\r
+ for(int i=0;i<needed;i++) addElement(subArray ? new ForArray() : null);\r
+ }\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+ \r
+}\r
\r
public class ForIndex {\r
\r
+ public String name;\r
public VariableBase base;\r
public IExpression expression;\r
\r
public ForIndex(Function function, String name, IExpression expression) {\r
this.expression = expression;\r
- this.base = function.addIndex(name, this);\r
+ this.name = name;\r
+ if(function != null)\r
+ this.base = function.addIndex(name, this);\r
}\r
\r
}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
public class Frame implements IEnvironment {\r
\r
final public IEnvironment parent;\r
final private int offset;\r
+ Map<String,Object> named;\r
\r
public Frame(IEnvironment parent, int offset) {\r
this.parent = parent;\r
public void put(int index, Object value) {\r
parent.put(parent.offset() + index, value);\r
}\r
+\r
+ public void put(String key, Object value) {\r
+ if(named == null) named = new HashMap<String,Object>();\r
+ named.put(key, value);\r
+ }\r
\r
@Override\r
public Object getValue(int index) {\r
return parent.getValue(parent.offset() + index);\r
}\r
+\r
+ @Override\r
+ public Object getNamedValue(String key) {\r
+ if(named == null) return null;\r
+ return named.get(key);\r
+ }\r
\r
@Override\r
public ISystem getSystem() {\r
import java.util.HashMap;\r
import java.util.Map;\r
\r
-public class Function implements Fn, IFrame {\r
+final public class Function implements Fn, IFrame {\r
\r
public static final boolean PRINT = false;\r
\r
return parameters;\r
}\r
\r
+ @Override\r
+ public Object evaluateInput(IEnvironment environment, int argPosition) {\r
+ VariableDeclaration decl = inputs.get(argPosition);\r
+ return decl.modification.args.get(0).modification.evaluate(environment);\r
+ }\r
+ \r
}\r
return ((Double)exp1.evaluate(environment)) >= ((Double)exp2.evaluate(environment));\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new GreaterOrEqualThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
\r
}\r
return ((Double)exp1.evaluate(environment)) > ((Double)exp2.evaluate(environment));\r
}\r
\r
- \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new GreaterThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+\r
}\r
public interface IEnvironment {\r
\r
// Object getValue(String key);\r
+ Object getNamedValue(String key);\r
Object getValue(int index);\r
-// void put(String key, Object value);\r
+ void put(String key, Object value);\r
void put(int index, Object value);\r
// Object evaluateFunction(IEnvironment parent, String name, ArgumentList args);\r
\r
public interface IExpression {\r
\r
public Object evaluate(IEnvironment environment);\r
+ public IExpression withBase(IFrame frame, String prefix);\r
\r
}\r
}\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new IfThenElse(exp.withBase(frame, prefix), t.withBase(frame, prefix), e.withBase(frame, prefix));\r
+ }\r
+\r
}\r
return d1 <= d2;\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new LessOrEqualThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
\r
}\r
return ((Double)left) < ((Double)right);\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new LessThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+\r
}\r
\r
import java.io.StringReader;\r
\r
+import fi.semantum.sysdyn.solver.Model.Globals;\r
import fi.semantum.sysdyn.solver.parser.ModelParser;\r
import fi.semantum.sysdyn.solver.parser.Node;\r
import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
public LineReader(String input, NodeCache cache) {\r
chars = input.toCharArray();\r
this.cache = cache;\r
- model = new Model();\r
+ model = new Model(new Globals());\r
parser = new Parser();\r
}\r
\r
\r
class Model implements IFrame {\r
\r
+ static class Globals {\r
+ public Map<String,Model> classes = new HashMap<String,Model>();\r
+ }\r
+ \r
final public static boolean PRINT = false;\r
\r
public boolean initial = false;\r
\r
public Assignment[] assignmentArray;\r
public Assignment[] derivativeArray;\r
+ public ParameterDeclaration[] parameterArray;\r
+ \r
+ public final Globals globals;\r
+ \r
+ public Model(Globals globals) {\r
+ this.globals = globals;\r
+ }\r
\r
public Fn getFunction(String name) {\r
return functions.get(name);\r
\r
Variable[] parameters = fn.parameters();\r
\r
- for(int i=0;i<args.args.size();i++) {\r
+ for(int i=0;i<parameters.length;i++) {\r
Variable var = parameters[i];\r
- Object value = argh.get(i);\r
- var.assignPlain(frame, value);\r
+ if(i < argh.size()) {\r
+ Object value = argh.get(i);\r
+ var.assignPlain(frame, value);\r
+ } else {\r
+ Object value = fn.evaluateInput(environment, i);\r
+ var.assignPlain(frame, value);\r
+ }\r
}\r
\r
fn.setLocals(frame);\r
\r
}\r
\r
+ public void prettyPrint() {\r
+\r
+ System.err.println("initials");\r
+ for(Assignment a : initials) {\r
+ System.err.println("-"+a);\r
+ }\r
+ System.err.println("assignments");\r
+ for(Assignment a : assignments) {\r
+ System.err.println("-"+a);\r
+ }\r
+ System.err.println("derivatives");\r
+ for(Assignment a : derivatives) {\r
+ System.err.println("-"+a);\r
+ }\r
+ System.err.println("parameters");\r
+ for(ParameterDeclaration a : parameters) {\r
+ System.err.println("-"+a);\r
+ }\r
+ System.err.println("variables");\r
+ for(VariableDeclaration a : variables) {\r
+ System.err.println("-"+a);\r
+ }\r
+ System.err.println("functions");\r
+ for(Map.Entry<String, Fn> a : functions.entrySet()) {\r
+ System.err.println("-"+a.getKey() + " " + a.getValue());\r
+ }\r
+ \r
+ }\r
+ \r
}
\ No newline at end of file
}\r
\r
private Array arrayMul(Array a, Double d) {\r
- return a;\r
+ Array result = new Array();\r
+ for(Object o : a.elements()) {\r
+ if(o instanceof Double) {\r
+ result.addElement((Double)o*d);\r
+ } else {\r
+ throw new IllegalStateException();\r
+ }\r
+ }\r
+ return result;\r
}\r
\r
@Override\r
else if (left instanceof Double && right instanceof Array) return arrayMul((Array)right, (Double)left);\r
else throw new UnsupportedOperationException();\r
}\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Multiplication(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+ \r
}\r
return -((Double)exp.evaluate(environment));\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Negation(exp.withBase(frame, prefix));\r
+ }\r
+\r
}\r
while_statement,\r
statement,\r
name,\r
+ element,\r
element_list,\r
element_modification,\r
function_arguments,\r
return ((Double)exp1.evaluate(environment)) != ((Double)exp2.evaluate(environment));\r
}\r
\r
- \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new NotEquals(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+\r
}\r
for(IExpression e : exps) \r
if((Boolean)e.evaluate(environment)) return true;\r
return false;\r
- } \r
+ }\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ ArrayList<IExpression> ne = new ArrayList<IExpression>();\r
+ for(IExpression e : exps) ne.add(e.withBase(frame, prefix));\r
+ return new Or(ne);\r
+ }\r
+ \r
}\r
throw new UnsupportedOperationException();\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+ \r
}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import java.io.File;\r
+import java.io.StringReader;\r
import java.util.ArrayList;\r
import java.util.HashMap;\r
import java.util.Map;\r
\r
+import org.simantics.utils.FileUtils;\r
+\r
+import fi.semantum.sysdyn.solver.Model.Globals;\r
+import fi.semantum.sysdyn.solver.parser.ModelParser;\r
import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
\r
public class Parser {\r
IExpression exp = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
if(v instanceof Derivative) {\r
Derivative der = (Derivative)v;\r
- Assignment eq = new Assignment(der.variable,new Derivate(der.variable, exp));\r
+ Assignment eq = new Assignment(der.variable, der.variable.subscripts, new Derivate(der.variable, der.variable.subscripts, exp));\r
model.derivatives.add(eq);\r
return eq;\r
} else {\r
- Assignment eq = new Assignment((Variable)v,exp);\r
+ Variable var = (Variable)v;\r
+ Assignment eq = new Assignment(var, var.subscripts, exp);\r
if(model.initial)\r
model.initials.add(eq);\r
else\r
case equation_section:\r
if("initial".equals(n.op)) {\r
model.initial = true;\r
+ for(int i=0;i<n.jjtGetNumChildren();i++) {\r
+ walk((SimpleNode)n.jjtGetChild(i),indent+2, model);\r
+ }\r
} else {\r
model.initial = false;\r
+ for(int i=0;i<n.jjtGetNumChildren();i++) {\r
+ walk((SimpleNode)n.jjtGetChild(i),indent+2, model);\r
+ }\r
}\r
- break;\r
+ return null;\r
case composition:\r
if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0),indent+2, model);\r
ArrayList<Object> comps = new ArrayList<Object>();\r
}\r
return comps;\r
case for_index:\r
- return new ForIndex((Function)currentFrame, n.op, (IExpression)walk((SimpleNode)n.jjtGetChild(0),indent+2, model));\r
+ if(currentFrame instanceof Function)\r
+ return new ForIndex((Function)currentFrame, n.op, (IExpression)walk((SimpleNode)n.jjtGetChild(0),indent+2, model));\r
+ else\r
+ return new ForIndex(null, n.op, (IExpression)walk((SimpleNode)n.jjtGetChild(0),indent+2, model));\r
case for_indices:\r
ArrayList<ForIndex> indices = new ArrayList<ForIndex>();\r
for(int i=0;i<n.jjtGetNumChildren();i++) {\r
if(n.jjtGetNumChildren() == 1) return (IStatement)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
Variable variable = (Variable)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
IExpression expression2 = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
- return new Statement(variable, expression2);\r
+ return new Statement(variable, variable.subscripts, expression2);\r
case name:\r
return n.op;\r
case element_list:\r
elements.add(walk((SimpleNode)n.jjtGetChild(i),indent+2, model));\r
}\r
return elements;\r
+ case element:\r
+// if("inner".equals(n.op)) {\r
+// return null;\r
+// } else {\r
+ return walk((SimpleNode)n.jjtGetChild(0),indent+2, model);\r
+// }\r
case element_modification:\r
if(n.jjtGetNumChildren() == 2) {\r
String name = (String)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
}\r
break;\r
case function_arguments:\r
- ArgumentList arguments = new ArgumentList();\r
+ ArgumentList arguments = new ArgumentList(n.op);\r
for(int i=0;i<n.jjtGetNumChildren();i++) {\r
Object o = walk((SimpleNode)n.jjtGetChild(i),indent+2, model);\r
if(o instanceof ArgumentList) {\r
arguments.args.addAll(((ArgumentList)o).args);\r
} else if (o instanceof IExpression) {\r
arguments.args.add(new Argument("", (IExpression)o));\r
+ } else if (o instanceof ArrayList) {\r
+ ArrayList list = (ArrayList)o;\r
+ for(Object o2 : list) {\r
+ if(o2 instanceof Argument) {\r
+ arguments.args.add((Argument)o2);\r
+ } else if (o2 instanceof ForIndex) {\r
+ ForIndex fi = (ForIndex)o2;\r
+ arguments.args.add(new Argument(fi.name, fi.expression));\r
+ }\r
+ }\r
} else {\r
return null;\r
}\r
} else {\r
if(decl.modification instanceof ArgumentList) {\r
VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, (ArgumentList)decl.modification);\r
- if(currentFrame == model) model.variables.add(vd);\r
+ model.variables.add(vd);\r
clauses.add(vd);\r
- } else {\r
- VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
- if(currentFrame == model) model.variables.add(vd);\r
+ } else if (decl.modification instanceof IExpression) {\r
+ ArrayList<Argument> as = new ArrayList<Argument>();\r
+ as.add(new Argument("", (IExpression)decl.modification));\r
+ ArgumentList al = new ArgumentList(as);\r
+ VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, al);\r
+ model.variables.add(vd);\r
clauses.add(vd);\r
+ } else {\r
+ if("Real".equals(type_specifier)) {\r
+ VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
+ model.variables.add(vd);\r
+ clauses.add(vd);\r
+ } else if("Integer".equals(type_specifier)) {\r
+ VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
+ model.variables.add(vd);\r
+ clauses.add(vd);\r
+ } else if("Boolean".equals(type_specifier)) {\r
+ VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
+ model.variables.add(vd);\r
+ clauses.add(vd);\r
+ } else {\r
+ Model clazz = model.globals.classes.get(type_specifier);\r
+ for(VariableDeclaration vd : clazz.variables) {\r
+ String base = decl.variable.base.name + ".";\r
+ Variable var2 = vd.variable.withBase(currentFrame, base);\r
+ VariableDeclaration vd2 = new VariableDeclaration(var2, vd.direction, vd.type, vd.modification.withBase(currentFrame, base));\r
+ model.variables.add(vd2);\r
+ clauses.add(vd2);\r
+ }\r
+ for(ParameterDeclaration pd : clazz.parameters) {\r
+ String base = decl.variable.base.name + ".";\r
+ Variable var2 = pd.variable.withBase(currentFrame, base);\r
+ ParameterDeclaration pd2 = new ParameterDeclaration(var2, pd.modification.withBase(currentFrame, base));\r
+ model.parameters.add(pd2);\r
+ }\r
+ for(Assignment ass : clazz.assignments) {\r
+ Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + ".");\r
+ model.assignments.add(ass2);\r
+ }\r
+ for(Assignment ass : clazz.initials) {\r
+ Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + ".");\r
+ model.initials.add(ass2);\r
+ }\r
+ for(Assignment ass : clazz.derivatives) {\r
+ Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + ".");\r
+ model.derivatives.add(ass2);\r
+ }\r
+ \r
+ }\r
}\r
}\r
}\r
model.functions.put(functionName, function);\r
currentFrame = model;\r
return function;\r
+ \r
+ } else if("model".equals(n.op)) {\r
+\r
+ currentFrame = model;\r
+\r
+ if(n.jjtGetNumChildren() == 1) {\r
+ return walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
+ } else {\r
+ System.err.println("undefined children for class_definition model"); \r
+ }\r
+ return null;\r
+ \r
+ } else if("class".equals(n.op)) {\r
+ \r
+ Model clazz = new Model(model.globals);\r
+ SimpleNode specifier = (SimpleNode)n.jjtGetChild(0); \r
+ model.globals.classes.put(specifier.op, clazz);\r
+ currentFrame = clazz;\r
+ walk(specifier, indent+2, clazz);\r
+ currentFrame = model;\r
+ return null;\r
+ \r
+ } else {\r
+ System.err.println("class_definition " + n.op);\r
}\r
break;\r
case array:\r
- Array array = new Array();\r
if(n.jjtGetNumChildren() == 1) {\r
ArgumentList al = (ArgumentList)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
- for(Argument arg : al.args) array.addElement(arg.modification);\r
+ if("for".equals(al.op)) {\r
+ ForArray array = new ForArray();\r
+ array.addElement(al.args.get(0).modification);\r
+ array.addElement(al.args.get(1));\r
+ return array;\r
+ } else {\r
+ Array array = new Array();\r
+ for(Argument arg : al.args) array.addElement(arg.modification);\r
+ return array;\r
+ }\r
}\r
- return array;\r
case primary:\r
if(n.op != null) {\r
return Utils.parsePrimitive(n.op);\r
return walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
}\r
case arithmetic_expression:\r
- if(n.jjtGetNumChildren() == 2) {\r
+ {\r
+ int i=0;\r
+ IExpression left;\r
+ if(n.jjtGetNumChildren() % 2 == 0) {\r
String op = ((String)walk((SimpleNode)n.jjtGetChild(0), indent+2, model)).trim();\r
- if("-".equals(op)) return new Negation((IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model));\r
- }\r
- if(n.jjtGetNumChildren() > 1) {\r
- IExpression left = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
- for(int i=1;i<n.jjtGetNumChildren();i+=2) {\r
- String op = ((String)walk((SimpleNode)n.jjtGetChild(i), indent+2, model)).trim();\r
- IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(i+1), indent+2, model);\r
- if("+".equals(op)) left = new Addition(left, exp2);\r
- else if("-".equals(op)) left = new Subtraction(left, exp2);\r
+ left = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
+ if("-".equals(op)) {\r
+ left = new Negation(left);\r
}\r
- return left;\r
+ i=2;\r
} else {\r
- return walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
+ left = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
+ i=1;\r
+ }\r
+\r
+ for(;i<n.jjtGetNumChildren();i+=2) {\r
+ String op = ((String)walk((SimpleNode)n.jjtGetChild(i), indent+2, model)).trim();\r
+ IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(i+1), indent+2, model);\r
+ if("+".equals(op)) left = new Addition(left, exp2);\r
+ else if("-".equals(op)) left = new Subtraction(left, exp2);\r
}\r
+\r
+ return left;\r
+ }\r
+ \r
case term:\r
if(n.jjtGetNumChildren() > 1) {\r
IExpression term = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
String op = ((String)walk((SimpleNode)n.jjtGetChild(i), indent+2, model)).trim();\r
IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(i+1), indent+2, model);\r
if("*".equals(op)) term = new Multiplication(term, exp2);\r
+ else if(".*".equals(op)) term = new ElementwiseProduct(term, exp2);\r
else if("/".equals(op)) term = new Division(term, exp2);\r
}\r
return term;\r
return new Derivative((Variable)args2.args.get(0).modification);\r
}\r
} else if("initial".equals(n.op)) {\r
- return new Application("initial", new ArgumentList());\r
+ return new Application("initial", new ArgumentList(""));\r
} else if("application".equals(n.op)) {\r
String name = (String)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
ArgumentList args2 = (ArgumentList)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
}\r
}\r
\r
+ System.err.println("fall-through " + n);\r
+ \r
// should not get this far\r
return null;\r
}\r
\r
+ public static final boolean WAIT = false;\r
+ \r
+ public static void main(String[] args) throws Exception {\r
+ \r
+ if(WAIT) {\r
+ for(int i=0;i<1e12;i++) {\r
+ int k = System.in.read();\r
+ if(k==13) break;\r
+ Thread.sleep(10);\r
+ }\r
+ }\r
+ \r
+// NodeCache cache = new NodeCache();\r
+//\r
+//// long start = System.nanoTime();\r
+//\r
+// File f = new File("C:/Users/Antti Villberg/Downloads/isomalli.txt");\r
+// String contents = FileUtils.getContents(f);\r
+// LineReader reader = new LineReader(contents, cache);\r
+// reader.parse();\r
+//\r
+//// long duration = System.nanoTime()-start;\r
+//// System.err.println("complete parse file in " + 1e-9*duration + "s.");\r
+//\r
+//// start = System.nanoTime();\r
+//\r
+// if(WAIT) {\r
+// for(int i=0;i<1e12;i++) {\r
+// int k = System.in.read();\r
+// if(k==13) break;\r
+// Thread.sleep(10);\r
+// }\r
+// }\r
+\r
+ \r
+\r
+ \r
+ File f1 = new File("d:/sysdynfn.txt");\r
+ String contents1 = FileUtils.getContents(f1);\r
+ File f2 = new File("d:/sysdyntest.txt");\r
+ String contents2 = contents1 + FileUtils.getContents(f2);\r
+ \r
+ StringReader reader = new StringReader(contents2);\r
+ ModelParser modelParser = new ModelParser(reader);\r
+ SimpleNode n = (SimpleNode)modelParser.stored_definition();\r
+ System.err.println("n: " +n );\r
+ Parser parser = new Parser();\r
+ Model m = new Model(new Globals());\r
+ parser.walk(n, 0, m);\r
+ \r
+ m.prettyPrint();\r
+ \r
+// ModelicaCompilationUnit unit = ModelicaAnalyzer.analyze(contents2);\r
+// System.err.println("unit: " + unit);\r
+ \r
+\r
+// reader = new LineReader(contents2, cache);\r
+// reader.parse();\r
+// Model model = reader.model;\r
+ \r
+// String code = FileUtils.getContents(f);\r
+// Model model = new Parser().parseModelica(code);\r
+ \r
+// duration = System.nanoTime()-start;\r
+// System.err.println("parsed file in " + 1e-9*duration + "s.");\r
+\r
+ Solver solver = new Solver();\r
+ solver.prepare(contents2);\r
+ \r
+//\r
+// if(WAIT) {\r
+// for(int i=0;i<1e12;i++) {\r
+// int k = System.in.read();\r
+// if(k==13) break;\r
+// Thread.sleep(10);\r
+// }\r
+// }\r
+//\r
+// long start = System.nanoTime();\r
+ for(int i=0;i<50;i++) {\r
+ solver.step();\r
+ solver.printEnvironment();\r
+ }\r
+// long duration = System.nanoTime()-start;\r
+// System.err.println("stepped simulation in " + 1e-9*duration + "s.");\r
+ \r
+ }\r
+ \r
}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import java.io.StringReader;\r
import java.util.ArrayList;\r
-import java.util.HashMap;\r
+\r
+import fi.semantum.sysdyn.solver.Model.Globals;\r
+import fi.semantum.sysdyn.solver.parser.ModelParser;\r
+import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
\r
public class Solver {\r
\r
}\r
\r
public void prepare(String input) throws Exception {\r
- LineReader reader = new LineReader(input, cache);\r
- reader.parse();\r
\r
- model = reader.model;\r
+ long startNanos = System.nanoTime();\r
+ \r
+// LineReader reader = new LineReader(input, cache);\r
+// reader.parse();\r
+// \r
+// model = reader.model;\r
+ \r
+ StringReader reader = new StringReader(input);\r
+ ModelParser modelParser = new ModelParser(reader);\r
+ SimpleNode n = (SimpleNode)modelParser.stored_definition();\r
+ Parser parser = new Parser();\r
+ model = new Model(new Globals());\r
+ parser.walk(n, 0, model);\r
+ \r
env = new Environment(model, step, start);\r
\r
int size = model.prepare();\r
+ env.setSize(size);\r
\r
for(Fn fn : model.functions.values()) {\r
if(fn instanceof Function)\r
\r
model.assignmentArray = model.assignments.toArray(new Assignment[model.assignments.size()]);\r
model.derivativeArray = model.derivatives.toArray(new Assignment[model.derivatives.size()]);\r
+ model.parameterArray = model.parameters.toArray(new ParameterDeclaration[model.parameters.size()]);\r
\r
newValues = new Object[Math.max(model.assignments.size(),model.derivatives.size())];\r
\r
for(ParameterDeclaration pd : model.parameters) {\r
try {\r
if(!pd.assigned) {\r
- pd.variable.assign(env, pd.modification.evaluate(env));\r
+ pd.variable.assign(env, null, pd.modification.evaluate(env));\r
pd.assigned = true;\r
}\r
} catch (Exception e) {\r
for(Argument arg : vd.modification.args) {\r
if("start".equals(arg.name)) {\r
Object value = arg.modification.evaluate(env);\r
- vd.variable.assign(env, value);\r
+ vd.variable.assign(env, null, value);\r
// make sure the variable is not initialized \r
// twice, this is probably not the most \r
// efficient way\r
try {\r
if(!ass.assigned) {\r
Object value = ass.expression.evaluate(env);\r
- ass.target.assign(env, value);\r
+ ass.target.assign(env, ass.subscripts, value);\r
ass.assigned = true;\r
}\r
} catch (Exception e) {\r
env.initial = false;\r
\r
ready = true;\r
+ \r
+ long endNanos = System.nanoTime();\r
+ \r
+ System.err.println("Prepared model in " + 1e-6*(endNanos-startNanos) + "ms.");\r
+ \r
+ }\r
+ \r
+ public String[] keys() {\r
+ return env.getValueKeyArray();\r
}\r
\r
- public HashMap<String, Double> values() {\r
- return env.getValueMap();\r
+ public double[] values() {\r
+ return env.getValueArray();\r
}\r
\r
public void step() {\r
newValues[i] = assignments[i].expression.evaluate(env);\r
}\r
for(int i=0;i<model.assignments.size();i++) {\r
- assignments[i].target.assign(env, newValues[i]);\r
+ assignments[i].target.assign(env, assignments[i].subscripts, newValues[i]);\r
}\r
\r
// Solve derivatives\r
newValues[i] = derivatives[i].expression.evaluate(env);\r
}\r
for(int i=0;i<model.derivatives.size();i++) {\r
- derivatives[i].target.assign(env, newValues[i]);\r
+ derivatives[i].target.assign(env, assignments[i].subscripts, newValues[i]);\r
}\r
}\r
\r
// TODO: implement some on the fly parameter change stuff for different experiment types\r
\r
+ public void printEnvironment() {\r
+ System.err.println("Environment");\r
+ String[] keys = keys();\r
+ double[] values = values();\r
+ for(int i=0;i<keys.length;i++) {\r
+ System.err.println(keys[i] + " = " + values[i]);\r
+ }\r
+ }\r
+ \r
}\r
public class Statement implements IStatement {\r
\r
public Variable target;\r
+ public IExpression[] subscripts;\r
public IExpression expression;\r
\r
- public Statement(Variable target, IExpression expression) {\r
+ public Statement(Variable target, IExpression[] subscripts, IExpression expression) {\r
this.target = target;\r
+ this.subscripts = subscripts;\r
this.expression = expression;\r
}\r
\r
@Override\r
public void evaluate(IEnvironment environment) {\r
Object value = expression.evaluate(environment);\r
- target.assign(environment, value);\r
+ target.assign(environment, subscripts, value);\r
}\r
\r
}\r
public Object evaluate(IEnvironment environment) {\r
return ((Double)exp1.evaluate(environment)) - ((Double)exp2.evaluate(environment));\r
}\r
+ \r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return new Subtraction(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+ }\r
+ \r
\r
}\r
return "time";\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ return this;\r
+ }\r
+\r
+ \r
}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import org.omg.PortableInterceptor.SUCCESSFUL;\r
+\r
+\r
public class Variable implements IExpression {\r
\r
public VariableBase base;\r
this.base = base;\r
}\r
\r
+ public Variable(VariableBase base, IExpression[] subscripts) {\r
+ this.base = base;\r
+ this.subscripts = subscripts;\r
+ }\r
+\r
private int makeSubscriptIndex(IEnvironment env) {\r
if(base.dimensions == null) return 0;\r
int result = 0;\r
\r
}\r
\r
- public int subscriptIndex(IEnvironment env) {\r
+ public int subscriptIndex(IEnvironment env, IExpression[] subscripts) {\r
if(subscripts == null) return 0;\r
return makeSubscriptIndex(env);\r
}\r
str.append(", ");\r
}\r
// is the expression inside subscript always a constant?\r
- str.append(((Double)((Constant)subscripts[i]).value).intValue());\r
+ Object sub = subscripts[i];\r
+ if(sub instanceof Constant) {\r
+ str.append(((Double)((Constant)sub).value).intValue());\r
+ } else if (sub instanceof Variable) {\r
+ str.append(((Variable)sub).base.name);\r
+ }\r
}\r
str.append(']');\r
return str.toString();\r
\r
public int assignArray(IEnvironment env, int index, Array value, int asd) {\r
for(int i=0;i<value.elements().size();i++) {\r
-// String s = name + "_" + (i+1);\r
Object element = value.element(i);\r
if(element instanceof Double) {\r
env.put(index+asd++, (Double)element);\r
return asd;\r
}\r
\r
- public int index(IEnvironment env) {\r
- return base.index + subscriptIndex(env);\r
+ public int index(IEnvironment env, IExpression[] subscripts) {\r
+ return base.index + subscriptIndex(env, subscripts);\r
}\r
\r
public void setArrayIndex(IEnvironment environment, Array array, Object value) {\r
\r
}\r
\r
- public Object getArrayIndex(IEnvironment environment, Array array) {\r
+ public Object getArrayIndex(IEnvironment environment, IExpression[] subscripts, Array array) {\r
Object result = array;\r
for(IExpression e : subscripts) {\r
int index = Utils.getIndex(e.evaluate(environment));\r
IExpression exp = (IExpression)result;\r
return exp.evaluate(environment);\r
}\r
+ if(result instanceof Array)\r
+ throw new IllegalStateException();\r
return result;\r
}\r
\r
env.put(base.index, value);\r
}\r
\r
- public void assign(IEnvironment env, Object value) {\r
+ public void assign(IEnvironment env, IExpression[] subscripts, Object value) {\r
if(value instanceof Array) {\r
if(base.isStoredAsArray()) {\r
- env.put(index(env), value);\r
+ env.put(index(env, subscripts), value);\r
} else {\r
- assignArray(env, index(env), (Array)value, 0);\r
+ assignArray(env, index(env, subscripts), (Array)value, 0);\r
}\r
} else {\r
if(base.isStoredAsArray()) {\r
}\r
setArrayIndex(env, existing, value);\r
} else {\r
- env.put(index(env), value);\r
+ env.put(index(env, subscripts), value);\r
}\r
}\r
}\r
\r
+ public int intoArray(IEnvironment env, int index, int d, Array target) {\r
+\r
+ if(d == base.dimensions.length-1) {\r
+ for(int i=0;i<base.dimensions[d];i++) {\r
+ target.addElement(env.getValue(index));\r
+ index++;\r
+ }\r
+ return index;\r
+ }\r
+ \r
+ for(int i=0;i<base.dimensions[d];i++) {\r
+ Array array = new Array();\r
+ index = intoArray(env, index, d+1, array);\r
+ target.addElement(array);\r
+ }\r
+ \r
+ return index;\r
+ \r
+ }\r
+ \r
@Override\r
public Object evaluate(IEnvironment environment) {\r
+ return evaluate(environment, subscripts);\r
+ }\r
+\r
+ public Object evaluate(IEnvironment environment, IExpression[] subscripts) {\r
if(base.isStoredAsArray()) {\r
Array array = (Array)environment.getValue(base.index);\r
- if(hasScalarSubscript()) {\r
- Object o = getArrayIndex(environment, array);\r
+ if(hasScalarSubscript(subscripts)) {\r
+ Object o = getArrayIndex(environment, subscripts, array);\r
if(o instanceof Variable) throw new IllegalStateException();\r
+ if(o instanceof Array)\r
+ throw new IllegalStateException();\r
return o;\r
}\r
else return array;\r
} else {\r
- Object result = environment.getValue(index(environment)); \r
+ \r
+ if(base.dimension() > 1) {\r
+ Array array = new Array();\r
+ intoArray(environment, base.index, 0, array);\r
+ return array;\r
+ }\r
+ \r
+ Object result = environment.getNamedValue(base.name);\r
+ if(result == null) result = environment.getValue(index(environment, subscripts));\r
if(result == null) throw new UnassignedVariableException("No value for " + base.name);\r
+ \r
return result;\r
}\r
}\r
\r
- private boolean hasScalarSubscript() {\r
+ private boolean hasScalarSubscript(IExpression[] subscripts) {\r
if(subscripts == null) return false;\r
else return true;\r
}\r
\r
+ public Variable withBase(IFrame frame, String prefix) {\r
+ if(subscripts != null) {\r
+ IExpression[] subscripts2 = new IExpression[subscripts.length];\r
+ for(int i=0;i<subscripts.length;i++)\r
+ subscripts2[i] = subscripts[i].withBase(frame, prefix);\r
+ return new Variable(frame, prefix + base.name, subscripts2);\r
+ } else {\r
+ return new Variable(frame, prefix + base.name,null);\r
+ }\r
+ }\r
+ \r
}\r
*******************************************************************************/\r
package fi.semantum.sysdyn.solver;\r
\r
+import java.util.Arrays;\r
+\r
public class VariableBase {\r
\r
public String name;\r
this.name = name;\r
this.index = index;\r
}\r
+ public VariableBase(String name, int index, int[] dimensions) {\r
+ this.name = name;\r
+ this.index = index;\r
+ this.dimensions = dimensions;\r
+ }\r
public void tellSubscripts(IExpression[] e) {\r
if(e == null) return;\r
if(dimensions == null) \r
for(int d : dimensions) if(d == -1) return true;\r
return false;\r
}\r
+ \r
+ VariableBase withBase(String prefix) {\r
+ return new VariableBase(prefix+name, index, dimensions);\r
+ }\r
+ \r
}\r
throw new UnsupportedOperationException();\r
}\r
\r
+ @Override\r
+ public IExpression withBase(IFrame frame, String prefix) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+ \r
}\r
// class_specifier\r
( "encapsulated" )?\r
( "partial" )?\r
- ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
+ ( "class" { jjtThis.op = "class"; } | "model" { jjtThis.op = "model"; } | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
"package" | "function" { jjtThis.op = "function"; } | "operator" | "operator function" | "operator record" )\r
class_specifier()\r
}\r
extends_clause() |\r
( "redeclare" )?\r
( "final" )?\r
- ( "inner" )? ( "outer" )?\r
+ ( "inner" { jjtThis.op = "inner"; } )? ( "outer" { jjtThis.op = "outer"; } )?\r
( (class_definition() | component_clause()) |\r
"replaceable" (class_definition() | component_clause())\r
(constraining_clause() comment())?)\r
\r
void mul_op() : {\r
} {\r
- "*" { jjtThis.op = "*";} | "/" { jjtThis.op = "/";} | ".*" | "./"\r
+ "*" { jjtThis.op = "*";} | "/" { jjtThis.op = "/";} | ".*" { jjtThis.op = ".*";} | "./"\r
}\r
\r
void factor() : {\r
} {\r
//expression [ "," function_arguments | for for_indices ]\r
//| named_arguments\r
- LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() )?\r
+ LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() { jjtThis.op = "for"; } )?\r
| named_arguments()\r
}\r
\r
* \r
* @return Open Modelica home directory\r
*/\r
- private static File getOMHome() {\r
+ public static File getOMHome() {\r
Preferences node = ConfigurationScope.INSTANCE.getNode(Activator.PLUGIN_ID);\r
String omHomePath = node.get(OpenModelicaPreferences.OM_HOME, null);\r
if (omHomePath != null) {\r
thread.run();\r
}\r
\r
- public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent) { \r
+ public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent, File omHome, boolean isOldOMVersion) { \r
if (!modelDir.isDirectory()) {\r
return null;\r
}\r
}\r
\r
// full model files are (apparently) only needed for old parameter comparison routines\r
- if (isOldOMVersion()) {\r
+ if (isOldOMVersion) {\r
location.fullModelDir = new File(location.getModelDir(), "fullModel");\r
if (!location.fullModelDir.isDirectory()) {\r
location.fullModelDir.mkdir();\r
location.fullModelScriptFile = new File(location.fullModelDir, location.getModelName() + "_full.mos");\r
}\r
\r
- location.omHome = getOMHome();\r
+ location.omHome = omHome;\r
\r
return location;\r
}\r
FunctionUtils.updateFunctionFilesForExperiment(this);\r
\r
\r
- SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText);\r
+ SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText, ModelicaManager.getOMHome(), ModelicaManager.isOldOMVersion());\r
if (fmu) {\r
ModelicaManager.createFMUSimulationScripts(location, inits, additionalScript);\r
}\r
--- /dev/null
+package org.simantics.sysdyn.manager;\r
+\r
+import java.util.concurrent.Semaphore;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IDynamicExperiment;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.model.ExperimentLoadingFailed;\r
+import org.simantics.simulation.project.IExperimentActivationListener;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.utils.DataContainer;\r
+\r
+public class SysdynExperiments {\r
+\r
+ public static String activateExperiment(IProgressMonitor monitor, final IProject project, final IExperimentManager manager, final Resource experimentResource) {\r
+ \r
+ if(monitor == null) monitor = new NullProgressMonitor();\r
+ \r
+ final SubMonitor mon = SubMonitor.convert(monitor, "Activating experiment", 100000);\r
+\r
+// SysdynExperimentManagerListener.listenManager(manager);\r
+ IExperiment[] experiments = manager.getExperiments();\r
+ SubMonitor shutdownMon = mon.newChild(10000);\r
+ int workPerExperiment;\r
+ if (experiments.length > 0)\r
+ workPerExperiment = 10000 / experiments.length;\r
+ else\r
+ workPerExperiment = 10000;\r
+ for(IExperiment e : experiments)\r
+ if(e.getState() != ExperimentState.DISPOSED)\r
+ e.shutdown(shutdownMon.newChild(workPerExperiment));\r
+ mon.setWorkRemaining(90000);\r
+\r
+ final Semaphore activated = new Semaphore(0);\r
+ final DataContainer<Throwable> problem = new DataContainer<Throwable>();\r
+ final DataContainer<IExperiment> run = new DataContainer<IExperiment>();\r
+ manager.startExperiment(experimentResource, new IExperimentActivationListener() {\r
+\r
+ @Override\r
+ public void onExperimentActivated(final IExperiment experiment) {\r
+// MessageService.defaultLog(new org.eclipse.core.runtime.Status(IStatus.INFO, "org.simantics.simulation.ui", 0, "Activated experiment " + experiment.getIdentifier() , null));\r
+ activated.release();\r
+ run.set(experiment);\r
+ }\r
+ @Override\r
+ public void onFailure(Throwable e) {\r
+ problem.set(e);\r
+ activated.release();\r
+ }\r
+ @Override\r
+ public void onMessage(IStatus message) {\r
+// MessageService.getDefault().log(message);\r
+ }\r
+ @Override\r
+ public IProgressMonitor getProgressMonitor() {\r
+ return mon;\r
+ }\r
+ }, true);\r
+ try {\r
+ activated.acquire();\r
+ Throwable t = problem.get();\r
+ if (t != null) {\r
+ if (t instanceof ExperimentLoadingFailed) {\r
+// ErrorLogger.defaultLogError(t);\r
+// ShowMessage.showError("Experiment Activation Failed", t.getMessage());\r
+ } else {\r
+// ExceptionUtils.logAndShowError(t);\r
+ }\r
+ }\r
+\r
+ return run.get().getIdentifier();\r
+ //return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Experiment activation failed, see exception for details.", problem.get());\r
+ } catch (InterruptedException e) {\r
+ return null;\r
+ }\r
+ }\r
+ \r
+ \r
+ public static String activateExperiment(Resource experiment) throws DatabaseException {\r
+\r
+// Resource experiment = Layer0Utils.getPossibleChild(graph, model, name);\r
+// if( experiment == null) return false;\r
+\r
+// SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+// if (!graph.isInstanceOf(experiment, SIMU.Experiment)) return false;\r
+ \r
+ final IProject project = Simantics.getProject();\r
+ if (project == null) return null;\r
+ \r
+ final IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ if(experimentManager == null) return null;\r
+ \r
+ return SysdynExperiments.activateExperiment(null, project, experimentManager, experiment);\r
+ \r
+ }\r
+ \r
+ public static void run(String experimentId) throws DatabaseException {\r
+\r
+ final IProject project = Simantics.getProject();\r
+ if (project == null) return;\r
+ \r
+ final IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ if(experimentManager == null) return;\r
+ \r
+ IExperiment experiment = experimentManager.getExperiment(experimentId);\r
+ if(experiment instanceof IDynamicExperiment)\r
+ ((IDynamicExperiment)experiment).simulate(true);\r
+ \r
+ }\r
+ \r
+\r
+ \r
+ \r
+}\r
package org.simantics.sysdyn.solver;\r
\r
+import java.io.File;\r
import java.util.HashMap;\r
\r
import org.simantics.modelica.ModelicaManager;\r
import org.simantics.sysdyn.modelica.ModelicaWriter;\r
import org.simantics.sysdyn.representation.Model;\r
import org.simantics.sysdyn.solver.SolverSettings.SolverType;\r
+import org.simantics.utils.FileUtils;\r
\r
import fi.semantum.sysdyn.solver.Solver;\r
\r
public class InternalSolver implements ISolver {\r
\r
+ public static final boolean PRINT_CODE = false;\r
+ \r
private SysdynExperiment experiment;\r
private SysdynModel model;\r
private ISolverMonitor monitor;\r
\r
@Override\r
public void initialize() throws Exception {\r
- String omVersion = ModelicaManager.getDefaultOMVersion();\r
- String modelContent = ModelicaWriter.write(model.getModules(), false, omVersion);\r
+// String omVersion = ModelicaManager.getDefaultOMVersion();\r
+ String modelContent = ModelicaWriter.write(model.getModules(), false, "1.9");\r
\r
// update some stuff\r
FunctionUtils.updateFunctionFilesForExperiment(experiment);\r
\r
location = ModelicaManager.createSimulationLocation(experiment.getExperimentDir(), \r
- model.getConfiguration().getLabel(), modelContent);\r
+ model.getConfiguration().getLabel(), modelContent, null, false);\r
\r
// set solver parameters\r
Model representation = model.getConfiguration().getModel();\r
\r
@Override\r
public void buildModel() throws Exception {\r
- String flat = ModelicaManager.getFlatModelText(location, monitor, FunctionUtils.getLibraryPathsForModelica(experiment));\r
- solver.prepare(flat);\r
+ \r
+// String flat = ModelicaManager.getFlatModelText(location, monitor, FunctionUtils.getLibraryPathsForModelica(experiment));\r
+// System.err.println("=== FLAT ===");\r
+// System.err.println(flat);\r
+// System.err.println("=== FLAT ENDS ===");\r
+ \r
+ StringBuilder code = new StringBuilder();\r
+ for(String path : FunctionUtils.getLibraryPathsForModelica(experiment)) {\r
+ File f = new File(location.modelFile.getParentFile(), path);\r
+ code.append(FileUtils.getContents(f));\r
+ }\r
+ code.append(FileUtils.getContents(location.modelFile));\r
+ \r
+ if(PRINT_CODE) {\r
+ System.err.println("=== CODE === ");\r
+ System.err.println(code.toString());\r
+ System.err.println("=== CODE ENDS ===");\r
+ }\r
+\r
+ solver.prepare(code.toString());\r
+ \r
}\r
\r
@Override\r
public void runSolver() throws Exception {\r
+ \r
+ long startTime = System.nanoTime();\r
+ \r
// the number of result intervals in the simulation (account for initial values)\r
int count = (int)((stop - start) / interval) + 1;\r
// the number of steps in one result interval\r
// an array containing an accurate time stamp for each interval\r
double[] times = new double[count];\r
// a map containing values of all variables for each interval\r
- HashMap<String, double[]> values = new HashMap<String, double[]>();\r
+\r
+ String[] keys = solver.keys();\r
+\r
+ double[][] values = new double[keys.length][];\r
+ \r
+// HashMap<String, double[]> values = new HashMap<String, double[]>();\r
// initialize the temporary data structures\r
times[0] = start;\r
- HashMap<String, Double> tmp = solver.values();\r
- for (String key : tmp.keySet()) {\r
- values.put(key, new double[count]);\r
- values.get(key)[0] = tmp.get(key);\r
+ \r
+ double[] valueArray = solver.values();\r
+// HashMap<String, Double> tmp = solver.values();\r
+// String[] keys = new ArrayList<String>(tmp.keySet()).toArray(new String[tmp.size()]);\r
+\r
+ for(int i=0;i<keys.length;i++) {\r
+ values[i] = new double[count];\r
+ values[i][0] = valueArray[i];\r
}\r
\r
// run the simulation\r
solver.step();\r
}\r
times[interval] = times[interval-1] + steps * step;\r
- tmp = solver.values();\r
- for (String key : tmp.keySet()) {\r
- values.get(key)[interval] = tmp.get(key);\r
+\r
+ valueArray = solver.values();\r
+ for(int i=0;i<keys.length;i++) {\r
+ values[i][interval] = valueArray[i];\r
}\r
+ \r
}\r
\r
results = new HashMap<String, SysdynDataSet>();\r
- for (String name : values.keySet()) {\r
- results.put(name, new SysdynDataSet(name, null, times, values.get(name)));\r
+ for(int i=0;i<keys.length;i++) {\r
+ String name = keys[i];\r
+ double[] arr = values[i];\r
+ results.put(name, new SysdynDataSet(name, null, times, arr));\r
}\r
+\r
+// for (String name : values.keySet()) {\r
+// results.put(name, new SysdynDataSet(name, null, times, values.get(name)));\r
+// }\r
+ \r
+ long endTime = System.nanoTime();\r
+ \r
+ System.err.println("ran simulation in " + 1e-6*(endTime-startTime) + "ms.");\r
+ \r
}\r
\r
@Override\r
protected String name;\r
protected SysdynExperiment experiment;\r
protected ISolver solver;\r
+ protected ISolverMonitor solverMonitor;\r
\r
public SysdynSimulationJob(String name, SysdynExperiment experiment) {\r
super(name);\r
this.name = name;\r
this.experiment = experiment;\r
this.solver = null;\r
+ this.solverMonitor = SysdynConsole.INSTANCE;\r
}\r
\r
@Override\r
// has changed, a new solver must be created\r
if (solver == null || !solver.getType().equals(type)) {\r
if (SolverType.INTERNAL.equals(type)) {\r
- solver = new InternalSolver(experiment, experiment.sysdynModel, SysdynConsole.INSTANCE);\r
+ solver = new InternalSolver(experiment, experiment.sysdynModel, solverMonitor);\r
}\r
else if (SolverType.OPENMODELICA.equals(type)) {\r
return new Status(Status.ERROR, pluginId, "The experiment should be reloaded");\r