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; /** * Returns F(x) such that F'(x) = f(x). * F(x) is equal to the integral from 0 to x of f(t). * @author Oliver Chu */ public class Integrate extends BuiltinSub { private class F extends BuiltinSub { private Subprogram function; public void setSub(Subprogram f) { function = f; } private double evaluate(double x) throws MintException { double dx = 0.025; double a = 0.0; double b = x; double sum = 0.0; while (a < b) { SmartList<Pointer> args = new SmartList<Pointer>(); args.add(Heap.allocateReal(a)); sum += dx * PointerTools.dereferenceReal( function.execute(new Environment(), new SmartList<String>(), args, new Interpreter())); a += dx; } return sum; } @Override public Pointer apply(SmartList<Pointer> args) throws MintException { Pointer a0 = args.get(0); double ex; if (a0.type == Constants.INT_TYPE) { ex = (double) PointerTools.dereferenceInt(a0); } else { ex = PointerTools.dereferenceReal(a0); } return Heap.allocateReal(evaluate(ex)); } } @Override public Pointer apply(SmartList<Pointer> args) throws MintException { Pointer arg0 = args.get(0); if (arg0.type != Constants.SUBPROGRAM_TYPE) { throw new MintException("Must integrate a subprogram that " + "represents a one-argument mathematical function."); } F f = new F(); f.setSub(PointerTools.dereferenceSub(arg0)); SmartList<Pointer> sOfPtrs = new SmartList<Pointer>(); sOfPtrs.add(Heap.allocateName("x")); Subprogram diffedSub = new Subprogram("F", sOfPtrs, f); return Heap.allocateSub(diffedSub); } }