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
\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
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
}\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
}\r
return result;\r
}\r
+ \r
+ public boolean isVector() {\r
+ return isVector;\r
+ }\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.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
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
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
}\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
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
\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
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
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
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
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
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
}\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
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
\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
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
}\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
| "*" | "/" | ".*" | "./"\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
\r
void add_op() : {\r
} {\r
- "+" { jjtThis.op = "+";} | "-" { jjtThis.op = "-";} | ".+" | ".-"\r
+ "+" { jjtThis.op = "+";} | "-" { jjtThis.op = "-";} | ".+" { jjtThis.op = ".+";} | ".-" { jjtThis.op = ".-";}\r
}\r
\r
\r
\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