The R Project SVN R

Rev

Rev 63171 | Rev 63462 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 r 1
/*
831 maechler 2
 *  R : A Computer Language for Statistical Data Analysis
2 r 3
 *  Copyright (C) 1995, 1996, 1997  Robert Gentleman and Ross Ihaka
59035 ripley 4
 *  Copyright (C) 2000-12	    The R Core Team.
35069 maechler 5
 *  Copyright (C) 2005		    The R Foundation
2 r 6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
42307 ripley 18
 *  along with this program; if not, a copy is available at
19
 *  http://www.r-project.org/Licenses/
2 r 20
 */
21
 
5187 hornik 22
#ifdef HAVE_CONFIG_H
7701 hornik 23
#include <config.h>
5187 hornik 24
#endif
25
 
54294 ripley 26
/* Note: gcc may warn in several places about C99 features as extensions.
54277 ripley 27
   This is a very-long-standing GCC bug, http://gcc.gnu.org/PR7263
54279 ripley 28
   The system <complex.h> header can work around it: some do.
54277 ripley 29
*/
54275 ripley 30
 
54256 ripley 31
#if 0
54775 ripley 32
/* For testing substitute fns */
54293 ripley 33
#undef HAVE_CARG
34
#undef HAVE_CABS
54328 ripley 35
#undef HAVE_CPOW
54256 ripley 36
#undef HAVE_CEXP
37
#undef HAVE_CLOG
38
#undef HAVE_CSQRT
39
#undef HAVE_CSIN
40
#undef HAVE_CCOS
41
#undef HAVE_CTAN
42
#undef HAVE_CASIN
43
#undef HAVE_CACOS
44
#undef HAVE_CATAN
45
#undef HAVE_CSINH
46
#undef HAVE_CCOSH
47
#undef HAVE_CTANH
48
#endif
49
 
54775 ripley 50
#ifdef __CYGWIN__
51
/* as of 1.7.8 it had cacos, but it does not work */
52
#undef HAVE_CACOS
53
#endif
54
 
58276 ripley 55
#ifdef __SUNPRO_C
58274 ripley 56
/* segfaults in Solaris Studio 12.3 */
57
#undef HAVE_CPOW
58
#endif
59
 
15508 pd 60
#include <Defn.h>		/* -> ../include/R_ext/Complex.h */
60667 ripley 61
#include <Internal.h>
11499 ripley 62
#include <Rmath.h>
2 r 63
 
9417 ripley 64
#include "arithmetic.h"		/* complex_*  */
54170 ripley 65
#include <complex.h>
2632 maechler 66
 
60166 ripley 67
/* interval at which to check interrupts, a guess */
68
#define NINTERRUPT 10000000
69
 
70
 
54277 ripley 71
/* GCC has problems with header files on e.g. Solaris.
54279 ripley 72
   That OS defines the imaginary type, but GCC does not.
61018 ripley 73
   Probably needed elsewhere, e.g. AIX, HP-UX (PR#15083)
54329 ripley 74
   And use on Win32/64 suppresses warnings.
61018 ripley 75
   The warning is also seen on Mac OS 10.5, but not later.
54279 ripley 76
*/
61018 ripley 77
#if defined(__GNUC__) && (defined(__sun__) || defined(__hpux__) || defined(Win32))
54277 ripley 78
# undef  I
79
# define I (__extension__ 1.0iF)
80
#endif
81
 
82
 
57740 ripley 83
/* 
58049 ripley 84
   Note: this could use the C11 CMPLX() macro.
57740 ripley 85
   As could mycpow, z_tan and some of the substitutes.
86
 */
54170 ripley 87
static R_INLINE double complex toC99(Rcomplex *x)
88
{
89
#if __GNUC__
90
    double complex ans = (double complex) 0; /* -Wall */
91
    __real__ ans = x->r;
92
    __imag__ ans = x->i;
93
    return ans;
94
#else
95
    return x->r + x->i * I;
35225 ripley 96
#endif
54170 ripley 97
}
54294 ripley 98
#define C99_COMPLEX2(x, i) toC99(COMPLEX(x) + i)
99
 
100
static R_INLINE void 
59086 ripley 101
SET_C99_COMPLEX(Rcomplex *x, R_xlen_t i, double complex value)
54170 ripley 102
{
103
    Rcomplex *ans = x+i;
104
    ans->r = creal(value);
105
    ans->i = cimag(value);
106
}
9417 ripley 107
 
41713 ripley 108
SEXP attribute_hidden complex_unary(ARITHOP_TYPE code, SEXP s1, SEXP call)
2 r 109
{
59048 ripley 110
    R_xlen_t i, n;
580 ihaka 111
    SEXP ans;
2 r 112
 
580 ihaka 113
    switch(code) {
114
    case PLUSOP:
115
	return s1;
116
    case MINUSOP:
117
	ans = duplicate(s1);
59048 ripley 118
	n = XLENGTH(s1);
580 ihaka 119
	for (i = 0; i < n; i++) {
54170 ripley 120
	    Rcomplex x = COMPLEX(s1)[i];
580 ihaka 121
	    COMPLEX(ans)[i].r = -x.r;
122
	    COMPLEX(ans)[i].i = -x.i;
2 r 123
	}
580 ihaka 124
	return ans;
125
    default:
41713 ripley 126
	errorcall(call, _("invalid complex unary operator"));
580 ihaka 127
    }
41713 ripley 128
    return R_NilValue; /* -Wall */
2 r 129
}
130
 
54329 ripley 131
static R_INLINE double complex R_cpow_n(double complex X, int k)
54256 ripley 132
{
54163 ripley 133
    if(k == 0) return (double complex) 1.;
134
    else if(k == 1) return X;
135
    else if(k < 0) return 1. / R_cpow_n(X, -k);
49062 maechler 136
    else {/* k > 0 */
54163 ripley 137
	double complex z = (double complex) 1.;;
49062 maechler 138
	while (k > 0) {
54163 ripley 139
	    if (k & 1) z = z * X;
54256 ripley 140
	    if (k == 1) break;
49062 maechler 141
	    k >>= 1; /* efficient division by 2; now have k >= 1 */
142
	    X = X * X;
143
	}
144
	return z;
145
    }
146
}
147
 
55513 ripley 148
#if defined(Win32)
55510 ripley 149
# undef HAVE_CPOW
150
#endif
49062 maechler 151
/* reason for this:
55512 ripley 152
  1) X^n  (e.g. for n = +/- 2, 3) is unnecessarily inaccurate in glibc;
55510 ripley 153
     cut-off 65536 : guided from empirical speed measurements
54329 ripley 154
 
55512 ripley 155
  2) On Mingw (but not Mingw-w64) the system cpow is explicitly linked
156
     against the (slow) MSVCRT pow, and gets (0+0i)^Y as 0+0i for all Y.
55611 ripley 157
 
158
  3) PPC Mac OS X crashes on powers of 0+0i (at least under Rosetta).
55618 ripley 159
  Really 0i^-1 should by Inf+NaNi, but getting that portably seems too hard.
57740 ripley 160
  (C1x's CMPLX will eventually be possible.)
55510 ripley 161
*/
49062 maechler 162
 
38705 ripley 163
static double complex mycpow (double complex X, double complex Y)
35225 ripley 164
{
55611 ripley 165
    double complex Z;
166
    double yr = creal(Y), yi = cimag(Y); 
167
    int k;
168
    if (X == 0.0) {
55618 ripley 169
	if (yi == 0.0) Z = R_pow(0.0, yr); else Z = R_NaN + R_NaN*I;
55611 ripley 170
    } else if (yi == 0.0 && yr == (k = (int) yr) && abs(k) <= 65536)
54328 ripley 171
	Z = R_cpow_n(X, k);
55512 ripley 172
    else
55510 ripley 173
#ifdef HAVE_CPOW
54328 ripley 174
	Z = cpow(X, Y);
175
#else
176
    {
55512 ripley 177
	/* Used for FreeBSD and MingGW, hence mainly with gcc */
54328 ripley 178
	double rho, r, i, theta;
179
	r = hypot(creal(X), cimag(X));
180
	i = atan2(cimag(X), creal(X));
181
	theta = i * yr;
182
	if (yi == 0.0)
183
	    rho = pow(r, yr);
184
	else {
185
	    /* rearrangement of cexp(X * clog(Y)) */
54329 ripley 186
	    r = log(r);
54328 ripley 187
	    theta += r * yi;
188
	    rho = exp(r * yr - i * yi);
49062 maechler 189
	}
55512 ripley 190
#ifdef __GNUC__
55611 ripley 191
	__real__ Z = rho * cos(theta);
192
	__imag__ Z = rho * sin(theta);
55512 ripley 193
#else
55611 ripley 194
	Z = rho * cos(theta) + (rho * sin(theta)) * I;
55512 ripley 195
#endif
54328 ripley 196
    }
197
#endif
198
    return Z;
35225 ripley 199
}
35227 ripley 200
 
201
/* See arithmetic.c */
202
#define mod_iterate(n1,n2,i1,i2) for (i=i1=i2=0; i<n; \
203
	i1 = (++i1 == n1) ? 0 : i1,\
204
	i2 = (++i2 == n2) ? 0 : i2,\
205
	++i)
1839 ihaka 206
 
38505 ripley 207
SEXP attribute_hidden complex_binary(ARITHOP_TYPE code, SEXP s1, SEXP s2)
2 r 208
{
59048 ripley 209
    R_xlen_t i,i1, i2, n, n1, n2;
580 ihaka 210
    SEXP ans;
16613 ripley 211
 
54256 ripley 212
    /* Note: "s1" and "s2" are protected in the calling code. */
59048 ripley 213
    n1 = XLENGTH(s1);
214
    n2 = XLENGTH(s2);
16613 ripley 215
     /* S4-compatibility change: if n1 or n2 is 0, result is of length 0 */
35069 maechler 216
    if (n1 == 0 || n2 == 0) return(allocVector(CPLXSXP, 0));
16613 ripley 217
 
580 ihaka 218
    n = (n1 > n2) ? n1 : n2;
219
    ans = allocVector(CPLXSXP, n);
35069 maechler 220
 
580 ihaka 221
    switch (code) {
222
    case PLUSOP:
35227 ripley 223
	mod_iterate(n1, n2, i1, i2) {
60186 ripley 224
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
54170 ripley 225
	    Rcomplex x1 = COMPLEX(s1)[i1], x2 = COMPLEX(s2)[i2];
580 ihaka 226
	    COMPLEX(ans)[i].r = x1.r + x2.r;
227
	    COMPLEX(ans)[i].i = x1.i + x2.i;
2 r 228
	}
580 ihaka 229
	break;
230
    case MINUSOP:
35227 ripley 231
	mod_iterate(n1, n2, i1, i2) {
60186 ripley 232
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
54170 ripley 233
	    Rcomplex x1 = COMPLEX(s1)[i1], x2 = COMPLEX(s2)[i2];
580 ihaka 234
	    COMPLEX(ans)[i].r = x1.r - x2.r;
235
	    COMPLEX(ans)[i].i = x1.i - x2.i;
236
	}
237
	break;
238
    case TIMESOP:
35227 ripley 239
	mod_iterate(n1, n2, i1, i2) {
60186 ripley 240
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
54174 ripley 241
	    SET_C99_COMPLEX(COMPLEX(ans), i,
242
			    C99_COMPLEX2(s1, i1) * C99_COMPLEX2(s2, i2));
580 ihaka 243
	}
244
	break;
245
    case DIVOP:
35227 ripley 246
	mod_iterate(n1, n2, i1, i2) {
60186 ripley 247
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
54170 ripley 248
	    SET_C99_COMPLEX(COMPLEX(ans), i,
249
			    C99_COMPLEX2(s1, i1) / C99_COMPLEX2(s2, i2));
580 ihaka 250
	}
251
	break;
252
    case POWOP:
35227 ripley 253
	mod_iterate(n1, n2, i1, i2) {
60186 ripley 254
	    if ((i+1) % NINTERRUPT == 0) R_CheckUserInterrupt();
54170 ripley 255
	    SET_C99_COMPLEX(COMPLEX(ans), i,
256
			    mycpow(C99_COMPLEX2(s1, i1), C99_COMPLEX2(s2, i2)));
580 ihaka 257
	}
258
	break;
259
    default:
32861 ripley 260
	error(_("unimplemented complex operation"));
580 ihaka 261
    }
16613 ripley 262
 
24539 luke 263
    /* quick return if there are no attributes */
264
    if (ATTRIB(s1) == R_NilValue && ATTRIB(s2) == R_NilValue)
265
	return ans;
266
 
16613 ripley 267
    /* Copy attributes from longer argument. */
1010 ihaka 268
    if (n1 > n2)
269
	copyMostAttrib(s1, ans);
270
    else if (n1 == n2) {
271
	copyMostAttrib(s2, ans);
272
	copyMostAttrib(s1, ans);
54174 ripley 273
    } else
1010 ihaka 274
	copyMostAttrib(s2, ans);
580 ihaka 275
    return ans;
2 r 276
}
277
 
36990 ripley 278
SEXP attribute_hidden do_cmathfuns(SEXP call, SEXP op, SEXP args, SEXP env)
831 maechler 279
{
6098 pd 280
    SEXP x, y = R_NilValue;	/* -Wall*/
59048 ripley 281
    R_xlen_t i, n;
2 r 282
 
580 ihaka 283
    checkArity(op, args);
51316 ripley 284
    check1arg(args, call, "z");
26610 ripley 285
    if (DispatchGroup("Complex", call, op, args, env, &x))
45446 ripley 286
	return x;
580 ihaka 287
    x = CAR(args);
59048 ripley 288
    n = xlength(x);
580 ihaka 289
    if (isComplex(x)) {
290
	switch(PRIMVAL(op)) {
291
	case 1:	/* Re */
292
	    y = allocVector(REALSXP, n);
35225 ripley 293
	    for(i = 0 ; i < n ; i++)
580 ihaka 294
		REAL(y)[i] = COMPLEX(x)[i].r;
295
	    break;
296
	case 2:	/* Im */
297
	    y = allocVector(REALSXP, n);
35225 ripley 298
	    for(i = 0 ; i < n ; i++)
580 ihaka 299
		REAL(y)[i] = COMPLEX(x)[i].i;
300
	    break;
301
	case 3:	/* Mod */
6098 pd 302
	case 6:	/* abs */
580 ihaka 303
	    y = allocVector(REALSXP, n);
35225 ripley 304
	    for(i = 0 ; i < n ; i++)
54249 ripley 305
#if HAVE_CABS
54170 ripley 306
		REAL(y)[i] = cabs(C99_COMPLEX2(x, i));
54249 ripley 307
#else
308
		REAL(y)[i] = hypot(COMPLEX(x)[i].r, COMPLEX(x)[i].i);
309
#endif
580 ihaka 310
	    break;
311
	case 4:	/* Arg */
312
	    y = allocVector(REALSXP, n);
35225 ripley 313
	    for(i = 0 ; i < n ; i++)
54249 ripley 314
#if HAVE_CARG
54174 ripley 315
		REAL(y)[i] = carg(C99_COMPLEX2(x, i));
54249 ripley 316
#else
317
		REAL(y)[i] = atan2(COMPLEX(x)[i].i, COMPLEX(x)[i].r);
318
#endif
580 ihaka 319
	    break;
320
	case 5:	/* Conj */
321
	    y = allocVector(CPLXSXP, n);
35225 ripley 322
	    for(i = 0 ; i < n ; i++) {
580 ihaka 323
		COMPLEX(y)[i].r = COMPLEX(x)[i].r;
324
		COMPLEX(y)[i].i = -COMPLEX(x)[i].i;
325
	    }
326
	    break;
2 r 327
	}
580 ihaka 328
    }
35225 ripley 329
    else if(isNumeric(x)) { /* so no complex numbers involved */
580 ihaka 330
	if(isReal(x)) PROTECT(x);
331
	else PROTECT(x = coerceVector(x, REALSXP));
332
	switch(PRIMVAL(op)) {
333
	case 1:	/* Re */
334
	case 5:	/* Conj */
335
	    y = allocVector(REALSXP, n);
35225 ripley 336
	    for(i = 0 ; i < n ; i++)
580 ihaka 337
		REAL(y)[i] = REAL(x)[i];
338
	    break;
339
	case 2:	/* Im */
36129 ripley 340
	    y = allocVector(REALSXP, n);
341
	    for(i = 0 ; i < n ; i++)
342
		REAL(y)[i] = 0.0;
343
	    break;
580 ihaka 344
	case 4:	/* Arg */
345
	    y = allocVector(REALSXP, n);
35225 ripley 346
	    for(i = 0 ; i < n ; i++)
580 ihaka 347
		if(ISNAN(REAL(x)[i]))
348
		    REAL(y)[i] = REAL(x)[i];
35069 maechler 349
		else if (REAL(x)[i] >= 0)
350
		    REAL(y)[i] = 0;
580 ihaka 351
		else
35069 maechler 352
		    REAL(y)[i] = M_PI;
580 ihaka 353
	    break;
354
	case 3:	/* Mod */
6098 pd 355
	case 6:	/* abs */
580 ihaka 356
	    y = allocVector(REALSXP, n);
35225 ripley 357
	    for(i = 0 ; i < n ; i++)
580 ihaka 358
		REAL(y)[i] = fabs(REAL(x)[i]);
359
	    break;
360
	}
361
	UNPROTECT(1);
362
    }
32861 ripley 363
    else errorcall(call, _("non-numeric argument to function"));
580 ihaka 364
    PROTECT(x);
365
    PROTECT(y);
41002 jmc 366
    DUPLICATE_ATTRIB(y, x);
580 ihaka 367
    UNPROTECT(2);
368
    return y;
2 r 369
}
370
 
54262 ripley 371
/* used in format.c and printutils.c */
35250 ripley 372
#define MAX_DIGITS 22
38705 ripley 373
void attribute_hidden z_prec_r(Rcomplex *r, Rcomplex *x, double digits)
2 r 374
{
35253 ripley 375
    double m = 0.0, m1, m2;
35250 ripley 376
    int dig, mag;
377
 
378
    r->r = x->r; r->i = x->i;
35253 ripley 379
    m1 = fabs(x->r); m2 = fabs(x->i);
380
    if(R_FINITE(m1)) m = m1;
381
    if(R_FINITE(m2) && m2 > m) m = m2;
35250 ripley 382
    if (m == 0.0) return;
383
    if (!R_FINITE(digits)) {
384
	if(digits > 0) return; else {r->r = r->i = 0.0; return ;}
385
    }
386
    dig = (int)floor(digits+0.5);
387
    if (dig > MAX_DIGITS) return; else if (dig < 1) dig = 1;
388
    mag = (int)floor(log10(m));
389
    dig = dig - mag - 1;
390
    if (dig > 306) {
391
	double pow10 = 1.0e4;
392
	digits = (double)(dig - 4);
54776 ripley 393
	r->r = fround(pow10 * x->r, digits)/pow10;
394
	r->i = fround(pow10 * x->i, digits)/pow10;
35250 ripley 395
    } else {
396
	digits = (double)(dig);
54776 ripley 397
	r->r = fround(x->r, digits);
398
	r->i = fround(x->i, digits);
35250 ripley 399
    }
2 r 400
}
401
 
54275 ripley 402
/* These substitute functions are rarely used, and not extensively
403
   tested, e.g. over CRAN.  Please do not change without very good
404
   reason!
54253 ripley 405
 
54275 ripley 406
   Currently (Feb 2011) they are used on FreeBSD.
407
*/
35225 ripley 408
 
54249 ripley 409
#ifndef HAVE_CLOG
54256 ripley 410
#define clog R_clog
54275 ripley 411
/* FIXME: maybe add full IEC60559 support */
54253 ripley 412
static double complex clog(double complex x)
54249 ripley 413
{
414
    double xr = creal(x), xi = cimag(x);
415
    return log(hypot(xr, xi)) + atan2(xi, xr)*I;
416
}
417
#endif
54258 ripley 418
 
54249 ripley 419
#ifndef HAVE_CSQRT
54256 ripley 420
#define csqrt R_csqrt
54249 ripley 421
/* FreeBSD does have this one */
54253 ripley 422
static double complex csqrt(double complex x)
54249 ripley 423
{
424
    return mycpow(x, 0.5+0.0*I);
425
}
426
#endif
54258 ripley 427
 
54249 ripley 428
#ifndef HAVE_CEXP
54256 ripley 429
#define cexp R_cexp
54253 ripley 430
/* FIXME: check/add full IEC60559 support */
431
static double complex cexp(double complex x)
54249 ripley 432
{
433
    double expx = exp(creal(x)), y = cimag(x);
434
    return expx * cos(y) + (expx * sin(y)) * I;
435
}
436
#endif
54258 ripley 437
 
54249 ripley 438
#ifndef HAVE_CCOS
54256 ripley 439
#define ccos R_ccos
54253 ripley 440
static double complex ccos(double complex x)
54249 ripley 441
{
54256 ripley 442
    double xr = creal(x), xi = cimag(x);
54262 ripley 443
    return cos(xr)*cosh(xi) - sin(xr)*sinh(xi)*I; /* A&S 4.3.56 */
54249 ripley 444
}
445
#endif
54258 ripley 446
 
54249 ripley 447
#ifndef HAVE_CSIN
54256 ripley 448
#define csin R_csin
54253 ripley 449
static double complex csin(double complex x)
54249 ripley 450
{
54256 ripley 451
    double xr = creal(x), xi = cimag(x);
54262 ripley 452
    return sin(xr)*cosh(xi) + cos(xr)*sinh(xi)*I; /* A&S 4.3.55 */
54249 ripley 453
}
454
#endif
54258 ripley 455
 
54275 ripley 456
#ifndef HAVE_CTAN
457
#define ctan R_ctan
458
static double complex ctan(double complex z)
459
{
460
    /* A&S 4.3.57 */
461
    double x2, y2, den, ri;
462
    x2 = 2.0 * creal(z);
463
    y2 = 2.0 * cimag(z);
464
    den = cos(x2) + cosh(y2);
465
    /* any threshold between -log(DBL_EPSILON) and log(DBL_XMAX) will do*/
466
    if (ISNAN(y2) || fabs(y2) < 50.0) ri = sinh(y2)/den;
467
    else ri = (y2 < 0 ? -1.0 : 1.0);
468
    return sin(x2)/den + ri * I;
469
}
470
#endif
471
 
54249 ripley 472
#ifndef HAVE_CASIN
54256 ripley 473
#define casin R_casin
474
static double complex casin(double complex z)
54249 ripley 475
{
54262 ripley 476
    /* A&S 4.4.37 */
54258 ripley 477
    double alpha, t1, t2, x = creal(z), y = cimag(z), ri;
54256 ripley 478
    t1 = 0.5 * hypot(x + 1, y);
479
    t2 = 0.5 * hypot(x - 1, y);
480
    alpha = t1 + t2;
481
    ri = log(alpha + sqrt(alpha*alpha - 1));
54262 ripley 482
    /* This comes from 
483
       'z_asin() is continuous from below if x >= 1
484
        and continuous from above if x <= -1.'
485
    */
486
    if(y < 0 || (y == 0 && x > 1)) ri *= -1;
54256 ripley 487
    return asin(t1  - t2) + ri*I;
54249 ripley 488
}
489
#endif
54258 ripley 490
 
54249 ripley 491
#ifndef HAVE_CACOS
54256 ripley 492
#define cacos R_cacos
493
static double complex cacos(double complex z)
54249 ripley 494
{
54256 ripley 495
    return M_PI_2 - casin(z);
54249 ripley 496
}
497
#endif
54258 ripley 498
 
54249 ripley 499
#ifndef HAVE_CATAN
54256 ripley 500
#define catan R_catan
501
static double complex catan(double complex z)
54249 ripley 502
{
54256 ripley 503
    double x = creal(z), y = cimag(z), rr, ri;
504
    rr = 0.5 * atan2(2 * x, (1 - x * x - y * y));
505
    ri = 0.25 * log((x * x + (y + 1) * (y + 1)) /
506
		    (x * x + (y - 1) * (y - 1)));
54275 ripley 507
    return rr + ri*I;
54249 ripley 508
}
509
#endif
54258 ripley 510
 
54249 ripley 511
#ifndef HAVE_CCOSH
54256 ripley 512
#define ccosh R_ccosh
513
static double complex ccosh(double complex z)
54249 ripley 514
{
54262 ripley 515
    return ccos(z * I); /* A&S 4.5.8 */
54249 ripley 516
}
517
#endif
54258 ripley 518
 
54249 ripley 519
#ifndef HAVE_CSINH
54256 ripley 520
#define csinh R_csinh
521
static double complex csinh(double complex z)
54249 ripley 522
{
54262 ripley 523
    return -I * csin(z * I); /* A&S 4.5.7 */
54249 ripley 524
}
525
#endif
54258 ripley 526
 
54249 ripley 527
#ifndef HAVE_CTANH
54256 ripley 528
#define ctanh R_ctanh
529
static double complex ctanh(double complex z)
54249 ripley 530
{
54262 ripley 531
    return -I * ctan(z * I); /* A&S 4.5.9 */
54249 ripley 532
}
533
#endif
54258 ripley 534
 
54275 ripley 535
static double complex z_tan(double complex z)
54249 ripley 536
{
54275 ripley 537
    double y = cimag(z);
538
    double complex r = ctan(z);
539
    if(R_FINITE(y) && fabs(y) > 25.0) {
540
	/* at this point the real part is nearly zero, and the
541
	   imaginary part is one: but some OSes get the imag as NaN */
542
#if __GNUC__
543
	__imag__ r = y < 0 ? -1.0 : 1.0;
544
#else
545
	r = creal(r) + (y < 0 ? -1.0 : 1.0) * I;
546
#endif
547
    }
54262 ripley 548
    return r;
54249 ripley 549
}
54258 ripley 550
 
54275 ripley 551
/* Don't rely on the OS at the branch cuts */
552
 
553
static double complex z_asin(double complex z)
54249 ripley 554
{
54275 ripley 555
    if(cimag(z) == 0 && fabs(creal(z)) > 1) {
556
	double alpha, t1, t2, x = creal(z), ri;
557
	t1 = 0.5 * fabs(x + 1);
558
	t2 = 0.5 * fabs(x - 1);
559
	alpha = t1 + t2;
560
	ri = log(alpha + sqrt(alpha*alpha - 1));
561
	if(x > 1) ri *= -1;
562
	return asin(t1  - t2) + ri*I;
563
    }
564
    return casin(z);
54249 ripley 565
}
54258 ripley 566
 
54275 ripley 567
static double complex z_acos(double complex z)
54249 ripley 568
{
54275 ripley 569
    if(cimag(z) == 0 && fabs(creal(z)) > 1) return M_PI_2 - z_asin(z);
570
    return cacos(z);
54249 ripley 571
}
572
 
54275 ripley 573
static double complex z_atan(double complex z)
574
{
575
    if(creal(z) == 0 && fabs(cimag(z)) > 1) {
576
	double y = cimag(z), rr, ri;
577
	rr = (y > 0) ? M_PI_2 : -M_PI_2;
578
	ri = 0.25 * log(((y + 1) * (y + 1))/((y - 1) * (y - 1)));
579
	return rr + ri*I;
580
    }
581
    return catan(z);
582
}
54273 ripley 583
 
54275 ripley 584
static double complex z_acosh(double complex z)
585
{
586
    return z_acos(z) * I;
587
}
588
 
589
static double complex z_asinh(double complex z)
590
{
591
    return -I * z_asin(z * I);
592
}
593
 
594
static double complex z_atanh(double complex z)
595
{
596
    return -I * z_atan(z * I);
597
}
598
 
54273 ripley 599
static Rboolean cmath1(double complex (*f)(double complex),
59090 ripley 600
		       Rcomplex *x, Rcomplex *y, R_xlen_t n)
54273 ripley 601
{
59090 ripley 602
    R_xlen_t i;
54273 ripley 603
    Rboolean naflag = FALSE;
604
    for (i = 0 ; i < n ; i++) {
605
	if (ISNA(x[i].r) || ISNA(x[i].i)) {
606
	    y[i].r = NA_REAL; y[i].i = NA_REAL;
607
	} else {
608
	    SET_C99_COMPLEX(y, i, f(toC99(x + i)));
55516 ripley 609
	    if ( (ISNAN(y[i].r) || ISNAN(y[i].i)) &&
610
		!(ISNAN(x[i].r) || ISNAN(x[i].i)) ) naflag = TRUE;
54273 ripley 611
	}
612
    }
613
    return naflag;
614
}
615
 
38505 ripley 616
SEXP attribute_hidden complex_math1(SEXP call, SEXP op, SEXP args, SEXP env)
2 r 617
{
580 ihaka 618
    SEXP x, y;
59048 ripley 619
    R_xlen_t n;
19912 duncan 620
    Rboolean naflag = FALSE;
54273 ripley 621
 
6098 pd 622
    PROTECT(x = CAR(args));
59048 ripley 623
    n = xlength(x);
6098 pd 624
    PROTECT(y = allocVector(CPLXSXP, n));
2 r 625
 
580 ihaka 626
    switch (PRIMVAL(op)) {
54174 ripley 627
    case 10003: naflag = cmath1(clog, COMPLEX(x), COMPLEX(y), n); break;
628
    case 3: naflag = cmath1(csqrt, COMPLEX(x), COMPLEX(y), n); break;
629
    case 10: naflag = cmath1(cexp, COMPLEX(x), COMPLEX(y), n); break;
630
    case 20: naflag = cmath1(ccos, COMPLEX(x), COMPLEX(y), n); break;
631
    case 21: naflag = cmath1(csin, COMPLEX(x), COMPLEX(y), n); break;
19912 duncan 632
    case 22: naflag = cmath1(z_tan, COMPLEX(x), COMPLEX(y), n); break;
54275 ripley 633
    case 23: naflag = cmath1(z_acos, COMPLEX(x), COMPLEX(y), n); break;
634
    case 24: naflag = cmath1(z_asin, COMPLEX(x), COMPLEX(y), n); break;
635
    case 25: naflag = cmath1(z_atan, COMPLEX(x), COMPLEX(y), n); break;
54174 ripley 636
    case 30: naflag = cmath1(ccosh, COMPLEX(x), COMPLEX(y), n); break;
637
    case 31: naflag = cmath1(csinh, COMPLEX(x), COMPLEX(y), n); break;
638
    case 32: naflag = cmath1(ctanh, COMPLEX(x), COMPLEX(y), n); break;
54275 ripley 639
    case 33: naflag = cmath1(z_acosh, COMPLEX(x), COMPLEX(y), n); break;
640
    case 34: naflag = cmath1(z_asinh, COMPLEX(x), COMPLEX(y), n); break;
641
    case 35: naflag = cmath1(z_atanh, COMPLEX(x), COMPLEX(y), n); break;
54174 ripley 642
 
580 ihaka 643
    default:
41725 ripley 644
	/* such as sign, gamma */
645
	errorcall(call, _("unimplemented complex function"));
580 ihaka 646
    }
6098 pd 647
    if (naflag)
55518 ripley 648
	warningcall(call, "NaNs produced in function \"%s\"", PRIMNAME(op));
41002 jmc 649
    DUPLICATE_ATTRIB(y, x);
6098 pd 650
    UNPROTECT(2);
580 ihaka 651
    return y;
2 r 652
}
653
 
54262 ripley 654
static void z_rround(Rcomplex *r, Rcomplex *x, Rcomplex *p)
655
{
54776 ripley 656
    r->r = fround(x->r, p->r);
657
    r->i = fround(x->i, p->r);
54262 ripley 658
}
659
 
54174 ripley 660
static void z_prec(Rcomplex *r, Rcomplex *x, Rcomplex *p)
661
{
662
    z_prec_r(r, x, p->r);
663
}
664
 
665
static void z_logbase(Rcomplex *r, Rcomplex *z, Rcomplex *base)
666
{
667
    double complex dz = toC99(z), dbase = toC99(base);
668
    SET_C99_COMPLEX(r, 0, clog(dz)/clog(dbase));
669
}
670
 
671
static void z_atan2(Rcomplex *r, Rcomplex *csn, Rcomplex *ccs)
672
{
673
    double complex dr, dcsn = toC99(csn), dccs = toC99(ccs);
674
    if (dccs == 0) {
675
	if(dcsn == 0) {
54256 ripley 676
	    r->r = NA_REAL; r->i = NA_REAL; /* Why not R_NaN? */
54174 ripley 677
	    return;
54293 ripley 678
	} else {
679
	    double y = creal(dcsn);
680
	    if (ISNAN(y)) dr = y;
681
	    else dr = ((y >= 0) ? M_PI_2 : -M_PI_2);
682
	}
54174 ripley 683
    } else {
684
	dr = catan(dcsn / dccs);
685
	if(creal(dccs) < 0) dr += M_PI;
686
	if(creal(dr) > M_PI) dr -= 2 * M_PI;
687
    }
688
    SET_C99_COMPLEX(r, 0, dr);
689
}
690
 
54273 ripley 691
 
692
	/* Complex Functions of Two Arguments */
693
 
694
typedef void (*cm2_fun)(Rcomplex *, Rcomplex *, Rcomplex *);
695
SEXP attribute_hidden complex_math2(SEXP call, SEXP op, SEXP args, SEXP env)
2 r 696
{
59048 ripley 697
    R_xlen_t i, n, na, nb;
6994 pd 698
    Rcomplex ai, bi, *a, *b, *y;
54273 ripley 699
    SEXP sa, sb, sy;
700
    Rboolean naflag = FALSE;
701
    cm2_fun f;
702
 
703
    switch (PRIMVAL(op)) {
704
    case 0: /* atan2 */
705
	f = z_atan2; break;
706
    case 10001: /* round */
707
	f = z_rround; break;
708
    case 2: /* passed from do_log1arg */
709
    case 10:
710
    case 10003: /* passed from do_log */
711
	f = z_logbase; break;
712
    case 10004: /* signif */
713
	f = z_prec; break;
714
    default:
715
	errorcall_return(call, _("unimplemented complex function"));
716
    }
717
 
718
    PROTECT(sa = coerceVector(CAR(args), CPLXSXP));
719
    PROTECT(sb = coerceVector(CADR(args), CPLXSXP));
59048 ripley 720
    na = XLENGTH(sa); nb = XLENGTH(sb);
54273 ripley 721
    if ((na == 0) || (nb == 0)) return(allocVector(CPLXSXP, 0));
580 ihaka 722
    n = (na < nb) ? nb : na;
723
    PROTECT(sy = allocVector(CPLXSXP, n));
54273 ripley 724
    a = COMPLEX(sa); b = COMPLEX(sb); y = COMPLEX(sy);
6098 pd 725
    for (i = 0; i < n; i++) {
54273 ripley 726
	ai = a[i % na]; bi = b[i % nb];
6098 pd 727
	if(ISNA(ai.r) && ISNA(ai.i) &&
728
	   ISNA(bi.r) && ISNA(bi.i)) {
54273 ripley 729
	    y[i].r = NA_REAL; y[i].i = NA_REAL;
54170 ripley 730
	} else {
6098 pd 731
	    f(&y[i], &ai, &bi);
55516 ripley 732
	    if ( (ISNAN(y[i].r) || ISNAN(y[i].i)) &&
733
		 !(ISNAN(ai.r) || ISNAN(ai.i) || ISNAN(bi.r) || ISNAN(bi.i)) )
734
		naflag = TRUE;
2 r 735
	}
580 ihaka 736
    }
6098 pd 737
    if (naflag)
55518 ripley 738
	warningcall(call, "NaNs produced in function \"%s\"", PRIMNAME(op));
580 ihaka 739
    if(n == na) {
41002 jmc 740
	DUPLICATE_ATTRIB(sy, sa);
54170 ripley 741
    } else if(n == nb) {
41002 jmc 742
	DUPLICATE_ATTRIB(sy, sb);
580 ihaka 743
    }
744
    UNPROTECT(3);
745
    return sy;
2 r 746
}
747
 
36990 ripley 748
SEXP attribute_hidden do_complex(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 749
{
1839 ihaka 750
    /* complex(length, real, imaginary) */
580 ihaka 751
    SEXP ans, re, im;
59048 ripley 752
    R_xlen_t i, na, nr, ni;
580 ihaka 753
    na = asInteger(CAR(args));
754
    if(na == NA_INTEGER || na < 0)
41686 ripley 755
	error(_("invalid length"));
580 ihaka 756
    PROTECT(re = coerceVector(CADR(args), REALSXP));
757
    PROTECT(im = coerceVector(CADDR(args), REALSXP));
59048 ripley 758
    nr = XLENGTH(re);
759
    ni = XLENGTH(im);
1839 ihaka 760
    /* is always true: if (na >= 0) {*/
761
    na = (nr > na) ? nr : na;
762
    na = (ni > na) ? ni : na;
763
    /* }*/
580 ihaka 764
    ans = allocVector(CPLXSXP, na);
765
    for(i=0 ; i<na ; i++) {
766
	COMPLEX(ans)[i].r = 0;
767
	COMPLEX(ans)[i].i = 0;
768
    }
769
    UNPROTECT(2);
770
    if(na > 0 && nr > 0) {
771
	for(i=0 ; i<na ; i++)
772
	    COMPLEX(ans)[i].r = REAL(re)[i%nr];
773
    }
774
    if(na > 0 && ni > 0) {
775
	for(i=0 ; i<na ; i++)
776
	    COMPLEX(ans)[i].i = REAL(im)[i%ni];
777
    }
778
    return ans;
2 r 779
}
780
 
61750 ripley 781
static void R_cpolyroot(double *opr, double *opi, int *degree,
782
			double *zeror, double *zeroi, Rboolean *fail);
580 ihaka 783
 
36990 ripley 784
SEXP attribute_hidden do_polyroot(SEXP call, SEXP op, SEXP args, SEXP rho)
2 r 785
{
580 ihaka 786
    SEXP z, zr, zi, r, rr, ri;
10866 maechler 787
    Rboolean fail;
788
    int degree, i, n;
789
 
580 ihaka 790
    checkArity(op, args);
791
    z = CAR(args);
792
    switch(TYPEOF(z)) {
793
    case CPLXSXP:
794
	PROTECT(z);
795
	break;
796
    case REALSXP:
797
    case INTSXP:
798
    case LGLSXP:
799
	PROTECT(z = coerceVector(z, CPLXSXP));
800
	break;
801
    default:
31908 ripley 802
	UNIMPLEMENTED_TYPE("polyroot", z);
580 ihaka 803
    }
61750 ripley 804
#ifdef LONG_VECTOR_SUPPORT
805
    R_xlen_t nn = XLENGTH(z);
806
    if (nn > R_SHORT_LEN_MAX) error("long vectors are not supported");
807
    n = (int) nn;
808
#else
809
    n = LENGTH(z);
810
#endif
18490 ripley 811
    degree = 0;
812
    for(i = 0; i < n; i++) {
813
	if(COMPLEX(z)[i].r!= 0.0 || COMPLEX(z)[i].i != 0.0) degree = i;
814
    }
815
    n = degree + 1; /* omit trailing zeroes */
580 ihaka 816
    if(degree >= 1) {
817
	PROTECT(rr = allocVector(REALSXP, n));
818
	PROTECT(ri = allocVector(REALSXP, n));
819
	PROTECT(zr = allocVector(REALSXP, n));
820
	PROTECT(zi = allocVector(REALSXP, n));
2 r 821
 
61750 ripley 822
	for(i = 0 ; i < n ; i++) {
5107 maechler 823
	    if(!R_FINITE(COMPLEX(z)[i].r) || !R_FINITE(COMPLEX(z)[i].i))
41686 ripley 824
		error(_("invalid polynomial coefficient"));
580 ihaka 825
	    REAL(zr)[degree-i] = COMPLEX(z)[i].r;
826
	    REAL(zi)[degree-i] = COMPLEX(z)[i].i;
2 r 827
	}
10885 maechler 828
	R_cpolyroot(REAL(zr), REAL(zi), &degree, REAL(rr), REAL(ri), &fail);
41686 ripley 829
	if(fail) error(_("root finding code failed"));
580 ihaka 830
	UNPROTECT(2);
831
	r = allocVector(CPLXSXP, degree);
61750 ripley 832
	for(i = 0 ; i < degree ; i++) {
580 ihaka 833
	    COMPLEX(r)[i].r = REAL(rr)[i];
834
	    COMPLEX(r)[i].i = REAL(ri)[i];
2 r 835
	}
580 ihaka 836
	UNPROTECT(3);
837
    }
838
    else {
839
	UNPROTECT(1);
840
	r = allocVector(CPLXSXP, 0);
841
    }
842
    return r;
2 r 843
}
61750 ripley 844
 
845
/* Formerly src/appl/cpoly.c:
846
 *
847
 *  Copyright (C) 1997-1998 Ross Ihaka
848
 *  Copyright (C) 1999-2001 R Core Team
849
 *
850
 *	cpoly finds the zeros of a complex polynomial.
851
 *
852
 *	On Entry
853
 *
854
 *	opr, opi      -	 double precision vectors of real and
855
 *			 imaginary parts of the coefficients in
856
 *			 order of decreasing powers.
857
 *
858
 *	degree	      -	 int degree of polynomial.
859
 *
860
 *
861
 *	On Return
862
 *
863
 *	zeror, zeroi  -	 output double precision vectors of
864
 *			 real and imaginary parts of the zeros.
865
 *
866
 *	fail	      -	 output int parameter,	true  only if
867
 *			 leading coefficient is zero or if cpoly
868
 *			 has found fewer than degree zeros.
869
 *
870
 *	The program has been written to reduce the chance of overflow
871
 *	occurring. If it does occur, there is still a possibility that
872
 *	the zerofinder will work provided the overflowed quantity is
873
 *	replaced by a large number.
874
 *
875
 *	This is a C translation of the following.
876
 *
877
 *	TOMS Algorithm 419
878
 *	Jenkins and Traub.
879
 *	Comm. ACM 15 (1972) 97-99.
880
 *
881
 *	Ross Ihaka
882
 *	February 1997
883
 */
884
 
885
#include <R_ext/Arith.h> /* for declaration of hypot */
886
#include <R_ext/Memory.h> /* for declaration of R_alloc */
887
 
888
#include <float.h> /* for FLT_RADIX */
889
 
890
#include <Rmath.h> /* for R_pow_di */
891
 
892
static void calct(Rboolean *);
893
static Rboolean fxshft(int, double *, double *);
894
static Rboolean vrshft(int, double *, double *);
895
static void nexth(Rboolean);
896
static void noshft(int);
897
 
898
static void polyev(int, double, double,
899
		   double *, double *, double *, double *, double *, double *);
900
static double errev(int, double *, double *, double, double, double, double);
901
static double cpoly_cauchy(int, double *, double *);
902
static double cpoly_scale(int, double *, double, double, double, double);
903
static void cdivid(double, double, double, double, double *, double *);
904
 
905
/* Global Variables (too many!) */
906
 
907
static int nn;
908
static double *pr, *pi, *hr, *hi, *qpr, *qpi, *qhr, *qhi, *shr, *shi;
909
static double sr, si;
910
static double tr, ti;
911
static double pvr, pvi;
912
 
913
static const double eta =  DBL_EPSILON;
914
static const double are = /* eta = */DBL_EPSILON;
915
static const double mre = 2. * M_SQRT2 * /* eta, i.e. */DBL_EPSILON;
916
static const double infin = DBL_MAX;
917
 
918
static void R_cpolyroot(double *opr, double *opi, int *degree,
919
			double *zeror, double *zeroi, Rboolean *fail)
920
{
921
    static const double smalno = DBL_MIN;
922
    static const double base = (double)FLT_RADIX;
923
    static int d_n, i, i1, i2;
924
    static double zi, zr, xx, yy;
925
    static double bnd, xxx;
926
    Rboolean conv;
927
    int d1;
928
    double *tmp;
929
    static const double cosr =/* cos 94 */ -0.06975647374412529990;
930
    static const double sinr =/* sin 94 */  0.99756405025982424767;
931
    xx = M_SQRT1_2;/* 1/sqrt(2) = 0.707.... */
932
 
933
    yy = -xx;
934
    *fail = FALSE;
935
 
936
    nn = *degree;
937
    d1 = nn - 1;
938
 
939
    /* algorithm fails if the leading coefficient is zero. */
940
 
941
    if (opr[0] == 0. && opi[0] == 0.) {
942
	*fail = TRUE;
943
	return;
944
    }
945
 
946
    /* remove the zeros at the origin if any. */
947
 
948
    while (opr[nn] == 0. && opi[nn] == 0.) {
949
	d_n = d1-nn+1;
950
	zeror[d_n] = 0.;
951
	zeroi[d_n] = 0.;
952
	nn--;
953
    }
954
    nn++;
955
    /*-- Now, global var.  nn := #{coefficients} = (relevant degree)+1 */
956
 
957
    if (nn == 1) return;
958
 
959
    /* Use a single allocation as these as small */
63181 ripley 960
    const void *vmax = vmaxget();
61750 ripley 961
    tmp = (double *) R_alloc((size_t) (10*nn), sizeof(double));
962
    pr = tmp; pi = tmp + nn; hr = tmp + 2*nn; hi = tmp + 3*nn;
963
    qpr = tmp + 4*nn; qpi = tmp + 5*nn; qhr = tmp + 6*nn; qhi = tmp + 7*nn;
964
    shr = tmp + 8*nn; shi = tmp + 9*nn;
965
 
966
    /* make a copy of the coefficients and shr[] = | p[] | */
967
    for (i = 0; i < nn; i++) {
968
	pr[i] = opr[i];
969
	pi[i] = opi[i];
970
	shr[i] = hypot(pr[i], pi[i]);
971
    }
972
 
973
    /* scale the polynomial with factor 'bnd'. */
974
    bnd = cpoly_scale(nn, shr, eta, infin, smalno, base);
975
    if (bnd != 1.) {
976
	for (i=0; i < nn; i++) {
977
	    pr[i] *= bnd;
978
	    pi[i] *= bnd;
979
	}
980
    }
981
 
982
    /* start the algorithm for one zero */
983
 
984
    while (nn > 2) {
985
 
986
	/* calculate bnd, a lower bound on the modulus of the zeros. */
987
 
988
	for (i=0 ; i < nn ; i++)
989
	    shr[i] = hypot(pr[i], pi[i]);
990
	bnd = cpoly_cauchy(nn, shr, shi);
991
 
992
	/* outer loop to control 2 major passes */
993
	/* with different sequences of shifts */
994
 
995
	for (i1 = 1; i1 <= 2; i1++) {
996
 
997
	    /* first stage calculation, no shift */
998
 
999
	    noshft(5);
1000
 
1001
	    /*	inner loop to select a shift */
1002
	    for (i2 = 1; i2 <= 9; i2++) {
1003
 
1004
		/* shift is chosen with modulus bnd */
1005
		/* and amplitude rotated by 94 degrees */
1006
		/* from the previous shift */
1007
 
1008
		xxx= cosr * xx - sinr * yy;
1009
		yy = sinr * xx + cosr * yy;
1010
		xx = xxx;
1011
		sr = bnd * xx;
1012
		si = bnd * yy;
1013
 
1014
		/*  second stage calculation, fixed shift */
1015
 
1016
		conv = fxshft(i2 * 10, &zr, &zi);
1017
		if (conv)
1018
		    goto L10;
1019
	    }
1020
	}
1021
 
1022
	/* the zerofinder has failed on two major passes */
1023
	/* return empty handed */
1024
 
1025
	*fail = TRUE;
63171 ripley 1026
	vmaxset(vmax);
61750 ripley 1027
	return;
1028
 
1029
	/* the second stage jumps directly to the third stage iteration.
1030
	 * if successful, the zero is stored and the polynomial deflated.
1031
	 */
1032
    L10:
1033
	d_n = d1+2 - nn;
1034
	zeror[d_n] = zr;
1035
	zeroi[d_n] = zi;
1036
	--nn;
1037
	for (i=0; i < nn ; i++) {
1038
	    pr[i] = qpr[i];
1039
	    pi[i] = qpi[i];
1040
	}
1041
    }/*while*/
1042
 
1043
    /*	calculate the final zero and return */
1044
    cdivid(-pr[1], -pi[1], pr[0], pi[0], &zeror[d1], &zeroi[d1]);
1045
 
63171 ripley 1046
    vmaxset(vmax);
61750 ripley 1047
    return;
1048
}
1049
 
1050
 
1051
/*  Computes the derivative polynomial as the initial
1052
 *  polynomial and computes l1 no-shift h polynomials.	*/
1053
 
1054
static void noshft(int l1)
1055
{
1056
    int i, j, jj, n = nn - 1, nm1 = n - 1;
1057
 
1058
    double t1, t2, xni;
1059
 
1060
    for (i=0; i < n; i++) {
1061
	xni = (double)(nn - i - 1);
1062
	hr[i] = xni * pr[i] / n;
1063
	hi[i] = xni * pi[i] / n;
1064
    }
1065
 
1066
    for (jj = 1; jj <= l1; jj++) {
1067
 
1068
	if (hypot(hr[n-1], hi[n-1]) <=
1069
	    eta * 10.0 * hypot(pr[n-1], pi[n-1])) {
1070
	    /*	If the constant term is essentially zero, */
1071
	    /*	shift h coefficients. */
1072
 
1073
	    for (i = 1; i <= nm1; i++) {
1074
		j = nn - i;
1075
		hr[j-1] = hr[j-2];
1076
		hi[j-1] = hi[j-2];
1077
	    }
1078
	    hr[0] = 0.;
1079
	    hi[0] = 0.;
1080
	}
1081
	else {
1082
	    cdivid(-pr[nn-1], -pi[nn-1], hr[n-1], hi[n-1], &tr, &ti);
1083
	    for (i = 1; i <= nm1; i++) {
1084
		j = nn - i;
1085
		t1 = hr[j-2];
1086
		t2 = hi[j-2];
1087
		hr[j-1] = tr * t1 - ti * t2 + pr[j-1];
1088
		hi[j-1] = tr * t2 + ti * t1 + pi[j-1];
1089
	    }
1090
	    hr[0] = pr[0];
1091
	    hi[0] = pi[0];
1092
	}
1093
    }
1094
}
1095
 
1096
 
1097
/*  Computes l2 fixed-shift h polynomials and tests for convergence.
1098
 *  initiates a variable-shift iteration and returns with the
1099
 *  approximate zero if successful.
1100
 */
1101
static Rboolean fxshft(int l2, double *zr, double *zi)
1102
{
1103
/*  l2	  - limit of fixed shift steps
1104
 *  zr,zi - approximate zero if convergence (result TRUE)
1105
 *
1106
 * Return value indicates convergence of stage 3 iteration
1107
 *
1108
 * Uses global (sr,si), nn, pr[], pi[], .. (all args of polyev() !)
1109
*/
1110
 
1111
    Rboolean pasd, bool, test;
1112
    static double svsi, svsr;
1113
    static int i, j, n;
1114
    static double oti, otr;
1115
 
1116
    n = nn - 1;
1117
 
1118
    /* evaluate p at s. */
1119
 
1120
    polyev(nn, sr, si, pr, pi, qpr, qpi, &pvr, &pvi);
1121
 
1122
    test = TRUE;
1123
    pasd = FALSE;
1124
 
1125
    /* calculate first t = -p(s)/h(s). */
1126
 
1127
    calct(&bool);
1128
 
1129
    /* main loop for one second stage step. */
1130
 
1131
    for (j=1; j<=l2; j++) {
1132
 
1133
	otr = tr;
1134
	oti = ti;
1135
 
1136
	/* compute next h polynomial and new t. */
1137
 
1138
	nexth(bool);
1139
	calct(&bool);
1140
	*zr = sr + tr;
1141
	*zi = si + ti;
1142
 
1143
	/* test for convergence unless stage 3 has */
1144
	/* failed once or this is the last h polynomial. */
1145
 
1146
	if (!bool && test && j != l2) {
1147
	    if (hypot(tr - otr, ti - oti) >= hypot(*zr, *zi) * 0.5) {
1148
		pasd = FALSE;
1149
	    }
1150
	    else if (! pasd) {
1151
		pasd = TRUE;
1152
	    }
1153
	    else {
1154
 
1155
		/* the weak convergence test has been */
1156
		/* passed twice, start the third stage */
1157
		/* iteration, after saving the current */
1158
		/* h polynomial and shift. */
1159
 
1160
		for (i = 0; i < n; i++) {
1161
		    shr[i] = hr[i];
1162
		    shi[i] = hi[i];
1163
		}
1164
		svsr = sr;
1165
		svsi = si;
1166
		if (vrshft(10, zr, zi)) {
1167
		    return TRUE;
1168
		}
1169
 
1170
		/* the iteration failed to converge. */
1171
		/* turn off testing and restore */
1172
		/* h, s, pv and t. */
1173
 
1174
		test = FALSE;
1175
		for (i=1 ; i<=n ; i++) {
1176
		    hr[i-1] = shr[i-1];
1177
		    hi[i-1] = shi[i-1];
1178
		}
1179
		sr = svsr;
1180
		si = svsi;
1181
		polyev(nn, sr, si, pr, pi, qpr, qpi, &pvr, &pvi);
1182
		calct(&bool);
1183
	    }
1184
	}
1185
    }
1186
 
1187
    /* attempt an iteration with final h polynomial */
1188
    /* from second stage. */
1189
 
1190
    return(vrshft(10, zr, zi));
1191
}
1192
 
1193
 
1194
/* carries out the third stage iteration.
1195
 */
1196
static Rboolean vrshft(int l3, double *zr, double *zi)
1197
{
1198
/*  l3	    - limit of steps in stage 3.
1199
 *  zr,zi   - on entry contains the initial iterate;
1200
 *	      if the iteration converges it contains
1201
 *	      the final iterate on exit.
1202
 * Returns TRUE if iteration converges
1203
 *
1204
 * Assign and uses  GLOBAL sr, si
1205
*/
1206
    Rboolean bool, b;
1207
    static int i, j;
1208
    static double r1, r2, mp, ms, tp, relstp;
1209
    static double omp;
1210
 
1211
    b = FALSE;
1212
    sr = *zr;
1213
    si = *zi;
1214
 
1215
    /* main loop for stage three */
1216
 
1217
    for (i = 1; i <= l3; i++) {
1218
 
1219
	/* evaluate p at s and test for convergence. */
1220
	polyev(nn, sr, si, pr, pi, qpr, qpi, &pvr, &pvi);
1221
 
1222
	mp = hypot(pvr, pvi);
1223
	ms = hypot(sr, si);
1224
	if (mp <=  20. * errev(nn, qpr, qpi, ms, mp, /*are=*/eta, mre)) {
1225
	    goto L_conv;
1226
	}
1227
 
1228
	/* polynomial value is smaller in value than */
1229
	/* a bound on the error in evaluating p, */
1230
	/* terminate the iteration. */
1231
 
1232
	if (i != 1) {
1233
 
1234
	    if (!b && mp >= omp && relstp < .05) {
1235
 
1236
		/* iteration has stalled. probably a */
1237
		/* cluster of zeros. do 5 fixed shift */
1238
		/* steps into the cluster to force */
1239
		/* one zero to dominate. */
1240
 
1241
		tp = relstp;
1242
		b = TRUE;
1243
		if (relstp < eta)
1244
		    tp = eta;
1245
		r1 = sqrt(tp);
1246
		r2 = sr * (r1 + 1.) - si * r1;
1247
		si = sr * r1 + si * (r1 + 1.);
1248
		sr = r2;
1249
		polyev(nn, sr, si, pr, pi, qpr, qpi, &pvr, &pvi);
1250
		for (j = 1; j <= 5; ++j) {
1251
		    calct(&bool);
1252
		    nexth(bool);
1253
		}
1254
		omp = infin;
1255
		goto L10;
1256
	    }
1257
	    else {
1258
 
1259
		/* exit if polynomial value */
1260
		/* increases significantly. */
1261
 
1262
		if (mp * .1 > omp)
1263
		    return FALSE;
1264
	    }
1265
	}
1266
	omp = mp;
1267
 
1268
	/* calculate next iterate. */
1269
 
1270
    L10:
1271
	calct(&bool);
1272
	nexth(bool);
1273
	calct(&bool);
1274
	if (!bool) {
1275
	    relstp = hypot(tr, ti) / hypot(sr, si);
1276
	    sr += tr;
1277
	    si += ti;
1278
	}
1279
    }
1280
    return FALSE;
1281
 
1282
L_conv:
1283
    *zr = sr;
1284
    *zi = si;
1285
    return TRUE;
1286
}
1287
 
1288
static void calct(Rboolean *bool)
1289
{
1290
    /* computes	 t = -p(s)/h(s).
1291
     * bool   - logical, set true if h(s) is essentially zero.	*/
1292
 
1293
    int n = nn - 1;
1294
    double hvi, hvr;
1295
 
1296
    /* evaluate h(s). */
1297
    polyev(n, sr, si, hr, hi,
1298
	   qhr, qhi, &hvr, &hvi);
1299
 
1300
    *bool = hypot(hvr, hvi) <= are * 10. * hypot(hr[n-1], hi[n-1]);
1301
    if (!*bool) {
1302
	cdivid(-pvr, -pvi, hvr, hvi, &tr, &ti);
1303
    }
1304
    else {
1305
	tr = 0.;
1306
	ti = 0.;
1307
    }
1308
}
1309
 
1310
static void nexth(Rboolean bool)
1311
{
1312
    /* calculates the next shifted h polynomial.
1313
     * bool :	if TRUE  h(s) is essentially zero
1314
     */
1315
    int j, n = nn - 1;
1316
    double t1, t2;
1317
 
1318
    if (!bool) {
1319
	for (j=1; j < n; j++) {
1320
	    t1 = qhr[j - 1];
1321
	    t2 = qhi[j - 1];
1322
	    hr[j] = tr * t1 - ti * t2 + qpr[j];
1323
	    hi[j] = tr * t2 + ti * t1 + qpi[j];
1324
	}
1325
	hr[0] = qpr[0];
1326
	hi[0] = qpi[0];
1327
    }
1328
    else {
1329
	/* if h(s) is zero replace h with qh. */
1330
 
1331
	for (j=1; j < n; j++) {
1332
	    hr[j] = qhr[j-1];
1333
	    hi[j] = qhi[j-1];
1334
	}
1335
	hr[0] = 0.;
1336
	hi[0] = 0.;
1337
    }
1338
}
1339
 
1340
/*--------------------- Independent Complex Polynomial Utilities ----------*/
1341
 
1342
static
1343
void polyev(int n,
1344
	    double s_r, double s_i,
1345
	    double *p_r, double *p_i,
1346
	    double *q_r, double *q_i,
1347
	    double *v_r, double *v_i)
1348
{
1349
    /* evaluates a polynomial  p  at  s	 by the horner recurrence
1350
     * placing the partial sums in q and the computed value in v_.
1351
     */
1352
    int i;
1353
    double t;
1354
 
1355
    q_r[0] = p_r[0];
1356
    q_i[0] = p_i[0];
1357
    *v_r = q_r[0];
1358
    *v_i = q_i[0];
1359
    for (i = 1; i < n; i++) {
1360
	t = *v_r * s_r - *v_i * s_i + p_r[i];
1361
	q_i[i] = *v_i = *v_r * s_i + *v_i * s_r + p_i[i];
1362
	q_r[i] = *v_r = t;
1363
    }
1364
}
1365
 
1366
static
1367
double errev(int n, double *qr, double *qi,
1368
	     double ms, double mp, double a_re, double m_re)
1369
{
1370
    /*	bounds the error in evaluating the polynomial by the horner
1371
     *	recurrence.
1372
     *
1373
     *	qr,qi	 - the partial sum vectors
1374
     *	ms	 - modulus of the point
1375
     *	mp	 - modulus of polynomial value
1376
     * a_re,m_re - error bounds on complex addition and multiplication
1377
     */
1378
    double e;
1379
    int i;
1380
 
1381
    e = hypot(qr[0], qi[0]) * m_re / (a_re + m_re);
1382
    for (i=0; i < n; i++)
1383
	e = e*ms + hypot(qr[i], qi[i]);
1384
 
1385
    return e * (a_re + m_re) - mp * m_re;
1386
}
1387
 
1388
 
1389
static
1390
double cpoly_cauchy(int n, double *pot, double *q)
1391
{
1392
    /* Computes a lower bound on the moduli of the zeros of a polynomial
1393
     * pot[1:nn] is the modulus of the coefficients.
1394
     */
1395
    double f, x, delf, dx, xm;
1396
    int i, n1 = n - 1;
1397
 
1398
    pot[n1] = -pot[n1];
1399
 
1400
    /* compute upper estimate of bound. */
1401
 
1402
    x = exp((log(-pot[n1]) - log(pot[0])) / (double) n1);
1403
 
1404
    /* if newton step at the origin is better, use it. */
1405
 
1406
    if (pot[n1-1] != 0.) {
1407
	xm = -pot[n1] / pot[n1-1];
1408
	if (xm < x)
1409
	    x = xm;
1410
    }
1411
 
1412
    /* chop the interval (0,x) unitl f le 0. */
1413
 
1414
    for(;;) {
1415
	xm = x * 0.1;
1416
	f = pot[0];
1417
	for (i = 1; i < n; i++)
1418
	    f = f * xm + pot[i];
1419
	if (f <= 0.0) {
1420
	    break;
1421
	}
1422
	x = xm;
1423
    }
1424
 
1425
    dx = x;
1426
 
1427
    /* do Newton iteration until x converges to two decimal places. */
1428
 
1429
    while (fabs(dx / x) > 0.005) {
1430
	q[0] = pot[0];
1431
	for(i = 1; i < n; i++)
1432
	    q[i] = q[i-1] * x + pot[i];
1433
	f = q[n1];
1434
	delf = q[0];
1435
	for(i = 1; i < n1; i++)
1436
	    delf = delf * x + q[i];
1437
	dx = f / delf;
1438
	x -= dx;
1439
    }
1440
    return x;
1441
}
1442
 
1443
static
1444
double cpoly_scale(int n, double *pot,
1445
		   double eps, double BIG, double small, double base)
1446
{
1447
    /* Returns a scale factor to multiply the coefficients of the polynomial.
1448
     * The scaling is done to avoid overflow and to avoid
1449
     *	undetected underflow interfering with the convergence criterion.
1450
     * The factor is a power of the base.
1451
 
1452
     * pot[1:n] : modulus of coefficients of p
1453
     * eps,BIG,
1454
     * small,base - constants describing the floating point arithmetic.
1455
     */
1456
 
1457
    int i, ell;
1458
    double x, high, sc, lo, min_, max_;
1459
 
1460
    /* find largest and smallest moduli of coefficients. */
1461
    high = sqrt(BIG);
1462
    lo = small / eps;
1463
    max_ = 0.;
1464
    min_ = BIG;
1465
    for (i = 0; i < n; i++) {
1466
	x = pot[i];
1467
	if (x > max_) max_ = x;
1468
	if (x != 0. && x < min_)
1469
	    min_ = x;
1470
    }
1471
 
1472
    /* scale only if there are very large or very small components. */
1473
 
1474
    if (min_ < lo || max_ > high) {
1475
	x = lo / min_;
1476
	if (x <= 1.)
1477
	    sc = 1. / (sqrt(max_) * sqrt(min_));
1478
	else {
1479
	    sc = x;
1480
	    if (BIG / sc > max_)
1481
		sc = 1.0;
1482
	}
1483
	ell = (int) (log(sc) / log(base) + 0.5);
1484
	return R_pow_di(base, ell);
1485
    }
1486
    else return 1.0;
1487
}
1488
 
1489
 
1490
static
1491
void cdivid(double ar, double ai, double br, double bi,
1492
	    double *cr, double *ci)
1493
{
1494
/* complex division c = a/b, i.e., (cr +i*ci) = (ar +i*ai) / (br +i*bi),
1495
   avoiding overflow. */
1496
 
1497
    double d, r;
1498
 
1499
    if (br == 0. && bi == 0.) {
1500
	/* division by zero, c = infinity. */
1501
	*cr = *ci = R_PosInf;
1502
    }
1503
    else if (fabs(br) >= fabs(bi)) {
1504
	r = bi / br;
1505
	d = br + r * bi;
1506
	*cr = (ar + ai * r) / d;
1507
	*ci = (ai - ar * r) / d;
1508
    }
1509
    else {
1510
	r = br / bi;
1511
	d = bi + r * br;
1512
	*cr = (ar * r + ai) / d;
1513
	*ci = (ai * r - ar) / d;
1514
    }
1515
}
1516
 
1517
/* static double cpoly_cmod(double *r, double *i)
1518
 * --> replaced by hypot() everywhere
1519
*/