1 8 9 package org.lsmp.djep.djep; 10 import org.lsmp.djep.djep.diffRules.*; 11 import org.lsmp.djep.xjep.*; 12 import org.nfunk.jep.*; 13 import org.nfunk.jep.function.*; 14 import java.util.Hashtable ; 15 import java.util.Enumeration ; 16 import java.io.PrintStream ; 17 18 42 public class DifferentiationVisitor extends DeepCopyVisitor 43 { 44 private static final boolean DEBUG = false; 45 private DJep localDJep; 46 private DJep globalDJep; 47 private NodeFactory nf; 48 private TreeUtils tu; 49 54 public DifferentiationVisitor(DJep jep) 55 { 56 this.globalDJep = jep; 57 58 addDiffRule(new AdditionDiffRule("+")); 59 addDiffRule(new SubtractDiffRule("-")); 60 addDiffRule(new MultiplyDiffRule("*")); 61 addDiffRule(new DivideDiffRule("/")); 62 addDiffRule(new PowerDiffRule("^")); 63 addDiffRule(new PassThroughDiffRule("UMinus",globalDJep.getOperatorSet().getUMinus().getPFMC())); 64 65 } 66 67 68 84 boolean addStandardDiffRules() 85 { 86 try 87 { 88 addDiffRule(new MacroDiffRules(globalDJep,"sin","cos(x)")); 89 addDiffRule(new MacroDiffRules(globalDJep,"cos","-sin(x)")); 90 addDiffRule(new MacroDiffRules(globalDJep,"tan","1/((cos(x))^2)")); 91 92 MacroFunction sec = new MacroFunction("sec",1,"1/cos(x)",globalDJep); 93 globalDJep.addFunction("sec",sec); 94 MacroFunction cosec = new MacroFunction("cosec",1,"1/sin(x)",globalDJep); 95 globalDJep.addFunction("cosec",cosec); 96 MacroFunction cot = new MacroFunction("cot",1,"1/tan(x)",globalDJep); 97 globalDJep.addFunction("cot",cot); 98 99 addDiffRule(new MacroDiffRules(globalDJep,"sec","sec(x) * tan(x)")); 100 addDiffRule(new MacroDiffRules(globalDJep,"cosec","-cosec(x) * cot(x)")); 101 addDiffRule(new MacroDiffRules(globalDJep,"cot","-(cosec(x))^2")); 102 103 addDiffRule(new MacroDiffRules(globalDJep,"asin","1/(sqrt(1-x^2))")); 104 addDiffRule(new MacroDiffRules(globalDJep,"acos","-1/(sqrt(1-x^2))")); 105 addDiffRule(new MacroDiffRules(globalDJep,"atan","1/(1+x^2)")); 106 107 addDiffRule(new MacroDiffRules(globalDJep,"sinh","cosh(x)")); 108 addDiffRule(new MacroDiffRules(globalDJep,"cosh","sinh(x)")); 109 addDiffRule(new MacroDiffRules(globalDJep,"tanh","1-(tanh(x))^2")); 110 111 addDiffRule(new MacroDiffRules(globalDJep,"asinh","1/(sqrt(1+x^2))")); 112 addDiffRule(new MacroDiffRules(globalDJep,"acosh","1/(sqrt(x^2-1))")); 113 addDiffRule(new MacroDiffRules(globalDJep,"atanh","1/(1-x^2)")); 114 115 addDiffRule(new MacroDiffRules(globalDJep,"sqrt","1/(2 (sqrt(x)))")); 116 117 globalDJep.addFunction("exp",new Exp()); 118 addDiffRule(new MacroDiffRules(globalDJep,"exp","exp(x)")); 119 addDiffRule(new MacroDiffRules(globalDJep,"ln","1/x")); 122 addDiffRule(new MacroDiffRules(globalDJep,"log", globalDJep.getNodeFactory().buildOperatorNode(globalDJep.getOperatorSet().getDivide(), 124 globalDJep.getNodeFactory().buildConstantNode( 125 globalDJep.getTreeUtils().getNumber(1/Math.log(10.0))), 126 globalDJep.getNodeFactory().buildVariableNode(globalDJep.getSymbolTable().makeVarIfNeeded("x"))))); 127 addDiffRule(new MacroDiffRules(globalDJep,"abs","abs(x)/x")); 129 addDiffRule(new MacroDiffRules(globalDJep,"angle","y/(x^2+y^2)","-x/(x^2+y^2)")); 130 addDiffRule(new MacroDiffRules(globalDJep,"mod","1","0")); 131 addDiffRule(new PassThroughDiffRule(globalDJep,"sum")); 132 addDiffRule(new PassThroughDiffRule(globalDJep,"re")); 133 addDiffRule(new PassThroughDiffRule(globalDJep,"im")); 134 addDiffRule(new PassThroughDiffRule(globalDJep,"rand")); 135 136 MacroFunction complex = new MacroFunction("macrocomplex",2,"x+i*y",globalDJep); 137 globalDJep.addFunction("macrocomplex",complex); 138 addDiffRule(new MacroFunctionDiffRules(globalDJep,complex)); 139 140 147 151 155 return true; 158 } 159 catch(ParseException e) 160 { 161 System.err.println(e.getMessage()); 162 return false; 163 } 164 } 165 166 167 Hashtable diffRules = new Hashtable (); 168 169 void addDiffRule(DiffRulesI rule) 170 { 171 diffRules.put(rule.getName(),rule); 172 if(DEBUG) System.out.println("Adding rule for "+rule.getName()); 173 } 174 175 DiffRulesI getDiffRule(String name) 176 { 177 return (DiffRulesI) diffRules.get(name); 178 } 179 180 183 public void printDiffRules() { printDiffRules(System.out); } 184 185 188 public void printDiffRules(PrintStream out) 189 { 190 out.println("Standard Functions and their derivatives"); 191 for(Enumeration enume = globalDJep.getFunctionTable().keys(); enume.hasMoreElements();) 192 { 193 String key = (String ) enume.nextElement(); 194 PostfixMathCommandI value = (PostfixMathCommandI) globalDJep.getFunctionTable().get(key); 195 DiffRulesI rule = (DiffRulesI) diffRules.get(key); 196 if(rule==null) 197 out.print(key+" No diff rules specified ("+value.getNumberOfParameters()+" arguments)."); 198 else 199 out.print(rule.toString()); 200 out.println(); 201 } 202 for(Enumeration enume = diffRules.keys(); enume.hasMoreElements();) 203 { 204 String key = (String ) enume.nextElement(); 205 DiffRulesI rule = (DiffRulesI) diffRules.get(key); 206 if(!globalDJep.getFunctionTable().containsKey(key)) 207 { 208 out.print(rule.toString()); 209 out.println("\tnot in JEP function list"); 210 } 211 } 212 } 213 214 222 public Node differentiate(Node node,String var,DJep djep) throws ParseException,IllegalArgumentException 223 { 224 this.localDJep = djep; 225 this.nf=djep.getNodeFactory(); 226 this.tu=djep.getTreeUtils(); 227 229 if (node == null) 230 throw new IllegalArgumentException ("node parameter is null"); 231 if (var == null) 232 throw new IllegalArgumentException ("var parameter is null"); 233 234 Node res = (Node) node.jjtAccept(this,var); 235 return res; 236 } 237 238 239 240 246 247 public Object visit(ASTFunNode node, Object data) throws ParseException 248 { 249 String name = node.getName(); 250 251 Node children[] = TreeUtils.getChildrenAsArray(node); 253 Node dchildren[] = acceptChildrenAsArray(node,data); 254 255 if(node.getPFMC() instanceof DiffRulesI) 256 { 257 return ((DiffRulesI) node.getPFMC()).differentiate(node,(String ) data,children,dchildren,localDJep); 258 } 259 DiffRulesI rules = (DiffRulesI) diffRules.get(name); 260 if(rules != null) 261 return rules.differentiate(node,(String ) data,children,dchildren,localDJep); 262 263 throw new ParseException("Sorry I don't know how to differentiate "+node+"\n"); 264 } 265 266 273 public Object visit(ASTVarNode node, Object data) throws ParseException { 274 String varName = (String ) data; 275 Variable var = node.getVar(); 276 if(var instanceof DVariable) 277 { 278 DVariable difvar = (DVariable) var; 279 if(varName.equals(var.getName())) 280 return nf.buildConstantNode(tu.getONE()); 281 else if(difvar.hasEquation()) 282 { 283 PartialDerivative deriv = difvar.findDerivative((String ) data,localDJep); 284 return nf.buildVariableNode(deriv); 285 } 286 else 287 return nf.buildConstantNode(tu.getZERO()); 288 } 289 if(var instanceof PartialDerivative) 290 { 291 PartialDerivative pvar = (PartialDerivative) var; 292 DVariable dvar = pvar.getRoot(); 293 PartialDerivative deriv = dvar.findDerivative(pvar,varName,localDJep); 294 return nf.buildVariableNode(deriv); 295 } 296 throw new ParseException("Encountered non differentiable variable"); 297 } 298 299 303 public Object visit(ASTConstant node, Object data) throws ParseException { 304 return nf.buildConstantNode(tu.getZERO()); 305 } 306 } 307 308 309 | Popular Tags |