Message Boards Message Boards

GROUPS:

Creating a matrix with LibraryLink

Posted 5 years ago
5288 Views
|
3 Replies
|
3 Total Likes
|
In a previous post I explained how to work with passing in a list of data and calculating its mean value.
In this post we are going to pass in two arguments, a row and column value, and return a matrix with that
specified dimension.

Here is the code (CreateMatrix.c):


 
 #include "WolframLibrary.h"
 
 DLLEXPORT int CreateMatrix(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
 
         mint row,col,rows,cols,count;
 
         MTensor out;
         mint out_type = MType_Integer;
        mint out_rank = 2 ;
        mint out_dims[2];
        mint* out_data;
        int err;

        rows = MArgument_getInteger(Args[0]);
        cols = MArgument_getInteger(Args[1]);
        out_dims[0] = rows;
        out_dims[1] = cols;

        err = libData->MTensor_new( out_type, out_rank, out_dims, &out );
        out_data = libData->MTensor_getIntegerData(out);

        count=1;
        for(row=0; row<rows; row++) {
                for(col=0; col<cols; col++) {
                        out_data[col+cols*row] = count++;
                }
        }

        MArgument_setMTensor(Res,out);
        return LIBRARY_NO_ERROR;
}


The key new functionality in this code is the creation of an MTensor using libData->MTensor_new and filling the
rows and columns of that tensor with (increasing) integer values, using 'count'.

To create a new tensor you need to specify the type (MType_Integer), the rank (2 for a matrix) and the dimensions (rows and cols in this case).

To fill the matrix you need to get the (uninitialized) integer data out of the tensor, using libData->MTensor_getIntgerData. Then you can fill the data with a nested for loop over the rows and columns.

The Wolfram Language build and function loading code will now need to specify that we are going to pass in two arguments, a rows
and a columns argument and that we are going to return a 2 dimensional integer tensor (CreateMatrix.m):


Needs["CCompilerDriver`"];
lib = CreateLibrary[{"CreateMatrix.c"},"CreateMatrix"];
CreateMatrix = LibraryFunctionLoad[lib,"CreateMatrix",{Integer,Integer},{Integer,2}];


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["CreateMatrix.m"]
 
 In[2]:= CreateMatrix[3,4] // Grid
 
 Out[2]= 1   2    3    4

        5   6    7    8

        9   10   11   12

In[3]:= CreateMatrix[3,12] // Grid

Out[3]= 1    2    3    4    5    6    7    8    9    10   11   12

        13   14   15   16   17   18   19   20   21   22   23   24

        25   26   27   28   29   30   31   32   33   34   35   36


In the next post we will take a look at how to work with complex numbers.
3 Replies
Posted 2 years ago

Dear Arnoud,

How to adapt this code to work for C++ too?


Just found out!

Replace:

DLLEXPORT int CreateMatrix(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res)

with

extern "C" __declspec(dllexport) 
int CreateMatrix(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res)
Posted 2 years ago

Seemingly an easy task: How to adapt the code above to produce a matrix of real numbers?

Here are the changes I have done so far:

#include "WolframLibrary.h"

extern "C" __declspec(dllexport) 
int CreateMatrix(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {

        mint rows,cols;

        MTensor out;
        mint out_type = MType_Real;
        mint out_rank = 2 ;
        mint out_dims[2];
        mreal* out_data;
        int err;

        rows = MArgument_getInteger(Args[0]);
        cols = MArgument_getInteger(Args[1]);
        out_dims[0] = rows;
        out_dims[1] = cols;

        err = libData->MTensor_new( out_type, out_rank, out_dims, &out );
        out_data = libData->MTensor_getRealData(out);

        for(int row=0; row<rows; row++) {
                for(int col=0; col<cols; col++) {
                        out_data[col+cols*row] = 1.1;
                }
        }

        MArgument_setMTensor(Res,out);
        return LIBRARY_NO_ERROR;
}

Missed completely that there are other specification functions. here was my problem:

CreateMatrix = LibraryFunctionLoad[lib, "CreateMatrix", {Integer, Integer}, {Real, 2}];
Posted 15 days ago

You also can use:

EXTERN_C DLLEXPORT int CreateMatrix(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) 
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract