// Copyright (c) 1999, Silicon Graphics, Inc. -- ALL RIGHTS RESERVED
//
// Permission is granted free of charge to copy, modify, use and distribute
// this software  provided you include the entirety of this notice in all
// copies made.
//
// THIS SOFTWARE IS PROVIDED ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
// WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT
// FOR A PARTICULAR PURPOSE OR NON-INFRINGING.   SGI ASSUMES NO RISK AS TO THE
// QUALITY AND PERFORMANCE OF THE SOFTWARE.   SHOULD THE SOFTWARE PROVE
// DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY
// SERVICING, REPAIR OR CORRECTION.  THIS DISCLAIMER OF WARRANTY CONSTITUTES
// AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS
// AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
//
// UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING,
// WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY), CONTRACT, OR
// OTHERWISE, SHALL SGI BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
// INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER WITH RESPECT TO THE
// SOFTWARE INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK
// STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL
// OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SGI SHALL HAVE BEEN INFORMED OF
// THE POSSIBILITY OF SUCH DAMAGES.  THIS LIMITATION OF LIABILITY SHALL NOT
// APPLY TO LIABILITY RESULTING FROM SGI's NEGLIGENCE TO THE EXTENT APPLICABLE
// LAW PROHIBITS SUCH LIMITATION.  SOME JURISDICTIONS DO NOT ALLOW THE
// EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT
// EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
//
// These license terms shall be governed by and construed in accordance with
// the laws of the United States and the State of California as applied to
// agreements entered into and to be performed entirely within California
// between California residents.  Any litigation relating to these license
// terms shall be subject to the exclusive jurisdiction of the Federal Courts
// of the Northern District of California (or, absent subject matter
// jurisdiction in such courts, the courts of the State of California), with
// venue lying exclusively in Santa Clara County, California.
//
// 5/2014 Added Strings to ArithmeticExceptions.
// 5/2015 Added support for direct asin() implementation in CR.

package com.hp.creals;
// import android.util.Log;

import java.math.BigInteger;

/**
* Unary functions on constructive reals implemented as objects.
* The <TT>execute</tt> member computes the function result.
* Unary function objects on constructive reals inherit from
* <TT>UnaryCRFunction</tt>.
*/
// Naming vaguely follows ObjectSpace JGL convention.
public abstract class UnaryCRFunction {
    abstract public CR execute(CR x);

/**
* The function object corresponding to the identity function.
*/
    public static final UnaryCRFunction identityFunction =
        new identity_UnaryCRFunction();

/**
* The function object corresponding to the <TT>negate</tt> method of CR.
*/
    public static final UnaryCRFunction negateFunction =
        new negate_UnaryCRFunction();

/**
* The function object corresponding to the <TT>inverse</tt> method of CR.
*/
    public static final UnaryCRFunction inverseFunction =
        new inverse_UnaryCRFunction();

/**
* The function object corresponding to the <TT>abs</tt> method of CR.
*/
    public static final UnaryCRFunction absFunction =
        new abs_UnaryCRFunction();

/**
* The function object corresponding to the <TT>exp</tt> method of CR.
*/
    public static final UnaryCRFunction expFunction =
        new exp_UnaryCRFunction();

/**
* The function object corresponding to the <TT>cos</tt> method of CR.
*/
    public static final UnaryCRFunction cosFunction =
        new cos_UnaryCRFunction();

/**
* The function object corresponding to the <TT>sin</tt> method of CR.
*/
    public static final UnaryCRFunction sinFunction =
        new sin_UnaryCRFunction();

/**
* The function object corresponding to the tangent function.
*/
    public static final UnaryCRFunction tanFunction =
        new tan_UnaryCRFunction();

/**
* The function object corresponding to the inverse sine (arcsine) function.
* The argument must be between -1 and 1 inclusive.  The result is between
* -PI/2 and PI/2.
*/
    public static final UnaryCRFunction asinFunction =
        new asin_UnaryCRFunction();
        // The following also works, but is slower:
        // CR half_pi = CR.PI.divide(CR.valueOf(2));
        // UnaryCRFunction.sinFunction.inverseMonotone(half_pi.negate(),
        //                                             half_pi);

/**
* The function object corresponding to the inverse cosine (arccosine) function.
* The argument must be between -1 and 1 inclusive.  The result is between
* 0 and PI.
*/
    public static final UnaryCRFunction acosFunction =
        new acos_UnaryCRFunction();

/**
* The function object corresponding to the inverse cosine (arctangent) function.
* The result is between -PI/2 and PI/2.
*/
    public static final UnaryCRFunction atanFunction =
        new atan_UnaryCRFunction();

/**
* The function object corresponding to the <TT>ln</tt> method of CR.
*/
    public static final UnaryCRFunction lnFunction =
        new ln_UnaryCRFunction();

/**
* The function object corresponding to the <TT>sqrt</tt> method of CR.
*/
    public static final UnaryCRFunction sqrtFunction =
        new sqrt_UnaryCRFunction();

/**
* Compose this function with <TT>f2</tt>.
*/
    public UnaryCRFunction compose(UnaryCRFunction f2) {
        return new compose_UnaryCRFunction(this, f2);
    }

/**
* Compute the inverse of this function, which must be defined
* and strictly monotone on the interval [<TT>low</tt>, <TT>high</tt>].
* The resulting function is defined only on the image of
* [<TT>low</tt>, <TT>high</tt>].
* The original function may be either increasing or decreasing.
*/
    public UnaryCRFunction inverseMonotone(CR low, CR high) {
        return new inverseMonotone_UnaryCRFunction(this, low, high);
    }

/**
* Compute the derivative of a function.
* The function must be defined on the interval [<TT>low</tt>, <TT>high</tt>],
* and the derivative must exist, and must be continuous and
* monotone in the open interval [<TT>low</tt>, <TT>high</tt>].
* The result is defined only in the open interval.
*/
    public UnaryCRFunction monotoneDerivative(CR low, CR high) {
        return new monotoneDerivative_UnaryCRFunction(this, low, high);
    }

}

// Subclasses of UnaryCRFunction for various built-in functions.
class sin_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.sin();
    }
}

class cos_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.cos();
    }
}

class tan_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.sin().divide(x.cos());
    }
}

class asin_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.asin();
    }
}

class acos_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.acos();
    }
}

// This uses the identity (sin x)^2 = (tan x)^2/(1 + (tan x)^2)
// Since we know the tangent of the result, we can get its sine,
// and then use the asin function.  Note that we don't always
// want the positive square root when computing the sine.
class atan_UnaryCRFunction extends UnaryCRFunction {
    CR one = CR.valueOf(1);
    public CR execute(CR x) {
        CR x2 = x.multiply(x);
        CR abs_sin_atan = x2.divide(one.add(x2)).sqrt();
        CR sin_atan = x.select(abs_sin_atan.negate(), abs_sin_atan);
        return sin_atan.asin();
    }
}

class exp_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.exp();
    }
}

class ln_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.ln();
    }
}

class identity_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x;
    }
}

class negate_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.negate();
    }
}

class inverse_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.inverse();
    }
}

class abs_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.abs();
    }
}

class sqrt_UnaryCRFunction extends UnaryCRFunction {
    public CR execute(CR x) {
        return x.sqrt();
    }
}

class compose_UnaryCRFunction extends UnaryCRFunction {
    UnaryCRFunction f1;
    UnaryCRFunction f2;
    compose_UnaryCRFunction(UnaryCRFunction func1,
                            UnaryCRFunction func2) {
        f1 = func1; f2 = func2;
    }
    public CR execute(CR x) {
        return f1.execute(f2.execute(x));
    }
}

class inverseMonotone_UnaryCRFunction extends UnaryCRFunction {
  // The following variables are final, so that they
  // can be referenced from the inner class inverseIncreasingCR.
  // I couldn't find a way to initialize these such that the
  // compiler accepted them as final without turning them into arrays.
    final UnaryCRFunction f[] = new UnaryCRFunction[1];
                                // Monotone increasing.
                                // If it was monotone decreasing, we
                                // negate it.
    final boolean f_negated[] = new boolean[1];
    final CR low[] = new CR[1];
    final CR high[] = new CR[1];
    final CR f_low[] = new CR[1];
    final CR f_high[] = new CR[1];
    final int max_msd[] = new int[1];
                        // Bound on msd of both f(high) and f(low)
    final int max_arg_prec[] = new int[1];
                                // base**max_arg_prec is a small fraction
                                // of low - high.
    final int deriv_msd[] = new int[1];
                                // Rough approx. of msd of first
                                // derivative.
    final static BigInteger BIG1023 = BigInteger.valueOf(1023);
    static final boolean ENABLE_TRACE = false;  // Change to generate trace
    static void trace(String s) {
        if (ENABLE_TRACE) {
            System.out.println(s);
            // Change to Log.v("UnaryCRFunction", s); for Android use.
        }
    }
    inverseMonotone_UnaryCRFunction(UnaryCRFunction func, CR l, CR h) {
        low[0] = l; high[0] = h;
        CR tmp_f_low = func.execute(l);
        CR tmp_f_high = func.execute(h);
        // Since func is monotone and low < high, the following test
        // converges.
        if (tmp_f_low.compareTo(tmp_f_high) > 0) {
            f[0] = UnaryCRFunction.negateFunction.compose(func);
            f_negated[0] = true;
            f_low[0] = tmp_f_low.negate();
            f_high[0] = tmp_f_high.negate();
        } else {
            f[0] = func;
            f_negated[0] = false;
            f_low[0] = tmp_f_low;
            f_high[0] = tmp_f_high;
        }
        max_msd[0] = low[0].abs().max(high[0].abs()).msd();
        max_arg_prec[0] = high[0].subtract(low[0]).msd() - 4;
        deriv_msd[0] = f_high[0].subtract(f_low[0])
                    .divide(high[0].subtract(low[0])).msd();
    }
    class inverseIncreasingCR extends CR {
        final CR arg;
        inverseIncreasingCR(CR x) {
            arg = f_negated[0]? x.negate() : x;
        }
        // Comparison with a difference of one treated as equality.
        int sloppy_compare(BigInteger x, BigInteger y) {
            BigInteger difference = x.subtract(y);
            if (difference.compareTo(big1) > 0) {
                return 1;
            }
            if (difference.compareTo(bigm1) < 0) {
                return -1;
            }
            return 0;
        }
        protected BigInteger approximate(int p) {
            final int extra_arg_prec = 4;
            final UnaryCRFunction fn = f[0];
            int small_step_deficit = 0; // Number of ineffective steps not
                                        // yet compensated for by a binary
                                        // search step.
            int digits_needed = max_msd[0] - p;
            if (digits_needed < 0) return big0;
            int working_arg_prec = p - extra_arg_prec;
            if (working_arg_prec > max_arg_prec[0]) {
                working_arg_prec = max_arg_prec[0];
            }
            int working_eval_prec = working_arg_prec + deriv_msd[0] - 20;
                        // initial guess
            // We use a combination of binary search and something like
            // the secant method.  This always converges linearly,
            // and should converge quadratically under favorable assumptions.
            // F_l and f_h are always the approximate images of l and h.
            // At any point, arg is between f_l and f_h, or no more than
            // one outside [f_l, f_h].
            // L and h are implicitly scaled by working_arg_prec.
            // The scaled values of l and h are strictly between low and high.
            // If at_left is true, then l is logically at the left
            // end of the interval.  We approximate this by setting l to
            // a point slightly inside the interval, and letting f_l
            // approximate the function value at the endpoint.
            // If at_right is true, r and f_r are set correspondingly.
            // At the endpoints of the interval, f_l and f_h may correspond
            // to the endpoints, even if l and h are slightly inside.
            // F_l and f_u are scaled by working_eval_prec.
            // Working_eval_prec may need to be adjusted depending
            // on the derivative of f.
            boolean at_left, at_right;
            BigInteger l, f_l;
            BigInteger h, f_h;
            BigInteger low_appr = low[0].get_appr(working_arg_prec)
                                        .add(big1);
            BigInteger high_appr = high[0].get_appr(working_arg_prec)
                                          .subtract(big1);
            BigInteger arg_appr = arg.get_appr(working_eval_prec);
            boolean have_good_appr = (appr_valid && min_prec < max_msd[0]);
            if (digits_needed < 30 && !have_good_appr) {
                trace("Setting interval to entire domain");
                h = high_appr;
                f_h = f_high[0].get_appr(working_eval_prec);
                l = low_appr;
                f_l = f_low[0].get_appr(working_eval_prec);
                // Check for clear out-of-bounds case.
                // Close cases may fail in other ways.
                  if (f_h.compareTo(arg_appr.subtract(big1)) < 0
                    || f_l.compareTo(arg_appr.add(big1)) > 0) {
                    throw new ArithmeticException("inverse(out-of-bounds)");
                  }
                at_left = true;
                at_right = true;
                small_step_deficit = 2;        // Start with bin search steps.
            } else {
                int rough_prec = p + digits_needed/2;

                if (have_good_appr &&
                    (digits_needed < 30 || min_prec < p + 3*digits_needed/4)) {
                    rough_prec = min_prec;
                }
                BigInteger rough_appr = get_appr(rough_prec);
                trace("Setting interval based on prev. appr");
                trace("prev. prec = " + rough_prec + " appr = " + rough_appr);
                h = rough_appr.add(big1)
                              .shiftLeft(rough_prec - working_arg_prec);
                l = rough_appr.subtract(big1)
                              .shiftLeft(rough_prec - working_arg_prec);
                if (h.compareTo(high_appr) > 0)  {
                    h = high_appr;
                    f_h = f_high[0].get_appr(working_eval_prec);
                    at_right = true;
                } else {
                    CR h_cr = CR.valueOf(h).shiftLeft(working_arg_prec);
                    f_h = fn.execute(h_cr).get_appr(working_eval_prec);
                    at_right = false;
                }
                if (l.compareTo(low_appr) < 0) {
                    l = low_appr;
                    f_l = f_low[0].get_appr(working_eval_prec);
                    at_left = true;
                } else {
                    CR l_cr = CR.valueOf(l).shiftLeft(working_arg_prec);
                    f_l = fn.execute(l_cr).get_appr(working_eval_prec);
                    at_left = false;
                }
            }
            BigInteger difference = h.subtract(l);
            for(int i = 0;; ++i) {
                if (Thread.interrupted() || please_stop)
                    throw new AbortedException();
                trace("***Iteration: " + i);
                trace("Arg prec = " + working_arg_prec
                      + " eval prec = " + working_eval_prec
                      + " arg appr. = " + arg_appr);
                trace("l = " + l); trace("h = " + h);
                trace("f(l) = " + f_l); trace("f(h) = " + f_h);
                if (difference.compareTo(big6) < 0) {
                    // Answer is less than 1/2 ulp away from h.
                    return scale(h, -extra_arg_prec);
                }
                BigInteger f_difference = f_h.subtract(f_l);
                // Narrow the interval by dividing at a cleverly
                // chosen point (guess) in the middle.
                {
                    BigInteger guess;
                    boolean binary_step =
                        (small_step_deficit > 0 || f_difference.signum() == 0);
                    if (binary_step) {
                        // Do a binary search step to guarantee linear
                        // convergence.
                        trace("binary step");
                        guess = l.add(h).shiftRight(1);
                        --small_step_deficit;
                    } else {
                      // interpolate.
                      // f_difference is nonzero here.
                      trace("interpolating");
                      BigInteger arg_difference = arg_appr.subtract(f_l);
                      BigInteger t = arg_difference.multiply(difference);
                      BigInteger adj = t.divide(f_difference);
                          // tentative adjustment to l to compute guess
                      // If we are within 1/1024 of either end, back off.
                      // This greatly improves the odds of bounding
                      // the answer within the smaller interval.
                      // Note that interpolation will often get us
                      // MUCH closer than this.
                      if (adj.compareTo(difference.shiftRight(10)) < 0) {
                        adj = adj.shiftLeft(8);
                        trace("adjusting left");
                      } else if (adj.compareTo(difference.multiply(BIG1023)
                                                       .shiftRight(10)) > 0){
                        adj = difference.subtract(difference.subtract(adj)
                                                  .shiftLeft(8));
                        trace("adjusting right");
                      }
                      if (adj.signum() <= 0)
                          adj = big2;
                      if (adj.compareTo(difference) >= 0)
                          adj = difference.subtract(big2);
                      guess = (adj.signum() <= 0? l.add(big2) : l.add(adj));
                    }
                    int outcome;
                    BigInteger tweak = big2;
                    BigInteger f_guess;
                    for(boolean adj_prec = false;; adj_prec = !adj_prec) {
                        CR guess_cr = CR.valueOf(guess)
                                        .shiftLeft(working_arg_prec);
                        trace("Evaluating at " + guess_cr
                              + " with precision " + working_eval_prec);
                        CR f_guess_cr = fn.execute(guess_cr);
                        trace("fn value = " + f_guess_cr);
                        f_guess = f_guess_cr.get_appr(working_eval_prec);
                        outcome = sloppy_compare(f_guess, arg_appr);
                        if (outcome != 0) break;
                        // Alternately increase evaluation precision
                        // and adjust guess slightly.
                        // This should be an unlikely case.
                        if (adj_prec) {
                            // adjust working_eval_prec to get enough
                            // resolution.
                            int adjustment = -f_guess.bitLength()/4;
                            if (adjustment > -20) adjustment = - 20;
                            CR l_cr = CR.valueOf(l)
                                        .shiftLeft(working_arg_prec);
                            CR h_cr = CR.valueOf(h)
                                        .shiftLeft(working_arg_prec);
                            working_eval_prec += adjustment;
                            trace("New eval prec = " + working_eval_prec
                                  + (at_left? "(at left)" : "")
                                  + (at_right? "(at right)" : ""));
                            if (at_left) {
                                f_l = f_low[0].get_appr(working_eval_prec);
                            } else {
                                f_l = fn.execute(l_cr)
                                        .get_appr(working_eval_prec);
                            }
                            if (at_right) {
                                f_h = f_high[0].get_appr(working_eval_prec);
                            } else {
                                f_h = fn.execute(h_cr)
                                        .get_appr(working_eval_prec);
                            }
                            arg_appr = arg.get_appr(working_eval_prec);
                        } else {
                            // guess might be exactly right; tweak it
                            // slightly.
                            trace("tweaking guess");
                            BigInteger new_guess = guess.add(tweak);
                            if (new_guess.compareTo(h) >= 0) {
                                guess = guess.subtract(tweak);
                            } else {
                                guess = new_guess;
                            }
                            // If we keep hitting the right answer, it's
                            // important to alternate which side we move it
                            // to, so that the interval shrinks rapidly.
                            tweak = tweak.negate();
                        }
                    }
                    if (outcome > 0) {
                        h = guess;
                        f_h = f_guess;
                        at_right = false;
                    } else {
                        l = guess;
                        f_l = f_guess;
                        at_left = false;
                    }
                    BigInteger new_difference = h.subtract(l);
                    if (!binary_step) {
                        if (new_difference.compareTo(difference
                                                     .shiftRight(1)) >= 0) {
                            ++small_step_deficit;
                        } else {
                            --small_step_deficit;
                        }
                    }
                    difference = new_difference;
                }
            }
        }
    }
    public CR execute(CR x) {
        return new inverseIncreasingCR(x);
    }
}

class monotoneDerivative_UnaryCRFunction extends UnaryCRFunction {
  // The following variables are final, so that they
  // can be referenced from the inner class inverseIncreasingCR.
    final UnaryCRFunction f[] = new UnaryCRFunction[1];
                                // Monotone increasing.
                                // If it was monotone decreasing, we
                                // negate it.
    final CR low[] = new CR[1]; // endpoints and mispoint of interval
    final CR mid[] = new CR[1];
    final CR high[] = new CR[1];
    final CR f_low[] = new CR[1]; // Corresponding function values.
    final CR f_mid[] = new CR[1];
    final CR f_high[] = new CR[1];
    final int difference_msd[] = new int[1];  // msd of interval len.
    final int deriv2_msd[] = new int[1];
                                // Rough approx. of msd of second
                                // derivative.
                                // This is increased to be an appr. bound
                                // on the msd of |(f'(y)-f'(x))/(x-y)|
                                // for any pair of points x and y
                                // we have considered.
                                // It may be better to keep a copy per
                                // derivative value.

    monotoneDerivative_UnaryCRFunction(UnaryCRFunction func, CR l, CR h) {
        f[0] = func;
        low[0] = l; high[0] = h;
        mid[0] = l.add(h).shiftRight(1);
        f_low[0] = func.execute(l);
        f_mid[0] = func.execute(mid[0]);
        f_high[0] = func.execute(h);
        CR difference = h.subtract(l);
        // compute approximate msd of
        // ((f_high - f_mid) - (f_mid - f_low))/(high - low)
        // This should be a very rough appr to the second derivative.
        // We add a little slop to err on the high side, since
        // a low estimate will cause extra iterations.
        CR appr_diff2 = f_high[0].subtract(f_mid[0].shiftLeft(1)).add(f_low[0]);
        difference_msd[0] = difference.msd();
        deriv2_msd[0] = appr_diff2.msd() - difference_msd[0] + 4;
    }
    class monotoneDerivativeCR extends CR {
        CR arg;
        CR f_arg;
        int max_delta_msd;
        monotoneDerivativeCR(CR x) {
            arg = x;
            f_arg = f[0].execute(x);
            // The following must converge, since arg must be in the
            // open interval.
            CR left_diff = arg.subtract(low[0]);
            int max_delta_left_msd = left_diff.msd();
            CR right_diff = high[0].subtract(arg);
            int max_delta_right_msd = right_diff.msd();
            if (left_diff.signum() < 0 || right_diff.signum() < 0) {
                throw new ArithmeticException("fn not monotone");
            }
            max_delta_msd = (max_delta_left_msd < max_delta_right_msd?
                                max_delta_left_msd
                                : max_delta_right_msd);
        }
        protected BigInteger approximate(int p) {
            final int extra_prec = 4;
            int log_delta = p - deriv2_msd[0];
            // Ensure that we stay within the interval.
              if (log_delta > max_delta_msd) log_delta = max_delta_msd;
            log_delta -= extra_prec;
            CR delta = ONE.shiftLeft(log_delta);

            CR left = arg.subtract(delta);
            CR right = arg.add(delta);
            CR f_left = f[0].execute(left);
            CR f_right = f[0].execute(right);
            CR left_deriv = f_arg.subtract(f_left).shiftRight(log_delta);
            CR right_deriv = f_right.subtract(f_arg).shiftRight(log_delta);
            int eval_prec = p - extra_prec;
            BigInteger appr_left_deriv = left_deriv.get_appr(eval_prec);
            BigInteger appr_right_deriv = right_deriv.get_appr(eval_prec);
            BigInteger deriv_difference =
                appr_right_deriv.subtract(appr_left_deriv).abs();
            if (deriv_difference.compareTo(big8) < 0) {
                return scale(appr_left_deriv, -extra_prec);
            } else {
                if (Thread.interrupted() || please_stop)
                    throw new AbortedException();
                deriv2_msd[0] =
                        eval_prec + deriv_difference.bitLength() + 4/*slop*/;
                deriv2_msd[0] -= log_delta;
                return approximate(p);
            }
        }
    }
    public CR execute(CR x) {
        return new monotoneDerivativeCR(x);
    }
}
