Documentation

Data Conversion Between .NET and MATLAB

There are many instances when you may need to convert various native data types to types compatible with MATLAB®. Use this section as a guideline to performing some of these basic tasks.

See Rules for Data Conversion Between .NET and MATLAB for a complete list of rules to convert between .NET and MATLAB Compiler SDK™ data types.

Managing Data Conversion Issues with MATLAB Compiler SDK .NET Data Conversion Classes

To support data conversion between managed types and MATLAB types, MATLAB Compiler SDK provides a set of data conversion classes derived from the abstract class, MWArray.

The MWArray data conversion classes allow you to pass most native .NET value types as parameters directly without using explicit data conversion. There is an implicit cast operator for most native numeric and string types that will convert the native type to the appropriate MATLAB array.

When you invoke a method on a component, the input and output parameters are a derived type of MWArray. To pass parameters, you can either instantiate one of the MWArray subclasses explicitly, or, in many cases, pass the parameters as a managed data type and rely on the implicit data conversion feature of MATLAB Compiler SDK.

Overview of Classes and Methods in the Data Conversion Class Hierarchy

To support MATLAB data types, the MATLAB Compiler SDK product provides the MWArray data conversion classes in the MWArray assembly. You reference this assembly in your managed application to convert native arrays to MATLAB arrays and vice versa.

See the MWArray API documentation for full details on the classes and methods provided.

The data conversion classes are built as a class hierarchy that represents the major MATLAB array types.

Note

For information about these data conversion classes, see the MATLAB MWArray Class Library Reference, available in the matlabroot\help\dotnetbuilder\MWArrayAPI folder, where matlabroot represents your MATLAB installation folder

The root of the hierarchy is the MWArray abstract class. The MWArray class has the following subclasses representing the major MATLAB types: MWNumericArray, MWLogicalArray, MWCharArray, MWCellArray, and MWStructArray.

MWArray and its derived classes provide the following functionality:

  • Constructors and destructors to instantiate and dispose of MATLAB arrays

  • Properties to get and set the array data

  • Indexers to support a subset of MATLAB array indexing

  • Implicit and explicit data conversion operators

  • General methods

Automatic Casting to MATLAB Types

Note

Because the conversion process is typically automatic, you do not need to understand the conversion process to pass and return arguments with MATLAB Compiler SDK .NET assemblies.

In most instances, if a native .NET primitive or array is used as an input parameter in a C# program, the MATLAB Compiler SDK product transparently converts it to an instance of the appropriate MWArray class before it is passed on to the generated method. The MATLAB Compiler SDK product can convert most CLS-compliant string, numeric type, or multidimensional array of these types to an appropriate MWArray type.

Note

This conversion is transparent in C# applications, but might require an explicit casting operator in other languages, for example, op_implicit in Visual Basic®.

Here is an example. Consider the .NET statement:

result = theFourier.plotfft(3, data, interval);

In this statement the third argument, namely interval, is of the .NET native type System.Double. The MATLAB Compiler SDK product casts this argument to a MATLAB 1-by-1 double MWNumericArray type (which is a wrapper class containing a MATLAB double array).

See Rules for Data Conversion Between .NET and MATLAB for a list of all the data types that are supported along with their equivalent types in the MATLAB product.

Note

There are some data types commonly used in the MATLAB product that are not available as native .NET types. Examples are cell arrays, structure arrays, and arrays of complex numbers. Represent these array types as instances of MWCellArray, MWStructArray, and MWNumericArray, respectively.

Multidimensional Array Processing in MATLAB and .NET

MATLAB and .NET implement different indexing strategies for multidimensional arrays. When you create a variable of type MWNumericArray, MATLAB automatically creates an equivalent array, using its own internal indexing. For example, MATLAB indexes using this schema:

(row column page1 page2 ...)
while .NET indexes as follows:
(... page2 page1 row column) 

Given the multi-dimensional MATLAB myarr:

>> myarr(:,:,1) = [1, 2, 3; 4, 5, 6]; 
>> myarr(:,:,2) = [7, 8, 9; 10, 11, 12]; 
>> myarr 

myarr(:,:,1) = 

     1     2     3 
     4     5     6 


myarr(:,:,2) = 

     7     8     9 
    10    11    12 

You would code this equivalent in .NET:

double[,,] myarr = {{{1.000000, 2.000000, 3.000000}, 
{4.000000, 5.000000, 6.000000}}, {{7.000000, 8.000000, 
9.000000}, {10.000000, 11.000000, 12.000000}}}; 

Manual Data Conversion from Native Types to MATLAB Types

Native Data Conversion

The MATLAB Compiler SDK product provides MATLAB array classes in order to facilitate data conversion between native data and compiled MATLAB functions.

This example explicitly creates a numeric constant using the constructor for the MWNumericArray class with a System.Int32 argument. This variable can then be passed to one of the generated .NET methods.

int data = 24; 
MWNumericArray array = new MWNumericArray(data);
Console.WriteLine("Array is of type " + array.NumericType);

When you run this example, the results are:

Array is of type double 

In this example, the native integer (int data) is converted to an MWNumericArray containing a 1-by-1 MATLAB double array, which is the default MATLAB type.

Tip

To preserve the integer type, use the MWNumericArray constructor that provides the ability to control the automatic conversion.

MWNumericArray array = new MWNumericArray(data, false);

The MATLAB Compiler SDK product does not support some MATLAB array types because they are not CLS-compliant. See Unsupported MATLAB Array Types for a list of the unsupported types.

For more information about the concepts involved in data conversion, see Managing Data Conversion Issues with MATLAB Compiler SDK .NET Data Conversion Classes.

Type Specification

If you want to create a MATLAB numeric array of a specific type, set the optional makeDouble argument to False. The native type then determines the type of the MATLAB array that is created.

Here, the code specifies that the array should be constructed as a MATLAB 1-by-1 16-bit integer array:

short data = 24; 
MWNumericArray array = new MWNumericArray(data, false);
Console.WriteLine("Array is of type " + array.NumericType);

Running this example produces the following results:

Array is of type int16 

Optional Argument Specification

In the MATLAB product, varargin and varargout are used to specify arguments that are not required. Consider the following MATLAB function:

function y = mysum(varargin)
y = sum([varargin{:}]);

This function returns the sum of the inputs. The inputs are provided as a varargin, which means that the caller can specify any number of inputs to the function. The result is returned as a scalar double array.

For the mysum function, the MATLAB Compiler SDK product generates the following interfaces:

// Single output interfaces
public MWArray mysum()
public MWArray mysum(params MWArray[] varargin)
// Standard interface
public MWArray[] mysum(int numArgsOut)
public MWArray[] mysum(int numArgsOut, 
           params MWArray[] varargin)
// feval interface
public void mysum(int numArgsOut, ref MWArray ArgsOut,  
						params MWArray[] varargin)

The varargin arguments can be passed as either an MWArray[], or as a list of explicit input arguments. (In C#, the params modifier for a method argument specifies that a method accepts any number of parameters of the specific type.) Using params allows your code to add any number of optional inputs to the encapsulated MATLAB function.

Here is an example of how you might use the single output interface of the mysum method in a .NET application:

static void Main(string[] args]
{
MWArray sum= null;
MySumClass mySumClass = null;
try
  {
   mySumClass= new MySumClass();
   sum= mySumClass.mysum((double)2, 4);
   Console.WriteLine("Sum= {0}", sum);
   sum= mySumClass.mysum((double)2, 4, 6, 8);
   Console.WriteLine("Sum= {0}", sum);
  }
}

The number of input arguments can vary.

Note

For this particular signature, you must explicitly cast the first argument to MWArray or a type other than integer. Doing this distinguishes the signature from the method signature, which takes an integer as the first argument. If the first argument is not explicitly cast to MWArray or as a type other than integer, the argument can be mistaken as representing the number of output arguments.

 Pass Input Arguments

 Construct a Single Input Argument

 Pass a Native .NET Type

 Use the feval Interface

Pass a Variable Number of Outputs

When present, varargout arguments are handled in the same way that varargin arguments are handled. Consider the following MATLAB function:

function varargout = randvectors()
for i=1:nargout
   varargout{i} = rand(1, i);
end

This function returns a list of random double vectors such that the length of the ith vector is equal to i. The MATLAB Compiler SDK product generates a .NET interface to this function as follows:

public void randvectors()
public MWArray[] randvectors(int numArgsOut)
public void randvectors(int numArgsOut, ref MWArray[] varargout)

 Usage Example

Return Value Handling

The previous examples show guidelines to use if you know the type and dimensionality of the output argument. Sometimes, in MATLAB programming, this information is unknown, or can vary. In this case, the code that calls the method might need to query the type and dimensionality of the output arguments.

There are two ways to make the query:

  • Use .NET reflection to query any object for its type.

  • Use any of several methods provided by the MWArray class to query information about the underlying MATLAB array.

.NET Reflection

You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object. You can then invoke the type's methods or access its fields and properties. See the MSDN Library for more information about reflection.

The following code sample calls the myprimes method, and then determines the type using reflection. The example assumes that the output is returned as a numeric vector array but the exact numeric type is unknown.

public void GetPrimes(int n)
{
	MWArray primes= null;
	MyPrimesClass myPrimesClass= null;
	try
	 {
		myPrimesClass= new MyPrimesClass();
		primes= myPrimesClass.myprimes((double)n);
		Array primesArray= ((MWNumericArray)primes).
			ToVector(MWArrayComponent.Real);
		if (primesArray is double[])
		 {
			double[] doubleArray= (double[])primesArray;
			/* Do something with doubleArray . . . */
		 }
		else if (primesArray is float[])
		 {
			float[] floatArray= (float[])primesArray;
			/* Do something with floatArray . . . */
		 }
		else if (primesArray is int[])
		 {
			int[] intArray= (int[])primesArray;
			/*Do something with intArray . . . */
		 }
		else if (primesArray is long[])
		 {
			long[] longArray= (long[])primesArray;
			/*Do something with longArray . . . */
		 }
		else if (primesArray is short[])
		 {
			short[] shortArray= (short[])primesArray;
			/*Do something with shortArray . . . */
		 }
		else if (primesArray is byte[])
		 {
			byte[] byteArray= (byte[])primesArray;
			/*Do something with byteArray . . . */
		 }
		else
		 {
			throw new ApplicationException("
				Bad type returned from myprimes");
		 }
	 }
}

The example uses the toVector method to return a .NET primitive array (primesArray), which represents the underlying MATLAB array. See the following code fragment from the example:

primes= myPrimesClass.myprimes((double)n);
		Array primesArray= ((MWNumericArray)primes).
			ToVector(MWArrayComponent.Real);

Note

The toVector is a method of the MWNumericArray class. It returns a copy of the array component in column major order. The type of the array elements is determined by the data type of the numeric array.

MWArray Query

The next example uses the MWNumericArray NumericType method, along with MWNumericType enumeration to determine the type of the underlying MATLAB array. See the switch (numericType) statement.

public void GetPrimes(int n)
{
	MWArray primes= null;
	MyPrimesClass myPrimesClass= null;
	try
	 {
		myPrimesClass= new MyPrimesClass();
		primes= myPrimesClass.myprimes((double)n);
		if ((!primes.IsNumericArray) || (2 !=
			primes.NumberofDimensions))
		 {
			throw new ApplicationException("Bad type returned
				by mwprimes");
		 }
		MWNumericArray _primes= (MWNumericArray)primes;
		MWNumericType numericType= _primes.NumericType;
		Array primesArray= _primes.ToVector(
			MWArrayComponent.Real);
		switch (numericType)
		 {
			case MWNumericType.Double:
			 {
				double[] doubleArray= (double[])primesArray;
				/* (Do something with doubleArray . . .) */
				break;
			 }
			case MWNumericType.Single:
			 {
				float[] floatArray= (float[])primesArray;
				/* (Do something with floatArray . . .) */
				break;
			 }
			case MWNumericType.Int32:
			 {
				int[] intArray= (int[])primesArray;
				/* (Do something with intArray . . .) */
				break;
			 }
			case MWNumericType.Int64:
			 {
				long[] longArray= (long[])primesArray;
				/* (Do something with longArray . . .) */
				break;
			 }
			case MWNumericType.Int16:
			 {
				short[] shortArray= (short[])primesArray;
				/* (Do something with shortArray . . .) */
				break;
			 }
			case MWNumericType.UInt8:
			 {
				byte[] byteArray= (byte[])primesArray;
				/* (Do something with byteArray . . .) */
				break;
			 }
			default:
			 {
				throw new ApplicationException("Bad type returned 
					by myprimes");
			 }
		 }
	 }
}

The code in the example also checks the dimensionality by calling NumberOfDimensions; see the following code fragment:

if ((!primes.IsNumericArray) || (2 !=
			primes.NumberofDimensions))
		 {
			throw new ApplicationException("Bad type returned
				by mwprimes"); 
      }

This call throws an exception if the array is not numeric and of the proper dimension.