On 06/12/2013 8:21 AM, Larissa Hauer wrote:
Hi everybody,

I'm trying to pass a matrix from R to C, where some computation is done
for performance reasons, and back to R for evaluation. But I've run into
the problem that R and C seem to have different ways of representing the
matrix in main memory. The C representation of a 2D matrix in linear
memory is concatenation of the rows whereas in R, it's a concatenation
of the columns.  That leads to the problem. that an R-matrix, for example
123
456
789
is seen by C as
147
258
369
and vice versa.

Here's an example of C code that simply prints the matrix it gets from R:

#include <stdlib.h>
#include "R.h"

void printMatrix(int *mPtr, int *m, int *n) {
    int (*matrix)[*n] = mPtr;

    int j,k;

    for(j = 0; j < *m; j++){
      for(k = 0; k < *n; k++) {
        printf("%d", matrix[j][k]);
      }
    printf("\n");
    }
}

And here's what happens when I call the function in R:

> m <- 3; n <- 3
> mat <- matrix(c(1:9), nrow=m, ncol=n, byrow=TRUE)
> mat
       [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
> mat <- .C("printMatrix", mat, as.integer(m), as.integer(n))[[1]]
147
258
369


No matter if you create the matrix with byrow=TRUE or FALSE, C always
interprets it the other way round. Is there a way to avoid this? I've
read previous posts on passing a matrix from R to C, but the essence of
the answers was that "a matrix in R is just a vector with attributes",
but I don't see how this helps. Maybe someone can clarify.

I would not assume that a 2D matrix in C doesn't have gaps in it between the rows. Let C treat it as a vector, and write a little macro that does the indexing. For example,

#define INDEX(i,j) (i) + rows*(j)

Then mPtr[INDEX(i,j)] will do R-style indexing (except it will be 0-based, not 1-based. You could fix that too if you wanted.)

Duncan Murdoch

Thanks a lot in advance!

Cheers
Larissa

Here's the C main function showing that the C code itself is correct:

#include <stdlib.h>

void printMatrix(int *mPtr, int *m, int *n);

int main(void) {
    int m, n, i;
    int *mPtr, *nPtr;
    m = 3;
    n = 3;
    mPtr = &m;
    nPtr = &n;

    int *M = malloc(m * n * sizeof(int));

    for (i = 0; i < m * n; i++){
    M[i] = i + 1;
    }

    printMatrix(M, mPtr, nPtr);

    return EXIT_SUCCESS;

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to