メインコンテンツ

Resolve Error: Unable to Produce Column Vector from Scalar

Issue

When you assign a value to the end+1 element of a scalar, MATLAB® produces a two-element row vector. However, if you generate code for a function that uses (end+1) to grow an array and specify that the array is a variable-length column vector, the generated MEX function produces this error if the array is a scalar at run time:

Unable to produce column vector from scalar by using end+1 indexing.

Note

If you use {end+1} to grow a cell array that is a variable-size column vector at code generation time and a scalar at run time, the generated MEX function does not produce an error. Instead, it produces a two-element column vector, which means that the output of the generated code differs from the MATLAB output. See Growing Variable-Size Column Cell Array That Is Initialized as Scalar at Run Time.

Possible Solutions

This MATLAB function takes two input arguments, A and x, and assigns x to the end+1 element of A. If A is a row or column vector, MATLAB returns a row or column vector, respectively. When A is a scalar, MATLAB returns a two-element row vector.

function out = grow(A,x)
A(end+1) = x;
out = A;
end

Suppose that you generate code for this function and specify that A is a variable-length column vector and x is a scalar.

codegen grow -args {coder.typeof(0,[Inf 1]),0}
Code generation successful.

If you pass the generated MEX function a column vector with at least two elements, the MEX function produces a column vector with an additional element. However, if you pass the generated MEX function a scalar, the MEX function generates an error.

To resolve this error, try one of these solutions.

Pass Column Vector to MEX Function

Make sure that A is not a scalar at run time. Pass the generated MEX function a column vector with at least two elements.

grow_mex((1:5)',1)
ans =

     1
     2
     3
     4
     5
     1

Specify That Array is Scalar at Code Generation Time

If A is always a scalar at run time, specify that A is a scalar at code generation time:

codegen grow -args {0,0}
Code generation successful.
grow_mex(10,1)
ans =

    10     1

Grow Row Vector by Using Temporary Variable

If you want to return a column vector even if the input is a scalar, rewrite your MATLAB function to use a temporary variable that grows a row vector by using end+1. Then, transpose the temporary variable to return a column vector. For example, this function assigns the transpose of the input array A to a temporary variable, temp. This means that temp(end+1) is always a row vector. The function then assigns the transpose of the row vector to out to produce a column vector.

function out = growRow(A,x)
temp = A';
temp(end+1) = x;
out = temp';
end

Generate code for growRow and specify that A is a variable-length column vector.

codegen growRow -args {coder.typeof(0,[Inf 1]),1}
Code generation successful.

The generated MEX function returns a column vector even if the input is scalar.

growRow_mex(10,1)
ans =

    10
     1

Use Concatenation Operator

Rewrite your MATLAB function to use vertical concatenation instead of end+1. This approach returns a column vector if the input is a scalar at run time. For example, this function vertically concatenates A and x. If A is a scalar, the function returns a two-element column vector. If A is a column vector, the function returns a column vector with one additional row.

function out = growCat(A,x)
out = [A;x];
end

Generate code for growRow and specify that A is a variable-length column vector.

codegen growCat -args {coder.typeof(0,[Inf 1]),1}
Code generation successful.

The generated MEX function returns a column vector even if the input is scalar.

growCat_mex(10,1)
ans =

    10
     1

Explicitly Check for Scalar Input

To return a two-element row vector if the input array is a scalar and a column vector if the input array is a column vector, rewrite your MATLAB code to check for scalar input. This approach replicates MATLAB behavior for scalar inputs. For example, this function checks whether the input array is scalar by using the isscalar function. If the input is scalar, the function horizontally concatenates x to A and returns a two-element row vector. Otherwise, A must be a column vector and the function uses end+1 to append x to A as an additional row.

function out = growMat(A,x)
if isscalar(A)
    out = [A x];
else
    A(end+1) = x;
    out = A;
end
end

Generate code for growMat and specify that A is a variable-length column vector.

codegen growMat -args {coder.typeof(0,[Inf 1]),1}
Code generation successful.

The generated MEX function returns a row vector if A is scalar and a column vector if A is a column vector.

growMat_mex(10,1)
ans =

    10     1
growMat_mex((1:5)',1)
ans =

     1
     2
     3
     4
     5
     1

See Also

| |

Topics