From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- ic-reals-6.3/math-lib/exp_R.c | 122 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 ic-reals-6.3/math-lib/exp_R.c (limited to 'ic-reals-6.3/math-lib/exp_R.c') diff --git a/ic-reals-6.3/math-lib/exp_R.c b/ic-reals-6.3/math-lib/exp_R.c new file mode 100644 index 0000000..2a0d9ac --- /dev/null +++ b/ic-reals-6.3/math-lib/exp_R.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2000, Imperial College + * + * This file is part of the Imperial College Exact Real Arithmetic Library. + * See the copyright notice included in the distribution for conditions + * of use. + */ + +#include +#include "real.h" +#include "real-impl.h" +#include "math-lib.h" + +static TenXY *nextTensor(Real, Real, int); +static void expInside(); +static void expOutside(); + +Real +exp_R(Real x) +{ + Real u, v; + Bool xLtEq1, xGtEqNeg1, xLtEq1_and_GtEqNeg1; + static int doneInit = 0; + + if (!doneInit) { + registerForceFunc(expInside, "expInside", 2); + registerForceFunc(expOutside, "expOutside", 2); + doneInit++; + } + + /* + if (x->gen.tag.type == VECTOR) + return exp_QZ(x->vec.vec[0], x->vec.vec[1]); + */ + + xLtEq1 = ltEq_R_QInt(x, 1, 1); + xGtEqNeg1 = gtEq_R_QInt(x, -1, 1); + xLtEq1_and_GtEqNeg1 = and_B_B(xLtEq1, xGtEqNeg1); + + u = (Real) allocCls(expInside, (void *) x); + u->cls.tag.isSigned = TRUE; + v = (Real) allocCls(expOutside, (void *) x); + v->cls.tag.isSigned = TRUE; + +#ifdef DAVINCI + beginGraphUpdate(); + newEdgeToOnlyChild(u, x); + newEdgeToOnlyChild(v, x); + endGraphUpdate(); +#endif + + /* + * The order of the tests in the alt is not semantically + * significant. The tests are applied in order, so there is a + * very modest performance improvement by putting the -1,1 tests + * before the 999/1000,-999/1000 tests. Also there is a very + * small win by doing the negative test before the positive test. + */ + return realIf(4, + not_B(xLtEq1_and_GtEqNeg1), v, + xLtEq1_and_GtEqNeg1, u, + gtEq_R_QInt(x, 999, 1000), v, + ltEq_R_QInt(x, -999, 1000), v); +} + +static TenXY * +nextTensor(Real x, Real y, int n) +{ + return (TenXY *) tensor_Int(x, y, -1, 0, 0, 1, 2*n+1, 2*n+1, 2*n+1, 2*n+1); +} + +static void +expInside() +{ + Cls *cls, *newCls; + Real x; + ClsData *data; + void stdTensorCont(); + + cls = (Cls *) POP; + x = (Real) cls->userData; + + if ((data = (ClsData *) malloc(sizeof(ClsData))) == NULL) + Error(FATAL, E_INT, "exp_R", "malloc failed"); + + data->n = 1; + data->x = x; + data->nextTensor = nextTensor; + + newCls = allocCls(stdTensorCont, (void *) data); + newCls->tag.isSigned = FALSE; + + cls->redirect = tensor_Int(x, (Real) newCls, 0, -1, 1, 0, 1, 1, 1, 1); + +#ifdef DAVINCI + beginGraphUpdate(); + newEdgeToOnlyChild(newCls, x); + drawEqEdge(cls, cls->redirect); + endGraphUpdate(); +#endif +} + +static void +expOutside() +{ + Cls *cls; + Real w, x; + + cls = (Cls *) POP; + x = (Real) cls->userData; + x = div_R_Int(x, 2); + + w = exp_R(x); + + cls->redirect = mul_R_R(w, w); + +#ifdef DAVINCI + beginGraphUpdate(); + drawEqEdge(cls, cls->redirect); + endGraphUpdate(); +#endif +} -- cgit v1.2.3