=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2018/engine/d-itv.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -p -r1.1 -r1.5 --- OpenXM_contrib2/asir2018/engine/d-itv.c 2018/09/19 05:45:07 1.1 +++ OpenXM_contrib2/asir2018/engine/d-itv.c 2019/11/12 10:53:22 1.5 @@ -1,14 +1,22 @@ /* - * $OpenXM$ + * $OpenXM: OpenXM_contrib2/asir2018/engine/d-itv.c,v 1.4 2019/10/17 03:03:12 kondoh Exp $ */ #if defined(INTERVAL) #include #include "ca.h" #include "base.h" +#if 0 #if defined(PARI) #include "genpari.h" #endif +#endif +double addulpd(double); +double subulpd(double); +extern int mpfr_roundmode; +Num tobf(Num,int); + + #if defined(ITVDEBUG) void printbinint(int d) { @@ -31,6 +39,7 @@ void printbinint(int d) } #endif +#if 0 double NatToRealUp(N a, int *expo) { int *p; @@ -181,7 +190,8 @@ static double Q2doubleUp(Q a) static double PARI2doubleDown(BF a) { - GEN p; + //GEN p; + Num p; double d; ritopa(a, &p); @@ -194,7 +204,36 @@ static double PARI2doubleUp(BF a) { return PARI2doubleDown(a); } +#endif +static double Q2doubleDown(Q a) +{ + Num b; + double rd; + int current_roundmode=0; + + current_roundmode = mpfr_roundmode; + mpfr_roundmode = MPFR_RNDD; + b = tobf((Num)a,60); + mpfr_roundmode = current_roundmode; + rd = mpfr_get_d(BDY((BF)b),MPFR_RNDD); + return rd; +} + +static double Q2doubleUp(Q a) +{ + Num b; + double rd; + int current_roundmode=0; + + current_roundmode = mpfr_roundmode; + mpfr_roundmode = MPFR_RNDU; + b = tobf((Num)a,60); + mpfr_roundmode = current_roundmode; + rd = mpfr_get_d(BDY((BF)b),MPFR_RNDU); + return rd; +} + double subulpd(double d) { double inf; @@ -216,7 +255,7 @@ double addulpd(double d) return (-sup); } -double ToRealDown(Num a) +double toRealDown(Num a) { double inf; @@ -227,22 +266,26 @@ double ToRealDown(Num a) case N_R: inf = subulpd(BDY((Real)a)); break; case N_B: - inf = PARI2doubleDown((BF)a); break; + inf = mpfr_get_d(BDY((BF)a),MPFR_RNDD); + break; case N_IP: - inf = ToRealDown(INF((Itv)a)); + inf = toRealDown(INF((Itv)a)); break; case N_IntervalDouble: inf = INF((IntervalDouble)a); break; + case N_IntervalBigFloat: + inf = mpfr_get_d(BDY((BF)INF((IntervalBigFloat)a)),MPFR_RNDD); + break; case N_A: default: inf = 0.0; - error("ToRealDown: not supported operands."); + error("toRealDown: not supported operands."); break; } return inf; } -double ToRealUp(Num a) +double toRealUp(Num a) { double sup; @@ -253,15 +296,19 @@ double ToRealUp(Num a) case N_R: sup = addulpd(BDY((Real)a)); break; case N_B: - sup = PARI2doubleUp((BF)a); break; + sup = mpfr_get_d(BDY((BF)a),MPFR_RNDU); + break; case N_IP: - sup = ToRealUp(SUP((Itv)a)); break; + sup = toRealUp(SUP((Itv)a)); break; case N_IntervalDouble: sup = SUP((IntervalDouble)a); break; + case N_IntervalBigFloat: + sup = mpfr_get_d(BDY((BF)INF((IntervalBigFloat)a)),MPFR_RNDU); + break; case N_A: default: sup = 0.0; - error("ToRealUp: not supported operands."); + error("toRealUp: not supported operands."); break; } return sup; @@ -270,6 +317,9 @@ double ToRealUp(Num a) void Num2double(Num a, double *inf, double *sup) { + *inf = 0.0; + *sup = 0.0; + if (a && NUM(a) ) switch ( NID(a) ) { case N_Q: *inf = Q2doubleDown((Q)a); @@ -280,12 +330,12 @@ void Num2double(Num a, double *inf, double *sup) *sup = BDY((Real)a); break; case N_B: - *inf = PARI2doubleDown((BF)a); - *sup = PARI2doubleUp((BF)a); + *inf = mpfr_get_d(BDY((BF)a), MPFR_RNDD); + *sup = mpfr_get_d(BDY((BF)a), MPFR_RNDU); break; case N_IP: - *inf = ToRealDown(INF((Itv)a)); - *sup = ToRealUp(SUP((Itv)a)); + *inf = toRealDown(INF((Itv)a)); + *sup = toRealUp(SUP((Itv)a)); break; case N_IntervalDouble: *inf = INF((IntervalDouble)a); @@ -293,8 +343,6 @@ void Num2double(Num a, double *inf, double *sup) break; case N_A: default: - *inf = 0.0; - *sup = 0.0; error("Num2double: not supported operands."); break; } @@ -480,7 +528,7 @@ void divitvd(Num a, Num b, IntervalDouble *c) void pwritvd(Num a, Num e, IntervalDouble *c) { - int ei; + long ei; IntervalDouble t; if ( !e ) { @@ -498,16 +546,19 @@ void pwritvd(Num a, Num e, IntervalDouble *c) error("pwritvd : can't calculate a fractional power"); #endif } else { - ei = QTOS((Q)e); + //ei = QTOS((Q)e); + ei = mpz_get_si(BDY((Z)e)); + if (ei<0) ei = -ei; pwritv0d((IntervalDouble)a,ei,&t); - if ( SGN((Q)e) < 0 ) +// if ( SGN((Q)e) < 0 ) + if ( sgnq((Q)e) < 0 ) divnum(0,(Num)ONE,(Num)t,(Num *)c); else *c = t; } } -void pwritv0d(IntervalDouble a, int e, IntervalDouble *c) +void pwritv0d(IntervalDouble a, long e, IntervalDouble *c) { double inf, sup; double t, Xmin, Xmax; @@ -673,6 +724,24 @@ void absitvd(IntervalDouble a, Num *b) MKReal(t,rp); *b = (Num)rp; } +} +void absintvald(IntervalDouble a, IntervalDouble *b) +{ + double ai,as,inf,sup; + + ai = INF(a); + as = SUP(a); + if ( as < 0 ) { + sup = -ai; + inf = -as; + } else if (ai < 0) { + inf = 0.0; + sup = MAX(as, -ai); + } else { + inf = ai; + sup = as; + } + MKIntervalDouble(inf,sup,*b); } void distanceitvd(IntervalDouble a, IntervalDouble b, Num *c)