Main Content

When you invoke a method on a generated class, the input arguments
received by the method must be in the MATLAB^{®} internal array format.
You can either convert them yourself within the calling program, or
pass the arguments as Java^{®} data types, which are then automatically
converted by the calling mechanism.

To convert them yourself, use instances of the `MWArray`

classes;
in this case you are using *manual conversion*.
Storing your data using the classes and data types defined in the Java language
means that you are relying on *automatic conversion*.
Most likely, you will use a combination of manual and automatic conversion.

To manually convert to one of the standard MATLAB data
types, use the `MWArray`

data conversion classes
provided by the compiler. For class reference and usage information,
see the `com.mathworks.toolbox.javabuilder`

package.

The Magic Square example (Integrate a Java Package into an Application)
exemplifies manual conversion. The following code fragment from that
program shows a `java.lang.Double`

argument that
is converted to an `MWNumericArray`

type that can
be used by the MATLAB function without further conversion:

n = new MWNumericArray(Double.valueOf(args[0]), MWClassID.DOUBLE); theMagic = new Class1(); result = theMagic.makesqr(1, n);

**Passing an MWArray. **This example constructs an `MWNumericArray`

of
type `MWClassID.DOUBLE`

. The call to `myprimes`

passes
the number of outputs, `1`

, and the `MWNumericArray`

, `x`

:

x = new MWNumericArray(n, MWClassID.DOUBLE); cls = new myclass(); y = cls.myprimes(1, x);

The Java bridge converts the `MWNumericArray`

object
to a MATLAB scalar `double`

to pass to the MATLAB function.

When passing an argument only a small number of times, it is usually just as efficient to pass a primitive Java type or object. In this case, the calling mechanism converts the data for you into an equivalent MATLAB type.

For instance, either of the following Java types would
be automatically converted to the MATLAB `double`

type:

A Java

`double`

primitiveAn object of class

`java.lang.Double`

For reference information about data conversion (tables showing each Java type along with its converted MATLAB type, and each MATLAB type with its converted Java type), see Rules for Data Conversion Between Java and MATLAB.

When calling the `makesqr`

method used in the `getmagic`

application,
you could construct an object of type `MWNumericArray`

.
Doing so would be an example of manual conversion. Instead, you could
rely on automatic conversion, as shown in the following code fragment:

result = M.makesqr(1, arg[0]);

In this case, a Java `double`

is passed
as `arg[0]`

.

Here is another example:

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

In this Java statement, the third argument is of type `java.lang.Double`

.
According to conversion rules, the `java.lang.Double`

automatically
converts to a MATLAB 1-by-1 `double`

array.

The example calls the `myprimes`

method with
two arguments. The first specifies the number of arguments to return.
The second is an object of class `java.lang.Double`

that
passes the one data input to `myprimes`

.

cls = new myclass(); y = cls.myprimes(1, new Double((double)n));

This second argument is converted to a MATLAB 1-by-1 `double`

array,
as required by the MATLAB function. This is the default conversion
rule for `java.lang.Double`

.

This example constructs an `MWNumericArray`

of
type `MWClassID.DOUBLE`

. The call to `myprimes`

passes
the number of outputs, `1`

, and the `MWNumericArray`

, `x`

.

x = new MWNumericArray(n, MWClassID.DOUBLE); cls = new myclass(); y = cls.myprimes(1, x);

The compiler converts the `MWNumericArray`

object
to a MATLAB scalar `double`

to pass to the MATLAB function.

The conversion rules apply not only when calling your own methods,
but also when calling constructors and factory methods belonging to
the `MWArray`

classes.

For example, the following code fragment calls the constructor
for the `MWNumericArray`

class with a Java `double`

as
the input argument:

double Adata = 24; MWNumericArray A = new MWnumericArray(Adata); System.out.println("Array A is of type " + A.classID());

The compiler converts the input argument to an instance of `MWNumericArray`

,
with a `ClassID`

property of `MWClassID.DOUBLE`

.
This `MWNumericArray`

object is the equivalent of
a MATLAB 1-by-1 `double`

array.

When you run this example, the result is as follows:

Array A is of type double

When calling an `MWArray`

class method constructor,
supplying a specific data type causes the MATLAB
Compiler SDK™ product
to convert to that type instead of the default.

For example, in the following code fragment, the code specifies
that `A`

should be constructed as a MATLAB 1-by-1
16-bit integer array:

double Adata = 24; MWNumericArray A = new MWnumericArray(Adata, MWClassID.INT16); System.out.println("Array A is of type " + A.classID());

When you run this example, the result is as follows:

Array A is of type int16

So far, the examples have not used MATLAB functions that
have `varargin`

or `varargout`

arguments.
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`

argument, which means that
the caller can specify any number of inputs to the function. The result
is returned as a scalar `double`

.

The MATLAB Compiler SDK product generates a Java interface to this function as follows:

/* mlx interface - List version*/ public void mysum(List lhs, List rhs) throws MWException { (implementation omitted) } /* mlx interface - Array version*/ public void mysum(Object[] lhs, Object[] rhs) throws MWException { (implementation omitted) } /* standard interface - no inputs */ public Object[] mysum(int nargout) throws MWException { (implementation omitted) } /* standard interface - variable inputs */ public Object[] mysum(int nargout, Object varargin) throws MWException { (implementation omitted) }

In all cases, the `varargin`

argument is passed
as type `Object`

. This lets you provide any number
of inputs in the form of an array of Object, that is `Object[]`

,
and the contents of this array are passed to the compiled MATLAB function
in the order in which they appear in the array. Here is an example
of how you might use the `mysum`

method in a Java program:

public double getsum(double[] vals) throws MWException { myclass cls = null; Object[] x = {vals}; Object[] y = null; try { cls = new myclass(); y = cls.mysum(1, x); return ((MWNumericArray)y[0]).getDouble(1); } finally { MWArray.disposeArray(y); if (cls != null) cls.dispose(); } }

In this example, an `Object`

array of length
1 is created and initialized with a reference to the supplied `double`

array.
This argument is passed to the `mysum`

method. The
result is known to be a scalar `double`

, so the code
returns this `double`

value with the statement:

return ((MWNumericArray)y[0]).getDouble(1);

Cast the return value to `MWNumericArray`

and
invoke the `getDouble(int)`

method to return the
first element in the array as a primitive `double`

value.

**Pass Array Inputs. **The next example performs a more general calculation:

public double getsum(Object[] vals) throws MWException { myclass cls = null; Object[] x = null; Object[] y = null; try { x = new Object[vals.length]; for (int i = 0; i < vals.length; i++) x[i] = new MWNumericArray(vals[i], MWClassID.DOUBLE); cls = new myclass(); y = cls.mysum(1, x); return ((MWNumericArray)y[0]).getDouble(1); } finally { MWArray.disposeArray(x); MWArray.disposeArray(y); if (cls != null) cls.dispose(); } }

This version of `getsum`

takes an array of `Object`

as
input and converts each value to a `double`

array.
The list of `double`

arrays is then passed to the `mysum`

function,
where it calculates the total sum of each input array.

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 `i`

th vector is equal
to `i`

. The MATLAB
Compiler™ product generates
a Java interface to this function as follows:

/* mlx interface - List version */ public void randvectors(List lhs, List rhs) throws MWException { (implementation omitted) } /* mlx interface - Array version */ public void randvectors(Object[] lhs, Object[] rhs) throws MWException { (implementation omitted) } /* Standard interface - no inputs*/ public Object[] randvectors(int nargout) throws MWException { (implementation omitted) }

**Pass Optional Arguments with the Standard Interface. **Here is one way to use the `randvectors`

method
in a Java program:

public double[][] getrandvectors(int n) throws MWException { myclass cls = null; Object[] y = null; try { cls = new myclass(); y = cls.randvectors(n); double[][] ret = new double[y.length][]; for (int i = 0; i < y.length; i++) ret[i] = (double[])((MWArray)y[i]).getData(); return ret; } finally { MWArray.disposeArray(y); if (cls != null) cls.dispose(); } }

The `getrandvectors`

method returns a two-dimensional `double`

array
with a triangular structure. The length of the `i`

th
row equals `i`

. Such arrays are commonly referred
to as *jagged* arrays. Jagged arrays are easily
supported in Java because a Java matrix is just an array
of arrays.

The previous examples used the fact that you knew the type and dimensionality of the output argument. In the case that this information is unknown, or can vary (as is possible in MATLAB programming), the code that calls the method might need to query the type and dimensionality of the output arguments.

There are several ways to do this. Do one of the following:

Use reflection support in the Java language to query any object for its type.

Use several methods provided by the

`MWArray`

class to query information about the underlying MATLAB array.Coercing to a specific type using the

`to`

`Type`

`Array`

methods.

This code sample calls the `myprimes`

method,
and then determines the type using reflection. The example assumes
that the output is returned as a numeric matrix but the exact numeric
type is unknown.

public void getprimes(int n) throws MWException { myclass cls = null; Object[] y = null; try { cls = new myclass(); y = cls.myprimes(1, new Double((double)n)); Object a = ((MWArray)y[0]).toArray(); if (a instanceof double[][]) { double[][] x = (double[][])a; /* (do something with x...) */ } else if (a instanceof float[][]) { float[][] x = (float[][])a; /* (do something with x...) */ } else if (a instanceof int[][]) { int[][] x = (int[][])a; /* (do something with x...) */ } else if (a instanceof long[][]) { long[][] x = (long[][])a; /* (do something with x...) */ } else if (a instanceof short[][]) { short[][] x = (short[][])a; /* (do something with x...) */ } else if (a instanceof byte[][]) { byte[][] x = (byte[][])a; /* (do something with x...) */ } else { throw new MWException( "Bad type returned from myprimes"); } }

This example uses the `toArray`

method to return
a Java primitive array representing the underlying MATLAB array.
The `toArray`

method works just like `getData`

in
the previous examples, except that the returned array has the same
dimensionality as the underlying MATLAB array.

The next example uses the `MWArray`

`classID`

method
to determine the type of the underlying MATLAB array. It also
checks the dimensionality by calling `numberOfDimensions`

.
If any unexpected information is returned, an exception is thrown.
It then checks the `MWClassID`

and processes the
array accordingly.

public void getprimes(int n) throws MWException { myclass cls = null; Object[] y = null; try { cls = new myclass(); y = cls.myprimes(1, new Double((double)n)); MWClassID clsid = ((MWArray)y[0]).classID(); if (!clsid.isNumeric() || ((MWArray)y[0]).numberOfDimensions() != 2) { throw new MWException("Bad type returned from myprimes"); } if (clsid == MWClassID.DOUBLE) { double[][] x = (double[][])((MWArray)y[0]).toArray(); /* (do something with x...) */ } else if (clsid == MWClassID.SINGLE) { float[][] x = (float[][])((MWArray)y[0]).toArray(); /* (do something with x...) */ } else if (clsid == MWClassID.INT32 || clsid == MWClassID.UINT32) { int[][] x = (int[][])((MWArray)y[0]).toArray(); /* (do something with x...) */ } else if (clsid == MWClassID.INT64 || clsid == MWClassID.UINT64) { long[][] x = (long[][])((MWArray)y[0]).toArray(); /* (do something with x...) */ } else if (clsid == MWClassID.INT16 || clsid == MWClassID.UINT16) { short[][] x = (short[][])((MWArray)y[0]).toArray(); /* (do something with x...) */ } else if (clsid == MWClassID.INT8 || clsid == MWClassID.UINT8) { byte[][] x = (byte[][])((MWArray)y[0]).toArray(); /* (do something with x...) */ } } finally { MWArray.disposeArray(y); if (cls != null) cls.dispose(); } }

The next example demonstrates how you can coerce or force data
to a specified numeric type by invoking any of the to* Type*Array
methods. These methods return an array of Java elements of the
type specified in the name of the called method. The data is coerced
or forced to the primitive type specified in the method name. Note
that when using these methods, data will be truncated when needed
to allow conformance to the specified data type.

Object results = null; try { // call a compiled MATLAB function results = myobject.myfunction(2); // first output is known to be a numeric matrix MWArray resultA = (MWNumericArray) results[0]; double[][] a = (double[][]) resultA.toDoubleArray(); // second output is known to be // a 3-dimensional numeric array MWArray resultB = (MWNumericArray) results[1]; int[][][] b = (int[][][]) resultB.toIntArray(); } finally { MWArray.disposeArray(results); }