/* GeoGebra - Dynamic Mathematics for Everyone http://www.geogebra.org This file is part of GeoGebra. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. */ package org.geogebra.common.kernel.algos; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.arithmetic.Evaluate2Var; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.ExpressionValue; import org.geogebra.common.kernel.arithmetic.Function; import org.geogebra.common.kernel.arithmetic.FunctionNVar; import org.geogebra.common.kernel.arithmetic.FunctionVariable; import org.geogebra.common.kernel.arithmetic.FunctionalNVar; import org.geogebra.common.kernel.arithmetic.MyDouble; import org.geogebra.common.kernel.arithmetic.NumberValue; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoFunction; import org.geogebra.common.kernel.geos.GeoFunctionNVar; import org.geogebra.common.kernel.geos.GeoNumeric; /** * Find Numerator * * @author Michael Borcherds */ public class AlgoNumeratorDenominatorFun extends AlgoElement { private Evaluate2Var f; // input private GeoElement g; // output private Commands type; /** * @param cons * construction * @param f * function * @param type * denominator / numerator */ public AlgoNumeratorDenominatorFun(Construction cons, Evaluate2Var f, Commands type) { super(cons); this.f = f; this.type = type; if (f instanceof GeoFunction || f instanceof GeoNumeric) { g = new GeoFunction(cons); } else { g = new GeoFunctionNVar(cons); } setInputOutput(); // for AlgoElement compute(); } @Override public Commands getClassName() { return type; } // for AlgoElement @Override protected void setInputOutput() { input = new GeoElement[1]; input[0] = (GeoElement) f; super.setOnlyOutput(g); setDependencies(); // done by AlgoElement } /** * @return denominator or numerator */ public GeoElement getResult() { return g; } @Override public final void compute() { if (!f.isDefined()) { g.setUndefined(); return; } ExpressionValue[] numDen = new ExpressionValue[2]; f.getFunctionExpression().deepCopy(kernel).wrap().getFraction(numDen, false); ExpressionValue ev; if (type == Commands.Numerator) { ev = numDen[0]; } else if (numDen[1] == null) { ev = new ExpressionNode(kernel, 1); } else { ev = numDen[1]; } // Application.debug(root.left.getClass()+""); if (ev.isExpressionNode()) { if (g instanceof GeoFunction) { Function fun = new Function((ExpressionNode) ev, f.getFunction().getFunctionVariables()[0]); ((GeoFunction) g).setFunction(fun); } else { FunctionNVar fun = new FunctionNVar((ExpressionNode) ev, f.getFunction().getFunctionVariables()); ((GeoFunctionNVar) g).setFunction(fun); } } else if (ev instanceof FunctionVariable) { if (f instanceof GeoFunction) { // construct function f(x) = x FunctionVariable fv = ((GeoFunction) f) .getFunctionVariables()[0].deepCopy(kernel); ExpressionNode en = new ExpressionNode(kernel, fv); Function tempFun = new Function(en, fv); tempFun.initFunction(); ((GeoFunction) g).setFunction(tempFun); } else { // construct eg f(a,b)=b GeoFunctionNVar ff = ((GeoFunctionNVar) f); FunctionNVar fun = ff.getFunction(); FunctionVariable[] vars = fun.getFunctionVariables(); ExpressionNode en = new ExpressionNode(kernel, ev); FunctionNVar newFun = new FunctionNVar(en, vars); ((GeoFunctionNVar) g).setFunction(newFun); } } else if (ev instanceof NumberValue) { if (f instanceof GeoFunction) { // construct function f(x) = 1 FunctionVariable fv = new FunctionVariable(kernel); ExpressionNode en = new ExpressionNode(kernel, new MyDouble(kernel, ((NumberValue) ev).getDouble())); Function tempFun = new Function(en, fv); tempFun.initFunction(); ((GeoFunction) g).setFunction(tempFun); } else { // GeoFunctionNVar // construct eg f(a,b)=3 GeoFunctionNVar ff = ((GeoFunctionNVar) f); FunctionNVar fun = ff.getFunction(); FunctionVariable[] vars = fun.getFunctionVariables(); ExpressionNode en = new ExpressionNode(kernel, ev); FunctionNVar newFun = new FunctionNVar(en, vars); ((GeoFunctionNVar) g).setFunction(newFun); } } else { // Application.debug(ev.getClass()+""); g.setUndefined(); return; } ((FunctionalNVar) g).setDefined(true); } /** * over-ridden in AlgoDenominator */ protected ExpressionValue getPart(ExpressionValue[] node) { return node[0]; } }