de Rigo, D. (2012). Applying semantic constraints to array programming: the module "check_is" of the Mastrave modelling library. In: Semantic Array Programming with Mastrave - Introduction to Semantic Computational Modelling. http://mastrave.org/doc/mtv_m/check_is
Applying semantic constraints to array programming: the module "check_is" of the Mastrave modelling library
Operations with arrays are often performed by delegating low-level details (e.g. loops among scalar elements of the arrays) to state-of-the-art numerical/scientific libraries while offering clean abstract operators (e.g. GNU Octave, MATLAB, GNU R, Numpy and Scipy in Python, ...). Array operators and functions concisely apply to multi-dimensional variables as if they were atomic, almost completely removing the need for explicit loops. They may offer a very terse and high-performance replacement for verbose object-oriented approaches, especially when dealing with complex data-processing of large/heterogeneous data.
However, this compact approach has a drawback. As arrays are considered to be a basic type, array variables can legitimately (and silently...) be assigned with other arrays of heterogeneous size or with values which semantically might be wrong for a given algorithm. Although this abstraction offers a powerful and extremely concise notation, complex array-based algorithms and models still may consist of hundreds or thousands of code lines, for which good practices such as assertions and ad-hoc consistency checks may tend to proliferate. Here, a collection of array-based concise and consistent semantic constraints is presented along with a specialised module to properly manage array-based semantics in array programming. Although the module is implemented in GNU Octave/MATLAB language (it is able to run in both computing environments), the set of array-based semantic constraints is language neutral and it may be easily accessed in other languages via multi-language array programming bridges. Aside from the actual implementation of algorithms, the semantic constraints may prove helpful as standard support in the design phase to annotate array-based semantic properties of input, output and intermediate data-layers of complex chains of data-transformations.
The set of array-based semantic constraints here listed implements the standard semantic support for the Semantic Array Programming paradigm.
Coherent array-based mathematical description of models can simplify complex algorithm design and prototyping while moving mathematical reasoning directly into the source code - because of its substantial size reduction - where the mathematical description is actually expressed in a completely formalized and reproducible way. This powerful approach mostly relies on programming languages which are dynamically and weakly typed (e.g. GNU Octave, MATLAB, GNU R, Numpy and Scipy in Python, ...) where the concepts of vector, matrix and multidimensional array can all be represented by the native type double, which in some languages can also seamlessly represent complex-valued numbers.
Operations with arrays are often performed by delegating low-level details (e.g. loops among scalar elements of the arrays) to state-of-the-art numerical/scientific libraries - on which array programming languages transparently rely while offering clean abstract operators. Array operators and functions concisely apply to multi-dimensional variables as if they were atomic, almost completely removing the need for explicit loops. They may offer a very terse and high-performance replacement for verbose object-oriented approaches, especially when dealing with complex data-processing of large/heterogeneous data.
However, this compact approach has a drawback. As arrays are considered to be a basic type, array variables can legitimately (and silently...) be assigned with other arrays of heterogeneous size or with values which semantically might be wrong for a given algorithm (e.g. negative values for algorithms expecting positive ones). Although this abstraction offers a powerful and extremely concise notation, complex array-based algorithms and models still may consist of hundreds or thousands of code lines, for which good practices such as assertions and ad-hoc consistency checks may tend to proliferate. This however raises relevant issues on the sustainability and effectiveness of such intensely needed "DIY" ad-hoc solutions.
Here, a collection of array-based concise and consistent semantic constraints is presented along with a specialised module to properly manage array-based semantics in array programming. Although the module is implemented in GNU Octave/MATLAB language (it is able to run in both computing environments), the set of array-based semantic constraints is language neutral. Aside from the actual implementation of algorithms, the semantic constraints may prove helpful as standard support in the design phase to annotate array-based semantic properties of input, output and intermediate data-layers of complex chains of data-transformations. The module may be easily accessed in other languages via multi-language array programming bridges (e.g. [1][2]). The sole assumption regarding the data-types to check is that an array programming language may offer as basic array-types at least one of the following categories:
- multi-dimensional arrays of numbers (booleans, integers, reals or complex-valued) or characters;
- sets of uneven arrays, indexed either with positive integers (e.g. cell-arrays in GNU Octave/MATLAB [3]) or with strings (e.g. structures in GNU Octave/MATLAB [4]).
- Functional programming types are supported by extending basic data to include anonymous functions and function handles ([5]).
- Numbers are extended with the infinite and the concept of "not a number" denoting undefined (e.g. 1/0) or missing data. This follows the standard IEEE 754 for floating-point arithmetic.
Examples of array-based semantic constraints. Left: an array of raster layers (e.g. covariates/predictors to serve as input for a multivariate statistical analysis). The elements composing the array may be accessed and denoted with different levels of granularity, from the single element of a given spatial cell (pixel value) up to sparse collection of them, entire matrix layers and list of matrices. Right: Another semantic dimension associated with the aforementioned arrays is defined by the numerical values of each array element. Permissible values may vary depending on specific requirements of the particular algorithm which is expected to operate on the arrays.
The set of array-based semantic constraints here listed implements the standard semantic support for the Semantic Array Programming paradigm. This support is meant to allow concise pieces of array-programming code to be immersed within a robust semantic network of array-concepts, without renouncing to extremely compact representations.
Copyright and license notice of the function check_is
Copyright © 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 Daniele de Rigo
The file check_is.m is part of Mastrave.
Mastrave is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Mastrave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Mastrave. If not, see http://www.gnu.org/licenses/.
Function declaration
[answer, msg, must] = check_is( obj , obj_type , msg = '' , ... )
Description
Module for checking whether the variable obj belongs to the category obj_type . obj_type categories implement the concept of semantic array-based constraints on which the paradigm of Semantic Array Programming is based.
The behaviour of the function depends on the number of output arguments.
If nargout==0 , then if the check ends successfully, the module returns to the caller. Otherwise, an error is thrown displaying a message whose format is msg .
If nargout==1 , then the module returns a boolean value answer which is true if the check ends successfully, false otherwise.
If nargout==2 , then the module returns the boolean answer as in the previous case, along with an error message whose format is msg (the message is an empty string if the check ends successfully).
If nargout==3 , the module returns answer and msg as in the previous case, along with the struct must whose fields contain the constraints to be satisfied.
If other arguments are passed after msg , they are managed like the optional arguments in the function @sprintf (see the help of @sprintf for more details about the format of msg and the optional arguments).
The semantic constraints associated to each input argument and documented within the help of all Mastrave functions are implemented by invoking this function.
Representation of semantic constraints
In order for a function to be compliant with the Mastrave coding standards, it must explicitly express (and document) a set of semantic constraints for each of its input arguments and optionally for its output arguments. Semantic constraints take the form of a sequence of categories between :: . The special token :: is used as "quotation" delimiter of the semantic constraints which are expected to be delimited by :: both as prefix and suffix. The general documentation syntax is:
argument_name ::semantic constraints::
Documentation describing the argument
argument_name and the reason why its
semantic constraints ought to hold.
where ::semantic constraint:: is a generic placeholder which actually stays for one or more of the categories described in the following section "Input arguments". Within the Semantic Array Programming paradigm, the use of these array-based semantic checks is indeed straightforward and in many cases do not require the user to pay attention to the mathematical details underpinning the implementation of the concept of array-based semantic check. For reference, these details are briefly summarised in the following.
The role of the category obj_type for the variable obj could be
formalized within the deontic logic. In case to obj a single category
is applied, the category can be interpreted as a necessity.
If obj_type value is ::p::, then for obj it must hold the deontic
logic proposition (basic unary modal operators ☐ and ◇ are here used):
☐ p % it ought to be that p
(Beware that the label ::p::, and in the following the label ::q::, are used as generic place-holders, so that neither ::p:: nor ::q:: are valid constraints.) A consequence of ::p:: is that:
not ( ◇ not(p) )
% it is not permissible that not-p
meaning that if the semantic constraint ::p:: - which we suppose to be required e.g. for a given input argument of a certain module - is not satisfied, then it is not permissible that module's execution to be continued.
If obj_type value is ::p,q::, then for obj it must hold the deontic
logic proposition:
( ☐ p ) and ( ☐ q ) % it ought to be both that p and q
a consequence of it is that:
not ( ◇ not(p) ) or not ( ◇ not(q) )
% it is not permissible that either not-p or not-q
If obj_type value is ::p|q::, then for obj it must hold the deontic
logic proposition:
( ☐ p ) or ( ☐ q ) % it ought to be either p or q
whose consequence is that:
( ◇ not(p) ) and ( ◇ not(q) ) and not ( ◇ ( not(p) and not(q) ) )
% not-p and not-q are both permissible,
% however it is not permissible that neither p nor q
An accurate (despite possibly inefficient) implementation of the
previous deontic logic propositions on obj may be obtained by
replacing each atomic proposition:
☐ p
with the call to @check_is:
T = check_is( obj , ::p:: )
so that e.g. the semantic constraint ::p|q:: on obj can be implemented as:
T1 = check_is( obj , ::p:: )
T2 = check_is( obj , ::q:: )
T = check_is( T1 | T2 , ::true:: )
The validity of the aggregated check result T must hold.
Input arguments
obj ::generic:: Object on which to check the obj_type constraint. obj_type ::generic|row_string:: Constraint to be checked. Follows here a list of the implemented categories for obj_type : obj_type value constraint to verify ────────────────────────────────────────────────────────────────────────── model class( obj ) must be the same as class( model ) and if model is a ::cell::-array or a struct, each element of model must recursively have the same class of the corresponding element of obj . model cannot be a string: if you need to check if obj is a string, use instead something like: check_is( obj , 'string' , ... 'must be a string!' ) Only the classes of the (element composing the) object are compared. As a consequence, the numeric or string values and also the size of a given array element of obj may not imply a matching failure, provided that the class of the corresponding element of model is the same. However, in case the class of that element is a container of heterogeneous items (e.g. a cell-array of a struct), then the size of the element is considered. This is because the i-th item of the obj element has to be checked for ensuring its class is the same of the one of the i-th item of the corresponding element of model . As a general rule, heterogeneous containers are checked item by item, while homogeneous containers (e.g. ordinary arrays) are not. \((\newcommand{\obj}[1]{\text{obj}}\newcommand{\semapi}[2]{:\,\!:\!\!{\large \mid}\, {#2} \,{\large \mid}\!\!:\,\!:{}^{\hspace{-3mm}{}^{{}^{\LARGE \mathtt{\text{#1}\;\;}^{\mbox{}}}}}}\newcommand{\semap}[1]{\semapi{#1}{\obj{}}}\newcommand{\atpos}[1]{{[\,#1\,]}}\)) ────────────────────────────────────────────────────────────────────────── 'generic', Synonym of: logical( 1 ) 'anything' Rationale: to support an always-passing test. ────────────────────────────────────────────────────────────────────────── 'nothing', Synonym of: logical( 0 ) 'fail' Rationale: to support an always-failing test. ────────────────────────────────────────────────────────────────────────── 'true' Synonym of: logical( obj ) Rationale: to offer a generic logical test in case no one of the supported specific tests applies. ────────────────────────────────────────────────────────────────────────── 'false' Synonym of: ~logical( obj ) Rationale: to offer a generic logical test in case no one of the supported specific tests applies. ────────────────────────────────────────────────────────────────────────── 'any' Synonym of: isnumeric( obj ) && ... any( obj (:) ) \((\semap{numeric} \;\;\land\;\; \exists i, \;\text{obj}\atpos{i} \equiv true\)) ────────────────────────────────────────────────────────────────────────── 'all' Synonym of: isnumeric( obj ) && ... all( obj (:) ) \((\semap{numeric} \;\;\land\;\; \forall i, \;\text{obj}\atpos{i} \equiv true\)) ────────────────────────────────────────────────────────────────────────── 'logical' Synonym of: islogical( obj ) ────────────────────────────────────────────────────────────────────────── 'binary' Synonym of: islogical( obj ) || ( ... isnumeric( obj ) && ... all( obj (:) == ... logical( obj (:)) ) ) ────────────────────────────────────────────────────────────────────────── 'numeric' Synonym of: isnumeric( obj ) || ... islogical( obj ) ────────────────────────────────────────────────────────────────────────── 'real' Synonym of: isnumeric( obj ) || ... islogical( obj ) && ... ~any(imag( obj (:)) ) ────────────────────────────────────────────────────────────────────────── 'finite' obj must be ::numeric:: and its elements must have finite values so that no infinite nor NaN elements are allowed. \((\semap{numeric} \;\;\land\;\; \forall i, \; -\infty \lt \text{obj}\atpos{i} \lt \infty\)) ────────────────────────────────────────────────────────────────────────── 'nanless' obj must be ::numeric:: and its elements' value cannot be NaN. Example of usage: to support algorithms relaying on operators whose use may be problematic when dealing with NaN values (e.g. statistics such as @var, scan operators such as @cumsum, ... ) with a default check for ensuring input data to have been properly pre-processed. Typically, this kind of constraint may require a pre-processing step for the NaN values to be replaced with neutral values (e.g. in a sum operator, 0 is the neutral value, while in a product operator the neutral value would be 1, etc..). Then, a post-processing step might be further required for the NaN values to be reintroduced (e.g. the operator average may be split in the sum the elements ─ with zeros replacing NaN values ─ divided by the counting of non-NaN elements: when all elements are NaN, the division by 0 would reintroduce NaN as the average value for that particular case). ────────────────────────────────────────────────────────────────────────── 'nonzero' obj must be ::numeric:: and its elements' value cannot be zero. \((\semap{numeric} \;\;\land\;\; \forall i, \;\text{obj}\atpos{i} \neq 0\)) ────────────────────────────────────────────────────────────────────────── 'numstring' Synonym of: ischar( obj ) || ... isnumeric( obj ) ||... islogical( obj ) ────────────────────────────────────────────────────────────────────────── 'realstring' Synonym of: ischar( obj ) || (... isnumeric( obj ) || ... islogical( obj ) && ... ~any(imag( obj (:)) ) ) ────────────────────────────────────────────────────────────────────────── 'char' , Synonym of: ischar( obj ) 'string' ────────────────────────────────────────────────────────────────────────── 'row_string' obj must be a one-row string. ────────────────────────────────────────────────────────────────────────── 'varname' Synonym of: ischar( obj ) && ... isvarname( obj ) && ... obj (1) ~= '_' Rationale: to ensure obj is a portable variable name. ────────────────────────────────────────────────────────────────────────── 'format_string' obj must be a valid format string for the *printf family of functions. ────────────────────────────────────────────────────────────────────────── 'regexp' obj must be a valid regular expression for the regex* family of functions. ────────────────────────────────────────────────────────────────────────── 'cell' Synonym of: iscell( obj ) 'list' Almost all array-programming languages support a native array container for uneven objects. In MATLAB/GNU Octave, this special array type is called "cell-array" and allows each of its elements to be a numeric type, a string, a function-handle, a struct or another nested cell-array, irrespective of the type of the other elements. Other array-programming languages may use the concept of "list" for expressing a pretty similar type of array container. Please, be aware that a "cell-array" is not supposed to be a one-dimensional array: it may be a generic n-dimensional array of uneven elements. In some array-programming languages, "list" arrays are only one-dimensional. Here, ::list:: is used as a synonym for ::cell::, thus implying the array not to be constrained to necessarily be a one-dimensional one. If this instead were the intended semantics, please mimic it e.g. by also requiring the array to be a ::vector::. ────────────────────────────────────────────────────────────────────────── 'struct' Synonym of: isstruct( obj ) ────────────────────────────────────────────────────────────────────────── 'sparse' Synonym of: issparse( obj ) ────────────────────────────────────────────────────────────────────────── 'full' Synonym of: ~issparse( obj ) 'nonsparse' ────────────────────────────────────────────────────────────────────────── 'function_handle' Synonym of: isa( obj , 'function_handle' ) 'funhandle' 'func' ────────────────────────────────────────────────────────────────────────── 'strfunhandle' Synonym of: ischar( obj ) || ... 'strfunc' isa( obj , 'function_handle' ) ────────────────────────────────────────────────────────────────────────── 'numfunhandle' Synonym of: isnumeric( obj ) || ... 'numfunc' islogical( obj ) || ... isa( obj , 'function_handle' ) ────────────────────────────────────────────────────────────────────────── 'numstrfunhandle' Synonym of: isnumeric( obj ) || ... 'numstrfunc' islogical( obj ) || ... ischar( obj ) || ... isa( obj , 'function_handle' ) ────────────────────────────────────────────────────────────────────────── 'int8' Synonym of: isa( obj , 'int8' ) ────────────────────────────────────────────────────────────────────────── 'uint8' Synonym of: isa( obj , 'uint8' ) ────────────────────────────────────────────────────────────────────────── 'int16' Synonym of: isa( obj , 'int16' ) ────────────────────────────────────────────────────────────────────────── 'uint16' Synonym of: isa( obj , 'uint16' ) ────────────────────────────────────────────────────────────────────────── 'int32' Synonym of: isa( obj , 'int32' ) ────────────────────────────────────────────────────────────────────────── 'uint32' Synonym of: isa( obj , 'uint32' ) ────────────────────────────────────────────────────────────────────────── 'tileable' obj must be ::numeric:: or a ::char:: or a ::cell::-array or a struct. Rationale: to ensure obj can be tiled, e.g. using repmat( obj , .. ). ────────────────────────────────────────────────────────────────────────── 'numcellstring' obj must be ::numeric:: or a ::char:: or a 'sortable' ::cell::-array whose elements obj_type must be ::char:: . Rationale: to ensure obj can be sorted, e.g. using sort( obj , .. ). ────────────────────────────────────────────────────────────────────────── 'realcellstring' obj must be ::real:: or a ::char:: or a 'tsortable' ::cell::-array whose elements obj_type must be ::char:: . Rationale: to ensure obj can be sorted, e.g. using sort( obj , .. ), with the guarantee of total-order. This excludes complex numbers with nonzero imaginary part. ────────────────────────────────────────────────────────────────────────── 'sorted' obj must be sorted in either ascending or descending order. ────────────────────────────────────────────────────────────────────────── 'sorted-ascend' obj must be sorted in ascending order. ────────────────────────────────────────────────────────────────────────── 'sorted-descend' obj must be sorted in descending order. ────────────────────────────────────────────────────────────────────────── 'row_elems' obj must be a row-vector or a ::cell::-array whose elements must be row-vectors. ────────────────────────────────────────────────────────────────────────── 'cellstring' obj must be a ::char:: or a ::cell::-array 'liststring' whose elements obj_type must be ::char:: . \((\semap{string} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{string}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellstring-r' obj must be a ::char:: or a cell-array 'liststring-r' whose elements obj_type must be ::cellstring-r:: . \((\semap{string} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellstring-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellstring-1' obj must be a ::cell::-array of ::char:: . 'liststring-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{string}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellstring-2' obj must be a ::cell::-array of cell-arrays 'liststring-2' of ::char:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{string}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnumeric' obj must be ::numeric:: or a ::cell::-array 'listnumeric' whose elements obj_type must be ::numeric:: . \((\semap{numeric} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{numeric}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnumeric-r' obj must be ::numeric:: or a ::cell::-array 'listnumeric-r' whose elements obj_type must be ::cellnumeric-r:: . \((\semap{numeric} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellnumeric-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnumeric-1' obj must be a ::cell::-array of 'listnumeric-1' ::numeric:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{numeric}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnumeric-2' obj must be a ::cell::-array of cell-arrays 'listnumeric-2' of ::numeric:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{numeric}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellfinite' obj must be ::finite:: or a ::cell::-array 'listfinite' whose elements obj_type must be ::finite:: . \((\semap{finite} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{finite}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellfinite-r' obj must be ::finite:: or a ::cell::-array 'listfinite-r' whose elements obj_type must be ::cellfinite-r:: . \((\semap{finite} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellfinite-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellfinite-1' obj must be a ::cell::-array of ::finite:: . 'listfinite-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{finite}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellfinite-2' obj must be a ::cell::-array of cell-arrays 'listfinite-2' of ::finite:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{finite}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnanless' obj must be ::nanless:: or a ::cell::-array 'listnanless' whose elements obj_type must be ::nanless:: . \((\semap{nanless} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{nanless}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnanless-r' obj must be ::nanless:: or a ::cell::-array 'listnanless-r' whose elements obj_type must be ::cellnanless-r:: . \((\semap{nanless} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellnanless-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnanless-1' obj must be a ::cell::-array of 'listnanless-1' ::nanless:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{nanless}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnanless-2' obj must be a ::cell::-array of cell-arrays 'listnanless-2' of ::nanless:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{nanless}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnonzero' obj must be ::nonzero:: or a ::cell::-array 'listnonzero' whose elements obj_type must be ::nonzero:: . \((\semap{nonzero} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{nonzero}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnonzero-r' obj must be ::nonzero:: or a ::cell::-array 'listnonzero-r' whose elements obj_type must be ::cellnonzero-r:: . \((\semap{nonzero} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellnonzero-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnonzero-1' obj must be a ::cell::-array of 'listnonzero-1' ::nonzero:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{nonzero}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnonzero-2' obj must be a ::cell::-array of cell-arrays 'listnonzero-2' of ::nonzero:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{nonzero}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellint' obj must be integer or a ::cell::-array 'listint' whose elements obj_type must be integers. \((\semap{int} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{int}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellint-r' obj must be integers or a ::cell::-array 'listint-r' whose elements obj_type must be ::cellint-r:: . \((\semap{int} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellint-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellint-1' obj must be a ::cell::-array of integers. 'listint-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{int}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellint-2' obj must be a ::cell::-array of cell-arrays 'listint-2' of integers. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{int}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellscalar' obj must be a scalar or a ::cell::-array 'listscalar' whose elements obj_type must be scalars. \((\semap{scalar} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{scalar}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellscalar-r' obj must be a scalar or a ::cell::-array 'listscalar-r' whose elements obj_type must be ::cellscalar-r:: . \((\semap{scalar} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellscalar-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellscalar-1' obj must be a ::cell::-array of scalars. 'listscalar-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{scalar}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellscalar-2' obj must be a ::cell::-array of cell-arrays 'listscalar-2' of scalars. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{scalar}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellvector' obj must be a vector or a ::cell::-array 'listvector' whose elements obj_type must be vectors. \((\semap{vector} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{vector}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellvector-r' obj must be a vector or a ::cell::-array 'listvector-r' whose elements obj_type must be ::cellvector-r::. \((\semap{vector} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellvector-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellvector-1' obj must be a ::cell::-array of vectors. 'listvector-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{vector}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellvector-2' obj must be a ::cell::-array of cell-arrays 'listvector-2' of vectors. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{vector}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellmatrix' obj must be a matrix or a ::cell::-array 'listmatrix' whose elements obj_type must be matrices. \((\semap{matrix} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{matrix}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellmatrix-r' obj must be a matrix or a ::cell::-array 'listmatrix-r' whose elements obj_type must be ::cellmatrix-r:: . \((\semap{matrix} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellmatrix-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellmatrix-1' obj must be a ::cell::-array of matrices. 'listmatrix-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{matrix}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellmatrix-2' obj must be a ::cell::-array of cell-arrays 'listmatrix-2' of matrices. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{matrix}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cell3-array' obj must be a ::3-array:: or a 'list3-array' ::cell::-array whose elements obj_type must be 3-arrays. \((\semap{3-array} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{3-array}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cell3-array-r' obj must be a ::3-array:: or a 'list3-array-r' ::cell::-array whose elements obj_type must be ::cell3-array-r:: . \((\semap{3-array} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell3-array-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cell3-array-1' obj must be a ::cell::-array of 'list3-array-1' ::3-arrays:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{3-array}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cell3-array-2' obj must be a ::cell::-array of cell-arrays 'list3-array-2' of ::3-array:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{3-array}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cell4-array' obj must be a ::4-array:: or a 'list4-array' ::cell::-array whose elements obj_type must be 4-arrays. \((\semap{4-array} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{4-array}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cell4-array-r' obj must be a ::4-array:: or a 'list4-array-r' ::cell::-array whose elements obj_type must be ::cell4-array-r:: . \((\semap{4-array} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell4-array-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cell4-array-1' obj must be a ::cell::-array of 'list4-array-1' ::4-arrays:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{4-array}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cell4-array-2' obj must be a ::cell::-array of cell-arrays 'list4-array-2' of ::4-array:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{4-array}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cell5-array' obj must be a ::5-array:: or a 'list5-array' ::cell::-array whose elements obj_type must be 5-arrays. \((\semap{5-array} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{5-array}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cell5-array-r' obj must be a ::5-array:: or a 'list5-array-r' ::cell::-array whose elements obj_type must be ::cell5-array-r:: . \((\semap{5-array} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell5-array-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cell5-array-1' obj must be a ::cell::-array of ::5-arrays:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{5-array}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cell5-array-2' obj must be a ::cell::-array of cell-arrays 'list5-array-2' of ::5-array:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{5-array}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellreal' obj must be ::real:: or a ::cell::-array 'listreal' whose elements obj_type must be ::real:: . \((\semap{real} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{real}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellreal-r' obj must be ::real:: or a ::cell::-array 'listreal-r' whose elements obj_type must be ::cellreal-r:: . \((\semap{real} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellreal-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellreal-1' obj must be a ::cell::-array of ::real:: . 'listreal-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{real}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellreal-2' obj must be a ::cell::-array of cell-arrays 'listreal-2' of ::real:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{real}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnumstring' obj must be ::numstring:: or a 'listnumstring' ::cell::-array whose elements obj_type must be ::numstring:: . \((\semap{numstring} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{numstring}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnumstring-r' obj must be ::numstring:: or a 'listnumstring-r' ::cell::-array whose elements obj_type must be ::cellnumstring-r:: . \((\semap{numstring} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellnumstring-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnumstring-1' obj must be a ::cell::-array of 'listnumstring-1' ::numstring::. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{numstring}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnumstring-2' obj must be a ::cell::-array of cell-arrays 'listnumstring-2' of ::numstring::. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{numstring}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellrealstring' obj must be ::realstring:: or a 'listrealstring' ::cell::-array whose elements obj_type must be ::realstring:: . \((\semap{realstring} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{realstring}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellrealstring-r' obj must be ::realstring:: or a 'listrealstring-r' ::cell::-array whose elements obj_type must be ::cellrealstring-r:: . \((\semap{realstring} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellrealstring-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellrealstring-1' obj must be a ::cell::-array of 'listrealstring-1' ::realstring:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{realstring}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellrealstring-2' obj must be a ::cell::-array of cell-arrays 'listrealstring-2' of ::realstring:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{realstring}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellfunhandle' obj must be a function handle or a ::cell:: 'listfunhandle' array whose elements obj_type must be function handles. \((\semap{funhandle} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{funhandle}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellfunhandle-r' obj must be a function handle or a ::cell:: 'listfunhandle-r' array whose elements obj_type must be ::cellfunhandle-r:: . \((\semap{funhandle} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellfunhandle-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellfunhandle-1' obj must be a ::cell::-array of function 'listfunhandle-1' handles. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{funhandle}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellfunhandle-2' obj must be a ::cell::-array of cell-arrays 'listfunhandle-2' of function handles. \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{funhandle}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellindex' obj must be ::index:: or a ::cell::-array 'listindex' whose elements obj_type must be ::index:: . \((\semap{index} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{index}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellindex-r' obj must be ::index:: or a ::cell::-array 'listindex-r' whose elements obj_type must be ::cellindex-r::. \((\semap{index} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellindex-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellindex-1' obj must be a ::cell::-array of ::index:: . 'listindex-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{index}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellindex-2' obj must be a ::cell::-array of cell-arrays 'listindex-2' of ::index:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{index}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnumel' obj must be ::numel:: or a ::cell::-array 'listnumel' whose elements obj_type must be ::numel:: . \((\semap{numel} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{numel}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnumel-r' obj must be ::numel:: or a ::cell::-array 'listnumel-r' whose elements obj_type must be ::cellnumel-r:: . \((\semap{numel} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellnumel-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellnumel-1' obj must be a ::cell::-array of ::numel:: . 'listnumel-1' \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{numel}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellnumel-2' obj must be a ::cell::-array of cell-arrays 'listnumel-2' of ::numel:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{numel}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellprob' obj must be of ::probability:: or a ::cell:: 'listprob' array whose elements obj_type must be ::probability:: . \((\semap{prob} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{prob}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellprob-r' obj must be of ::probability:: or a ::cell:: 'listprob-r' array whose elements obj_type must be ::cellprob-r:: . \((\semap{prob} \;\;\lor\;\; \)) \((\left ( \semap{cell} \;\;\land\;\; \forall i, \;\semapi{cellprob-r}{\text{obj}\atpos{i}} \right )\)) ────────────────────────────────────────────────────────────────────────── 'cellprob-1' obj must be a ::cell::-array of 'listprob-1' ::probability:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{prob}{\text{obj}\atpos{i}}\)) ────────────────────────────────────────────────────────────────────────── 'cellprob-2' obj must be a ::cell::-array of cell-arrays 'listprob-2' of ::probability:: . \((\semap{cell} \;\;\land\;\; \forall i, \;\semapi{cell}{\text{obj}\atpos{i}} \;\;\land\;\;\)) \((\forall i \,\forall j, \;\semapi{prob}{\text{obj}\atpos{i}\atpos{j}}\)) ────────────────────────────────────────────────────────────────────────── 'cellempty' obj must be empty or a ::cell::-array whose 'listempty' elements must be empty. ────────────────────────────────────────────────────────────────────────── 'cellempty-c' obj must be empty or a ::cell::-array whose 'listempty-c' elements must be empty. If obj is a cell-array, it is not checked if it is empty but only if its elements are empty. Status: experimental. ────────────────────────────────────────────────────────────────────────── 'cellempty-r' obj must be empty or a ::cell::-array whose 'listempty-r' elements obj_type must be ::cellempty-r:: . ────────────────────────────────────────────────────────────────────────── 'cellempty-1' obj must be a ::cell::-array of empty 'listempty-1' elements. ────────────────────────────────────────────────────────────────────────── 'cellempty-2' obj must be a ::cell::-array of cell-arrays 'listempty-2' of empty elements. ────────────────────────────────────────────────────────────────────────── 'cellnonempty' obj must be empty or a ::cell::-array whose 'listnonempty' elements cannot be empty. ────────────────────────────────────────────────────────────────────────── 'cellnonempty-c' obj must be empty or a ::cell::-array whose 'listnonempty-c' elements cannot be empty. If obj is a cell-array, it is not checked if it is non-empty but only if its elements are non-empty. Status: experimental. ────────────────────────────────────────────────────────────────────────── 'cellnonempty-r' obj must be ::nonempty:: or a ::cell::-array 'listnonempty-r' whose elements obj_type must be ::cellnonempty-r:: . ────────────────────────────────────────────────────────────────────────── 'cellnonempty-1' obj must be a ::cell::-array of ::nonempty:: 'listnonempty-1' elements. ────────────────────────────────────────────────────────────────────────── 'cellnonempty-2' obj must be a ::cell::-array of cell-arrays 'listnonempty-2' of ::nonempty:: elements. ────────────────────────────────────────────────────────────────────────── 'cellscalempty' obj must be ::scalempty:: or a 'listscalempty' ::cell::-array whose elements obj_type must be ::scalempty:: . ────────────────────────────────────────────────────────────────────────── 'cellscalempty-c' obj must be ::scalempty:: or a ::cell::-array 'listscalempty-c' whose elements obj_type must be ::scalempty:: . If obj is a cell-array, it is not checked if it is ::scalempty:: but only if its elements are scalempty. Status: experimental. ────────────────────────────────────────────────────────────────────────── 'cellscalempty-r' obj must be ::scalempty:: or a 'listscalempty-r' ::cell::-array whose elements obj_type must be ::cellscalempty-r:: . ────────────────────────────────────────────────────────────────────────── 'cellscalempty-1' obj must be a ::cell::-array of ::scalempty:: 'listscalempty-1' elements. ────────────────────────────────────────────────────────────────────────── 'cellscalempty-2' obj must be a ::cell::-array of cell-arrays 'listscalempty-2' of ::scalempty:: elements. ────────────────────────────────────────────────────────────────────────── 'cellxorempty' obj must be a non-cell-array or a 'listxorempty' ::cell::-array whose elements obj_type must be all empty or all ::nonempty:: . ────────────────────────────────────────────────────────────────────────── 'cellxorempty-c' obj must be a non-cell-array or a 'listxorempty-c' ::cell::-array whose elements obj_type must be ::xorempty:: which means all empty or all ::nonempty:: . If obj is a cell-array, it is not checked if it is ::xorempty:: but only if its elements are ::xorempty:: . Status: experimental. ────────────────────────────────────────────────────────────────────────── 'cellxorempty-r' obj must be a non-cell-array or a 'listxorempty-r' ::cell::-array whose elements obj_type must be all empty or all ::cellnonempty-r:: . ────────────────────────────────────────────────────────────────────────── 'cellxorempty-1' obj must be a ::cell::-array whose elements 'listxorempty-1' must be all empty or all ::nonempty:: . ────────────────────────────────────────────────────────────────────────── 'cellxorempty-2' obj must be a ::cell::-array of cell-arrays 'listxorempty-2' whose elements must be all empty or all ::nonempty:: . ────────────────────────────────────────────────────────────────────────── 'celltileable' obj must be ::tileable:: or a ::cell::-array 'listtileable' whose elements obj_type must be ::tileable:: . ────────────────────────────────────────────────────────────────────────── 'celltileable-c' obj must be ::tileable:: or a ::cell::-array 'listtileable-c' whose elements obj_type must be ::tileable:: . If obj is a cell-array, it is not checked if it is ::tileable:: but only if its elements are ::tileable:: . ────────────────────────────────────────────────────────────────────────── 'celltileable-r' obj must be ::tileable:: or a ::cell::-array 'listtileable-r' whose elements obj_type must be ::celltileable-r:: . ────────────────────────────────────────────────────────────────────────── 'celltileable-1' obj must be a ::cell::-array of 'listtileable-1' ::tileable:: . ────────────────────────────────────────────────────────────────────────── 'celltileable-2' obj must be a ::cell::-array of cell-arrays 'listtileable-2' of ::tileable:: . ────────────────────────────────────────────────────────────────────────── 'same_rows' obj must be a ::cell::-array of objects, each of them having the same number of rows. ────────────────────────────────────────────────────────────────────────── 'same_columns' obj must be a ::cell::-array of objects, each of them having the same number of columns. ────────────────────────────────────────────────────────────────────────── 'same_length' obj must be a ::cell::-array of objects, each of them having the same length. ────────────────────────────────────────────────────────────────────────── 'same_size' obj must be a ::cell::-array of objects, each of them having the same size. ────────────────────────────────────────────────────────────────────────── 'same_ndims' obj must be a ::cell::-array of objects, each of them having the same number of dimensions. ────────────────────────────────────────────────────────────────────────── 'same_numel' obj must be a ::cell::-array of objects, each of them having the same number of elements. ────────────────────────────────────────────────────────────────────────── 'same_vals' obj must be a ::cell::-array of objects, each of them equal to all other ones. Not-a-number values (nan) are never equal to each other. ────────────────────────────────────────────────────────────────────────── 'same_valnans' obj must be a ::cell::-array of objects, each of them equal to all other ones. Not-a-number values (nan) are always equal to each other. ────────────────────────────────────────────────────────────────────────── 'same_diff' obj must be ::subtractable:: and the @diff between elements of obj must be constant. ────────────────────────────────────────────────────────────────────────── 'comparable' obj must be a ::cell::-array of objects, each of them must be comparable with the other using the operator == . ────────────────────────────────────────────────────────────────────────── 'multipliable' obj must be a ::cell::-array of objects, each of them must be multipliable with the next one using the usual matrix product. ────────────────────────────────────────────────────────────────────────── 'subtractable' obj must be capable of being subtracted. In addition, its elements must be capable of being subtracted by means of the @diff operator. ────────────────────────────────────────────────────────────────────────── 'positive' obj must be numeric and each of its elements must be greater than zero. ────────────────────────────────────────────────────────────────────────── 'nonpositive' obj must be numeric and each of its elements must be less or equal to zero. ────────────────────────────────────────────────────────────────────────── 'negative' obj must be numeric and each of its elements must be less than zero. ────────────────────────────────────────────────────────────────────────── 'nonnegative' obj must be numeric and each of its elements must be greater or equal to zero. ────────────────────────────────────────────────────────────────────────── 'probability' obj must be of real values each of them 'possibility' being greater or equal to zero and less or 'proportion' equal to one. Rationale: to ensure all obj elements lie in the interval [0 1] and therefore are suitable to be interpreted as probabilities, fuzzy possibilities or proportions. Although all are required to lie in [0 1], the semantics of probabilities, fuzzy possibilities and proportions differs. A probability expresses the mathematical concept defined by the classical "probability axioms". A fuzzy possibility does not necessarily respect the "probability axioms". It expresses the concept of set membership in the fuzzy logic. A proportion expresses the dimensionless ratio between a subset/part of a given quantity and the whole quantity. ────────────────────────────────────────────────────────────────────────── 'angle' obj must be of real values each of them 'radian' being greater or equal to zero and less or equal to 2*pi. Rationale: to express normalised circular variables, so as for the values approaching the upper bound (2*pi) from the left and those approaching the lower bound (0) from the right to be semantically contiguous. Example of usage: a circular variable t with period T satisfies the semantic constraint: check_is( mod( t , T ) / T * 2*pi , ::angle:: ) ────────────────────────────────────────────────────────────────────────── 'versor_coord-L1' obj must be a matrix of real values each '1-partition' such that: sum( abs( obj ) , 2 ) == 1. Rationale: to ensure obj is suitable to be interpreted as a versor in L-1 space (L-1 norm is also known as Manhattan distance). This is also equivalent to requiring the columns of obj to be partitions of 1 (i.e. each column sums to 1). ────────────────────────────────────────────────────────────────────────── 'versor_coord-L2' obj must be a matrix of real values each such that: sum( obj .^2 , 2 ) == 1. Rationale: to ensure obj is suitable to be interpreted as a versor in L-2 space (L-2 norm is also known as Euclidean distance). ────────────────────────────────────────────────────────────────────────── 'versor_coord-Linf' obj must be a matrix of real values each such that: max( obj , [] , 2 ) == 1. Rationale: to ensure obj is suitable to be interpreted as a versor in L-infinite space (L-infinite norm is also known as Maximum distance). ────────────────────────────────────────────────────────────────────────── 'integer' obj must be numeric and each of its elements must be convertible to an integer without loss of information. ────────────────────────────────────────────────────────────────────────── 'natural' obj must be numeric and each of its elements 'numel' must be convertible to a non-negative integer without loss of information. Rationale: to ensure obj can represent the result of a (set of) count(s). ────────────────────────────────────────────────────────────────────────── 'natural_nonzero' obj must be numeric and each of its elements 'index' must be convertible to a positive integer without loss of information. Rationale: to ensure obj can represent a valid (set of) index(indices). ────────────────────────────────────────────────────────────────────────── 'empty' Synonim of: numel( obj )==0 ────────────────────────────────────────────────────────────────────────── 'nonempty' Synonim of: numel( obj )~=0 ────────────────────────────────────────────────────────────────────────── 'scalempty' Synonym of: numel( obj )<=1 ────────────────────────────────────────────────────────────────────────── 'scalar' Synonym of: numel( obj )==1 '1-vector' ────────────────────────────────────────────────────────────────────────── '2-vector' Synonym of: numel( obj )==2 ────────────────────────────────────────────────────────────────────────── '3-vector' Synonym of: numel( obj )==3 ────────────────────────────────────────────────────────────────────────── 'n-vectors' obj must be a ::cell::-array whose first '[n]-vectors' element n = obj {1} is a scalar or an array with the same number of elements of numel( obj )-1 . The number of elements of each object passed as ::cell::-element of obj (2:end) must be exactly equal to the (corresponding) value(s) of n . Synonym of: cellfun( @numel, obj (2:end) ) == n ────────────────────────────────────────────────────────────────────────── 'n]-vectors' obj must be a ::cell::-array whose first element n = obj {1} is a scalar or an array with the same number of elements of numel( obj )-1 . The number of elements of each object passed as ::cell::-element of obj (2:end) must be less or equal to the (corresponding) value(s) of n . Synonym of: cellfun( @numel, obj (2:end) ) <= n ────────────────────────────────────────────────────────────────────────── '[n-vectors' obj must be a ::cell::-array whose first element n = obj {1} is a scalar or an array with the same number of elements of numel( obj )-1 . The number of elements of each object passed as ::cell::-element of obj (2:end) must be greater or equal to the (corresponding) value(s) of n . Synonym of: cellfun( @numel, obj (2:end) ) >= n ────────────────────────────────────────────────────────────────────────── 'n[-vectors' obj must be a ::cell::-array whose first element n = obj {1} is a scalar or an array with the same number of elements of numel( obj )-1 . The number of elements of each object passed as ::cell::-element of obj (2:end) must be strictly less than the (corresponding) value(s) of n . Synonym of: cellfun( @numel, obj (2:end) ) < n ────────────────────────────────────────────────────────────────────────── ']n-vectors' obj must be a ::cell::-array whose first element n = obj {1} is a scalar or an array with the same number of elements of numel( obj )-1 . The number of elements of each object passed as ::cell::-element of obj (2:end) must be strictly greater than the (corresponding) value(s) of n . Synonym of: cellfun( @numel, obj (2:end) ) > n ────────────────────────────────────────────────────────────────────────── '{}-numeric' obj must be a ::cell::-array whose first 'categorical-numeric' element valid = obj {1} is an array of admissible numbers and the following elements obj (2:end) are numeric arrays composed only by admissible numbers. Here, the order in which the categories are listed in obj {1} does not have any special meaning (i.e. obj {1} is an unordered set). Rationale: to implement the concept of categorical variable for the special case in which the admissible categories lie in a given set of numbers. ────────────────────────────────────────────────────────────────────────── '{}-interval' obj must be a ::cell::-array whose first 'categorical-interval' element valid = obj {1} is an array of admissible ::interval::s and the following elements obj (2:end) are arrays composed only by admissible ::interval::s. Here, the order in which the categories are listed in obj {1} does not have any special meaning (i.e. obj {1} is an unordered set). Rationale: to implement the concept of categorical variable for the special case in which the admissible categories lie in a given set of intervals. (Under testing: not yet fully operational) ────────────────────────────────────────────────────────────────────────── '{}-numstring' obj must be a ::cell::-array whose first 'categorical' element valid = obj {1} is an array of admissible numbers or a ::cell::-array of ::numstring:: (numeric arrays or strings) and the following elements obj (2:end) are ::numstring:: composed only by admissible numbers or strings. Here, the order in which the categories are listed in obj {1} does not have any special meaning (i.e. obj {1} is an unordered set). Rationale: to implement the concept of categorical variable for the typical case in which the admissible categories lie in a given set of numbers (e.g. indices) or strings (e.g. textual descriptions). (Under testing: not yet fully operational) ────────────────────────────────────────────────────────────────────────── '{}-sortable-numstring' obj must be a ::cell::-array whose first 'sortable-categorical' element valid = obj {1} is an array of admissible numbers or a ::cell::-array of ::numstring:: (numeric arrays or strings) and the following elements obj (2:end) are ::numstring:: composed only by admissible numbers or strings. ::sortable-categorical:: elements differ from ::categorical:: elements because here the order in which the categories are listed in obj {1} is considered. It defines the ranking between categories: they are expected to be provided in obj {1} sorted in ascending order. Rationale: to implement the concept of sortable categorical variable for the typical case in which the admissible categories lie in a given set of numbers (e.g. indices) or strings (e.g. textual descriptions). (Under testing: not yet fully operational) ────────────────────────────────────────────────────────────────────────── '{}-function_handle' Forthcoming '{}-funhandle' '{}-func' ────────────────────────────────────────────────────────────────────────── '{}-strfunhandle' Forthcoming '{}-strfunc' ────────────────────────────────────────────────────────────────────────── '{}-numfunhandle' Forthcoming '{}-numfunc' ────────────────────────────────────────────────────────────────────────── '{}-numstrfunhandle' Forthcoming '{}-numstrfunc' ────────────────────────────────────────────────────────────────────────── 'scalar_logical' Synonym of: numel( obj )==1 && ... islogical( obj ) ────────────────────────────────────────────────────────────────────────── 'scalar_binary' Synonym of: numel( obj )==1 && ( ... islogical( obj ) || ( ... isnumeric( obj ) && ... all( obj (:) == ... logical( obj (:)) ) ) ) ────────────────────────────────────────────────────────────────────────── 'scalar_numeric' Synonym of: numel( obj )==1 && ... isnumeric( obj ) || ... islogical( obj ) ────────────────────────────────────────────────────────────────────────── 'scalar_real' Synonym of: numel( obj )==1 && ... isnumeric( obj ) || ... islogical( obj ) && ... ~any(imag( obj (:)) ) ────────────────────────────────────────────────────────────────────────── 'scalar_string' Synonym of: numel( obj )==1 && ... ischar( obj ) ────────────────────────────────────────────────────────────────────────── 'scalar_numstring' Synonym of: numel( obj )==1 && ... ischar( obj ) || ... isnumeric( obj ) || ... islogical( obj ) ────────────────────────────────────────────────────────────────────────── 'scalar_realstring' Synonym of: numel( obj )==1 && ... ischar( obj ) || (... isnumeric( obj ) || ... islogical( obj ) && ... ~any(imag( obj (:)) ) ) ────────────────────────────────────────────────────────────────────────── 'scalar_positive' obj must be scalar, numeric, greater than zero. ────────────────────────────────────────────────────────────────────────── 'scalar_nonpositive' obj must be scalar, numeric, less or equal to zero. ────────────────────────────────────────────────────────────────────────── 'scalar_negative' obj must be scalar, numeric, less than zero. ────────────────────────────────────────────────────────────────────────── 'scalar_nonnegative' obj must be scalar, numeric, greater or equal to zero. ────────────────────────────────────────────────────────────────────────── 'scalar_integer' obj must be scalar, numeric and convertible to an integer without loss of information. ────────────────────────────────────────────────────────────────────────── 'scalar_natural' obj must be scalar, numeric and convertible 'scalar_numel' to a non-negative integer without loss of information. ────────────────────────────────────────────────────────────────────────── 'scalar_natural_nonzero' obj must be scalar, numeric and convertible 'scalar_index' to a positive integer without loss of information. ────────────────────────────────────────────────────────────────────────── 'vector' obj must be a row or column vector. ────────────────────────────────────────────────────────────────────────── 'row_vector' obj must be a row vector. ────────────────────────────────────────────────────────────────────────── 'col_vector' obj must be a column vector. ────────────────────────────────────────────────────────────────────────── 'matrix' Synonym of: ndims( obj ) <= 2 ────────────────────────────────────────────────────────────────────────── '3-array' Synonym of: ndims( obj ) == 3 ────────────────────────────────────────────────────────────────────────── '4-array' Synonym of: ndims( obj ) == 4 ────────────────────────────────────────────────────────────────────────── '5-array' Synonym of: ndims( obj ) == 5 ────────────────────────────────────────────────────────────────────────── 'interval' Synonym of: ::real:: && ... size( obj , 2 ) == 2 && ... all( diff( obj ') >= 0 ) Rationale: to ensure obj represents an interval or a set of intervals. An interval is represented by its lower and upper endpoints whose values are expressed as a couple of real numbers (a row vector). Intervals cannot have negative length. ────────────────────────────────────────────────────────────────────────── 'sortable_interval' Synonym of: ::interval:: && ... all(diff(reshape( ... sortrows( obj ).',[],1 ... ))>=0) Rationale: to ensure a set of intervals can be sorted. A total-order criterion is adopted to ensure a sufficient condition in many cases of interest. The total-order criterion asks all intervals to be disjoint, i.e. to have zero-length intersections. ────────────────────────────────────────────────────────────────────────── 'o-sortable_interval' Synonym of: ::interval:: && ... all(reshape(diff( ... sortrows( obj ),[],1 ... ))>=0) Rationale: to ensure a set of intervals can be partially sorted by checking they either are disjoint or overlap, without any of them being strictly included by others (overlap partial sortability). A partial ordering criterion is adopted: two intervals are in ascending order if their lower endpoints are in ascending order (i.e. their values are non-decreasing) and their upper endpoints are in ascending order. Strict sub-intervals (intervals whose endpoints lie strictly inside a previous interval) do not pass the test. Non-strict sub-intervals could pass the test: e.g intervals having equal upper endpoints and non-decreasing lower endpoints pass the test. ────────────────────────────────────────────────────────────────────────── 'sorted_interval' Synonym of: ::interval:: && ... all(diff(reshape( ... obj .' ... ),[],1)>=0) Rationale: to ensure a set of intervals to be ascending ordered. A total-order criterion is adopted to ensure a sufficient condition in many cases of interest. The total-order criterion asks all intervals to be disjoint, i.e. to have zero-length intersections. ────────────────────────────────────────────────────────────────────────── 'o-sorted_interval' Synonym of: ::interval:: && ... all(reshape(diff( obj ),[],1)>=0) Rationale: to ensure a set of intervals to be ascending partially-ordered. They can either be disjoint or overlap, without any of them being strictly included by others (overlap partial sortability). A partial ordering criterion is adopted: two intervals are in ascending order if their lower endpoints are in ascending order (i.e. their values are non-decreasing) and their upper endpoints are in ascending order. Strict sub-intervals (intervals whose endpoints lie strictly inside a previous interval) do not pass the test. Non-strict sub-intervals could pass the test: e.g intervals having equal upper endpoints and non-decreasing lower endpoints pass the test. ────────────────────────────────────────────────────────────────────────── 'disjoint_interval' Synonym of: ::sorted_interval:: && ... all( ... diff(reshape( obj ',[],1)) ... >=0 ) Rationale: to ensure a set of sorted intervals to have zero-length intersections. ────────────────────────────────────────────────────────────────────────── 'contiguous_interval' Synonym of: ::disjoint_interval:: && ... all( obj (2:end,1) == ... obj (1:end-1) ) Rationale: to ensure a set of disjoint intervals to be contiguous (i.e. each interval upper endpoint must coincide with the lower endpoint of the subsequent interval of obj ). msg ::string:: String that contains the message to emit in case of check-failure. It can optionally contain C-language format tags that are replaced by the values specified in subsequent additional arguments. See @fprintf help for more details.
Example of usage
s={ 'cell' , 'string' , 'cellstring' , ... 'cellstring-r' , 'cellstring-1' , 'cellstring-2' }; obj1 = {}, obj2 = { 'a' 'bc' }, obj3 = 'a' , obj4 = { 'a' {} }, obj5 = { { 'a' 'bc' } {} }, obj6 = {{{ 'a' }}}, objlist = { obj1 , obj2 , obj3 , obj4 , obj5 , obj6 }; for i=1:numel(s) for j=1:numel(objlist) obj = objlist{j}; [answer, msg] = check_is( obj , s{i}, 'oops..'); fprintf('is obj%d a %s ?: %d (%s)\n', j, s{i}, answer, msg ); end end s={ 'same_rows' , 'same_columns' , 'same_numel' , ... 'same_length' , 'same_size' , 'same_ndims' , 'comparable' }; obj1 = rand(4,4), obj2 = rand(4,4), obj3 = rand(4,2,2), obj4 = rand(3,4), obj5 = rand(5,4), for i=1:numel(s) [answer, msg] = check_is( { obj1, obj2, obj3, obj4, obj5 }, ... s{i}, 'oops..' ); fprintf('%s : %d (%s)\n', s{i}, answer, msg ); end % ::multipliable:: % [OK]: check_is( { ones(3,2) ones(2,5) ones(5,4) } , 'multipliable' , 'err' ) % [FAIL]: incompatible size check_is( { ones(3,2) ones(7,5) ones(5,4) } , 'multipliable' , 'err' ) % [FAIL]: multi-array not supported by matrix product check_is( { ones(3,2) ones(2,5,3) ones(5,4) } , 'multipliable' , 'err' ) % ::same_vals:: , ::same_valnans:: obj1 = randn( 4 , 3 ); obj2 = obj1; obj2([3 5]) = [nan -inf]; % [OK]: check_is( { obj1 obj1 obj1 } , 'same_vals' , 'err' ) check_is( { obj1 obj1 obj1 } , 'same_valnans' , 'err' ) check_is( { obj2 obj2 obj2 } , 'same_valnans' , 'err' ) % [FAIL]: different objects check_is( { obj2 obj2 'foo' } , 'same_valnans' , 'err' ) % [FAIL]: assert( nan ~= nan ) check_is( { obj2 obj2 obj2 } , 'same_vals' , 'err' ) % ::sorted*:: objects a3 = rand( 3 , 2 , 4 ) cc = cell( 3 , 2 , 4 ); c = 'abcdefghijklmnopqrstuvwxyz'; for i=1:numel(cc) cc{i}=c(ceil(rand(1,ceil(rand*10))*numel(c))); end sa3 = sort( a3 , 1 ) scc = sort( cc , 1 ) sa3_ = sort( a3 , 1 , 'descend' ) scc_ = sort( cc , 1 , 'descend' ) % [FAIL]: unsorted objects check_is( a3 , 'sorted' , 'err' ) check_is( cc , 'sorted' , 'err' ) check_is( a3 , 'sorted-ascend' , 'err' ) check_is( cc , 'sorted-ascend' , 'err' ) check_is( a3 , 'sorted-descend' , 'err' ) check_is( cc , 'sorted-descend' , 'err' ) % [OK]: check_is( sa3 , 'sorted' , 'err' ) check_is( scc , 'sorted' , 'err' ) check_is( sa3 , 'sorted-ascend' , 'err' ) check_is( scc , 'sorted-ascend' , 'err' ) check_is( sa3_ , 'sorted-descend' , 'err' ) check_is( scc_ , 'sorted-descend' , 'err' ) % [FAIL]: objects sorted in ascending order check_is( sa3 , 'sorted-descend' , 'err' ) check_is( scc , 'sorted-descend' , 'err' ) % [FAIL]: objects sorted in descending order check_is( sa3_ , 'sorted-ascend' , 'err' ) check_is( scc_ , 'sorted-ascend' , 'err' ) % ::finite:: objects % [FAIL]: non numeric object check_is( { 'a' { 1:3 } } , 'finite' , 'err' ) % [FAIL]: non numeric object check_is( 'finite string' , 'finite' , 'err' ) % [FAIL]: object containing Inf values check_is( [-1 0 1 Inf 3] , 'finite' , 'err' ) % [FAIL]: object containing NaN values check_is( [-1 0 1 NaN 3] , 'finite' , 'err' ) % [OK]: numeric object containing only finite values check_is( [-1 0 1 2 3] , 'finite' , 'err' ) % [OK]: numeric object containing only finite values check_is( [] , 'finite' , 'err' ) % Versors in L-1 norm: ::versor_coord-L1:: % [FAIL]:non numeric object check_is( { 'a' { 1:3 } }, 'versor_coord-L1' , 'err' ) % [FAIL]:it is not an L-1 versor check_is( [1 3] , 'versor_coord-L1' , 'err' ) % [OK] check_is( [ pi/4 1-pi/4 ] , 'versor_coord-L1' , 'err' ) check_is( [1] , 'versor_coord-L1' , 'err' ) check_is( [ ] , 'versor_coord-L1' , 'err' ) % Versors in L-2 norm: ::versor_coord-L2:: % [FAIL]:non numeric object check_is( { 'a' { 1:3 } }, 'versor_coord-L2' , 'err' ) % [FAIL]:it is not an L-2 versor check_is( [1 3] , 'versor_coord-L2' , 'err' ) % [OK] check_is( [2 2].^-0.5 , 'versor_coord-L2' , 'err' ) check_is( [1] , 'versor_coord-L2' , 'err' ) check_is( [ ] , 'versor_coord-L2' , 'err' ) % Versors in L-infinite norm: ::versor_coord-Linf:: % [FAIL]:non numeric object check_is( { 'a' { 1:3 } }, 'versor_coord-Linf' , 'err' ) % [FAIL]:it is not an L-2 versor check_is( [1 3] , 'versor_coord-Linf' , 'err' ) % [OK] check_is( [1 0 .1;0 .2 1] , 'versor_coord-Linf' , 'err' ) check_is( [1] , 'versor_coord-Linf' , 'err' ) check_is( [ ] , 'versor_coord-Linf' , 'err' ) % ::format_string:: format = '%g, %d.\n' % [OK] check_is( format, 'format_string' , 'err' ) fprintf( 1 , format, pi, -1 ) format = '%&$' % [FAIL]:invalid format string check_is( format, 'format_string' , 'err' ) format = 123 % [FAIL]:it is not a string check_is( format, 'format_string' , 'err' ) % ::regexp::, regular expressions regexp = '.*' % [OK] check_is( pattern, 'regexp' , 'err' ) pattern = '.*[' % [FAIL]:invalid regular expression string check_is( pattern, 'regexp' , 'err' ) pattern = 123 % [FAIL]:it is not a string check_is( pattern, 'regexp' , 'err' ) % ::*funhandle:: % ::cellfunhandle:: f = @max % [OK] check_is( f , 'funhandle' , 'err' ) check_is( 'max' , 'strfunhandle' , 'err' ) check_is( f , 'cellfunhandle' , 'err' ) f = @(x)quantile( x, 0.2 ) % [OK] check_is( f , 'funhandle' , 'err' ) check_is( 0.2 , 'numfunhandle' , 'err' ) check_is( f , 'cellfunhandle' , 'err' ) f = { @max , @median , @min } % [FAIL]: expected a single funtion handle check_is( f , 'funhandle' , 'err' ) % [OK] check_is( f , 'cellfunhandle' , 'err' ) f = { @max , { @median , @min } } % [FAIL]: invalid cell-array of cell-arrays check_is( f , 'cellfunhandle' , 'err' ) f = 'max' % [FAIL]: it is not a function handle check_is( f , 'cellfunhandle' , 'err' ) % ::*-vector::, ::*n-vectors:: % [OK] check_is( pi , 'scalar' , 'err' ) check_is( pi , '1-vector', 'err' ) % [OK] check_is( { 'foo', 'bar' }, '2-vector', 'err' ) % [OK] check_is( [2 3 5] , '3-vector', 'err' ) % [FAIL] check_is( [2 3 5] , '2-vector', 'err' ) % [OK] check_is( { 3, [2 3 5] } , 'n-vectors', 'err' ) % [OK] check_is( { [1 3], pi, [2 3 5] }, 'n-vectors', 'err' ) % [FAIL]: [2 3 5] has not 2 elements check_is( { [1 2], pi, [2 3 5] }, 'n-vectors', 'err' ) % [FAIL]: the first element of the cell-array % must be an array check_is( { 'foo', pi, [2 3 5] }, 'n-vectors', 'err' ) % [FAIL]: the first element of the cell-array % must be scalar of have exactly % numel( obj )-1 % elements check_is( { 1:3 , pi, [2 3 5] }, 'n-vectors', 'err' ) % [OK]: numel( [2 3 5] ) <= 3 check_is( { 3, [2 3 5] } , '[n-vectors', 'err' ) % [OK] check_is( { [1 3], pi, [2 3 5] }, '[n-vectors', 'err' ) % [OK] check_is( { [1 2], pi, [2 3 5] }, '[n-vectors', 'err' ) % [FAIL]: [2 3 5] has less than 4 elements check_is( { [1 4], pi, [2 3 5] }, '[n-vectors', 'err' ) % [OK] check_is( { [1 4], pi, [2 3 5] }, 'n]-vectors', 'err' ) % [FAIL]: pi has not more than 1 element check_is( { [1 4], pi, [2 3 5] }, ']n-vectors', 'err' ) % [FAIL]: pi has not less than 1 element check_is( { [1 4], pi, [2 3 5] }, 'n[-vectors', 'err' ) % [OK] check_is( { [2 4], pi, [2 3 5] }, 'n[-vectors', 'err' )
See also: gettext Keywords: constraints, pre-conditions, post-conditions, checks Version: 0.13.27
Support
The Mastrave modelling library is committed to provide reusable and general - but also robust and scalable - modules for research modellers dealing with computational science. You can help the Mastrave project by providing feedbacks on unexpected behaviours of this module. Despite all efforts, all of us - either developers or users - (should) know that errors are unavoidable. However, the free software paradigm successfully highlights that scientific knowledge freedom also implies an impressive opportunity for collectively evolve the tools and ideas upon which our daily work is based. Reporting a problem that you found using Mastrave may help the developer team to find a possible bug. Please, be aware that Mastrave is entirely based on voluntary efforts: in order for your help to be as effective as possible, please read carefully the section on reporting problems. Thank you for your collaboration.