package builtin.math; import builtin.BuiltinSub; import gui.Constants; import gui.Environment; import gui.Heap; import gui.Interpreter; import gui.MintException; import gui.Pointer; import gui.PointerTools; import gui.SmartList; import gui.Subprogram; /** * @author Oliver Chu */ public class FindRoot extends BuiltinSub { public double runFunction(Subprogram functionalSub, double x) throws MintException { SmartList<Pointer> sListOfPtr = new SmartList<Pointer>(); sListOfPtr.add(Heap.allocateReal(x)); Pointer answer = functionalSub.execute(new Environment(), new SmartList<String>(), sListOfPtr, new Interpreter()); return PointerTools.dereferenceReal(answer); } @Override public Pointer apply(SmartList<Pointer> args) throws MintException { Pointer a0 = args.get(0); Pointer pGuess = args.get(1); if (a0.type != Constants.SUBPROGRAM_TYPE) { throw new MintException("Cannot find the roots of " + "a non-subprogram object."); } Subprogram ess = PointerTools.dereferenceSub(a0); double ex; if (pGuess.type == Constants.INT_TYPE) { ex = (double) PointerTools.dereferenceInt(pGuess); } else if (pGuess.type == Constants.REAL_TYPE) { ex = PointerTools.dereferenceReal(pGuess); } else { return Constants.MINT_NULL; } double goingUp = ex; double goingDown = ex; int j = 0; while (j < 1000000) { if (Math.abs(runFunction(ess, goingUp)) <= 0.000075) { return Heap.allocateReal(goingUp); } if (Math.abs(runFunction(ess, goingDown)) <= 0.000075) { return Heap.allocateReal(goingDown); } goingUp += 0.000025; goingDown += 0.000025; ++j; } return Constants.MINT_NULL; } }