The R Project SVN R

Rev

Rev 89318 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 89318 Rev 89376
Line 203... Line 203...
203
 
203
 
204
double R_pow(double x, double y) /* = x ^ y */
204
double R_pow(double x, double y) /* = x ^ y */
205
{
205
{
206
    /* squaring is the most common of the specially handled cases so
206
    /* squaring is the most common of the specially handled cases so
207
       check for it first. */
207
       check for it first. */
208
    if(y == 2.0)
208
    if(y == 2.)
209
	return x * x;
209
	return x * x;
210
    if(x == 1. || y == 0.)
210
    if(x == 1. || y == 0.)
211
	return(1.);
211
	return(1.);
212
    if(x == 0.) {
212
    if(x == 0.) {
213
	if(y > 0.) return(0.);
213
	if(y > 0.) return(0.);
214
	else if(y < 0) return(R_PosInf);
214
	else if(y < 0) return(R_PosInf);
215
	else return(y); /* NA or NaN, we assert */
215
	else return(y); /* NA or NaN, we assert */
216
    }
216
    }
-
 
217
    if (x >= -11. && x <= 11.) {
-
 
218
	if(y == 4.)
-
 
219
	    return x * x * x * x;
-
 
220
	if(y == 3.)
-
 
221
	    return x * x * x;
-
 
222
    }
217
    if (R_FINITE(x) && R_FINITE(y)) {
223
    if (R_FINITE(x) && R_FINITE(y)) {
218
	/* There was a special case for y == 0.5 here, but
224
	/* There was a special case for y == 0.5 here, but
219
	   gcc 4.3.0 -g -O2 mis-compiled it.  Showed up with
225
	   gcc 4.3.0 -g -O2 mis-compiled it.  Showed up with
220
	   100^0.5 as 3.162278, example(pbirthday) failed. */
226
	   100^0.5 as 3.162278, example(pbirthday) failed. */
221
#ifdef USE_POWL_IN_R_POW
227
#ifdef USE_POWL_IN_R_POW
Line 246... Line 252...
246
    return R_NaN; // all other cases: (-Inf)^{+-Inf, non-int}; (neg)^{+-Inf}
252
    return R_NaN; // all other cases: (-Inf)^{+-Inf, non-int}; (neg)^{+-Inf}
247
}
253
}
248
 
254
 
249
double R_pow_di(double x, int n)
255
double R_pow_di(double x, int n)
250
{
256
{
251
    double xn = 1.0;
257
    double xn = 1.;
252
 
258
 
253
    if (ISNAN(x)) return x;
259
    if (ISNAN(x)) return x;
254
    if (n == NA_INTEGER) return NA_REAL;
260
    if (n == NA_INTEGER) return NA_REAL;
255
 
261
 
256
    if (n != 0) {
262
    if (n != 0) {
Line 1198... Line 1204...
1198
}
1204
}
1199
 
1205
 
1200
 
1206
 
1201
/* Mathematical Functions of One Argument */
1207
/* Mathematical Functions of One Argument */
1202
 
1208
 
-
 
1209
/** compute f(sa)  in "ari"thmetic - with "extras", notably ensuring
-
 
1210
 *  <correct f>(arg) = res *and* correct treatment of NAs in sa */
-
 
1211
static SEXP math1_ari(SEXP sa, double(*f)(double), double arg, double res, SEXP lcall)
-
 
1212
{
-
 
1213
    SEXP sy;
-
 
1214
    R_xlen_t i, n;
-
 
1215
    int naflag;
-
 
1216
 
-
 
1217
    if (!isNumeric(sa))
-
 
1218
	errorcall(lcall, R_MSG_NONNUM_MATH);
-
 
1219
 
-
 
1220
    n = XLENGTH(sa);
-
 
1221
    /* coercion can lose the object bit */
-
 
1222
    PROTECT(sa = coerceVector(sa, REALSXP));
-
 
1223
    PROTECT(sy = NO_REFERENCES(sa) ? sa : allocVector(REALSXP, n));
-
 
1224
    const double *a = REAL_RO(sa);
-
 
1225
    double *y = REAL(sy);
-
 
1226
    naflag = 0;
-
 
1227
    for (i = 0; i < n; i++) {
-
 
1228
	double x = a[i]; /* in case y == a (when sy = sa) */
-
 
1229
	if (x == arg)
-
 
1230
	    y[i] = res;
-
 
1231
	else
-
 
1232
	/* This code assumes that ISNAN(x) implies ISNAN(f(x)), so we
-
 
1233
	   only need to check ISNAN(x) if ISNAN(f(x)) is true. */
-
 
1234
	    y[i] = f(x);
-
 
1235
	if (ISNAN(y[i])) {
-
 
1236
	    if (ISNAN(x))
-
 
1237
		y[i] = x; /* make sure the incoming NaN is preserved */
-
 
1238
	    else
-
 
1239
		naflag = 1;
-
 
1240
	}
-
 
1241
    }
-
 
1242
    /* These are primitives, so need to use the call */
-
 
1243
    if(naflag) warningcall(lcall, R_MSG_NA);
-
 
1244
 
-
 
1245
    if (sa != sy && ATTRIB(sa) != R_NilValue)
-
 
1246
	SHALLOW_DUPLICATE_ATTRIB(sy, sa);
-
 
1247
    UNPROTECT(2);
-
 
1248
    return sy;
-
 
1249
}
-
 
1250
 
1203
static SEXP math1(SEXP sa, double(*f)(double), SEXP lcall)
1251
static SEXP math1(SEXP sa, double(*f)(double), SEXP lcall)
1204
{
1252
{
1205
    SEXP sy;
1253
    SEXP sy;
1206
    R_xlen_t i, n;
1254
    R_xlen_t i, n;
1207
    int naflag;
1255
    int naflag;
Line 1235... Line 1283...
1235
	SHALLOW_DUPLICATE_ATTRIB(sy, sa);
1283
	SHALLOW_DUPLICATE_ATTRIB(sy, sa);
1236
    UNPROTECT(2);
1284
    UNPROTECT(2);
1237
    return sy;
1285
    return sy;
1238
}
1286
}
1239
 
1287
 
-
 
1288
/* Make the result precise for squares of integers up to 11 */
-
 
1289
// needed?? I see exact sqrt() for all of {0:1e8} with glibc R (Linux Fedora 42):
-
 
1290
//     chkRt <- function(n) {zN <- 0:n; stopifnot(sqrt(zN^2) == zN) } ; chkRt(1e8)
-
 
1291
static double Rsqrt(double x)
-
 
1292
{
-
 
1293
    if (x == 0.) return x; // => sqrt(-0.) = -0.
-
 
1294
    for(int i=1; i < 12; i++) {
-
 
1295
	if (x == i*i) return i;
-
 
1296
    }
-
 
1297
    return sqrt(x);
-
 
1298
}
-
 
1299
 
-
 
1300
static double Rexp(double x)
-
 
1301
{
-
 
1302
    /* exp(x) = 1 + x + x^2/2! + ...
-
 
1303
     * should return 1+x for very small x i.e.,  x^2/2 < D_EPS / 2
-
 
1304
     * <==> x^2 < D_EPS  <==> |x| < sqrt(D_EPS) : */
-
 
1305
    return (fabs(x) <= sqrt(DBL_EPSILON)) ? 1. + x : exp(x);
-
 
1306
}
-
 
1307
 
-
 
1308
/* should return x for very small x (e.g. expm1(x))*/
-
 
1309
static double f_x_x(double x, double(*f)(double), double m)
-
 
1310
{
-
 
1311
    return (fabs(x) <= m) ? x : f(x);
-
 
1312
}
-
 
1313
 
-
 
1314
static double Rexpm1(double x)
-
 
1315
{
-
 
1316
    /* expm1(x) = exp(x) - 1 =  x + x^2/2 + O(x^3)
-
 
1317
     *                       =. x  when  x^2/2 < |x| * D_EPS/2
-
 
1318
     *                             <==>  |x|   <  D_EPS */
-
 
1319
    return f_x_x(x, expm1, DBL_EPSILON);
-
 
1320
}
-
 
1321
 
-
 
1322
static double Rlog1p(double x)
-
 
1323
{
-
 
1324
    /* log1p(x) = log(1 + x) =  x - x^2/2  + O(x^3)
-
 
1325
     *                       =. x  when  |x| < D_EPS, see Rexpm1() */
-
 
1326
    return f_x_x(x, log1p, DBL_EPSILON);
-
 
1327
}
-
 
1328
 
-
 
1329
static double Rsin(double x)
-
 
1330
{
-
 
1331
    /* sin(x) = x - x^3/6 + O(x^5) = x*(1 - x^2/6) + O(.) =!= x  iff
-
 
1332
       (1 - x^2/6) .= 1  <==>  |x| < sqrt(6 eps); eps = DBL_Eps/2 */
-
 
1333
    return f_x_x(x, sin, sqrt(3. * DBL_EPSILON));
-
 
1334
}
-
 
1335
 
-
 
1336
static double Rtan(double x)
-
 
1337
{
-
 
1338
    /* tan(x) =  x + x^3/3 + O(x^5)
-
 
1339
              =. x  when |x|^3/3 < |x| EPS/2  <==>
-
 
1340
	                  x^2    < EPS * 3/2  <==>
-
 
1341
 	                   |x|   < sqrt(3/2 * EPS) */
-
 
1342
    return f_x_x(x, tan, sqrt(1.5 * DBL_EPSILON));
-
 
1343
}
-
 
1344
 
-
 
1345
static double Rcos(double x)
-
 
1346
{
-
 
1347
    /* cos(x) =  1 - x^2/2! + x^4/4!
-
 
1348
              =. 1 - x^2/2!  iff  x^4/24 < (1 - x^2/2) * EPS/2  ~= EPS/2 <==>
-
 
1349
 	                          x^4 < 12*EPS  */
-
 
1350
    if (fabs(x) < sqrt(sqrt(12. * DBL_EPSILON)))
-
 
1351
	return (1. - x*x*0.5);
-
 
1352
    else
-
 
1353
	return cos(x);
-
 
1354
}
-
 
1355
 
-
 
1356
static double Rasin(double x)
-
 
1357
{
-
 
1358
    /* asin(x) =  x + x^3/6 + 3/40 * x^5...   ==>
-
 
1359
               =. x when |x| < sqrt(3 * EPS)  -- see Rsin() above */
-
 
1360
    return f_x_x(x, asin, sqrt(3. * DBL_EPSILON));
-
 
1361
}
-
 
1362
 
-
 
1363
static double Ratan(double x)
-
 
1364
{
-
 
1365
    /* atan(x) =  x - x^3/3 + x^5/5 ... ==>
-
 
1366
               =. x  iff |x| < sqrt(3/2 * EPS) -- see Rtan() above*/
-
 
1367
    return f_x_x(x, atan, sqrt(1.5 * DBL_EPSILON));
-
 
1368
}
-
 
1369
 
-
 
1370
 
1240
 
1371
 
1241
attribute_hidden SEXP do_math1(SEXP call, SEXP op, SEXP args, SEXP env)
1372
attribute_hidden SEXP do_math1(SEXP call, SEXP op, SEXP args, SEXP env)
1242
{
1373
{
1243
    SEXP s;
1374
    SEXP s;
1244
 
1375
 
Line 1249... Line 1380...
1249
	return s;
1380
	return s;
1250
 
1381
 
1251
    if (isComplex(CAR(args)))
1382
    if (isComplex(CAR(args)))
1252
	return complex_math1(call, op, args, env);
1383
	return complex_math1(call, op, args, env);
1253
 
1384
 
1254
#define MATH1(x) math1(CAR(args), x, call);
1385
#define MATH1(x)      math1(CAR(args), x, call);
-
 
1386
#define MATH1_SQRT(x) math1(CAR(args), Rsqrt, call);
-
 
1387
#define MATH1_EXP(x)  math1_ari(CAR(args), Rexp,  0., 1., call);
-
 
1388
#define MATH1_EXPM1(x)math1_ari(CAR(args), Rexpm1,0., 0., call);
-
 
1389
#define MATH1_LOG1P(x)math1_ari(CAR(args), Rlog1p,0., 0., call);
-
 
1390
#define MATH1_SIN(x)  math1_ari(CAR(args), Rsin,  0., 0., call);
-
 
1391
#define MATH1_ASIN(x) math1_ari(CAR(args), Rasin, 0., 0., call);
-
 
1392
#define MATH1_TAN(x)  math1_ari(CAR(args), Rtan,  0., 0., call);
-
 
1393
#define MATH1_ATAN(x) math1_ari(CAR(args), Ratan, 0., 0., call);
-
 
1394
#define MATH1_COS(x)  math1_ari(CAR(args), Rcos,  0., 1., call);
-
 
1395
#define MATH1_00(x)   math1_ari(CAR(args),  x,    0., 0., call);
-
 
1396
#define MATH1_01(x)   math1_ari(CAR(args),  x,    0., 1., call);
-
 
1397
#define MATH1_10(x)   math1_ari(CAR(args),  x,    1., 0., call);
1255
    switch (PRIMVAL(op)) {
1398
    switch (PRIMVAL(op)) {
1256
    case 1: return MATH1(floor);
1399
    case 1: return MATH1(floor);
1257
    case 2: return MATH1(ceil);
1400
    case 2: return MATH1(ceil);
1258
    case 3: return MATH1(sqrt);
1401
    case 3: return MATH1_SQRT(sqrt);
1259
    case 4: return MATH1(sign);
1402
    case 4: return MATH1(sign);
1260
	/* case 5: return MATH1(trunc); separate from 2.6.0 */
1403
	/* case 5: return MATH1(trunc); separate from 2.6.0 */
1261
 
1404
 
1262
    case 10: return MATH1(exp);
1405
    case 10: return MATH1_EXP(exp);
1263
    case 11: return MATH1(expm1);
1406
    case 11: return MATH1_EXPM1(expm1);
1264
    case 12: return MATH1(log1p);
1407
    case 12: return MATH1_LOG1P(log1p);
1265
 
1408
 
1266
    case 20: return MATH1(cos);
1409
    case 20: return MATH1_COS(cos);
1267
    case 21: return MATH1(sin);
1410
    case 21: return MATH1_SIN(sin);
1268
    case 22: return MATH1(tan);
1411
    case 22: return MATH1_TAN(tan);
1269
    case 23: return MATH1(acos);
1412
    case 23: return MATH1_10(acos);
1270
    case 24: return MATH1(asin);
1413
    case 24: return MATH1_ASIN(asin);
1271
    case 25: return MATH1(atan);
1414
    case 25: return MATH1_ATAN(atan);
1272
 
1415
 
1273
    case 30: return MATH1(cosh);
1416
    case 30: return MATH1_01(cosh);
1274
    case 31: return MATH1(sinh);
1417
    case 31: return MATH1_00(sinh);
1275
    case 32: return MATH1(tanh);
1418
    case 32: return MATH1_00(tanh);
1276
    case 33: return MATH1(acosh);
1419
    case 33: return MATH1_10(acosh);
1277
    case 34: return MATH1(asinh);
1420
    case 34: return MATH1_00(asinh);
1278
    case 35: return MATH1(atanh);
1421
    case 35: return MATH1_00(atanh);
1279
 
1422
 
1280
    case 40: return MATH1(lgammafn);
1423
    case 40: return MATH1(lgammafn); // ../nmath/lgamma.c
1281
    case 41: return MATH1(gammafn);
1424
    case 41: return MATH1(gammafn);
1282
 
1425
 
1283
    case 42: return MATH1(digamma);
1426
    case 42: return MATH1(digamma); // ../nmath/polygamma.c
1284
    case 43: return MATH1(trigamma);
1427
    case 43: return MATH1(trigamma);
1285
	/* case 44: return MATH1(tetragamma);
1428
	/* case 44: return MATH1(tetragamma);
1286
	   case 45: return MATH1(pentagamma);
1429
	   case 45: return MATH1(pentagamma);
1287
	   removed in 2.0.0 -- rather use Math2's psigamma()
1430
	   removed in 2.0.0 -- rather use Math2's psigamma()
1288
 
1431