* @return the fully factored equation if possible.
* @throws ParserException
*/
private ConsCell rationalRootsFactoring(ConsCell equation) throws ParserException {
ConsCell original = equation.clone();
if (orderOfEquation(equation, parser.getVars()).lt(new BigDec(2)))
return equation;
ArrayList<ConsCell> eqn = foldSigns(getTerms(equation));
BigDec highestCoefficient = getCoefficient(eqn.get(0)), lowestCoefficient = getCoefficient(eqn.get(eqn.size() - 1)), lcm = BigDec.ONE;
if (!highestCoefficient.isInt() || !lowestCoefficient.isInt()) {
lcm = ((BigDec) highestCoefficient.toFraction().getCar(2)).lcm((BigDec) lowestCoefficient.toFraction().getCar(2));
equation = eqn.get(0).getLastConsCell().append(new ConsCell('*', ConsType.OPERATOR, new ConsCell(lcm, ConsType.NUMBER)));
for (int i = 0; i < eqn.size(); i++)
equation = equation.append(new ConsCell('+', ConsType.OPERATOR, eqn.get(i).getLastConsCell().append(new ConsCell('*', ConsType.OPERATOR, new ConsCell(lcm, ConsType.NUMBER))).getFirstConsCell().clone()));
equation = equation.getFirstConsCell();
equation = simplifyTerms(parser.removeDoubles(equation));
}
ArrayList<BigDec> roots = getRoots(equation);
for (BigDec root : roots) {
ConsCell output = polynomialDivision(equation, new ConsCell(parser.getVars().get(0), ConsType.IDENTIFIER, new ConsCell('+', ConsType.OPERATOR, new ConsCell(root, ConsType.NUMBER))),
new ConsCell(parser.getVars().get(0), ConsType.IDENTIFIER), true);
ConsCell last = output.getLastConsCell();
if (last.getCarType() == ConsType.OBJECT && last.getCar().equals("{false}")) { //If the polynomial division succeeded, return the factored form
last.remove();
ConsCell result = parser.removeDoubles(new ConsCell(new ConsCell(parser.getVars().get(0), ConsType.IDENTIFIER, new ConsCell('+', ConsType.OPERATOR, new ConsCell(root, ConsType.NUMBER))),
ConsType.CONS_CELL, new ConsCell('*', ConsType.OPERATOR, new ConsCell(rationalRootsFactoring(output), ConsType.CONS_CELL))));
if (!highestCoefficient.isInt() && lcm.neq(BigDec.ONE))
result = new ConsCell(BigDec.ONE, ConsType.NUMBER, new ConsCell('/', ConsType.OPERATOR, new ConsCell(lcm, ConsType.NUMBER, new ConsCell('*', ConsType.OPERATOR, result))));
return result;
}
}
return original;