How to convert float[][] type array to "emxArray_real_T *x"
Asked Answered
D

2

3

I have converted a function which takes a NxN matrix as input and gives a NxN matrix output from matlab to C, using the MatlabCoder. It gave me the function which has two parameters namely

void func(const emxArray_real_T *x, emxArray_real_T *y)

I get that x is the input to the function and i can get the output of the function from y. The problem is i have a array in float[][] and i wish to give this data as an input to the func, which only takes emxArray_real_T *x as an input.

Any ideas on how to convert this float[][] data to emxArray_real_T *x

emxArray_real_T has this structure

struct emxArray_real_T
{
    real_T *data;
    int32_T *size;
    int32_T allocatedSize;
    int32_T numDimensions;
    boolean_T canFreeData;
};
Dorpat answered 17/8, 2013 at 5:54 Comment(0)
D
3

I found this later that we can create any data into the emxArray_real_T * using these following steps...

Step 1: Lets say you have a array with float or double or anything else... it is of 2 dimensions.. it can be of any dimensions... it can be 3.. it can be of 4... now first step is to declare

emxArray_real_T *x, *y;

where x will be your input and you will get the output in y...

now till this time we have only declared the variables and not set any dimensions or any size in them...

Step 2: In the same file as your function that you want to call there should be these functions.. if not then you must declare them....

 static void emxInit_real_T(emxArray_real_T **pEmxArray, int32_T numDimensions)
 {
   emxArray_real_T *emxArray;
   int32_T i;
   *pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
   emxArray = *pEmxArray;
   emxArray->data = (real_T *)NULL;
   emxArray->numDimensions = numDimensions;
   emxArray->size = (int32_T *)malloc((uint32_T)(sizeof(int32_T) * numDimensions));
   emxArray->allocatedSize = 0;
   emxArray->canFreeData = TRUE;
   for (i = 0; i < numDimensions; i++) {
     emxArray->size[i] = 0;
   }
 }

now you can initialize your variables "x,y" as following

emxInit_real_T(&x, 2);
emxInit_real_T(&y, 2);

here 2 is the dimension of the matrix that we want as input or output..

Step 3: In my case the dimension of x is 2 so what i will do is like this Say my input is n*n matrix so i will do this

x->size[0]=n;
x->size[1]=n;

and similarly for y

y->size[0]=n;
y->size[1]=n;

if you have 3 or 4 dimension then you can put more like x->size[2]=that size.. and so on..

Step 4: Now we have ensure that the program allots the specified memory to these variables so for that there should be a function like below.. if not then your must declare it...

static void emxEnsureCapacity(emxArray__common *emxArray, int32_T oldNumel,
  int32_T elementSize)
{
  int32_T newNumel;
  int32_T i;
  void *newData;
  newNumel = 1;
  for (i = 0; i < emxArray->numDimensions; i++) {
    newNumel *= emxArray->size[i];
  }

  if (newNumel > emxArray->allocatedSize) {
    i = emxArray->allocatedSize;
    if (i < 16) {
      i = 16;
    }

    while (i < newNumel) {
      i <<= 1;
    }

    newData = calloc((uint32_T)i, (uint32_T)elementSize);
    if (emxArray->data != NULL) {
      memcpy(newData, emxArray->data, (uint32_T)(elementSize * oldNumel));
      if (emxArray->canFreeData) {
        free(emxArray->data);
      }
    }

    emxArray->data = newData;
    emxArray->allocatedSize = i;
    emxArray->canFreeData = TRUE;
  }
}

for this there should be struct names emxArray__common like below if not then do declare it like below

struct emxArray__common
{
  void *data;
  int32_T *size;
  int32_T allocatedSize;
  int32_T numDimensions;
  boolean_T canFreeData;
};
typedef struct emxArray__common emxArray__common;

Step 5: then do like this..

emxEnsureCapacity((emxArray__common *)x, 0, (int32_T)sizeof(real_T));
emxEnsureCapacity((emxArray__common *)y, 0, (int32_T)sizeof(real_T));

now both these varibles have the specified n*n memory in them. now the input data will be saved in the data of x... that will be saved in it row wise..

x->data[i*n+j]=input_data[i][j];

if you get what i mean by it. now you can pass the x and y in the function that you want to call and then the data returned will be in y and it will be row-wise too.. so read it carefully and ther you have it... you have executed the matlab function in c....

Dorpat answered 18/8, 2013 at 11:5 Comment(1)
This answer will work but is is using MATLAB Coder generated functions which are not meant to be used externally. The documentation posted by @Hartwig and my other answer show that the functions in <functionName>_emxAPI.h like emxCreate... should be used instead. The example main function in codegen/<lib|dll|exe>/foo/examples/main.c provides a specific example for your particular generated code.Orban
H
5

Basically you need to have the *data member of emxArray point to the float array. In C, float data is stored as single precision. Update the other members of emxArrayaccordingly.

You may want to checkout the MathWorks documentation on the C Code Interface for Arrays

This answer contains exact same scenario implemented in C# for double data-type.

Hartwig answered 17/8, 2013 at 9:3 Comment(0)
D
3

I found this later that we can create any data into the emxArray_real_T * using these following steps...

Step 1: Lets say you have a array with float or double or anything else... it is of 2 dimensions.. it can be of any dimensions... it can be 3.. it can be of 4... now first step is to declare

emxArray_real_T *x, *y;

where x will be your input and you will get the output in y...

now till this time we have only declared the variables and not set any dimensions or any size in them...

Step 2: In the same file as your function that you want to call there should be these functions.. if not then you must declare them....

 static void emxInit_real_T(emxArray_real_T **pEmxArray, int32_T numDimensions)
 {
   emxArray_real_T *emxArray;
   int32_T i;
   *pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
   emxArray = *pEmxArray;
   emxArray->data = (real_T *)NULL;
   emxArray->numDimensions = numDimensions;
   emxArray->size = (int32_T *)malloc((uint32_T)(sizeof(int32_T) * numDimensions));
   emxArray->allocatedSize = 0;
   emxArray->canFreeData = TRUE;
   for (i = 0; i < numDimensions; i++) {
     emxArray->size[i] = 0;
   }
 }

now you can initialize your variables "x,y" as following

emxInit_real_T(&x, 2);
emxInit_real_T(&y, 2);

here 2 is the dimension of the matrix that we want as input or output..

Step 3: In my case the dimension of x is 2 so what i will do is like this Say my input is n*n matrix so i will do this

x->size[0]=n;
x->size[1]=n;

and similarly for y

y->size[0]=n;
y->size[1]=n;

if you have 3 or 4 dimension then you can put more like x->size[2]=that size.. and so on..

Step 4: Now we have ensure that the program allots the specified memory to these variables so for that there should be a function like below.. if not then your must declare it...

static void emxEnsureCapacity(emxArray__common *emxArray, int32_T oldNumel,
  int32_T elementSize)
{
  int32_T newNumel;
  int32_T i;
  void *newData;
  newNumel = 1;
  for (i = 0; i < emxArray->numDimensions; i++) {
    newNumel *= emxArray->size[i];
  }

  if (newNumel > emxArray->allocatedSize) {
    i = emxArray->allocatedSize;
    if (i < 16) {
      i = 16;
    }

    while (i < newNumel) {
      i <<= 1;
    }

    newData = calloc((uint32_T)i, (uint32_T)elementSize);
    if (emxArray->data != NULL) {
      memcpy(newData, emxArray->data, (uint32_T)(elementSize * oldNumel));
      if (emxArray->canFreeData) {
        free(emxArray->data);
      }
    }

    emxArray->data = newData;
    emxArray->allocatedSize = i;
    emxArray->canFreeData = TRUE;
  }
}

for this there should be struct names emxArray__common like below if not then do declare it like below

struct emxArray__common
{
  void *data;
  int32_T *size;
  int32_T allocatedSize;
  int32_T numDimensions;
  boolean_T canFreeData;
};
typedef struct emxArray__common emxArray__common;

Step 5: then do like this..

emxEnsureCapacity((emxArray__common *)x, 0, (int32_T)sizeof(real_T));
emxEnsureCapacity((emxArray__common *)y, 0, (int32_T)sizeof(real_T));

now both these varibles have the specified n*n memory in them. now the input data will be saved in the data of x... that will be saved in it row wise..

x->data[i*n+j]=input_data[i][j];

if you get what i mean by it. now you can pass the x and y in the function that you want to call and then the data returned will be in y and it will be row-wise too.. so read it carefully and ther you have it... you have executed the matlab function in c....

Dorpat answered 18/8, 2013 at 11:5 Comment(1)
This answer will work but is is using MATLAB Coder generated functions which are not meant to be used externally. The documentation posted by @Hartwig and my other answer show that the functions in <functionName>_emxAPI.h like emxCreate... should be used instead. The example main function in codegen/<lib|dll|exe>/foo/examples/main.c provides a specific example for your particular generated code.Orban

© 2022 - 2024 — McMap. All rights reserved.