The R Project SVN R

Rev

Rev 5731 | Rev 6191 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5731 Rev 6098
Line 21... Line 21...
21
#include <Rconfig.h>
21
#include <Rconfig.h>
22
#endif
22
#endif
23
 
23
 
24
#include "Defn.h"
24
#include "Defn.h"
25
#include "Mathlib.h"
25
#include "Mathlib.h"
26
#include "Fortran.h"/* POW_DI */
26
#include "Fortran.h"		/* POW_DI */
27
#include "Applic.h"/* cpoly */
27
#include "Applic.h"		/* cpoly */
28
 
28
 
29
#include "arithmetic.h"/* complex_ */
29
#include "arithmetic.h"		/* complex_ */
30
 
30
 
31
static int naflag;
31
static int naflag;
32
 
32
 
33
SEXP complex_unary(int code, SEXP s1)
33
SEXP complex_unary(int code, SEXP s1)
34
{
34
{
Line 58... Line 58...
58
	    }
58
	    }
59
#endif
59
#endif
60
	}
60
	}
61
	return ans;
61
	return ans;
62
    default:
62
    default:
63
	error("illegal complex unary operator");
63
	error("illegal complex unary operator\n");
64
	return R_NilValue;/* -Wall*/
64
	return R_NilValue;	/* -Wall*/
65
    }
65
    }
66
}
66
}
67
 
67
 
68
static void complex_div(complex *c, complex *a, complex *b)
68
static void complex_div(complex *c, complex *a, complex *b)
69
{
69
{
Line 98... Line 98...
98
static void complex_pow(complex *r, complex *a, complex *b)
98
static void complex_pow(complex *r, complex *a, complex *b)
99
{
99
{
100
    double logr, logi, x, y;
100
    double logr, logi, x, y;
101
    int ib;
101
    int ib;
102
 
102
 
103
    if(b->i == 0.) {/* be fast (and more accurate)*/
103
    if(b->i == 0.) {		/* be fast (and more accurate)*/
-
 
104
	if(b->r == 1.) {	/* a^1 */
104
	if(b->r == 1.) { /* a^1 */ r->r = a->r; r->i = a->i; return;}
105
	    r->r = a->r; r->i = a->i; return;
-
 
106
	}
-
 
107
	if(a->i == 0.) {
105
	if(a->i == 0.) { r->r = pow(a->r, b->r); r->i = 0.; return;}
108
	    r->r = pow(a->r, b->r); r->i = 0.; return;
-
 
109
	}
106
	if(a->r == 0. && b->r == (ib = (int)b->r)) {/* (|a|*i)^b */
110
	if(a->r == 0. && b->r == (ib = (int)b->r)) {/* (|a|*i)^b */
107
	    x = POW_DI(&(a->i), &ib);
111
	    x = POW_DI(&(a->i), &ib);
108
	    if(ib % 2) { /* ib is odd ==> imaginary r */
112
	    if(ib % 2) {	/* ib is odd ==> imaginary r */
109
		r->r = 0.;
113
		r->r = 0.;
110
		r->i = ((ib>0 && ib %4 == 3)||(ib<0 && (-ib)%4 == 1))? -x : x;
114
		r->i = ((ib>0 && ib %4 == 3)||(ib<0 && (-ib)%4 == 1))? -x : x;
111
	    } else { /* even exponent b : real r */
115
	    } else {		/* even exponent b : real r */
112
		r->r = (ib %4)? -x : x; r->i = 0.;
116
		r->r = (ib %4)? -x : x; r->i = 0.;
113
	    }
117
	    }
114
	    return;
118
	    return;
115
	}
119
	}
116
    }
120
    }
Line 246... Line 250...
246
 
250
 
247
/* FIXME : Use the trick in arithmetic.c to eliminate "modulo" ops */
251
/* FIXME : Use the trick in arithmetic.c to eliminate "modulo" ops */
248
 
252
 
249
SEXP do_cmathfuns(SEXP call, SEXP op, SEXP args, SEXP env)
253
SEXP do_cmathfuns(SEXP call, SEXP op, SEXP args, SEXP env)
250
{
254
{
251
    SEXP x, y = R_NilValue;/* -Wall*/
255
    SEXP x, y = R_NilValue;	/* -Wall*/
252
    int i, n;
256
    int i, n;
253
 
257
 
254
    checkArity(op, args);
258
    checkArity(op, args);
255
    x = CAR(args);
259
    x = CAR(args);
256
    n = length(x);
260
    n = length(x);
Line 265... Line 269...
265
	    y = allocVector(REALSXP, n);
269
	    y = allocVector(REALSXP, n);
266
	    for(i=0 ; i<n ; i++)
270
	    for(i=0 ; i<n ; i++)
267
		REAL(y)[i] = COMPLEX(x)[i].i;
271
		REAL(y)[i] = COMPLEX(x)[i].i;
268
	    break;
272
	    break;
269
	case 3:	/* Mod */
273
	case 3:	/* Mod */
-
 
274
	case 6:	/* abs */
270
	    y = allocVector(REALSXP, n);
275
	    y = allocVector(REALSXP, n);
271
	    for(i=0 ; i<n ; i++) {
276
	    for(i=0 ; i<n ; i++) {
272
#ifdef IEEE_754
277
#ifdef IEEE_754
273
		REAL(y)[i] = hypot(COMPLEX(x)[i].r, COMPLEX(x)[i].i);
278
		REAL(y)[i] = hypot(COMPLEX(x)[i].r, COMPLEX(x)[i].i);
274
#else
279
#else
Line 334... Line 339...
334
		    REAL(y)[i] = REAL(x)[i];
339
		    REAL(y)[i] = REAL(x)[i];
335
		else
340
		else
336
		    REAL(y)[i] = 0;
341
		    REAL(y)[i] = 0;
337
	    break;
342
	    break;
338
	case 3:	/* Mod */
343
	case 3:	/* Mod */
-
 
344
	case 6:	/* abs */
339
	    y = allocVector(REALSXP, n);
345
	    y = allocVector(REALSXP, n);
340
	    for(i=0 ; i<n ; i++) {
346
	    for(i=0 ; i<n ; i++) {
341
#ifdef IEEE_754
347
#ifdef IEEE_754
342
		REAL(y)[i] = fabs(REAL(x)[i]);
348
		REAL(y)[i] = fabs(REAL(x)[i]);
343
#else
349
#else
Line 364... Line 370...
364
{
370
{
365
    r->r = rround(x->r, p->r);
371
    r->r = rround(x->r, p->r);
366
    r->i = rround(x->i, p->r);
372
    r->i = rround(x->i, p->r);
367
}
373
}
368
 
374
 
369
	/* Question:  This treats real and imaginary parts */
375
/* Question:  This treats real and imaginary parts separately.  Should
370
	/* separately.	Should it do them jointly? */
376
   it do them jointly? */
371
 
377
 
372
static void z_prec(complex *r, complex *x, complex *p)
378
static void z_prec(complex *r, complex *x, complex *p)
373
{
379
{
374
    r->r = prec(x->r, p->r);
380
    r->r = prec(x->r, p->r);
375
    r->i = prec(x->i, p->r);
381
    r->i = prec(x->i, p->r);
Line 574... Line 580...
574
 
580
 
575
SEXP complex_math1(SEXP call, SEXP op, SEXP args, SEXP env)
581
SEXP complex_math1(SEXP call, SEXP op, SEXP args, SEXP env)
576
{
582
{
577
    SEXP x, y;
583
    SEXP x, y;
578
    int n;
584
    int n;
579
    x = CAR(args);
585
    PROTECT(x = CAR(args));
580
    n = length(x);
586
    n = length(x);
581
    y = allocVector(CPLXSXP, n);
587
    PROTECT(y = allocVector(CPLXSXP, n));
582
    naflag = 0;
588
    naflag = 0;
583
 
589
 
584
    switch (PRIMVAL(op)) {
590
    switch (PRIMVAL(op)) {
585
    case 10002: cmath1(z_atan, COMPLEX(x), COMPLEX(y), n); break;
591
    case 10002: cmath1(z_atan, COMPLEX(x), COMPLEX(y), n); break;
586
    case 10003: cmath1(z_log, COMPLEX(x), COMPLEX(y), n); break;
592
    case 10003: cmath1(z_log, COMPLEX(x), COMPLEX(y), n); break;
587
 
593
 
588
    case 0:
-
 
589
	errorcall(call,
-
 
590
		  "abs() unimplemented for complex; use Mod()");
-
 
591
	break;
-
 
592
    case 3:  cmath1(z_sqrt, COMPLEX(x), COMPLEX(y), n); break;
594
    case 3:  cmath1(z_sqrt, COMPLEX(x), COMPLEX(y), n); break;
593
 
595
 
594
    case 10: cmath1(z_exp, COMPLEX(x), COMPLEX(y), n); break;
596
    case 10: cmath1(z_exp, COMPLEX(x), COMPLEX(y), n); break;
595
 
597
 
596
    case 20: cmath1(z_cos, COMPLEX(x), COMPLEX(y), n); break;
598
    case 20: cmath1(z_cos, COMPLEX(x), COMPLEX(y), n); break;
Line 612... Line 614...
612
#endif
614
#endif
613
 
615
 
614
    default:
616
    default:
615
	errorcall(call, "unimplemented complex function");
617
	errorcall(call, "unimplemented complex function");
616
    }
618
    }
-
 
619
    if (naflag)
617
    if (naflag) warning("NAs produced in function \"%s\"", PRIMNAME(op));
620
	warning("NAs produced in function \"%s\"", PRIMNAME(op));
-
 
621
    ATTRIB(y) = duplicate(ATTRIB(x));
-
 
622
    OBJECT(y) = OBJECT(x);
-
 
623
    UNPROTECT(2);
618
    return y;
624
    return y;
619
}
625
}
620
 
626
 
621
/* FIXME : Use the trick in arithmetic.c to eliminate "modulo" ops */
627
/* FIXME : Use the trick in arithmetic.c to eliminate "modulo" ops */
622
 
628
 
Line 626... Line 632...
626
    complex ai, bi, *a, *b, *y;
632
    complex ai, bi, *a, *b, *y;
627
    SEXP sy;
633
    SEXP sy;
628
 
634
 
629
    na = length(sa);
635
    na = length(sa);
630
    nb = length(sb);
636
    nb = length(sb);
-
 
637
    if ((na == 0) || (nb == 0))
-
 
638
	return(allocVector(CPLXSXP, 0));
631
    n = (na < nb) ? nb : na;
639
    n = (na < nb) ? nb : na;
632
    PROTECT(sa = coerceVector(sa, CPLXSXP));
640
    PROTECT(sa = coerceVector(sa, CPLXSXP));
633
    PROTECT(sb = coerceVector(sb, CPLXSXP));
641
    PROTECT(sb = coerceVector(sb, CPLXSXP));
634
    PROTECT(sy = allocVector(CPLXSXP, n));
642
    PROTECT(sy = allocVector(CPLXSXP, n));
635
    a = COMPLEX(sa);
643
    a = COMPLEX(sa);
636
    b = COMPLEX(sb);
644
    b = COMPLEX(sb);
637
    y = COMPLEX(sy);
645
    y = COMPLEX(sy);
638
    if (na < 1 || na < 1) {
646
    naflag = 0;
639
	for (i = 0; i < n; i++) {
647
    for (i = 0; i < n; i++) {
-
 
648
	ai = a[i % na];
-
 
649
	bi = b[i % nb];
-
 
650
	if(ISNA(ai.r) && ISNA(ai.i) &&
-
 
651
	   ISNA(bi.r) && ISNA(bi.i)) {
640
	    y[i].r = NA_REAL;
652
	    y[i].r = NA_REAL;
641
	    y[i].i = NA_REAL;
653
	    y[i].i = NA_REAL;
642
	}
654
	}
643
    }
-
 
644
    else {
655
	else {
645
	naflag = 0;
-
 
646
	for (i = 0; i < n; i++) {
-
 
647
	    ai = a[i % na];
656
	    f(&y[i], &ai, &bi);
648
	    bi = b[i % nb];
657
#ifndef IEEE_754
649
	    if(ISNA(ai.r) && ISNA(ai.i) &&
-
 
650
	       ISNA(bi.r) && ISNA(bi.i)) {
658
	    if(ISNA(y[i].r) || ISNA(y[i].i)) {
651
		y[i].r = NA_REAL;
659
		y[i].r = NA_REAL;
652
		y[i].i = NA_REAL;
660
		y[i].i = NA_REAL;
-
 
661
		naflag = 1;
653
	    }
662
	    }
654
	    else {
-
 
655
		f(&y[i], &ai, &bi);
-
 
656
#ifndef IEEE_754
-
 
657
		if(ISNA(y[i].r) || ISNA(y[i].i)) {
-
 
658
		    y[i].r = NA_REAL;
-
 
659
		    y[i].i = NA_REAL;
-
 
660
		    naflag = 1;
-
 
661
		}
-
 
662
#endif
663
#endif
663
	    }
-
 
664
	}
664
	}
665
    }
665
    }
-
 
666
    if (naflag)
666
    if (naflag) warning("NAs produced in function \"%s\"", PRIMNAME(op));
667
	warning("NAs produced in function \"%s\"", PRIMNAME(op));
667
    if(n == na) {
668
    if(n == na) {
668
	ATTRIB(sy) = duplicate(ATTRIB(sa));
669
	ATTRIB(sy) = duplicate(ATTRIB(sa));
669
	OBJECT(sy) = OBJECT(sa);
670
	OBJECT(sy) = OBJECT(sa);
670
    }
671
    }
671
    else if(n == nb) {
672
    else if(n == nb) {
Line 690... Line 691...
690
    case 10004:
691
    case 10004:
691
	return cmath2(op, CAR(args), CADR(args), z_prec);
692
	return cmath2(op, CAR(args), CADR(args), z_prec);
692
    case 0:
693
    case 0:
693
	return cmath2(op, CAR(args), CADR(args), z_atan2);
694
	return cmath2(op, CAR(args), CADR(args), z_atan2);
694
    default:
695
    default:
695
	errorcall(call, "unimplemented complex function");
696
	errorcall(call, "unimplemented complex function\n");
696
	return call;/* just for -Wall */
697
	return call;		/* just for -Wall */
697
    }
698
    }
698
}
699
}
699
 
700
 
700
SEXP do_complex(SEXP call, SEXP op, SEXP args, SEXP rho)
701
SEXP do_complex(SEXP call, SEXP op, SEXP args, SEXP rho)
701
{
702
{
Line 763... Line 764...
763
	PROTECT(zr = allocVector(REALSXP, n));
764
	PROTECT(zr = allocVector(REALSXP, n));
764
	PROTECT(zi = allocVector(REALSXP, n));
765
	PROTECT(zi = allocVector(REALSXP, n));
765
 
766
 
766
	for(i=0 ; i<n ; i++) {
767
	for(i=0 ; i<n ; i++) {
767
	    if(!R_FINITE(COMPLEX(z)[i].r) || !R_FINITE(COMPLEX(z)[i].i))
768
	    if(!R_FINITE(COMPLEX(z)[i].r) || !R_FINITE(COMPLEX(z)[i].i))
768
		errorcall(call, "invalid polynomial coefficient");
769
		errorcall(call, "invalid polynomial coefficient\n");
769
	    REAL(zr)[degree-i] = COMPLEX(z)[i].r;
770
	    REAL(zr)[degree-i] = COMPLEX(z)[i].r;
770
	    REAL(zi)[degree-i] = COMPLEX(z)[i].i;
771
	    REAL(zi)[degree-i] = COMPLEX(z)[i].i;
771
	}
772
	}
772
	F77_SYMBOL(cpoly)(REAL(zr), REAL(zi), &degree,
773
	F77_SYMBOL(cpoly)(REAL(zr), REAL(zi), &degree,
773
			  REAL(rr), REAL(ri), &fail);
774
			  REAL(rr), REAL(ri), &fail);