package symjava.symbolic; import java.util.List; import symjava.symbolic.arity.BinaryOp; import symjava.symbolic.utils.Utils; public class Pow extends BinaryOp { public Pow(Expr base, Expr exponent) { super(base, exponent); String displayExp = String.format("%s", this.arg2); if(exponent instanceof SymReal) { SymReal realExp = (SymReal)exponent; if(realExp.isInteger()) { displayExp = String.format("%d", realExp.getIntValue()); } if(realExp.isNegative()) displayExp = "{"+displayExp+"}"; } if(base instanceof Symbol) { label = base + "^" + displayExp + ""; label = "pow(" + base + ","+displayExp+")"; } else { label = "("+base + ")^" + displayExp; } //TODO? x^3 + x^2 + x + 1 sortKey = base.getSortKey()+"power"+String.valueOf(displayExp); } public static Expr simplifiedIns(Expr base, Expr exponent) { if(base instanceof SymReal && exponent instanceof SymReal) { return new SymDouble(Math.pow( ((SymReal)base).getDoubleValue(), ((SymReal)exponent).getDoubleValue()) ); } else if(base instanceof SymReal) { SymReal realBase = (SymReal)base; if(realBase.isZero()) return Symbol.C0; else if(realBase.isOne()) return Symbol.C1; }else if(exponent instanceof SymReal) { SymReal realExp = (SymReal)exponent; if(realExp.isZero()) return Symbol.C1; else if(realExp.isOne()) return base; else if(realExp.isNegativeOne()) return Reciprocal.simplifiedIns(base); } return new Pow(base, exponent); } @Override public Expr subs(Expr from, Expr to) { if(Utils.symCompare(this, from)) return to; return Pow.simplifiedIns(arg1.subs(from, to), arg2.subs(from, to)); } @Override public Expr diff(Expr expr) { if(arg2 instanceof SymReal) { SymReal realExp = (SymReal)arg2; return realExp.multiply(Pow.simplifiedIns(arg1, arg2 - 1)).multiply(arg1.diff(expr)); } else { Expr x = expr; Expr b = arg1; Expr e = arg2; Expr y = this; Expr log_b = Log.simplifiedIns(b); Expr term1 = e.diff(x).multiply(log_b); Expr term2 = e.multiply(b.diff(x)).divide(b); return y.multiply(term1.add(term2)); } } @Override public Expr simplify() { return Pow.simplifiedIns(arg1.simplify(), arg2.simplify()); } @Override public boolean symEquals(Expr other) { if(other instanceof Pow) { Pow o = (Pow)other; if(Utils.symCompare(arg1, o.arg1) && Utils.symCompare(arg2, o.arg2)) return true; } return false; } @Override public void flattenAdd(List outList) { //TODO //Do we need to do this: (a+b)^2 => a^2 +2ab+b^2 outList.add(this); } @Override public void flattenMultiply(List outList) { if(arg2 instanceof SymReal) { SymReal realExp = (SymReal)arg2; if(realExp.isPositive()) { double exp = realExp.getDoubleValue(); for(int i=0; i<(int)exp; i++) outList.add(arg1); double remain = exp - Math.floor(exp); if(remain > 0.0) { outList.add(simplifiedIns(arg1, Expr.valueOf(remain))); } return; } } outList.add(this); } }