package org.geogebra.common.kernel.cas; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.arithmetic.BooleanValue; import org.geogebra.common.kernel.arithmetic.Command; import org.geogebra.common.kernel.commands.CommandProcessor; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.commands.EvalInfo; import org.geogebra.common.kernel.geos.CasEvaluableFunction; import org.geogebra.common.kernel.geos.GeoBoolean; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoFunctionable; import org.geogebra.common.kernel.geos.GeoNumberValue; import org.geogebra.common.kernel.geos.GeoNumeric; import org.geogebra.common.main.MyError; /** * Integral[ <GeoFunction> ] Integral[ <GeoFunction>, <Number a>, <Number b> ] * Integral[ <GeoFunction f>, <GeoFunction g>, <Number a>, <Number b> ] */ public class CmdIntegral extends CommandProcessor { // from GeoGebra 4.0, Integral has been split into Integral and // IntegralBetween // old syntax and files will still work private String internalCommandName; /** * Create new command processor * * @param command * IntegralBetween, Integral or NIntegral * @param kernel * kernel */ public CmdIntegral(Kernel kernel, Commands command) { super(kernel); internalCommandName = command.name(); } @Override final public GeoElement[] process(Command c, EvalInfo info) throws MyError { if (c.getArgumentNumber() < 3 && !app.getSettings().getCasSettings().isEnabled()) { throw new MyError(kernelA.getLocalization(), "UnknownCommand"); } int n = c.getArgumentNumber(); boolean[] ok = new boolean[n]; GeoElement[] arg; switch (n) { case 1: arg = resArgs(c); if (arg[0].isGeoFunctionable()) { GeoElement[] ret = { integral(((GeoFunctionable) arg[0]).getGeoFunction(), null, info) }; ret[0].setLabel(c.getLabel()); return ret; } throw argErr(app, c, arg[0]); case 2: // Integral[ f(x,y), x] arg = resArgsLocalNumVar(c, 1, 1); if ((ok[0] = arg[0] instanceof CasEvaluableFunction) && (ok[1] = arg[1].isGeoNumeric())) { GeoElement[] ret = { integral((CasEvaluableFunction) arg[0], // function (GeoNumeric) arg[1], info) }; // var ret[0].setLabel(c.getLabel()); return ret; } throw argErr(app, c, getBadArg(ok, arg)); case 3: arg = resArgs(c); if ((ok[0] = (arg[0].isGeoFunctionable())) && (ok[1] = (arg[1] instanceof GeoNumberValue)) && (ok[2] = (arg[2] instanceof GeoNumberValue))) { AlgoIntegralDefinite algo = new AlgoIntegralDefinite(cons, c.getLabel(), ((GeoFunctionable) arg[0]).getGeoFunction(), (GeoNumberValue) arg[1], (GeoNumberValue) arg[2], "NIntegral".equals(internalCommandName)); GeoElement[] ret = { algo.getIntegral() }; return ret; } throw argErr(app, c, getBadArg(ok, arg)); case 4: arg = resArgs(c); // difference of two functions if ((ok[0] = (arg[0].isGeoFunctionable())) && (ok[1] = (arg[1].isGeoFunctionable())) && (ok[2] = (arg[2] instanceof GeoNumberValue)) && (ok[3] = (arg[3] instanceof GeoNumberValue && !(arg[3] instanceof BooleanValue)))) { AlgoIntegralFunctions algo = new AlgoIntegralFunctions(cons, c.getLabel(), ((GeoFunctionable) arg[0]).getGeoFunction(), ((GeoFunctionable) arg[1]).getGeoFunction(), (GeoNumberValue) arg[2], (GeoNumberValue) arg[3]); GeoElement[] ret = { algo.getIntegral() }; return ret; } // single function integral with evaluate option else if ((ok[0] = (arg[0].isGeoFunctionable())) && (ok[1] = (arg[1] instanceof GeoNumberValue)) && (ok[2] = (arg[2] instanceof GeoNumberValue)) && (ok[3] = (arg[3].isGeoBoolean()))) { AlgoIntegralDefinite algo = new AlgoIntegralDefinite(cons, c.getLabel(), ((GeoFunctionable) arg[0]).getGeoFunction(), (GeoNumberValue) arg[1], (GeoNumberValue) arg[2], (GeoBoolean) arg[3]); GeoElement[] ret = { algo.getIntegral() }; return ret; } else { throw argErr(app, c, getBadArg(ok, arg)); } case 5: arg = resArgs(c); // difference of two functions with evaluate option if ((ok[0] = (arg[0].isGeoFunctionable())) && (ok[1] = (arg[1].isGeoFunctionable())) && (ok[2] = (arg[2] instanceof GeoNumberValue)) && (ok[3] = (arg[3] instanceof GeoNumberValue) && (ok[4] = (arg[4].isGeoBoolean())))) { AlgoIntegralFunctions algo = new AlgoIntegralFunctions(cons, c.getLabel(), ((GeoFunctionable) arg[0]).getGeoFunction(), ((GeoFunctionable) arg[1]).getGeoFunction(), (GeoNumberValue) arg[2], (GeoNumberValue) arg[3], (GeoBoolean) arg[4]); GeoElement[] ret = { algo.getIntegral() }; return ret; } throw argErr(app, c, getBadArg(ok, arg)); default: throw argNumErr(app, c, n); } } /** * Integral of function f * * @param info * evaluation flags * @param f * function * @param var * variable * @return integral of given function wrt given variable */ final public GeoElement integral(CasEvaluableFunction f, GeoNumeric var, EvalInfo info) { AlgoIntegral algo = new AlgoIntegral(cons, f, var, true, info, "NIntegral".equals(internalCommandName)); return algo.getResult(); } }