Use Function Argument Validation to Specify Entry-Point Input Types - MATLAB & Simulink (original) (raw)

Unlike MATLAB®, which is a dynamically typed language, C and C++ are statically typed. Therefore, to generate C/C++ code, you must specify the types of the input variables to the MATLAB entry-point function. The code generator uses these specifications to infer the types of all variables in the generated code. One of the ways to specify input types is by using function argument validation (arguments blocks) in your MATLAB code. Alternatively, you can specify input types by using the codegen command with -args at the command line, by using the MATLAB Coder™ app, or by using assert statements in your MATLAB code. For an overview of these methods of input type specification, see Specify Types of Entry-Point Function Inputs.

Specify Input Types Using arguments Blocks

You can specify the class, size, and other aspects of input variables in your entry-point MATLAB function by using arguments blocks to perform function argument validation.

Pseudocode snippet demonstrating the syntax of the arguments block

Specifying input types using arguments blocks supports:

Input type specification using arguments blocks requires explicit specification of input argument size and class. Specify argument size in the argument declaration. To specify argument class, use one of these methods:

For example, construct an entry-point MATLAB function myMultiply, which returns the product of two input arguments, a and b. Use anarguments block to declare that a andb are unbounded row vectors of real double values. Specify the sizes of a and b in the argument declaration. Specify the class of a in the argument declaration and specify the class of b using themustBeA validator

function y = myMultiply(a,b) %#codegen arguments a (1,:) double b (1,:) {mustBeA(b, "double")} end y = a*b; end

At the MATLAB command line, run this codegen command.

The code generator uses the arguments block to assign types to all variables in the myMultiply function, without further input-type specification.

Instruct the Code Generator to Use arguments Block for Input-Type Specification

To instruct the code generator to determine input types using thearguments block, use one of these approaches:

When to Use arguments Blocks for Input-Type Specification

Consider using arguments blocks for input-type specification when one or more of these statements are true:

Advantages of Input-Type Specification Using Function Argument Validation

Input-type specification using function argument validation:

Limitations of Input-Type Specification Using Function Argument Validation

Input-type specification using function argument validation:

Use User-Written MATLAB Classes in arguments Blocks

Suppose that one of your entry-point input arguments is an instance ofMyClass, a MATLAB class that you wrote. If you use function argument validation (anarguments block) to specify input types, you must also use property validation (a properties block) to specify the types of all properties of MyClass.

For user-written MATLAB class inputs specified using function argument validation, property validation supports:

To specify that a property contains sparse data by using the validator mustBeSparse, explicitly assign a default sparse value to the property. This value is ignored during input-type specification, but is required to correctly create the property in the generated code. For example, create class MyClass and specify thatMyClass property prop contains sparse data. Explicitly assign prop a default sparse value.

classdef MyClass properties prop (1024,1024) double {mustBeSparse} = sparse(zeros(1024,1024)) end end

Input type specification for user-written MATLAB classes using properties blocks requires explicit specification of property size and class. Specify property size in the property declaration. To specify property class, use one of these methods:

Code generation does not support property validation usingcoder.specifyAsGPU for user-written MATLAB class inputs specified using an arguments block.

Incompatibility with MATLAB for Size and Type Coercion

In MATLAB execution, the arguments block performs size and type coercion. This means that the arguments block accepts all inputs that are compatible with or convertible to the sizes and types specified in the argument declaration. See Compatible Array Sizes for Basic Operations and Implicit Class Conversion.

For example, create the function multiplyVector. Use anarguments block to specify that input variablex is a 2-element row vector of doubles.

function y = multiplyVector(x) arguments x (1,2) double end y = x * 2; end

In MATLAB execution, multiplyVector accepts 2-element row vectors, 2-element column vectors, and scalars because 2-element column vectors and scalars are compatible with 2-element row vectors. MATLAB also implicitly converts arrays of different types into the specified type. For example, if you pass the string array ["1" "2"] tomultiplyVector, MATLAB converts the string array to the numeric array [1 2] and returns [2 4].

However, when you generate code for the entry-point functionmultiplyVector, the generated code performs neither size nor type coercion on the value passed to the entry-point function. For example, if you generate a MEX function from multiplyVector, the generated MEX functionmultiplyVector_mex will accept only a 2-element row vector of doubles. If you pass multiplyVector_mex a 2-element column vector or a scalar, the MEX function will produce a run-time error. If you passmultiplyVector_mex a vector containing values that are not doubles, the MEX function will produce a run-time error.

To work around this limitation and generate code that performs size coercion on input values, construct a wrapper entry-point function that calls your original entry-point function. Construct the wrapper function such that it accepts all inputs that are compatible with the size specified in your original entry-point function. The original entry-point function now performs coercion on the input values. This workaround succeeds becausearguments blocks that are not in entry-point functions do perform size and type coercion in the generated code. For example, create the functionwrapper, which calls the original entry-point functionmultiplyVector, and generate code for wrapper. The generated MEX function wrapper_mex accepts 2-element row vectors, 2-element column vectors, and scalars.

function out = wrapper(in) arguments in (:,:) double end out = multiplyVector(in); end

function y = multiplyVector(x) arguments x (1,2) double end y = x * 2; end

To perform both size and type coercion, you cannot use an arguments block to specify entry-point function input types. Instead, you must use thecodegen function with -args to generate code that supports multiple signatures. See Generate Code for Functions with Multiple Signatures.

Examples

Use the arguments Block to Specify String and Character Vector Input

Write a function that concatenates a character vector and a string scalar to form a string scalar. Use the arguments block to specify the argumentcharVec as an unbounded character vector and the argumentstrScalar as a string scalar.

function out = myString(charVec, strScalar) arguments charVec (1,:) char strScalar (1,1) string end out = charVec + strScalar; end

Generate C/C++ code for this function at the command line without further specification of input types.

Code generation successful.

Confirm that the generated MEX file produces the expected output.

joinedString = myString_mex('hello ',"world")

joinedString =

"hello world"

Use arguments Block to Specify Enumeration Input

Create an enumeration class for selected fruits, with values corresponding to the milligrams of vitamin C per serving:

classdef FruitClass < uint32 enumeration Orange (70) Kiwi (64) Strawberry (49) Grapefruit (39) Cantalope (29) Tomato (17) Pepper (95) end end

Write a function that, given a FruitClass input and atarget value representing milligrams of vitamin C, returns the number of servings of fruit that you must eat to achieve the target.

function out = calculateIntake(fruit, target) %#codegen arguments fruit (1,1) FruitClass target (1,1) double end fruitVal = double(fruit); out = target/fruitVal; end

Generate code for the calculateIntake function at the command line without further specification of input types.

Code generation successful.

Confirm that the generated MEX file produces the expected output.

servings = calculateIntake_mex(FruitClass.Strawberry,1000);

See Also

arguments | assert | codegen

Topics