You can download a presentation on dmdinline2 here.
Takes a matrix from R, converts it to a D RMatrix
struct, prints it out, and returns NULL
to R.
code <- '
import rtod2.matrix2;
import std.stdio;
Robj printmat(Robj rm) {
auto m = RMatrix(rm);
print(m, "Matrix from R");
return RNil;
}
'
compileD("foo", code)
m <- matrix(rnorm(12), ncol=2)
print(m)
.Call("printmat", m)
Take a matrix from R and copy it. The dup
method is normally used in D to make a copy of an object. A pointer to the data inside a D array x
is given by x.ptr
. I have followed that convention throughout rtod2, so you can access the data in an RMatrix x
using x.ptr
.
code <- '
import rtod2.matrix2;
import std.stdio;
Robj printmat2(Robj rm) {
auto m = RMatrix(rm);
RMatrix m2 = m.dup;
print(m2, "Copy of R matrix");
writeln("location of data in original matrix: ", m.ptr);
writeln("location of data in new matrix: ", m2.ptr);
return RNil;
}
'
compileD("foo", code)
m <- matrix(rnorm(12), ncol=3)
print(m)
.Call("printmat2", m)
You can allocate an R matrix from within D. The primary reason to that is if you want to return a matrix of data from D to R (the output of a simulation, for instance). In this example, you pass the dimensions of the matrix as arguments, set all elements to 2.7, and return the Robj to R. The rtod2
library handles all details related to protecting the matrix from the garbage collector.
code <- '
import rtod2.matrix2;
Robj alloc(Robj rr, Robj rc) {
auto m = RMatrix(rr.scalar!int, rc.scalar!int);
m.fill(2.7);
return m.robj;
}
'
compileD("foo", code)
.Call("alloc", 7, 4)
You can also allocate a Gretl matrix from within D. The main reason to do that is to call Gretl library functions. This example shows that you can access elements of a matrix by index. As is common for compiled languages, D uses zero indexing, meaning the first element of a row or column is 0, not 1, as it is in R. A new GretlMatrix is allocated by the multiplication operator, and the matrix is then returned to R. You have to include std.conv to use D's to!
template for conversions.
code <- '
import rtod2.matrix2;
import std.conv;
Robj gretlalloc() {
auto gm = GretlMatrix(2,2);
gm[0,0] = 1.1; gm[0,1] = 2.2;
gm[1,0] = 3.3; gm[1,1] = 4.4;
GretlMatrix gm2 = gm*gm;
return to!RMatrix(gm2).robj;
}
'
compileD("foo", code)
.Call("gretlalloc")
Because it's common to work with an entire row or column at one time, we can rewrite the example above using Col:
code <- '
import rtod2.matrix2;
import std.conv;
Robj gretlalloc() {
auto gm = GretlMatrix(2,2);
Col(gm, 0) = [1.1, 3.3];
Col(gm, 1) = [2.2, 4.4];
GretlMatrix gm2 = gm*gm;
return to!RMatrix(gm2).robj;
}
'
compileD("foo", code)
.Call("gretlalloc")
or using Row:
code <- '
import rtod2.matrix2;
import std.conv;
Robj gretlalloc() {
auto gm = GretlMatrix(2,2);
Row(gm, 0) = [1.1, 2.2];
Row(gm, 1) = [3.3, 4.4];
GretlMatrix gm2 = gm*gm;
return to!RMatrix(gm2).robj;
}
'
compileD("foo", code)
.Call("gretlalloc")