package org.geogebra.common.kernel.algos; import org.apache.commons.math3.analysis.UnivariateFunction; /** * Set of real numbers that are solutions to an equation */ public class Solution { /** roots */ public double[] curRoots = new double[30]; // current roots /** number of real roots */ public int curRealRoots; /** * * @param roots * roots to be added * @param number * number of roots to be added */ public void addToCurrentRoots(double[] roots, int number) { int length = curRealRoots + number; if (length >= curRoots.length) { // ensure space double[] temp = new double[2 * length]; for (int i = 0; i < curRealRoots; i++) { temp[i] = curRoots[i]; } curRoots = temp; } // insert new roots for (int i = 0; i < number; i++) { curRoots[curRealRoots + i] = roots[i]; } curRealRoots += number; } /** * Removed root at given position * * @param pos * position */ void removeRoot(int pos) { for (int i = pos + 1; i < curRealRoots; i++) { curRoots[i - 1] = curRoots[i]; } curRealRoots--; } /** * Remove all roots (reset the counter) */ public void resetRoots() { curRealRoots = 0; } /** * Remove roots where sign didn't change * * @param f * function * @param DELTA * half-width of the interval where we check sign */ void ensureSignChanged(UnivariateFunction f, double DELTA) { double left, right, leftEval, rightEval; boolean signUnChanged; for (int i = 0; i < curRealRoots; i++) { left = curRoots[i] - DELTA; right = curRoots[i] + DELTA; // ensure we get a non-zero y value to the left int count = 0; while (Math.abs(leftEval = f.value(left)) < DELTA && count++ < 100) { left = left - DELTA; } // ensure we get a non-zero y value to the right count = 0; while (Math.abs(rightEval = f.value(right)) < DELTA && count++ < 100) { right = right + DELTA; } // Application.debug("leftEval: " + leftEval + ", left: " + left); // Application.debug("rightEval: " + rightEval + ", right: " + // right); // check if the second derivative changed its sign here signUnChanged = leftEval * rightEval > 0; if (signUnChanged) { // remove root[i] removeRoot(i); i--; } } } /** * @param x * single root */ public void setSingleRoot(double x) { curRoots[0] = x; curRealRoots = 1; } }