In a
previous post I explained how to create a matrix with integer values when passing in a row and column argument.
In this post we are going to look at a data type we have not previously used: complex numbers (mcomplex). Unlike reals,
integers and strings this data type is a compound type with both a real and imaginary part which can be extracted using
mcreal(z) and mcimag(z). In this example we will extract both parts and return them back as a list to the calling Wolfram
Language function.
Here is the C code (ReIm.c):
#include "WolframLibrary.h"
DLLEXPORT int ReIm(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
mcomplex z;
mreal re,im;
MTensor out;
mint out_type;
mint out_rank;
mint* out_dims;
mint* out_pos;
int err;
z = MArgument_getComplex(Args[0]);
re = mcreal(z);
im = mcimag(z);
out_type = MType_Real;
out_rank = 1;
out_dims[0] = 2;
err = libData->MTensor_new(out_type, out_rank, out_dims, &out);
out_pos[0] = 1;
err = libData->MTensor_setReal(out, out_pos, re);
out_pos[0] = 2;
err = libData->MTensor_setReal(out, out_pos, im);
MArgument_setInteger(Res,out);
return LIBRARY_NO_ERROR;
}
Here we get the complex number by calling MArgument_getComplex on the first argument and immediately split it up into
its real and imaginary part using mcreal(z) and mcimag(z). To return these parts as a list we need to create a tensor
with one dimension (a list) and length 2. After creating this tensor we need to set the elements of the list with libData->MTensor_setReal
and finally return the result.
The following Wolfram Language code (ReIm.m) creates the library and loads the LibraryLink function. Note that the function expect a
single complex number as its input and will return a list of real numbers (of length two in this case):
Needs["CCompilerDriver`"];
lib = CreateLibrary[{"ReIm.c"},"ReIm"];
ReIm = LibraryFunctionLoad[lib,"ReIm",{Complex},{Real,1}];
Now we can try running this code in the Wolfram Language:
Mathematica 10.0 for Microsoft Windows (64-bit)
Copyright 1988-2013 Wolfram Research, Inc.
In[1]:= Get["ReIm.m"]
In[2]:= ReIm[0]
Out[2]= {0., 0.}
In[3]:= ReIm[I]
Out[3]= {0., 1.}
In[4]:= ReIm[Log[-1]]
Out[4]= {0., 3.14159}
In[5]:= ReIm[2.3+6.5*I]
Out[5]= {2.3, 6.5}
Note how Log[-1] gets evaluated to I*Pi before it is sent to the LibraryLink function. Integers and constants with a numerical value
are automatically converted to their real number approximation.
Next, let's take a look at
how to work with multiple functions in LibraryLink.