]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Multiple bugfixes for project model
authorvillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 3 Sep 2014 12:24:45 +0000 (12:24 +0000)
committervillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 3 Sep 2014 12:24:45 +0000 (12:24 +0000)
refs #5224

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

13 files changed:
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java
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/Division.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseDivision.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwisePower.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseProduct.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Function.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Subtraction.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableBase.java

index 8c09ab6f8ad7c812bef468bd4fd25f205dd5cd17..6c531d4149ade70a4a81d9d673e4f6c84997caab 100644 (file)
@@ -12,6 +12,8 @@ package fi.semantum.sysdyn.solver;
 \r
 import java.util.Map;\r
 \r
+import fi.semantum.sysdyn.solver.Array.Modifier2;\r
+\r
 public class Addition implements IExpression {\r
        \r
     public IExpression exp1;\r
@@ -38,7 +40,14 @@ public class Addition implements IExpression {
                if(o1 instanceof Array && o2 instanceof Array) {\r
                        Array la = (Array)o1;\r
                        Array ra = (Array)o2;\r
-                       return la.add(ra);\r
+                       return la.copy2(ra, new Modifier2() {\r
+                               \r
+                               @Override\r
+                               public Object modify(Object o1, Object o2) {\r
+                                       if(o1 instanceof Double && o2 instanceof Double) return ((Double)o1)+((Double)o2);\r
+                                       throw new IllegalStateException("Tried to add a non-numerical array");\r
+                               }\r
+                       });\r
                }\r
                throw new IllegalStateException();\r
        }\r
index eaa4cca140e9536bb46f9aef7cbd7d099eed53e1..8c34ffc4c43cbe3250973962109f7937569a2cc3 100644 (file)
@@ -301,75 +301,7 @@ public class Array implements IExpression {
                throw new IllegalStateException();\r
                \r
        }\r
-       \r
-       public Array add(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.add(otherArr));\r
-                       } else {\r
-                               throw new IllegalStateException();\r
-                       }\r
-               }\r
-               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
-               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.mul(otherArr));\r
-                       } else {\r
-                               throw new IllegalStateException();\r
-                       }\r
-               }\r
-               return result;\r
-       }\r
        /*\r
         * Both arrays are vectors \r
         */\r
@@ -445,6 +377,10 @@ public class Array implements IExpression {
                Object modify(Object o);\r
        }\r
        \r
+       interface Modifier2 {\r
+               Object modify(Object o1, Object o2);\r
+       }\r
+\r
        public Array copy(Modifier modifier) {\r
                Array result = new Array();\r
                for(Object element : elements) {\r
@@ -458,6 +394,33 @@ public class Array implements IExpression {
                return result;\r
        }\r
        \r
+       public Array copy2(Array other, Modifier2 modifier) {\r
+               Array result = new Array();\r
+               Collection<Object> es = elements();\r
+               Collection<Object> oes = other.elements();\r
+               if(es.size() != oes.size()) throw new IllegalStateException("Array dimensions do not match");\r
+               Iterator<Object> e = es.iterator();\r
+               Iterator<Object> oe = oes.iterator();\r
+               for(int i=0;i<es.size();i++) {\r
+                       Object element = e.next();\r
+                       Object otherElement = oe.next();\r
+                       if(element instanceof Array) {\r
+                               if(otherElement instanceof Array) {\r
+                                       result.addElement(((Array)element).copy2((Array)otherElement, modifier));\r
+                               } else {\r
+                                       throw new IllegalStateException("Array dimensions do not match");\r
+                               }\r
+                       } else {\r
+                               if(otherElement instanceof Array) {\r
+                                       throw new IllegalStateException("Array dimensions do not match");\r
+                               } else {\r
+                                       result.addElement(modifier.modify(element, otherElement));\r
+                               }\r
+                       }                               \r
+               }\r
+               return result;\r
+       }\r
+\r
        public boolean isVector() {\r
                return isVector;\r
        }\r
@@ -474,13 +437,13 @@ public class Array implements IExpression {
                                        if(element instanceof Array) throw new IllegalStateException();\r
                                        if(element instanceof IExpression) {\r
                                                IExpression exp = (IExpression)element;\r
-                                               return exp.evaluate(environment);\r
+                                               ret.addElement(exp.evaluate(environment));\r
                                        } else {\r
                                                ret.addElement(element);\r
                                        }\r
                                } else {\r
                                        if(element instanceof Array) {\r
-                                               return ret.addElement(((Array)element).subscript(environment, subscripts, position+1));\r
+                                               ret.addElement(((Array)element).subscript(environment, subscripts, position+1));\r
                                        } else {\r
                                                throw new IllegalStateException();\r
                                        }\r
index 6e3772a8c781a1f8bdfe649398b22db9e49c148a..b5194f7f0812972cfba07277b4adf044825ab149 100644 (file)
@@ -12,6 +12,8 @@ package fi.semantum.sysdyn.solver;
 \r
 import java.util.Map;\r
 \r
+import fi.semantum.sysdyn.solver.Array.Modifier2;\r
+\r
 public class Derivate implements IExpression {\r
 \r
        private Variable variable;\r
@@ -26,11 +28,9 @@ public class Derivate implements IExpression {
        \r
        @Override\r
        public Object evaluate(IEnvironment _environment) {\r
-               Environment environment = (Environment)_environment;\r
-//             Double old = (Double)environment.getValue(variable.name + variable.subscriptKey());\r
+               final Environment environment = (Environment)_environment;\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
                Object eval = e.evaluate(environment);\r
@@ -39,13 +39,18 @@ public class Derivate implements IExpression {
                } 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
+                       \r
+                       return oldArray.copy2(arr, new Modifier2() {\r
+\r
+                               @Override\r
+                               public Object modify(Object o1, Object o2) {\r
+                                       Double oldValue = (Double)o1;\r
+                                       Double der = (Double)o2;\r
+                                       return oldValue + environment.step*der;\r
+                               }\r
+                               \r
+                       });\r
+                       \r
                } else {\r
                        throw new UnsupportedOperationException();\r
                }\r
index d8d357feb3d30d9aab731dda97ebf948641916bf..42ce059792b360260257ad30cc2b3ec4733a89cf 100644 (file)
@@ -12,6 +12,8 @@ package fi.semantum.sysdyn.solver;
 \r
 import java.util.Map;\r
 \r
+import fi.semantum.sysdyn.solver.Array.Modifier;\r
+\r
 public class Division implements IExpression {\r
        \r
     public IExpression exp1;\r
@@ -27,16 +29,17 @@ public class Division implements IExpression {
        return exp1 + " / " + exp2;\r
     }\r
     \r
-    private Array arrayDiv(Array a, Double d) {\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
+    private Array arrayDiv(Array a, final Double d) {\r
+       return a.copy(new Modifier() {\r
+                       @Override\r
+                       public Object modify(Object o) {\r
+                       if(o instanceof Double) {\r
+                               return ((Double)o)/d;\r
+                       } else {\r
+                               throw new IllegalStateException();\r
+                       }\r
+                       }\r
+               });\r
     }\r
     \r
        @Override\r
index 51c91e92fb0ba38655c17f4b59cd6ddf978d5cd2..ffb93df7ad7b2d1afd247310064e6592cd5affcb 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
-import java.util.Collection;\r
-import java.util.Iterator;\r
 import java.util.Map;\r
 \r
+import fi.semantum.sysdyn.solver.Array.Modifier;\r
+import fi.semantum.sysdyn.solver.Array.Modifier2;\r
+\r
 public class ElementwiseDivision implements IExpression {\r
        \r
     public IExpression exp1;\r
@@ -36,33 +37,41 @@ public class ElementwiseDivision implements IExpression {
                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
+                       return la.copy2(ra, new Modifier2() {\r
+                               \r
+                               @Override\r
+                               public Object modify(Object o1, Object o2) {\r
+                                       if(o1 instanceof Double && o2 instanceof Double) return ((Double)o1)/((Double)o2);\r
+                                       throw new IllegalStateException("Tried to divide a non-numerical array");\r
+                               }\r
+                               \r
+                       });\r
                } else if(left instanceof Array && right instanceof Double) {\r
                        Array la = (Array)left;\r
-                       double rd = (Double)right;\r
-                       Collection<Object> lae = la.elements();\r
-                       Iterator<Object> li = lae.iterator();\r
-                       Array result = new Array();\r
-                       for(int i=0;i<lae.size();i++) {\r
-                               double ld = (Double)li.next();\r
-                               result.addElement(ld/rd);\r
-                       }\r
-                       return result;\r
+                       final double rd = (Double)right;\r
+                       return la.copy(new Modifier() {\r
+\r
+                               @Override\r
+                               public Object modify(Object o) {\r
+                                       if(o instanceof Double) return ((Double)o)/rd;\r
+                                       else throw new IllegalStateException("Tried to divide a non-numerical array");\r
+                               }\r
+                               \r
+                       });\r
+               } else if(left instanceof Double && right instanceof Array) {\r
+                       Array la = (Array)right;\r
+                       final double rd = (Double)left;\r
+                       return la.copy(new Modifier() {\r
+\r
+                               @Override\r
+                               public Object modify(Object o) {\r
+                                       if(o instanceof Double) return rd / ((Double)o);\r
+                                       else throw new IllegalStateException("Tried to divide a non-numerical array");\r
+                               }\r
+                               \r
+                       });\r
                } else if(left instanceof Double && right instanceof Double) {\r
-                       double ld = (Double)left;\r
-                       double rd = (Double)right;\r
-                       return ld*rd;\r
+                       return ((Double)left)/((Double)right);\r
                } else {\r
                        throw new UnsupportedOperationException();\r
                }\r
index 6fac7280f2da4b7734e414ebfb97175671ee798d..15ac7bc56a116149c58bd159e53dc2a0961a15f1 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
-import java.util.Collection;\r
-import java.util.Iterator;\r
 import java.util.Map;\r
 \r
+import fi.semantum.sysdyn.solver.Array.Modifier;\r
+import fi.semantum.sysdyn.solver.Array.Modifier2;\r
+\r
 public class ElementwisePower implements IExpression {\r
        \r
     public IExpression exp1;\r
@@ -36,19 +37,41 @@ public class ElementwisePower implements IExpression {
                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(Math.pow(ld,rd));\r
-                       }\r
-                       return result;\r
-               } else throw new UnsupportedOperationException();\r
+                       return la.copy2(ra, new Modifier2() {\r
+                               \r
+                               @Override\r
+                               public Object modify(Object o1, Object o2) {\r
+                                       if(o1 instanceof Double && o2 instanceof Double) return Math.pow((Double)o1,(Double)o2);\r
+                                       throw new IllegalStateException("Tried to pow a non-numerical array");\r
+                               }\r
+                       });\r
+               } else if (left instanceof Array && right instanceof Double) {\r
+                       Array la = (Array)left;\r
+                       final double rd = (Double)right;\r
+                       return la.copy(new Modifier() {\r
+\r
+                               @Override\r
+                               public Object modify(Object o) {\r
+                                       if(o instanceof Double) return Math.pow((Double)o,rd);\r
+                                       else throw new IllegalStateException("Tried to pow a non-numerical array");\r
+                               }\r
+                               \r
+                       });\r
+               } else if (left instanceof Double && right instanceof Array) {\r
+                       Array la = (Array)right;\r
+                       final double rd = (Double)left;\r
+                       return la.copy(new Modifier() {\r
+\r
+                               @Override\r
+                               public Object modify(Object o) {\r
+                                       if(o instanceof Double) return Math.pow(rd,(Double)o);\r
+                                       else throw new IllegalStateException("Tried to pow a non-numerical array");\r
+                               }\r
+                               \r
+                       });\r
+               } else {\r
+                       throw new UnsupportedOperationException();\r
+               }\r
        }\r
        \r
        @Override\r
index fa670ac86793c5e7781375a001c512b43440a12f..b15f67819bb671cc2a66b2bfac1a335f1c4c7c3e 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
-import java.util.Collection;\r
-import java.util.Iterator;\r
-import java.util.List;\r
 import java.util.Map;\r
 \r
+import fi.semantum.sysdyn.solver.Array.Modifier;\r
+import fi.semantum.sysdyn.solver.Array.Modifier2;\r
+\r
 public class ElementwiseProduct implements IExpression {\r
        \r
     public IExpression exp1;\r
@@ -37,37 +37,38 @@ public class ElementwiseProduct implements IExpression {
                if(left instanceof Array && right instanceof Array) {\r
                        Array la = (Array)left;\r
                        Array ra = (Array)right;\r
-                       List<Object> lae = la.elements();\r
-                       List<Object> rae = ra.elements();\r
-                       if(lae.size() != rae.size()) throw new UnsupportedOperationException();\r
-                       Array result = new Array(lae.size());\r
-                       int index = 0;\r
-                       for(Object o : lae) {\r
-                               Double ld = (Double)o;\r
-                               Double rd = (Double)rae.get(index++);\r
-                               result.addElement(ld*rd);\r
-                       }\r
-                       return result;\r
+                       return la.copy2(ra, new Modifier2() {\r
+                               \r
+                               @Override\r
+                               public Object modify(Object o1, Object o2) {\r
+                                       if(o1 instanceof Double && o2 instanceof Double) return ((Double)o1)*((Double)o2);\r
+                                       throw new IllegalStateException("Tried to multiply a non-numerical array");\r
+                               }\r
+                       });\r
                } else if (left instanceof Array && right instanceof Double) {\r
                        Array la = (Array)left;\r
-                       Double rd = (Double)right;\r
-                       List<Object> lae = la.elements();\r
-                       Array result = new Array(lae.size());\r
-                       for(Object o : lae) {\r
-                               Double ld = (Double)o;\r
-                               result.addElement(ld*rd);\r
-                       }\r
-                       return result;\r
+                       final double rd = (Double)right;\r
+                       return la.copy(new Modifier() {\r
+\r
+                               @Override\r
+                               public Object modify(Object o) {\r
+                                       if(o instanceof Double) return ((Double)o)*rd;\r
+                                       else throw new IllegalStateException("Tried to multiply a non-numerical array");\r
+                               }\r
+                               \r
+                       });\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
+                       Array la = (Array)right;\r
+                       final double rd = (Double)left;\r
+                       return la.copy(new Modifier() {\r
+\r
+                               @Override\r
+                               public Object modify(Object o) {\r
+                                       if(o instanceof Double) return ((Double)o)*rd;\r
+                                       else throw new IllegalStateException("Tried to multiply a non-numerical array");\r
+                               }\r
+                               \r
+                       });\r
                } else {\r
                        throw new UnsupportedOperationException();\r
                }\r
index 84d8afed45b0624bf54bbb31045d06d36bee8bf4..b4dc80e03f168f53fc0a3c8c12bd7fdd9ebf52c5 100644 (file)
@@ -16,6 +16,7 @@ import gnu.trove.list.array.TIntArrayList;
 import gnu.trove.map.hash.TObjectIntHashMap;\r
 \r
 import java.util.ArrayList;\r
+import java.util.Arrays;\r
 import java.util.Collection;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
@@ -29,7 +30,7 @@ interface Fn {
        public Object evaluateInput(IEnvironment environment, int argPosition);\r
        public void setLocals(IEnvironment environment);\r
        public int offset();\r
-       public Variable[] parameters();\r
+       public Variable[] parameters(int args);\r
 }\r
 \r
 abstract class Fn1 implements Fn {\r
@@ -37,17 +38,25 @@ abstract class Fn1 implements Fn {
        Variable[] parameters;\r
        \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
+               if(pCount > 0) {\r
+                       parameters = new Variable[pCount];\r
+                       for(int i=0;i<pCount;i++)\r
+                               parameters[i] = new Variable(new VariableBase("", i));\r
+               }\r
        }\r
        \r
        public int offset() {\r
                return 0;\r
        }\r
        \r
-       public Variable[] parameters() {\r
-               return parameters;\r
+       public Variable[] parameters(int argc) {\r
+               if(parameters != null) return parameters;\r
+               else {\r
+                       Variable[] ret = new Variable[argc];\r
+                       for(int i=0;i<argc;i++)\r
+                               ret[i] = new Variable(new VariableBase("", i));\r
+                       return ret;\r
+               }\r
        }\r
        \r
        @Override\r
@@ -349,38 +358,75 @@ final public class Environment implements IEnvironment, ISystem {
                });\r
                model.functions.put("sum", new Fn1(1) {\r
 \r
+                       public double sum(Array a) {\r
+                               double res = 0;\r
+                               for(Object element : a.elements()) {\r
+                                       if(element instanceof Array) {\r
+                                               res += sum((Array)element);\r
+                                       } else if(element instanceof Double) {\r
+                                               res += (Double)element;\r
+                                       } else {\r
+                                               throw new IllegalStateException("Tried to sum a non-numerical array");\r
+                                       }\r
+                               }\r
+                               return res;\r
+                       }\r
+                       \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
                                Object value = environment.getValue(0);\r
+                               if(value instanceof Double) return (Double)value;\r
                                Array arr = (Array)value;\r
-                               double res = 0;\r
-                               for(Object o : arr.elements())\r
-                                       res += (Double)o;\r
-                               return res;\r
+                               return sum(arr);\r
                        }\r
                        \r
                });\r
-               model.functions.put("ones", new Fn1(1) {\r
+               model.functions.put("ones", new Fn1(-1) {\r
 \r
+                       private Array make(int[] dims, int pos) {\r
+                               Array result = new Array();\r
+                               int d = dims[pos];\r
+                               if(pos == dims.length - 1) {\r
+                                       for(int i=0;i<d;i++) result.addElement(1.0);\r
+                               } else {\r
+                                       for(int i=0;i<d;i++) result.addElement(make(dims, pos+1));\r
+                               }\r
+                               return result;\r
+                       }\r
+                       \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
-                               Object value = environment.getValue(0);\r
-                               Double size = (Double)value;\r
-                               Array res = new Array();\r
-                               for(int i=0;i<size.intValue();i++) res.addElement(1.0);\r
-                               return res;\r
+                               int[] dims = new int[argc];\r
+                               for(int i=0;i<argc;i++) {\r
+                                       Double d = (Double)environment.getValue(0);\r
+                                       dims[i] = d.intValue();\r
+                               }\r
+                               return make(dims, 0);\r
                        }\r
                        \r
                });\r
-               model.functions.put("zeros", new Fn1(1) {\r
+               model.functions.put("zeros", new Fn1(-1) {\r
 \r
+                       private Array make(int[] dims, int pos) {\r
+                               Array result = new Array();\r
+                               int d = dims[pos];\r
+                               if(pos == dims.length - 1) {\r
+                                       for(int i=0;i<d;i++) result.addElement(0.0);\r
+                               } else {\r
+                                       for(int i=0;i<d;i++) result.addElement(make(dims, pos+1));\r
+                               }\r
+                               return result;\r
+                       }\r
+                       \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
-                               Object value = environment.getValue(0);\r
-                               Double size = (Double)value;\r
-                               Array res = new Array();\r
-                               for(int i=0;i<size.intValue();i++) res.addElement(0.0);\r
-                               return res;\r
+                               int[] dims = new int[argc];\r
+                               for(int i=0;i<argc;i++) {\r
+                                       Double d = (Double)environment.getValue(i);\r
+                                       dims[i] = d.intValue();\r
+                               }\r
+                               System.err.println("zeros " + Arrays.toString(dims));\r
+                               return make(dims, 0);\r
                        }\r
                        \r
                });\r
index 3c32e6e98901dd2f076cefd6813a419c6249dc83..200cf3653613fa792b54ccdf0df4ff75f11398a5 100644 (file)
@@ -106,7 +106,7 @@ final public class Function implements Fn, IFrame {
        }\r
        \r
        @Override\r
-       public Variable[] parameters() {\r
+       public Variable[] parameters(int argc) {\r
                return parameters;\r
        }\r
        \r
index e91f0ffc6bcd5203bea79fe6f2ef29bd23830dce..5735e4b6c6a1618c0a628ff26c547dfa34cd21f0 100644 (file)
@@ -29,7 +29,9 @@ public class GreaterThan implements IExpression {
     \r
        @Override\r
        public Object evaluate(IEnvironment environment) {\r
-               return ((Double)exp1.evaluate(environment)) > ((Double)exp2.evaluate(environment));\r
+               Object left = exp1.evaluate(environment);\r
+               Object right = exp2.evaluate(environment);\r
+               return ((Double)left) > ((Double)right);\r
        }\r
 \r
        @Override\r
index a5fde8b0204924b23ed8a1803c0b04674b96c447..537d238f783bd57577f6ab4ea67b824edcc51e38 100644 (file)
@@ -13,6 +13,7 @@ package fi.semantum.sysdyn.solver;
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
 import java.util.HashMap;\r
+import java.util.List;\r
 import java.util.Map;\r
 import java.util.TreeMap;\r
 \r
@@ -98,7 +99,7 @@ class Model implements IFrame {
                                argh.add(args.args[i].modification.evaluate(environment));\r
                        }\r
                        \r
-                       Variable[] parameters = fn.parameters();\r
+                       Variable[] parameters = fn.parameters(argh.size());\r
                        \r
                        for(int i=0;i<args.args.length+1;i++) {\r
                                Variable var = parameters[i];\r
@@ -121,10 +122,12 @@ class Model implements IFrame {
                                argh.add(arg);\r
                        }\r
                        \r
-                       Variable[] parameters = fn.parameters();\r
+                       Variable[] parameters = fn.parameters(args.args.length);\r
                        Object[] ps = new Object[parameters.length];\r
+                       boolean vector[] = new boolean[parameters.length];\r
                        \r
                        int vectorDimension = 0;\r
+                       ArrayList<Array> arrs = new ArrayList<Array>();\r
                        for(int i=0;i<parameters.length;i++) {\r
                                Variable var = parameters[i];\r
                                if(i < argh.size()) {\r
@@ -132,33 +135,20 @@ class Model implements IFrame {
                                } else {\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
+                               if(var.base.dimensions == null && ps[i] instanceof Array) {\r
+                                       int dim = ((Array)ps[i]).dimension();\r
+                                       if(vectorDimension > 0 && dim != vectorDimension) throw new IllegalStateException("Array dimensions do not agree");\r
+                                       vectorDimension = dim;\r
+                                       vector[i] = true;\r
+                                       arrs.add((Array)ps[i]);\r
+                               } else {\r
+                                       vector[i] = false;\r
+                               }\r
                        }\r
                        \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
+                               return arrayEvaluate(frame, fn, parameters, ps, vector, arrs);\r
                                \r
                        } else {\r
                        \r
@@ -167,7 +157,8 @@ class Model implements IFrame {
                                }\r
                                \r
                                fn.setLocals(frame);\r
-                               return fn.evaluate(frame, args.args.length);\r
+                               Object value = fn.evaluate(frame, args.args.length); \r
+                               return value;\r
                                \r
                        }\r
                        \r
@@ -175,6 +166,59 @@ class Model implements IFrame {
                        \r
        }\r
        \r
+       private Array arrayEvaluate(Frame frame, Fn fn, Variable[] parameters, Object[] ps, boolean[] vector, List<Array> arrs) {\r
+               \r
+               Array result = new Array();\r
+\r
+               Array first = arrs.get(0);\r
+               \r
+               int d = first.elements().size();\r
+               if(d == 0) return result;\r
+\r
+               Object firstElement = first.element(0);\r
+               boolean subArray = firstElement instanceof Array;\r
+               \r
+               for(int i=0;i<d;i++) {\r
+\r
+                       int vectorIndex = 0;\r
+\r
+                       if(subArray) {\r
+\r
+                               ArrayList<Array> subArrs = new ArrayList<Array>();\r
+                               for(int j=0;j<parameters.length;j++) {\r
+                                       if(vector[j]) {\r
+                                               Array a = arrs.get(vectorIndex++);\r
+                                               Array sub = (Array)a.element(i);\r
+                                               subArrs.add(sub);\r
+                                       }\r
+                               }\r
+                               \r
+                               result.addElement(arrayEvaluate(frame, fn, parameters, ps, vector, subArrs));\r
+\r
+                       } else {\r
+\r
+                               for(int j=0;j<parameters.length;j++) {\r
+                                       if(vector[j]) {\r
+                                               Array a = arrs.get(vectorIndex++);\r
+                                               Object sub = a.element(i);\r
+                                               parameters[j].assignPlain(frame, sub);\r
+                                       } else {\r
+                                               parameters[j].assignPlain(frame, ps[j]);\r
+                                       }\r
+                               }\r
+\r
+                               fn.setLocals(frame);\r
+                               Object ret = fn.evaluate(frame, parameters.length);\r
+                               result.addElement(ret);\r
+                               \r
+                       }\r
+                       \r
+               }                       \r
+               \r
+               return result;\r
+\r
+       }\r
+       \r
        private VariableBase resolveCopy(Map<String,VariableBase> work, VariableBase target) {\r
                VariableBase deep = work.get(target.name);\r
                if(deep == null) return target;\r
index 4ef86db87e688f6bbf195ba697315f33201ccb6a..e908d74d376c62abd99d4e0663460d5fa1fd1283 100644 (file)
@@ -12,6 +12,8 @@ package fi.semantum.sysdyn.solver;
 \r
 import java.util.Map;\r
 \r
+import fi.semantum.sysdyn.solver.Array.Modifier2;\r
+\r
 public class Subtraction implements IExpression {\r
        \r
     public IExpression exp1;\r
@@ -39,7 +41,14 @@ public class Subtraction implements IExpression {
                if(o1 instanceof Array && o2 instanceof Array) {\r
                        Array la = (Array)o1;\r
                        Array ra = (Array)o2;\r
-                       return la.sub(ra);\r
+                       return la.copy2(ra, new Modifier2() {\r
+                               \r
+                               @Override\r
+                               public Object modify(Object o1, Object o2) {\r
+                                       if(o1 instanceof Double && o2 instanceof Double) return ((Double)o1)-((Double)o2);\r
+                                       throw new IllegalStateException("Tried to subtract a non-numerical array");\r
+                               }\r
+                       });\r
                }\r
                throw new IllegalStateException();\r
        }\r
index e0a57a6c5c77d083604de828a92f54f540a45720..40c75d2db582a6c899ab43ecb36bdb9012e059bb 100644 (file)
@@ -219,24 +219,30 @@ public class VariableBase {
                        else return array;\r
                        \r
                } else {\r
-                       \r
+\r
                        if(dimension() > 1) {\r
+\r
+                               Array array = new Array();\r
+                               intoArray(environment, index, 0, array);\r
                                if(subscripts != null) {\r
-                                       \r
-                                       Array[] sub = SolverUtils.parseSubscripts(environment, subscripts);\r
-                                       if(SolverUtils.isSlice(sub)) {\r
-                                               Array arr = new Array();\r
-                                               intoArray(environment, index, 0, arr);\r
-                                               return arr.slice(sub);\r
-                                       } else { \r
-                                               return environment.getValue(index(environment, subscripts));\r
-                                       }\r
-                                       \r
-                               } else {\r
-                                       Array array = new Array();\r
-                                       intoArray(environment, index, 0, array);\r
-                                       return array;\r
+                                       return array.subscript(environment, subscripts);\r
                                }\r
+                               else return array;\r
+\r
+//                             if(subscripts != null) {\r
+//                                     \r
+//                                     Array[] sub = SolverUtils.parseSubscripts(environment, subscripts);\r
+//                                     if(SolverUtils.isSlice(sub)) {\r
+//                                             Array arr = new Array();\r
+//                                             intoArray(environment, index, 0, arr);\r
+//                                             return arr.slice(sub);\r
+//                                     } else { \r
+//                                             return environment.getValue(index(environment, subscripts));\r
+//                                     }\r
+//                                     \r
+//                             } else {\r
+//                                     return array;\r
+//                             }\r
                        }\r
                        \r
                        Object result = environment.getNamedValue(name);\r