4
|
6900 Views
|
2 Replies
|
6 Total Likes
View groups...
Share

# Working with complex numbers in LibraryLink

Posted 11 years ago
 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 usingmcreal(z) and mcimag(z). In this example we will extract both parts and return them back as a list to the calling WolframLanguage 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 intoits real and imaginary part using mcreal(z) and mcimag(z). To return these parts as a list we need to create a tensorwith one dimension (a list) and length 2. After creating this tensor we need to set the elements of the list with libData->MTensor_setRealand finally return the result.The following Wolfram Language code (ReIm.m) creates the library and loads the LibraryLink function. Note that the function expect asingle 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 valueare automatically converted to their real number approximation.Next, let's take a look at how to work with multiple functions in LibraryLink.
2 Replies
Sort By:
Posted 3 years ago
 Here's a version that avoids the name clash, the kernel crash and seems to work: #include "WolframLibrary.h"DLLEXPORT int notReIm(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {  mcomplex z; mreal re,im; z = MArgument_getComplex(Args[0]); re = mcreal(z); im = mcimag(z); mint row,col,rows,cols,count; MTensor out; mint out_type = MType_Integer; mint out_rank = 1 ; mint out_dims[1]; mint* out_data; int err; mint out_pos[2]; 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_setMTensor(Res,out); return LIBRARY_NO_ERROR; `}
Posted 5 years ago
 Hello!It seems as though MMA already has a function called "ReIm" (https://reference.wolfram.com/language/ref/ReIm.html) which means that you are calling that function in your MMA evaluation (as opposed to using your custom ReIm function).Also, I tried evaluating your code and MMA crashes regardless of the input. Will keep looking for the error and get back to you if I find it!All the best,Ivan S.
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.