package jscl.math.operator; import jscl.AngleUnit; import jscl.JsclMathEngine; import jscl.math.Generic; import jscl.math.JsclInteger; import jscl.math.NotIntegerException; import jscl.math.Variable; import jscl.mathml.MathML; import jscl.text.msg.JsclMessage; import jscl.text.msg.Messages; import org.solovyev.common.msg.MessageType; import javax.annotation.Nonnull; public class Derivative extends Operator { public static final String NAME = "∂"; public Derivative(Generic expression, Generic variable, Generic value, Generic order) { super(NAME, new Generic[]{expression, variable, value, order}); } private Derivative(Generic parameters[]) { super(NAME, createParameters(parameters)); } private static Generic[] createParameters(@Nonnull Generic[] parameters) { final Generic[] result = new Generic[4]; result[0] = parameters[0]; result[1] = parameters[1]; result[2] = parameters.length > 2 ? parameters[2] : parameters[1]; result[3] = parameters.length > 3 ? parameters[3] : JsclInteger.valueOf(1); return result; } @Override public int getMinParameters() { return 2; } @Override public int getMaxParameters() { return 4; } @Nonnull @Override protected String formatUndefinedParameter(int i) { switch (i) { case 0: return "f(x)"; case 1: return "x"; case 2: return "x_point"; case 3: return "order"; default: return super.formatUndefinedParameter(i); } } public Generic selfExpand() { if (JsclMathEngine.getInstance().getAngleUnits() != AngleUnit.rad) { JsclMathEngine.getInstance().getMessageRegistry().addMessage(new JsclMessage(Messages.msg_25, MessageType.warning)); } Variable variable = parameters[1].variableValue(); try { int n = parameters[3].integerValue().intValue(); Generic a = parameters[0]; for (int i = 0; i < n; i++) { a = a.derivative(variable); } return a.substitute(variable, parameters[2]); } catch (NotIntegerException e) { } return expressionValue(); } // todo serso: think /*public String toString() { final StringBuilder result = new StringBuilder(); int n = 4; if (parameters[3].compareTo(JsclInteger.valueOf(1)) == 0) { n = 3; if (parameters[2].compareTo(parameters[1]) == 0) n = 2; } result.append(name); result.append("("); for (int i = 0; i < n; i++) { result.append(parameters[i]).append(i < n - 1 ? ", " : ""); } result.append(")"); return result.toString(); }*/ public void toMathML(MathML element, Object data) { int exponent = data instanceof Integer ? (Integer) data : 1; if (exponent == 1) derivationToMathML(element, false); else { MathML e1 = element.element("msup"); derivationToMathML(e1, true); MathML e2 = element.element("mn"); e2.appendChild(element.text(String.valueOf(exponent))); e1.appendChild(e2); element.appendChild(e1); } MathML e1 = element.element("mfenced"); parameters[0].toMathML(e1, null); if (parameters[2].compareTo(parameters[1]) != 0) parameters[2].toMathML(e1, null); element.appendChild(e1); } @Nonnull @Override public Operator newInstance(@Nonnull Generic[] parameters) { return new Derivative(parameters); } void derivationToMathML(MathML element, boolean fenced) { if (fenced) { MathML e1 = element.element("mfenced"); derivationToMathML(e1); element.appendChild(e1); } else { derivationToMathML(element); } } @Override public Generic numeric() { try { parameters[3].integerValue(); return expand().numeric(); } catch (NotIntegerException e) { } return expressionValue(); } /*@Override public Generic simplify() { Generic result = null; try { result = expand().simplify(); } catch (ArithmeticException e) { result = super.simplify(); } return result; }*/ void derivationToMathML(MathML element) { Variable v = parameters[1].variableValue(); int n = 0; try { n = parameters[3].integerValue().intValue(); } catch (NotIntegerException e) { } if (n == 1) { MathML e1 = element.element("mfrac"); MathML e2 = element.element("mo"); e2.appendChild(element.text(/*"\u2146"*/"d")); e1.appendChild(e2); e2 = element.element("mrow"); MathML e3 = element.element("mo"); e3.appendChild(element.text(/*"\u2146"*/"d")); e2.appendChild(e3); v.toMathML(e2, null); e1.appendChild(e2); element.appendChild(e1); } else { MathML e1 = element.element("mfrac"); MathML e2 = element.element("msup"); MathML e3 = element.element("mo"); e3.appendChild(element.text(/*"\u2146"*/"d")); e2.appendChild(e3); parameters[3].toMathML(e2, null); e1.appendChild(e2); e2 = element.element("mrow"); e3 = element.element("mo"); e3.appendChild(element.text(/*"\u2146"*/"d")); e2.appendChild(e3); e3 = element.element("msup"); parameters[1].toMathML(e3, null); parameters[3].toMathML(e3, null); e2.appendChild(e3); e1.appendChild(e2); element.appendChild(e1); } } @Nonnull public Variable newInstance() { return new Derivative(null, null, null, null); } }