]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
refs #5198
authorvillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 21 Aug 2014 08:23:13 +0000 (08:23 +0000)
committervillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 21 Aug 2014 08:23:13 +0000 (08:23 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@30111 ac1ea38d-2e2b-0410-8846-a27921b304fc

fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Array.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Derivate.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseDivision.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseProduct.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Multiplication.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Solver.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Subtraction.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Variable.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt

index 68a0504bf4eecfed8c8a037c65c15309d95daf88..d0ceff4f2b3a340c33dcf6a75e5c5a78bd4c0246 100644 (file)
@@ -21,6 +21,8 @@ public class Array implements IExpression {
        public static final Array FULL = new Array();\r
        \r
        final private ArrayList<Object> elements;\r
+       \r
+       boolean isVector = true;\r
 \r
        public Array() {\r
                elements = new ArrayList<Object>();\r
@@ -32,7 +34,15 @@ public class Array implements IExpression {
 \r
        public Array addElement(Object element) {\r
                if(element instanceof Constant) addElement(((Constant)element).value);\r
-               else elements.add(element);\r
+               else {\r
+                       \r
+//                     if(element instanceof Double)\r
+//                             if(Double.isNaN((Double)element))\r
+//                                     throw new IllegalStateException();\r
+\r
+                       if(element instanceof Array) isVector = false;\r
+                       elements.add(element);\r
+               }\r
                return this;\r
        }\r
        \r
@@ -307,6 +317,29 @@ public class Array implements IExpression {
                return result;\r
        }\r
 \r
+       public Array sub(Array other) {\r
+               Array result = new Array();\r
+               Collection<Object> lae = elements();\r
+               Collection<Object> rae = other.elements();\r
+               if(lae.size() != rae.size()) throw new IllegalStateException();\r
+               Iterator<Object> li = lae.iterator();\r
+               Iterator<Object> ri = rae.iterator();\r
+               for(int i=0;i<lae.size();i++) {\r
+                       Object l = li.next();\r
+                       Object r = ri.next();\r
+                       if(l instanceof Double && r instanceof Double) {\r
+                               result.addElement(((Double)l)-((Double)r));\r
+                       } else if (l instanceof Array && r instanceof Array) {\r
+                               Array arr = (Array)l;\r
+                               Array otherArr = (Array)r;\r
+                               result.addElement(arr.sub(otherArr));\r
+                       } else {\r
+                               throw new IllegalStateException();\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+\r
        public Array mul(Array other) {\r
                Array result = new Array();\r
                Collection<Object> lae = elements();\r
@@ -329,6 +362,27 @@ public class Array implements IExpression {
                }\r
                return result;\r
        }\r
+       /*\r
+        * Both arrays are vectors \r
+        */\r
+       public double inner(Array other) {\r
+               double result = 0;\r
+               Collection<Object> lae = elements();\r
+               Collection<Object> rae = other.elements();\r
+               if(lae.size() != rae.size()) throw new IllegalStateException();\r
+               Iterator<Object> li = lae.iterator();\r
+               Iterator<Object> ri = rae.iterator();\r
+               for(int i=0;i<lae.size();i++) {\r
+                       Object l = li.next();\r
+                       Object r = ri.next();\r
+                       if(l instanceof Double && r instanceof Double) {\r
+                               result += ((Double)l)*((Double)r);\r
+                       } else {\r
+                               throw new IllegalStateException();\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
 \r
        public Array pow(Array other) {\r
                Array result = new Array();\r
@@ -378,5 +432,9 @@ public class Array implements IExpression {
                }\r
                return result;\r
        }\r
+       \r
+       public boolean isVector() {\r
+               return isVector;\r
+       }\r
 \r
 }\r
index 7d26af5630dc37235d18569a7fcb820211b29d18..6e3772a8c781a1f8bdfe649398b22db9e49c148a 100644 (file)
@@ -28,10 +28,27 @@ public class Derivate implements IExpression {
        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.base.index(_environment, subscripts));\r
+               Object old = variable.evaluate(environment);\r
+               \r
+//             Double old = (Double)environment.getValue(variable.base.index(_environment, subscripts));\r
                // FIXME: should not be fixed like this\r
                if(old == null) old = 0.0;\r
-               return old+environment.step*(Double)e.evaluate(environment);\r
+               Object eval = e.evaluate(environment);\r
+               if(eval instanceof Double) {\r
+                       return ((Double)old)+environment.step*(Double)eval;\r
+               } else if (eval instanceof Array) {\r
+                       Array arr = (Array)eval;\r
+                       Array oldArray = (Array)old;\r
+                       Array result = new Array();\r
+                       for(int i=0;i<arr.dimension();i++) {\r
+                               Double d = (Double)arr.element(i);\r
+                               Double o = (Double)oldArray.element(i);\r
+                               result.addElement(o+environment.step*d);\r
+                       }\r
+                       return result;\r
+               } else {\r
+                       throw new UnsupportedOperationException();\r
+               }\r
        }\r
        \r
        @Override\r
index 77362aa55ac60b302fdaef36d042ad86aecc58a3..51c91e92fb0ba38655c17f4b59cd6ddf978d5cd2 100644 (file)
@@ -59,6 +59,10 @@ public class ElementwiseDivision implements IExpression {
                                result.addElement(ld/rd);\r
                        }\r
                        return result;\r
+               } else if(left instanceof Double && right instanceof Double) {\r
+                       double ld = (Double)left;\r
+                       double rd = (Double)right;\r
+                       return ld*rd;\r
                } else {\r
                        throw new UnsupportedOperationException();\r
                }\r
index f87529c53fe4e52cb2d59ec303b05f27fa0347b1..fa670ac86793c5e7781375a001c512b43440a12f 100644 (file)
@@ -58,6 +58,16 @@ public class ElementwiseProduct implements IExpression {
                                result.addElement(ld*rd);\r
                        }\r
                        return result;\r
+               } else if (left instanceof Double && right instanceof Array) {\r
+                       Array ra = (Array)right;\r
+                       Double ld = (Double)left;\r
+                       List<Object> rae = ra.elements();\r
+                       Array result = new Array(rae.size());\r
+                       for(Object o : rae) {\r
+                               Double rd = (Double)o;\r
+                               result.addElement(ld*rd);\r
+                       }\r
+                       return result;\r
                } else {\r
                        throw new UnsupportedOperationException();\r
                }\r
index e4b1337a5a10522972e4c36a193543caf976f0cd..a5fde8b0204924b23ed8a1803c0b04674b96c447 100644 (file)
@@ -122,20 +122,54 @@ class Model implements IFrame {
                        }\r
                        \r
                        Variable[] parameters = fn.parameters();\r
+                       Object[] ps = new Object[parameters.length];\r
                        \r
+                       int vectorDimension = 0;\r
                        for(int i=0;i<parameters.length;i++) {\r
                                Variable var = parameters[i];\r
                                if(i < argh.size()) {\r
-                                       Object value = argh.get(i);\r
-                                       var.assignPlain(frame, value);\r
+                                       ps[i] = argh.get(i);\r
                                } else {\r
-                                       Object value = fn.evaluateInput(environment, i);\r
-                                       var.assignPlain(frame, value);\r
+                                       ps[i] = fn.evaluateInput(environment, i);\r
                                }\r
+                               if(var.base.dimensions == null && ps[i] instanceof Array)\r
+                                       vectorDimension = ((Array)ps[i]).dimension();\r
                        }\r
                        \r
-                       fn.setLocals(frame);\r
-                       return fn.evaluate(frame, args.args.length);\r
+                       if(vectorDimension > 0) {\r
+\r
+                               Array result = new Array();\r
+                               \r
+                               for(int i=0;i<vectorDimension;i++) {\r
+\r
+                                       for(int j=0;j<parameters.length;j++) {\r
+                                               Object o = ps[j];\r
+                                               if(o instanceof Array) {\r
+                                                       Object sub = ((Array)o).element(i);\r
+                                                       parameters[j].assignPlain(frame, sub);\r
+                                               } else {\r
+                                                       parameters[j].assignPlain(frame, o);\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       fn.setLocals(frame);\r
+                                       Object ret = fn.evaluate(frame, args.args.length);\r
+                                       result.addElement(ret);\r
+                                       \r
+                               }\r
+                               \r
+                               return result;\r
+                               \r
+                       } else {\r
+                       \r
+                               for(int i=0;i<parameters.length;i++) {\r
+                                       parameters[i].assignPlain(frame, ps[i]);\r
+                               }\r
+                               \r
+                               fn.setLocals(frame);\r
+                               return fn.evaluate(frame, args.args.length);\r
+                               \r
+                       }\r
                        \r
                }\r
                        \r
index e4d29b2cd32b62b81d961dd61bbd9c22e866be8e..154d4e91b4268ab4dfbc12ddebba1150f2be03a1 100644 (file)
@@ -38,7 +38,9 @@ public class Multiplication implements IExpression {
                else if(left instanceof Array && right instanceof Array) {\r
                        Array la = (Array)left;\r
                        Array ra = (Array)right;\r
-                       return la.mul(ra);\r
+                       if(la.isVector && ra.isVector) {\r
+                               return la.inner(ra);\r
+                       }\r
                }\r
                else if (left instanceof Array && right instanceof Double) return ((Array)left).mul((Double)right);\r
                else if (left instanceof Double && right instanceof Array) return ((Array)right).mul((Double)left);\r
index 6ea46d57300767a0b6291b6d0974406f7a2b8757..dd1e876ffdff07c47d61e084ceb8a8248b7a3097 100644 (file)
@@ -30,16 +30,15 @@ public class Solver {
 \r
        private static final boolean PRINT_EXCEPTIONS = false;  \r
        private static final int STACK_SIZE = 1000;\r
+       private static final int MAX_LOOPS = 50;\r
 \r
        private Model model;\r
        private Environment env;\r
 \r
        private Object[] newValues;\r
-       private Object[] derivatives;\r
        \r
        private double defaultStep;\r
        private double start;\r
-       private NodeCache cache;\r
        private boolean ready;\r
        \r
        private boolean dirty;\r
@@ -49,7 +48,6 @@ public class Solver {
                defaultStep = 0.1;\r
                start = 0;\r
                // is it okay to store the cache with the solver instance?\r
-               cache = new NodeCache();\r
                ready = false;\r
        }\r
        \r
@@ -112,6 +110,17 @@ public class Solver {
        private SimpleNode n;\r
        private String codeCache = null;\r
        \r
+       private void validate(Variable var, Object value) {\r
+               if(value instanceof Double) {\r
+                       if(Double.isNaN((Double)value)) {\r
+                               throw new IllegalStateException("value is invalid (NaN)");\r
+                       }\r
+               }\r
+               if(value instanceof Array) {\r
+                       for(Object o : ((Array)value).elements()) validate(var, o);\r
+               }\r
+       }\r
+       \r
        public void prepare(String input) throws Exception {\r
                \r
                long startNanos = System.nanoTime();\r
@@ -148,13 +157,16 @@ public class Solver {
                model.parameterArray = model.parameters.toArray(new ParameterDeclaration[model.parameters.size()]);\r
                \r
                newValues = new Object[Math.max(model.assignments.size(),model.derivatives.size())];\r
-               derivatives = new Object[model.derivatives.size()];\r
                \r
                int condition = 1;\r
                int loops = 0;\r
                \r
-               while(condition > 0 && loops++ < 50) {\r
+               StringBuilder errors = null;\r
+               \r
+               while(condition > 0 && loops++ < MAX_LOOPS) {\r
 \r
+                       if(loops == MAX_LOOPS) errors = new StringBuilder();\r
+                       \r
                        if(PRINT_EXCEPTIONS) {\r
                                System.err.println("== LOOP " + loops + " ==");\r
                        }\r
@@ -164,14 +176,21 @@ public class Solver {
                        for(ParameterDeclaration pd : model.parameters) {\r
                                try {\r
                                        if(!pd.assigned) {\r
-                                               pd.variable.assign(env, null, pd.modification.evaluate(env));\r
+                                               Object value = pd.modification.evaluate(env);\r
+                                               validate(pd.variable, value);\r
+                                               pd.variable.assign(env, null, value);\r
                                                pd.assigned = true;\r
                                        }\r
                                } catch (Exception e) {\r
+                                       String error = "  -" + pd.variable.toString() + ": " + e.getMessage();\r
+                                       if(errors != null) {\r
+                                               errors.append(error);\r
+                                               errors.append("\n");\r
+                                       }\r
                                        condition++;\r
                                        if(PRINT_EXCEPTIONS) {\r
                                                e.printStackTrace();\r
-                                               System.err.println("failed to assign " + pd.variable.toString());\r
+                                               System.err.println(error);\r
                                        }\r
                                }\r
                        }\r
@@ -187,12 +206,16 @@ public class Solver {
                                                        if(arg.name.endsWith("start")) {\r
                                                                Object value = arg.modification.evaluate(env);\r
                                                                if(vd.variable.base.dimension() == 1) {\r
+                                                                       validate(vd.variable, value);\r
                                                                        vd.variable.assign(env, null, value);\r
                                                                } else {\r
+                                                                       validate(vd.variable, value);\r
                                                                        if(value instanceof Double) {\r
                                                                                Array array = new Array();\r
                                                                                for(int i=0;i<vd.variable.base.dimension();i++) array.addElement(value);\r
                                                                                vd.variable.assign(env, null, array);\r
+                                                                       } else if (value instanceof Array) {\r
+                                                                               vd.variable.assign(env, null, value);\r
                                                                        } else {\r
                                                                                throw new IllegalStateException();\r
                                                                        }\r
@@ -209,10 +232,15 @@ public class Solver {
                                                }\r
                                        }\r
                                } catch (Exception e) {\r
+                                       String error = "  -" + vd.variable.toString() + ": " + e.getMessage();\r
+                                       if(errors != null) {\r
+                                               errors.append(error);\r
+                                               errors.append("\n");\r
+                                       }\r
                                        condition++;\r
                                        if(PRINT_EXCEPTIONS) {\r
                                                e.printStackTrace();\r
-                                               System.err.println("failed to assign " + vd.variable.toString());\r
+                                               System.err.println(error);\r
                                        }\r
                                }\r
                        }\r
@@ -222,20 +250,29 @@ public class Solver {
                                        if(!ass.assigned) {\r
                                                Object value = ass.expression.evaluate(env);\r
                                                if(value != null) {\r
+                                                       validate(ass.target, value);\r
                                                        ass.target.assign(env, ass.subscripts, value);\r
                                                        ass.assigned = true;\r
                                                }\r
                                        }\r
                                } catch (Exception e) {\r
+                                       String error = "  -" + ass.target.toString() + ": " + e.getMessage();\r
+                                       if(errors != null) {\r
+                                               errors.append(error);\r
+                                               errors.append("\n");\r
+                                       }\r
                                        condition++;\r
                                        if(PRINT_EXCEPTIONS) {\r
                                                e.printStackTrace();\r
-                                               System.err.println("failed to assign " + ass.target.toString());\r
+                                               System.err.println(error);\r
                                        }\r
                                }\r
                        }\r
                }\r
                \r
+               if(loops == (MAX_LOOPS+1))\r
+                       throw new IllegalStateException("Did not find initial state for model:\n" + errors.toString());\r
+               \r
                for(Assignment ass : model.assignments) {\r
                        if(ass.expression instanceof Constant)\r
                                ass.isConstant = true;\r
index 7534d1fbbc0e471a57f15f1207b2ccfe03fa7510..4ef86db87e688f6bbf195ba697315f33201ccb6a 100644 (file)
@@ -30,10 +30,18 @@ public class Subtraction implements IExpression {
     \r
        @Override\r
        public Object evaluate(IEnvironment environment) {\r
-               Double d1 = (Double)exp1.evaluate(environment);\r
-               Double d2 = (Double)exp2.evaluate(environment);\r
-               if(d1 == null || d2 == null) return null;\r
-               return d1-d2;\r
+               Object o1 = exp1.evaluate(environment);\r
+               Object o2 = exp2.evaluate(environment);\r
+               if(o1 == null || o2 == null) return null; \r
+               if(o1 instanceof Double && o2 instanceof Double) {\r
+                       return (Double)o1 - (Double)o2;\r
+               }\r
+               if(o1 instanceof Array && o2 instanceof Array) {\r
+                       Array la = (Array)o1;\r
+                       Array ra = (Array)o2;\r
+                       return la.sub(ra);\r
+               }\r
+               throw new IllegalStateException();\r
        }\r
        \r
        @Override\r
index 9335f68f77a6fcaa97490583747a0e50f60e3974..9420424bf3de6232dc88a1ff15086f47c170d6a5 100644 (file)
@@ -119,6 +119,11 @@ public class Variable implements IExpression {
                env.put(base.index, value);\r
        }\r
        \r
+       private int subscriptLength() {\r
+               if(this.subscripts == null) return 1;\r
+               return this.subscripts.length;\r
+       }\r
+       \r
        private void validateSize(IEnvironment env, IExpression[] subscripts, Object value) {\r
                \r
                if(value == null) return;\r
@@ -134,7 +139,7 @@ public class Variable implements IExpression {
                        }\r
                } else {\r
                        if(subscripts == null) {\r
-                               if(base.dimensions.length == this.subscripts.length && value instanceof Double) \r
+                               if(base.dimensions.length == subscriptLength() && value instanceof Double) \r
                                        return;\r
                                if(!(value instanceof Array))\r
                                        throw new IllegalStateException();\r
index 977d83d7ce37f61b67ec5204c1041c8ec5ac6628..7c4de3d30facd179525eced6d149fe5a9a28859b 100644 (file)
@@ -71,7 +71,7 @@ TOKEN:
 | "*" | "/" | ".*" | "./"\r
 | "^" | ".^"\r
 | "=" | ":=" \r
-| <IDENT: ["a"-"z","A"-"Z","_"] (["a"-"z","A"-"Z","_",".", "0"-"9"])* >\r
+| <IDENT: ["a"-"z","A"-"Z","_"] (["a"-"z","A"-"Z","_","0"-"9"] | "." ["a"-"z","A"-"Z","_","0"-"9"])* >\r
 | <STRING: "\"" (~["\"", "\\", "\n"] | "\\" ~["\n"])* "\"">\r
     { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); }\r
 | <EXP: "e" | "e-" | "E" | "E-" | "E+" | "e+" >\r
@@ -641,7 +641,7 @@ void arithmetic_expression() : {
 \r
 void add_op() : {\r
 } {\r
-    "+" { jjtThis.op = "+";} | "-" { jjtThis.op = "-";} | ".+" | ".-"\r
+    "+" { jjtThis.op = "+";} | "-" { jjtThis.op = "-";} | ".+" { jjtThis.op = ".+";} | ".-" { jjtThis.op = ".-";}\r
 }\r
 \r
 \r
@@ -652,7 +652,7 @@ void term() : {
 \r
 void mul_op() : {\r
 } {\r
-    "*" { jjtThis.op = "*";} | "/" { jjtThis.op = "/";} | ".*" { jjtThis.op = ".*";} | "./"  { jjtThis.op = "./";}\r
+    ".*" { jjtThis.op = ".*";} | "./"  { jjtThis.op = "./";} | "*" { jjtThis.op = "*";} | "/" { jjtThis.op = "/";} \r
 }\r
 \r
 void factor() : {\r