The R Project SVN R

Rev

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

Rev 33387 Rev 34194
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) 1997--2003  Robert Gentleman, Ross Ihaka and the
4
 *  Copyright (C) 1997--2005  Robert Gentleman, Ross Ihaka and the
5
 *                            R Development Core Team
5
 *                            R Development Core Team
6
 *
6
 *
7
 *  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
8
 *  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
9
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  the Free Software Foundation; either version 2 of the License, or
Line 179... Line 179...
179
 
179
 
180
/* Special Matrix Subscripting: Handles the case x[i] where */
180
/* Special Matrix Subscripting: Handles the case x[i] where */
181
/* x is an n-way array and i is a matrix with n columns. */
181
/* x is an n-way array and i is a matrix with n columns. */
182
/* This code returns a vector containing the integer subscripts */
182
/* This code returns a vector containing the integer subscripts */
183
/* to be extracted when x is regarded as unravelled. */
183
/* to be extracted when x is regarded as unravelled. */
-
 
184
/* Negative indices are not allowed. */
-
 
185
/* A zero anywhere in a row will cause a zero in the same */
-
 
186
/* position in the result. */
184
 
187
 
185
SEXP mat2indsub(SEXP dims, SEXP s)
188
SEXP mat2indsub(SEXP dims, SEXP s)
186
{
189
{
187
    int tdim, j, i, nrs = nrows(s);
190
    int tdim, j, i, k, nrs = nrows(s);
188
    SEXP rvec;
191
    SEXP rvec;
189
 
192
 
-
 
193
    if (ncols(s) != LENGTH(dims))
-
 
194
	error(_("incorrect number of columns in matrix subscript"));
190
    PROTECT(rvec = allocVector(INTSXP, nrs));
195
    PROTECT(rvec = allocVector(INTSXP, nrs));
191
    s = coerceVector(s, INTSXP);
196
    s = coerceVector(s, INTSXP);
192
    setIVector(INTEGER(rvec), nrs, 0);
197
    setIVector(INTEGER(rvec), nrs, 0);
193
 
198
 
194
    /* compute 0-based subscripts */
-
 
195
    for (i = 0; i < nrs; i++) {
199
    for (i = 0; i < nrs; i++) {
196
	tdim = 1;
200
	tdim = 1;
-
 
201
	/* compute 0-based subscripts for a row (0 in the input gets -1
-
 
202
	   in the output here) */
197
	for (j = 0; j < LENGTH(dims); j++) {
203
	for (j = 0; j < LENGTH(dims); j++) {
198
	    if(INTEGER(s)[i + j * nrs] == NA_INTEGER) {
204
	    k = INTEGER(s)[i + j * nrs];
-
 
205
	    if(k == NA_INTEGER) {
199
		INTEGER(rvec)[i] = NA_INTEGER;
206
		INTEGER(rvec)[i] = NA_INTEGER;
200
		break;
207
		break;
201
	    }
208
	    }
-
 
209
	    if(k < 0) error(_("negative values are not allowed in a matrix subscript"));
-
 
210
	    if(k == 0) {
-
 
211
		INTEGER(rvec)[i] = -1;
-
 
212
		break;
-
 
213
	    }
202
	    if (INTEGER(s)[i + j * nrs] > INTEGER(dims)[j])
214
	    if (k > INTEGER(dims)[j])
203
		error(_("subscript out of bounds"));
215
		error(_("subscript out of bounds"));
204
	    INTEGER(rvec)[i] += (INTEGER(s)[i+j*nrs] - 1) * tdim;
216
	    INTEGER(rvec)[i] += (k - 1) * tdim;
205
	    tdim *= INTEGER(dims)[j];
217
	    tdim *= INTEGER(dims)[j];
206
	}
218
	}
207
	/* transform to 1 based subscripting */
219
	/* transform to 1 based subscripting (0 in the input gets 0 
-
 
220
	   in the output here) */
208
	if(INTEGER(rvec)[i] != NA_INTEGER)
221
	if(INTEGER(rvec)[i] != NA_INTEGER)
209
	    INTEGER(rvec)[i]++;
222
	    INTEGER(rvec)[i]++;
210
    }
223
    }
211
    UNPROTECT(1);
224
    UNPROTECT(1);
212
    return (rvec);
225
    return (rvec);