Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
how to change class of mxArray?

Subject: how to change class of mxArray?

From: Bruce Elliott

Date: 15 Feb, 2014 06:04:08

Message: 1 of 10

Is it possible to cast a given mxArray to a different class?

I have created a MEX-File that passes a structure of input data to a C++ third-party library function. The types of the structure fields are defined by that library, and my intent has been to replicate them in the mxArray structure passed to the MEX function as an input argument. The idea is for the MEX-File to be as transparent an interface as possible between the Matlab workspace and the third-party library.

My problem is that when the calling function or user sets the values of any of the input fields before calling the MEX function, Matlab set the type to double by default. Since the MEX file expects the types to match those of the C++ structure, there is a mis-match for any other numeric types (int32, typically).

I can see three options, from easier but less desirable to more difficult but better from a design standpoint (I think):

1. I can require that the caller/end-user explicitly cast any numeric inputs that are other than double to the type expected by the C++ function. This solves the problem, but I'd rather not put the burden on the user, who is not likely to know a lot about data typing.

2. I can define the mxArray structure so that its numeric fields all have classID mxDOUBLE_CLASS, and then cast them to the appropriate C++ type when I create the corresponding C++ structure. The mxArray structure will no longer match the C++ structure by type, but that might not be so important.

3. I can have the MEX function check the classID of each field in the input mxArray structure, and if it is not what it should be, call some mx function to cast it to the correct classID. This meets my original intent, but I haven't found such a mx function. I could probably just destroy the field's mxArray and then mxCreate*() it again with the correct classID, after having stored a copy of the data and cast it as needed ... but then I might as well go with solution #2, unless I really do need that mxArray structure to match the C++ structure type by type.

Are there any better approaches that I've missed? If not, the #2 is probably what I'll do.

Thanks,
Bruce

Subject: how to change class of mxArray?

From: James Tursa

Date: 15 Feb, 2014 22:07:12

Message: 2 of 10

"Bruce Elliott" <bruce.elliott@jhuapl.nospam.edu> wrote in message <ldn00o$nj6$1@newscl01ah.mathworks.com>...
> Is it possible to cast a given mxArray to a different class?
>
> I have created a MEX-File that passes a structure of input data to a C++ third-party library function. The types of the structure fields are defined by that library, and my intent has been to replicate them in the mxArray structure passed to the MEX function as an input argument. The idea is for the MEX-File to be as transparent an interface as possible between the Matlab workspace and the third-party library.
>
> My problem is that when the calling function or user sets the values of any of the input fields before calling the MEX function, Matlab set the type to double by default. Since the MEX file expects the types to match those of the C++ structure, there is a mis-match for any other numeric types (int32, typically).
>
> I can see three options, from easier but less desirable to more difficult but better from a design standpoint (I think):
>
> 1. I can require that the caller/end-user explicitly cast any numeric inputs that are other than double to the type expected by the C++ function. This solves the problem, but I'd rather not put the burden on the user, who is not likely to know a lot about data typing.

Agreed that this is the most user-unfriendly option.


> 2. I can define the mxArray structure so that its numeric fields all have classID mxDOUBLE_CLASS, and then cast them to the appropriate C++ type when I create the corresponding C++ structure. The mxArray structure will no longer match the C++ structure by type, but that might not be so important.

Not sure what you mean by this. How can you *define* the fields to have double class? Isn't that a user input per your description?


> 3. I can have the MEX function check the classID of each field in the input mxArray structure, and if it is not what it should be, call some mx function to cast it to the correct classID. This meets my original intent, but I haven't found such a mx function. I could probably just destroy the field's mxArray and then mxCreate*() it again with the correct classID, after having stored a copy of the data and cast it as needed ... but then I might as well go with solution #2, unless I really do need that mxArray structure to match the C++ structure type by type.

You could deep copy the entire struct first using mxDuplicateArray and then piecemeal handle the field elements you want to change, but to avoid that deep copy of everything up front you would have to resort to unofficial undocumented mex API routines. E.g., a scheme to avoid the deep copy of everything up front might be as follows:

1) Unshare the struct array using undocumented methods, meaning you create a new struct array that has the same mxArray * data elements as the original, but with the reference count of each field element bumped up by 1. Note that there are no official API functions for doing this, but it can be done.

2) Then for each field element you need to change, create the copy in the new data type and put it into the struct array to replace the original field element (mxDestroyArray'ing the original first).


James Tursa

Subject: how to change class of mxArray?

From: Bruce Elliott

Date: 16 Feb, 2014 19:30:07

Message: 3 of 10

"James Tursa" wrote in message <ldooeg$s0v$1@newscl01ah.mathworks.com>...
> "Bruce Elliott" <bruce.elliott@jhuapl.nospam.edu> wrote in message <ldn00o$nj6$1@newscl01ah.mathworks.com>...
<... snip ...>
> > 2. I can define the mxArray structure so that its numeric fields all have classID mxDOUBLE_CLASS, and then cast them to the appropriate C++ type when I create the corresponding C++ structure. The mxArray structure will no longer match the C++ structure by type, but that might not be so important.
>
> Not sure what you mean by this. How can you *define* the fields to have double class? Isn't that a user input per your description?
>
Sorry - what I meant to say was that whenever I create an mxArray structure and copy its data from a C++ structure I could set all the numeric fields to be of class mxDOUBLE_CLASS. Any such structures in the MATLAB workspace (whether created there or received from MEX file) would have doubles for numeric fields.

Then, whenever I copy a mxArray structure to a C++ structure, in my code I would *assume* that the mxArray numeric data is all doubles and cast them to float or int as the C++ structure requires.

That avoids the problem I have right now, which is that my code is assuming a certain type for each numeric field, which is correct if the structure has not been changed since it was first created, but will be incorrect if the user set some value, changing the type to double.


> > 3. I can have the MEX function check the classID of each field in the input mxArray structure, and if it is not what it should be, call some mx function to cast it to the correct classID. This meets my original intent, but I haven't found such a mx function. I could probably just destroy the field's mxArray and then mxCreate*() it again with the correct classID, after having stored a copy of the data and cast it as needed ... but then I might as well go with solution #2, unless I really do need that mxArray structure to match the C++ structure type by type.
 
> You could deep copy the entire struct first using mxDuplicateArray and then piecemeal handle the field elements you want to change, but to avoid that deep copy of everything up front you would have to resort to unofficial undocumented mex API routines. E.g., a scheme to avoid the deep copy of everything up front might be as follows:
>
> 1) Unshare the struct array using undocumented methods, meaning you create a new struct array that has the same mxArray * data elements as the original, but with the reference count of each field element bumped up by 1. Note that there are no official API functions for doing this, but it can be done.
>
> 2) Then for each field element you need to change, create the copy in the new data type and put it into the struct array to replace the original field element (mxDestroyArray'ing the original first).
>
>
> James Tursa

I don't think these latter options will necessary. They all seem to introduce a certain degree of complexity only for the sake of allowing me to set the data of new mxArray structs using the same types as the source C++ structs - but really there is no important reason for this.

These arrays will not be especially large (array sizes on the order of hundreds of values), so I don't think storage is an issue. The major advantage I see for consistent typing is that it's easier to copy arrays of data using memcopy. If I'm copying an array of doubles to an array of ints, then I believe I have no choice but to do so element-by-element in explicit loops - is that correct?

In other words - if there is no way to avoid data sometimes coming from MATLAB as doubles because the user set the data there, then I will have no choice but to read it as doubles and then cast it to float or int. It doesn't matter if I first created the mxArray struct with all doubles or if I use some logic to "catch" any that have been converted to doubles - either way I'll have to recast any doubles that came from MATLAB, and I don't see a way to avoid that.

(Note: the ideal solution would be a way to "fix" the types in MATLAB, so that if the user sets an integer value to "3", it isn't automatically converted to a double. I'm not aware of any way to do that, however.)

I think I might as well just make it a policy that all these input/output structures will have numeric data stored as doubles (#2 above) so that I don't need special logic to check their types.

Have I missed anything?

Thanks,
Bruce

Subject: how to change class of mxArray?

From: Bruno Luong

Date: 16 Feb, 2014 22:55:07

Message: 4 of 10

Why can't you write a wrap-around MATLAB that casts whatever input type to integer as required by the MEX file before calling it?

Bruno

Subject: how to change class of mxArray?

From: Bruce Elliott

Date: 16 Feb, 2014 23:18:07

Message: 5 of 10

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <ldrfkb$b4k$1@newscl01ah.mathworks.com>...
> Why can't you write a wrap-around MATLAB that casts whatever input type to integer as required by the MEX file before calling it?
>
> Bruno
I've considered that, but the problem is that there are 100+ fields in this particular structure, so the m-file that performed the checks and recasting would have to know about the details of the structure typing, which really originates in the C++ library that I'm interfacing with. My goal has been to keep programming details like that in the C++ area (where it already exists by necessity) so that the Matlab layer is just "analyst data", i.e. details that matter to and are known by the analyst/user.

Of course, all that is to say "Yes" - your suggestion could probably be implemented, but I don't like it from the standpoint of design or future maintenance (the C++ library gets updated once a year or so, so there will be corresponding maintenance needed for these MEX files).

Subject: how to change class of mxArray?

From: James Tursa

Date: 16 Feb, 2014 23:19:06

Message: 6 of 10

"Bruce Elliott" <bruce.elliott@jhuapl.nospam.edu> wrote in message <ldr3jv$ed2$1@newscl01ah.mathworks.com>...
> "James Tursa" wrote in message <ldooeg$s0v$1@newscl01ah.mathworks.com>...
> > "Bruce Elliott" <bruce.elliott@jhuapl.nospam.edu> wrote in message <ldn00o$nj6$1@newscl01ah.mathworks.com>...
> <... snip ...>
> > > 2. I can define the mxArray structure so that its numeric fields all have classID mxDOUBLE_CLASS, and then cast them to the appropriate C++ type when I create the corresponding C++ structure. The mxArray structure will no longer match the C++ structure by type, but that might not be so important.
> >
> > Not sure what you mean by this. How can you *define* the fields to have double class? Isn't that a user input per your description?
> >
> Sorry - what I meant to say was that whenever I create an mxArray structure and copy its data from a C++ structure I could set all the numeric fields to be of class mxDOUBLE_CLASS. Any such structures in the MATLAB workspace (whether created there or received from MEX file) would have doubles for numeric fields.
>
> Then, whenever I copy a mxArray structure to a C++ structure, in my code I would *assume* that the mxArray numeric data is all doubles and cast them to float or int as the C++ structure requires.
>
> That avoids the problem I have right now, which is that my code is assuming a certain type for each numeric field, which is correct if the structure has not been changed since it was first created, but will be incorrect if the user set some value, changing the type to double.
>
>
> > > 3. I can have the MEX function check the classID of each field in the input mxArray structure, and if it is not what it should be, call some mx function to cast it to the correct classID. This meets my original intent, but I haven't found such a mx function. I could probably just destroy the field's mxArray and then mxCreate*() it again with the correct classID, after having stored a copy of the data and cast it as needed ... but then I might as well go with solution #2, unless I really do need that mxArray structure to match the C++ structure type by type.
>
> > You could deep copy the entire struct first using mxDuplicateArray and then piecemeal handle the field elements you want to change, but to avoid that deep copy of everything up front you would have to resort to unofficial undocumented mex API routines. E.g., a scheme to avoid the deep copy of everything up front might be as follows:
> >
> > 1) Unshare the struct array using undocumented methods, meaning you create a new struct array that has the same mxArray * data elements as the original, but with the reference count of each field element bumped up by 1. Note that there are no official API functions for doing this, but it can be done.
> >
> > 2) Then for each field element you need to change, create the copy in the new data type and put it into the struct array to replace the original field element (mxDestroyArray'ing the original first).
> >
> >
> > James Tursa
>
> I don't think these latter options will necessary. They all seem to introduce a certain degree of complexity only for the sake of allowing me to set the data of new mxArray structs using the same types as the source C++ structs - but really there is no important reason for this.
>
> These arrays will not be especially large (array sizes on the order of hundreds of values), so I don't think storage is an issue. The major advantage I see for consistent typing is that it's easier to copy arrays of data using memcopy. If I'm copying an array of doubles to an array of ints, then I believe I have no choice but to do so element-by-element in explicit loops - is that correct?

Yes, sort of. You can either write the loops by hand in your C-code for each and every input type you want to handle (fastest way), *OR* you can call back to MATLAB via mexCallMATLAB and have MATLAB do the conversion for you (slower way). It depends on how much code you are willing to write to get a speed advantage.

> In other words - if there is no way to avoid data sometimes coming from MATLAB as doubles because the user set the data there, then I will have no choice but to read it as doubles and then cast it to float or int. It doesn't matter if I first created the mxArray struct with all doubles or if I use some logic to "catch" any that have been converted to doubles - either way I'll have to recast any doubles that came from MATLAB, and I don't see a way to avoid that.
>
> (Note: the ideal solution would be a way to "fix" the types in MATLAB, so that if the user sets an integer value to "3", it isn't automatically converted to a double. I'm not aware of any way to do that, however.)

You could invent a custom class to do this ... i.e., the only way the user would have to set the data would be via a method, and you could control the data typing issues in that method. I would not recommend this approach, however. That's a lot of work on your part to address a simple interface type issue.

> I think I might as well just make it a policy that all these input/output structures will have numeric data stored as doubles (#2 above) so that I don't need special logic to check their types.

You can make this a policy, of course, but it makes your code unfriendly.

Since you are not working with large amounts of data, and assuming speed is not of primary importance, I would suggest considering this approach:

On Input:

- mxDuplicateArray the input (slower than the unofficial unsharing method I described earlier but uses official methods)

- Go through your fields 1-by-1 and use mexCallMATLAB to convert each field (if necessary) to the correct type. It's a one-liner code solution for you for the conversion, then a simple replacement of the field element (mxDestroyArray'ing the original)

- Then write your loops (or memcpy) to copy into the C++ struct.

On Output:

- Return everything as the C++ native type in the respective field elements, to allow memcpy for everything.


It typically doesn't matter for most users, but I will mention that memcpy on floating point variables gives an exact bit copy for signaling NaN's (they stay as signaling NaN's in the copy), whereas using an assignment in a loop element-by-element to copy the values will *change* the signaling NaN's into quiet NaN's (a different bit pattern). I.e., NaN checking and processing for floating point variables is done on assignments, but not on raw memory copies.


James Tursa

Subject: how to change class of mxArray?

From: Bruce Elliott

Date: 17 Feb, 2014 01:40:16

Message: 7 of 10

"James Tursa" wrote in message <ldrh1a$e8u$1@newscl01ah.mathworks.com>...
>... You can either write the loops by hand in your C-code for each and every input type you want to handle (fastest way), *OR* you can call back to MATLAB via mexCallMATLAB and have MATLAB do the conversion for you (slower way). It depends on how much code you are willing to write to get a speed advantage.
>
===========
I'll have to look into this - I haven't used mexCallMATLAB before. The code in question is just copying a set of input arguments to pass them to a computational routine (once), so performance is not a big concern.
===========

> >
> > (Note: the ideal solution would be a way to "fix" the types in MATLAB, so that if the user sets an integer value to "3", it isn't automatically converted to a double. I'm not aware of any way to do that, however.)
>
> You could invent a custom class to do this ... i.e., the only way the user would have to set the data would be via a method, and you could control the data typing issues in that method. I would not recommend this approach, however. That's a lot of work on your part to address a simple interface type issue.
>
===========
That's an interesting idea. My goal has been to make this as "thin" an interface between the user and the C++ library functions as I can, but on the other hand, this could end up being more of a full-blown application, in which case writing a custom class to handle the data might be worthwhile. I'll keep it in the back of my mind, anyway.
===========

> Since you are not working with large amounts of data, and assuming speed is not of primary importance, I would suggest considering this approach:
>
> On Input:
>
> - mxDuplicateArray the input (slower than the unofficial unsharing method I described earlier but uses official methods)
>
> - Go through your fields 1-by-1 and use mexCallMATLAB to convert each field (if necessary) to the correct type. It's a one-liner code solution for you for the conversion, then a simple replacement of the field element (mxDestroyArray'ing the original)
>
> - Then write your loops (or memcpy) to copy into the C++ struct.
>
> On Output:
>
> - Return everything as the C++ native type in the respective field elements, to allow memcpy for everything.
>
===========
Thanks! It looks like I'm going to have to apply some kind of "fix" to each block of code that I've written to copy all the structure field data, but this seems like a fairly small change - just one or two lines to do the conversions when needed. If the cost in execution time proves to be too great, then I'll look into more complicated methods, but this will be a good place to start.
===========

>
> It typically doesn't matter for most users, but I will mention that memcpy on floating point variables gives an exact bit copy for signaling NaN's (they stay as signaling NaN's in the copy), whereas using an assignment in a loop element-by-element to copy the values will *change* the signaling NaN's into quiet NaN's (a different bit pattern). I.e., NaN checking and processing for floating point variables is done on assignments, but not on raw memory copies.
>
===========
There should be no NaNs in any of these structures in normal use, but this is still good to know for future reference.

Thanks again for all the help,
 Bruce
===========

Subject: how to change class of mxArray?

From: Steven Lord

Date: 18 Feb, 2014 16:41:34

Message: 8 of 10


"Bruce Elliott" <bruce.elliott@jhuapl.nospam.edu> wrote in message
news:ldrgvf$e2b$1@newscl01ah.mathworks.com...
> "Bruno Luong" <b.luong@fogale.findmycountry> wrote in message
> <ldrfkb$b4k$1@newscl01ah.mathworks.com>...
>> Why can't you write a wrap-around MATLAB that casts whatever input type
>> to integer as required by the MEX file before calling it?
>>
>> Bruno
> I've considered that, but the problem is that there are 100+ fields in
> this particular structure, so the m-file that performed the checks and
> recasting would have to know about the details of the structure typing,
> which really originates in the C++ library that I'm interfacing with. My
> goal has been to keep programming details like that in the C++ area (where
> it already exists by necessity) so that the Matlab layer is just "analyst
> data", i.e. details that matter to and are known by the analyst/user.

If ALL the numeric fields in the structure should be in double precision,
use dynamic field names:

function S = convertNumericFieldsToDouble(S)
listOfFields = fieldnames(S);
for whichone = 1:length(listOfFields)
    fn = listOfFields{whichone};
    if isnumeric(S.(fn))
        S.(fn) = double(S.(fn)); % or uint64() or single() or whatever you
desire
    end
end

You could add in an "elseif isstruct(S.(fn))" case in the IF block that
recursively calls convertNumericFieldsToDouble on the substruct if you want
to recursively convert ALL the numeric data inside your struct, even if it's
in a sub-structure, to double. ISCELL would help if you also want to convert
inside cell arrays.

> Of course, all that is to say "Yes" - your suggestion could probably be
> implemented, but I don't like it from the standpoint of design or future
> maintenance (the C++ library gets updated once a year or so, so there will
> be corresponding maintenance needed for these MEX files).

You could lock down this behavior with tests, so that when the library is
updated you'll know specifically the behavior that changed.

http://www.mathworks.com/help/matlab/matlab-unit-test-framework.html

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: how to change class of mxArray?

From: Bruce Elliott

Date: 18 Feb, 2014 18:46:08

Message: 9 of 10

"Steven Lord" <Steven_Lord@mathworks.com> wrote in message <le02ft$i0o$1@newscl01ah.mathworks.com>...
> If ALL the numeric fields in the structure should be in double precision,
> use dynamic field names:
> <snip>

I wish I could, but the structure includes all the inputs to the calculational routine, which include chars, ints, and floats of varying dimensions and sizes. Since C++ doesn't support dynamic field names, I have no choice but go through all of them individually to copy them, essentially repeating the same blocks of code over and over, which means I might as well do the appropriate casting in each block of code.

Thanks for the suggestions, though.

Bruce

Subject: how to change class of mxArray?

From: Bruce Elliott

Date: 18 Feb, 2014 19:06:08

Message: 10 of 10

"Bruce Elliott" <bruce.elliott@jhuapl.nospam.edu> wrote in message <ldrpa0$2pf$1@newscl01ah.mathworks.com>...
> "James Tursa" wrote in message <ldrh1a$e8u$1@newscl01ah.mathworks.com>...
> >... You can either write the loops by hand in your C-code for each and every input type you want to handle (fastest way), *OR* you can call back to MATLAB via mexCallMATLAB and have MATLAB do the conversion for you (slower way). It depends on how much code you are willing to write to get a speed advantage.
> >
> ===========
> I'll have to look into this - I haven't used mexCallMATLAB before. The code in question is just copying a set of input arguments to pass them to a computational routine (once), so performance is not a big concern.
> ===========
>

I'm attempting to use mexCallMATLAB as suggested, but I'm getting a compile error. I reported this in a new newsgroup message, however, since it seems like a different issue than the main one for this thread.

- Bruce

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us