Argument validation for cell arrays?
36 views (last 30 days)
Show older comments
I am looking for a way to express in a function validation block
arguments
% ...
end
that the argument must be a cell array of three-vectors.
The closest I came was to check that the argument is a cell array with a variable number of elements, as in this example script:
% should be accepted
example({ [0;0;0], [0;1;0], [1;1;0], [1;0;0] });
% should fail, because of the char-array
example({ [0;0;0], [0;1;0], [1;1;0], 'not allowed' });
% should fail, because of unexpected size of last vector
example({ [0;0;0], [0;1;0], [1;1;0], [1;0] });
% definition
function example(points)
arguments
points (1,:) cell
end
size(points)
end
Best regards,
Klaus
To summarize the answers
- There is no builtin easy way to make such checks.
- If needed, a custom mustBeASomething function has to be defined. Preferably with useful error messages.
- Using user-defined classes would help further.
2 Comments
Mario Malic
on 8 Sep 2023
Hey, I am not sure if it is possible to validate your arguments within the argument block as I never used it, but here's an idea if you want to do by adding the code.
points1 = { [0;0;0], [0;1;0], [1;1;0], 'not allowed' };
test1 = string(cellfun(@class, points1, 'UniformOutput', false))
if (numel(unique(test1)) > 1)
error("multiple variable types")
end
points2 = { [0;0;0], [0;1;0], [1;1;0], [1;0] };
test2 = cellfun(@size, points2, 'UniformOutput', false)
test2Arr = cell2mat(test2');
if size(unique(test2Arr, 'rows'), 1) > 1
error ("different dimensions of points")
end
Accepted Answer
Stephen23
on 8 Sep 2023
Edited: Stephen23
on 8 Sep 2023
"that the argument must be a cell array of three-vectors."
You can easily write your own argument validation function:
example({ [0;0;0], [0;1;0], [1;1;0], [1;0;0] });
%example({ [0;0;0], [0;1;0], [1;1;0], 'not allowed' });
example({ [0;0;0], [0;1;0], [1;1;0], [1;0] });
function example(points)
arguments
points cell {isCell3Vec}
end
size(points)
end
function isCell3Vec(C)
X = cellfun(@isnumeric,C)&cellfun(@numel,C)==3;
assert(all(X(:)),'Input must be a cell array of 3-element vectors')
end
2 Comments
Steven Lord
on 8 Sep 2023
While cellfun is compact, it's also sometimes cryptic. I'd also suggest a slightly more descriptive / targeted error message, and in support of that I'd use a simple loop in the validator.
For the case where one of the inputs is a numeric array with 3 elements but is not a vector (remember, by the definition codified in the isvector function a vector must be a 2-D array.)
try
example({1:3, 4:6, reshape(7:9, [1 1 3])})
catch ME
fprintf("Call threw error:\n%s", ME.message)
end
Wrong length numeric vector:
try
example({1:3, 4:7})
catch ME
fprintf("Call threw error:\n%s", ME.message)
end
Not numeric but a 3 element vector:
try
example({'abc', 1:3, 4:6})
catch ME
fprintf("Call threw error:\n%s", ME.message)
end
function example(points)
arguments
points cell {isCell3Vec}
end
size(points)
end
function isCell3Vec(C)
for n = 1:numel(C)
x = C{n};
assert(isnumeric(x), "Element " + n + " of the input is not numeric.")
assert(numel(x) == 3, "Element " + n + " of the input is not 3 elements long.")
assert(isvector(x), "Element " + n + " of the input is not a vector.")
end
end
More Answers (0)
See Also
Categories
Find more on Characters and Strings in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!