The R Project SVN R

Rev

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

Rev 26266 Rev 26606
Line 1... Line 1...
1
/*
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1998-2003   The R Development Core Team.
4
 *  Copyright (C) 1998-2001   The R Development Core Team
-
 
5
 *  Copyright (C) 2002--2003  The R Foundation
5
 *
6
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *  (at your option) any later version.
Line 11... Line 12...
11
 *  This program is distributed in the hope that it will be useful,
12
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *  GNU General Public License for more details.
15
 *
16
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  A copy of the GNU General Public License is available via WWW at
-
 
18
 *  http://www.gnu.org/copyleft/gpl.html.  You can also obtain it by
17
 *  along with this program; if not, write to the Free Software
19
 *  writing to the Free Software Foundation, Inc., 59 Temple Place,
18
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 *  Suite 330, Boston, MA  02111-1307  USA.
19
 */
21
 */
20
 
22
 
21
#ifdef HAVE_CONFIG_H
23
#ifdef HAVE_CONFIG_H
22
#include <config.h>
24
#include <config.h>
23
#endif
25
#endif
24
 
26
 
25
#include <Defn.h>
27
#include <Defn.h>
26
#include <Rmath.h>
28
#include <Rmath.h>
27
#include <R_ext/RS.h>
29
#include <R_ext/RS.h>
28
#include <R_ext/Applic.h> /* for dgemm */
30
#include <R_ext/Applic.h> /* for dgemm */
29
/* "GetRowNames" and "GetColNames" are utility routines which */
-
 
30
/* locate and return the row names and column names from the */
-
 
31
/* dimnames attribute of a matrix.  They are useful because */
-
 
32
/* old versions of R used pair-based lists for dimnames */
-
 
33
/* whereas recent versions use vector based lists */
-
 
34
 
-
 
35
/* FIXME : This is nonsense.  When the "dimnames" attribute is */
-
 
36
/* grabbed off an array it is always adjusted to be a vector. */
-
 
37
 
31
 
-
 
32
/* "GetRowNames" and "GetColNames" are utility routines which
-
 
33
 * locate and return the row names and column names from the
-
 
34
 * dimnames attribute of a matrix.  They are useful because
-
 
35
 * old versions of R used pair-based lists for dimnames
-
 
36
 * whereas recent versions use vector based lists.
-
 
37
 
-
 
38
 * These are now very old, plus
-
 
39
 * ``When the "dimnames" attribute is
-
 
40
 *   grabbed off an array it is always adjusted to be a vector.''
-
 
41
*/
38
SEXP GetRowNames(SEXP dimnames)
42
SEXP GetRowNames(SEXP dimnames)
39
{
43
{
40
    if (TYPEOF(dimnames) == VECSXP)
44
    if (TYPEOF(dimnames) == VECSXP)
41
	return VECTOR_ELT(dimnames, 0);
45
	return VECTOR_ELT(dimnames, 0);
42
    else if (TYPEOF(dimnames) == LISTSXP)
-
 
43
	return CAR(dimnames);
-
 
44
    else
46
    else
45
	return R_NilValue;
47
	return R_NilValue;
46
}
48
}
47
 
49
 
48
SEXP GetColNames(SEXP dimnames)
50
SEXP GetColNames(SEXP dimnames)
49
{
51
{
50
    if (TYPEOF(dimnames) == VECSXP)
52
    if (TYPEOF(dimnames) == VECSXP)
51
	return VECTOR_ELT(dimnames, 1);
53
	return VECTOR_ELT(dimnames, 1);
52
    else if (TYPEOF(dimnames) == LISTSXP)
-
 
53
	return CADR(dimnames);
-
 
54
    else
54
    else
55
	return R_NilValue;
55
	return R_NilValue;
56
}
56
}
57
 
57
 
58
SEXP do_matrix(SEXP call, SEXP op, SEXP args, SEXP rho)
58
SEXP do_matrix(SEXP call, SEXP op, SEXP args, SEXP rho)
Line 354... Line 354...
354
}
354
}
355
 
355
 
356
#ifdef HAVE_DOUBLE_COMPLEX
356
#ifdef HAVE_DOUBLE_COMPLEX
357
/* ZGEMM - perform one of the matrix-matrix operations    */
357
/* ZGEMM - perform one of the matrix-matrix operations    */
358
/* C := alpha*op( A )*op( B ) + beta*C */
358
/* C := alpha*op( A )*op( B ) + beta*C */
359
extern void 
359
extern void
360
F77_NAME(zgemm)(const char *transa, const char *transb, const int *m,
360
F77_NAME(zgemm)(const char *transa, const char *transb, const int *m,
361
		const int *n, const int *k, const Rcomplex *alpha,
361
		const int *n, const int *k, const Rcomplex *alpha,
362
		const Rcomplex *a, const int *lda,
362
		const Rcomplex *a, const int *lda,
363
		const Rcomplex *b, const int *ldb,
363
		const Rcomplex *b, const int *ldb,
364
		const Rcomplex *beta, Rcomplex *c, const int *ldc);
364
		const Rcomplex *beta, Rcomplex *c, const int *ldc);
Line 413... Line 413...
413
    char *trans = "T", *uplo = "U";
413
    char *trans = "T", *uplo = "U";
414
    double one = 1.0, zero = 0.0;
414
    double one = 1.0, zero = 0.0;
415
    int i, j;
415
    int i, j;
416
    if (nr > 0 && nc > 0) {
416
    if (nr > 0 && nc > 0) {
417
        F77_CALL(dsyrk)(uplo, trans, &nc, &nr, &one, x, &nr, &zero, z, &nc);
417
        F77_CALL(dsyrk)(uplo, trans, &nc, &nr, &one, x, &nr, &zero, z, &nc);
418
	for (i = 1; i < nc; i++) 
418
	for (i = 1; i < nc; i++)
419
	    for (j = 0; j < i; j++) z[i + nc *j] = z[j + nc * i];
419
	    for (j = 0; j < i; j++) z[i + nc *j] = z[j + nc * i];
420
    }
420
    }
421
}
421
}
422
 
422
 
423
static void crossprod(double *x, int nrx, int ncx,
423
static void crossprod(double *x, int nrx, int ncx,
Line 494... Line 494...
494
	    ;
494
	    ;
495
#endif
495
#endif
496
	}
496
	}
497
#endif
497
#endif
498
}
498
}
-
 
499
/* "%*%" (op = 0)  or  crossprod (op = 1) : */
499
SEXP do_matprod(SEXP call, SEXP op, SEXP args, SEXP rho)
500
SEXP do_matprod(SEXP call, SEXP op, SEXP args, SEXP rho)
500
{
501
{
501
    int ldx, ldy, nrx, ncx, nry, ncy, mode;
502
    int ldx, ldy, nrx, ncx, nry, ncy, mode;
502
    SEXP x = CAR(args), y = CADR(args), xdims, ydims, ans;
503
    SEXP x = CAR(args), y = CADR(args), xdims, ydims, ans;
503
    Rboolean sym;
504
    Rboolean sym;
Line 516... Line 517...
516
    xdims = getAttrib(x, R_DimSymbol);
517
    xdims = getAttrib(x, R_DimSymbol);
517
    ydims = getAttrib(y, R_DimSymbol);
518
    ydims = getAttrib(y, R_DimSymbol);
518
    ldx = length(xdims);
519
    ldx = length(xdims);
519
    ldy = length(ydims);
520
    ldy = length(ydims);
520
 
521
 
521
    if (ldx != 2 && ldy != 2) {
522
    if (ldx != 2 && ldy != 2) {		/* x and y non-matrices */
522
	if (PRIMVAL(op) == 0) {
523
	if (PRIMVAL(op) == 0) {
523
	    nrx = 1;
524
	    nrx = 1;
524
	    ncx = LENGTH(x);
525
	    ncx = LENGTH(x);
525
	}
526
	}
526
	else {
527
	else {
Line 528... Line 529...
528
	    ncx = 1;
529
	    ncx = 1;
529
	}
530
	}
530
	nry = LENGTH(y);
531
	nry = LENGTH(y);
531
	ncy = 1;
532
	ncy = 1;
532
    }
533
    }
533
    else if (ldx != 2) {
534
    else if (ldx != 2) {		/* x not a matrix */
534
	nry = INTEGER(ydims)[0];
535
	nry = INTEGER(ydims)[0];
535
	ncy = INTEGER(ydims)[1];
536
	ncy = INTEGER(ydims)[1];
536
	nrx = 0;
537
	nrx = 0;
537
	ncx = 0;
538
	ncx = 0;
538
	if (PRIMVAL(op) == 0) {
539
	if (PRIMVAL(op) == 0) {
539
	    if (LENGTH(x) == nry) { /* x as row vector */
540
	    if (LENGTH(x) == nry) {	/* x as row vector */
540
		nrx = 1;
541
		nrx = 1;
541
		ncx = LENGTH(x);
542
		ncx = LENGTH(x);
542
	    }
543
	    }
543
	    else if (nry == 1) { /* x as col vector */
544
	    else if (nry == 1) {	/* x as col vector */
544
		nrx = LENGTH(x);
545
		nrx = LENGTH(x);
545
		ncx = 1;
546
		ncx = 1;
546
	    }
547
	    }
547
	}
548
	}
548
	else {
549
	else {
549
	    if (LENGTH(x) == nry) {
550
	    if (LENGTH(x) == nry) {	/* x is a row vector */
550
		nrx = LENGTH(x);
551
		nrx = LENGTH(x);
551
		ncx = 1;
552
		ncx = 1;
552
	    }
553
	    }
553
	}
554
	}
554
    }
555
    }
555
    else if (ldy != 2) {
556
    else if (ldy != 2) {		/* y not a matrix */
556
	nrx = INTEGER(xdims)[0];
557
	nrx = INTEGER(xdims)[0];
557
	ncx = INTEGER(xdims)[1];
558
	ncx = INTEGER(xdims)[1];
558
	nry = 0;
559
	nry = 0;
559
	ncy = 0;
560
	ncy = 0;
560
	if (PRIMVAL(op) == 0) {
561
	if (PRIMVAL(op) == 0) {
561
	    if (LENGTH(y) == ncx) { /* y as col vector */
562
	    if (LENGTH(y) == ncx) {	/* y as col vector */
562
		nry = LENGTH(y);
563
		nry = LENGTH(y);
563
		ncy = 1;
564
		ncy = 1;
564
	    }
565
	    }
565
	    else if (ncx == 1){ /* y as row vector */
566
	    else if (ncx == 1) {	/* y as row vector */
566
		nry = 1;
567
		nry = 1;
567
		ncy = LENGTH(y);
568
		ncy = LENGTH(y);
568
	    }
569
	    }
569
	}
570
	}
570
	else {
571
	else {
571
	    if (LENGTH(y) == nrx) {
572
	    if (LENGTH(y) == nrx) {	/* y is a row vector */
572
		nry = LENGTH(y);
573
		nry = LENGTH(y);
573
		ncy = 1;
574
		ncy = 1;
574
	    }
575
	    }
575
	}
576
	}
576
    }
577
    }
577
    else {
578
    else {				/* x and y matrices */
578
	nrx = INTEGER(xdims)[0];
579
	nrx = INTEGER(xdims)[0];
579
	ncx = INTEGER(xdims)[1];
580
	ncx = INTEGER(xdims)[1];
580
	nry = INTEGER(ydims)[0];
581
	nry = INTEGER(ydims)[0];
581
	ncy = INTEGER(ydims)[1];
582
	ncy = INTEGER(ydims)[1];
582
    }
583
    }
Line 595... Line 596...
595
    else
596
    else
596
	mode = REALSXP;
597
	mode = REALSXP;
597
    SETCAR(args, coerceVector(CAR(args), mode));
598
    SETCAR(args, coerceVector(CAR(args), mode));
598
    SETCADR(args, coerceVector(CADR(args), mode));
599
    SETCADR(args, coerceVector(CADR(args), mode));
599
 
600
 
600
    if (PRIMVAL(op) == 0) {
601
    if (PRIMVAL(op) == 0) {		       	/* op == 0 : matprod() */
-
 
602
 
601
	PROTECT(ans = allocMatrix(mode, nrx, ncy));
603
	PROTECT(ans = allocMatrix(mode, nrx, ncy));
602
	if (mode == CPLXSXP)
604
	if (mode == CPLXSXP)
603
	    cmatprod(COMPLEX(CAR(args)), nrx, ncx,
605
	    cmatprod(COMPLEX(CAR(args)), nrx, ncx,
604
		     COMPLEX(CADR(args)), nry, ncy, COMPLEX(ans));
606
		     COMPLEX(CADR(args)), nry, ncy, COMPLEX(ans));
605
	else
607
	else
606
	    matprod(REAL(CAR(args)), nrx, ncx,
608
	    matprod(REAL(CAR(args)), nrx, ncx,
607
		    REAL(CADR(args)), nry, ncy, REAL(ans));
609
		    REAL(CADR(args)), nry, ncy, REAL(ans));
-
 
610
 
608
	PROTECT(xdims = getAttrib(CAR(args), R_DimNamesSymbol));
611
	PROTECT(xdims = getAttrib(CAR(args), R_DimNamesSymbol));
609
	PROTECT(ydims = getAttrib(CADR(args), R_DimNamesSymbol));
612
	PROTECT(ydims = getAttrib(CADR(args), R_DimNamesSymbol));
-
 
613
 
610
	if (xdims != R_NilValue || ydims != R_NilValue) {
614
	if (xdims != R_NilValue || ydims != R_NilValue) {
611
	    SEXP dimnames, dimnamesnames, dn;
615
	    SEXP dimnames, dimnamesnames, dn;
612
	    PROTECT(dimnames = allocVector(VECSXP, 2));
616
	    PROTECT(dimnames = allocVector(VECSXP, 2));
613
	    PROTECT(dimnamesnames = allocVector(STRSXP, 2));
617
	    PROTECT(dimnamesnames = allocVector(STRSXP, 2));
614
	    if (xdims != R_NilValue) {
618
	    if (xdims != R_NilValue) {
Line 635... Line 639...
635
	    setAttrib(dimnames, R_NamesSymbol, dimnamesnames);
639
	    setAttrib(dimnames, R_NamesSymbol, dimnamesnames);
636
	    setAttrib(ans, R_DimNamesSymbol, dimnames);
640
	    setAttrib(ans, R_DimNamesSymbol, dimnames);
637
	    UNPROTECT(2);
641
	    UNPROTECT(2);
638
	}
642
	}
639
    }
643
    }
-
 
644
 
640
    else {
645
    else {					/* op == 1: crossprod() */
-
 
646
 
641
	PROTECT(ans = allocMatrix(mode, ncx, ncy));
647
	PROTECT(ans = allocMatrix(mode, ncx, ncy));
642
	if (mode == CPLXSXP)
648
	if (mode == CPLXSXP)
643
	    if(sym)
649
	    if(sym)
644
		ccrossprod(COMPLEX(CAR(args)), nrx, ncx,
650
		ccrossprod(COMPLEX(CAR(args)), nrx, ncx,
645
			   COMPLEX(CAR(args)), nry, ncy, COMPLEX(ans));
651
			   COMPLEX(CAR(args)), nry, ncy, COMPLEX(ans));
Line 653... Line 659...
653
	    else
659
	    else
654
#endif
660
#endif
655
		crossprod(REAL(CAR(args)), nrx, ncx,
661
		crossprod(REAL(CAR(args)), nrx, ncx,
656
			  REAL(CADR(args)), nry, ncy, REAL(ans));
662
			  REAL(CADR(args)), nry, ncy, REAL(ans));
657
	}
663
	}
-
 
664
 
658
	PROTECT(xdims = getAttrib(CAR(args), R_DimNamesSymbol));
665
	PROTECT(xdims = getAttrib(CAR(args), R_DimNamesSymbol));
659
	if(sym)
666
	if (sym)
660
	    PROTECT(ydims = xdims);
667
	    PROTECT(ydims = xdims);
661
	else
668
	else
662
	    PROTECT(ydims = getAttrib(CADR(args), R_DimNamesSymbol));
669
	    PROTECT(ydims = getAttrib(CADR(args), R_DimNamesSymbol));
-
 
670
 
663
	if (xdims != R_NilValue || ydims != R_NilValue) {
671
	if (xdims != R_NilValue || ydims != R_NilValue) {
664
	    SEXP dimnames, dimnamesnames, dnx=R_NilValue, dny=R_NilValue;
672
	    SEXP dimnames, dimnamesnames, dnx=R_NilValue, dny=R_NilValue;
-
 
673
 
-
 
674
	    /* allocate dimnames and dimnamesnames */
-
 
675
 
665
	    PROTECT(dimnames = allocVector(VECSXP, 2));
676
	    PROTECT(dimnames = allocVector(VECSXP, 2));
666
	    PROTECT(dimnamesnames = allocVector(STRSXP, 2));
677
	    PROTECT(dimnamesnames = allocVector(STRSXP, 2));
-
 
678
 
-
 
679
            /* There was a bug here.  The second element of a */
-
 
680
            /* dimnames list was being accessed for a 1-d array. */
-
 
681
            /* I have just excluded the use of dimnames in this */
-
 
682
            /* case. - ihaka Sep 30, 2003. */
-
 
683
 
667
	    if (xdims != R_NilValue) {
684
	    if (xdims != R_NilValue) {
-
 
685
                if (ldx == 2) {
668
		dnx = getAttrib(xdims, R_NamesSymbol);
686
		    dnx = getAttrib(xdims, R_NamesSymbol);
669
		SET_VECTOR_ELT(dimnames, 0, VECTOR_ELT(xdims, 1));
687
		    SET_VECTOR_ELT(dimnames, 0, VECTOR_ELT(xdims, 1));
670
		if(!isNull(dnx))
688
		    if(!isNull(dnx))
671
		    SET_STRING_ELT(dimnamesnames, 0, STRING_ELT(dnx, 1));
689
			SET_STRING_ELT(dimnamesnames, 0, STRING_ELT(dnx, 1));
-
 
690
		}
672
	    }
691
	    }
-
 
692
 
673
	    if (ydims != R_NilValue) {
693
	    if (ydims != R_NilValue) {
-
 
694
                if (ldy == 2) {
674
		dny = getAttrib(ydims, R_NamesSymbol);
695
		    dny = getAttrib(ydims, R_NamesSymbol);
675
		SET_VECTOR_ELT(dimnames, 1, VECTOR_ELT(ydims, 1));
696
		    SET_VECTOR_ELT(dimnames, 1, VECTOR_ELT(ydims, 1));
676
		if(!isNull(dny))
697
		    if(!isNull(dny))
677
		    SET_STRING_ELT(dimnamesnames, 1, STRING_ELT(dny, 1));
698
			SET_STRING_ELT(dimnamesnames, 1, STRING_ELT(dny, 1));
-
 
699
		}
678
	    }
700
	    }
-
 
701
 
-
 
702
            /* We sometimes attach a dimnames attribute */
-
 
703
            /* whose elements are all NULL ... */
-
 
704
            /* Thus is ugly but causes no real damage. */
-
 
705
	    
679
	    if (!isNull(dnx) || !isNull(dny))
706
	    if (!isNull(dnx) || !isNull(dny))
680
		setAttrib(dimnames, R_NamesSymbol, dimnamesnames);
707
		setAttrib(dimnames, R_NamesSymbol, dimnamesnames);
681
	    setAttrib(ans, R_DimNamesSymbol, dimnames);
708
	    setAttrib(ans, R_DimNamesSymbol, dimnames);
682
	    UNPROTECT(2);
709
	    UNPROTECT(2);
683
	}
710
	}
Line 1037... Line 1064...
1037
	    for (j = 0; j < p; j++) {
1064
	    for (j = 0; j < p; j++) {
1038
		ra = rans;
1065
		ra = rans;
1039
		if (keepNA)
1066
		if (keepNA)
1040
		    for (i = 0; i < n; i++) *ra++ += *rx++;
1067
		    for (i = 0; i < n; i++) *ra++ += *rx++;
1041
		else
1068
		else
1042
		    for (c = cnt, i = 0; i < n; i++, ra++, rx++, c++) 
1069
		    for (c = cnt, i = 0; i < n; i++, ra++, rx++, c++)
1043
			if (!ISNAN(*rx)) {
1070
			if (!ISNAN(*rx)) {
1044
			    *ra += *rx;
1071
			    *ra += *rx;
1045
			    if (OP == 3) (*c)++;
1072
			    if (OP == 3) (*c)++;
1046
			}
1073
			}
1047
	    }
1074
	    }
1048
	    if (OP == 3) {
1075
	    if (OP == 3) {
1049
		if (keepNA)
1076
		if (keepNA)
1050
		    for (ra = rans, i = 0; i < n; i++) 
1077
		    for (ra = rans, i = 0; i < n; i++)
1051
			*ra++ /= p;
1078
			*ra++ /= p;
1052
		else {
1079
		else {
1053
		    for (ra = rans, c = cnt, i = 0; i < n; i++, c++) 
1080
		    for (ra = rans, c = cnt, i = 0; i < n; i++, c++)
1054
			if (*c > 0) *ra++ /= *c; else *ra++ = NA_REAL;
1081
			if (*c > 0) *ra++ /= *c; else *ra++ = NA_REAL;
1055
		    Free(cnt);
1082
		    Free(cnt);
1056
		}
1083
		}
1057
	    }
1084
	    }
1058
	    UNPROTECT(1);
1085
	    UNPROTECT(1);