---------------------------------------------------------------------- CELL ARRAY AND STRUCT ARRAY SYNTAX -- DETAILS 2019/11/04 ---------------------------------------------------------------------- What is vectorized code? Vectorized code is code that accesses or or does something with MULTIPLE components of an array at once. The following are all vectorized code: x = [1 2 3 4 0]; y1 = x(2:4); x(2,:) = [5 4 3 2 1]; y2 = x(1,:); z = []; % Just initialization to empty, not vectorized z = [z 7]; % Concatenation is vectorized code z = [z x 7]; z = z.*2; z = z.^2; NON-vectorized syntax for both simple array and special array (cell or struct) is specified as follows, with no exception: - use () to enclose an index for a simple array (type double, char, uint8, etc.) - use {} to enclose an index for a cell array - use () to enclose an index for an array of structs Vectorized syntax is straight forward for simple arrays but MESSY for special arrays. This document presents a useful subset of the vectorized and non-vectorized syntax for special arrays. Use vectorized syntax with caution--test your code and refer to the documentation--especially when you switch to a new version of MATLAB. Recommendation: Use vectorized syntax on special arrays only when you can and when you will test your code immediately, e.g., when doing projects, but not writing exams! ---------------------------------------------------------------------- CELL ARRAYS ---------------------------------------------------------------------- INITIALIZING (1) Empty cell array C= {}; % length of C is zero D= cell(0,0); % length of D is zero (2) Non-empty cell array E= cell(2,5); % E is a 2x5 cell array; each component is an % empty array to which a variable of any type % can be added F= {'string 1', 45, [1 4 7], [], 'string 5'}; % a 1x5 cell array % Can first initialize G = cell(1,4) here, but not required for k=1:4 G{k}= k*2; % assigns components to G one at a time end Any type of variable (e.g. char, string, matrix) can be assigned to a single cell of a cell array. ADDRESSING WITH INDICES (1) Access array indices within a particular cell C= {'string 1', 45, [1 4 7], [], 'string 5'}; x= C{3}; % x is the array [1 4 7] y= C{3}(2); % y is 4 z= C{5}(3:6); % z is 'ring' u = C{4}; % u is the empty array [] (2) Access the first 3 elements of cell array C with these four elements: {7, 'cell 2', 23, 'cell 4'} d= C(1:3); % d is a cell array: {7, 'cell 2', 23} % Note the use of PARENTHESES (not curly % braces). The syntax C(1:3) outputs an % array; this is VECTORIZED code, and d has % the type cell. [e, f, g]= C{1:3} % e, f, and g contain 7, 'cell 2', and 23, % respectively (each of the first 3 % components of C). Note the use of % BRACES on the right-hand-side. % The syntax C{1:3} outputs the INDIVIDUAL % elements inside cell array C, so % e, f, and g have the type of the % individual elements inside C. h= C{1:3}; % h contains 7 only. Although the % right-hand-side outputs three individual % elements, using only one variable on % the left-hand-side means that only one, % the first, element can be stored. (3) Given cell arrays d and sd, copy a few cells of d into sd a. Standard solution - non-vectorized code for k= 1:4 sd{k}= d{k}; % note curly braces end b. Vectorized solution sd(1:4)= d(1:4); % MUST use parentheses (vector notation) % because of VECTORIZED code. Note the type % on both sides are the same (cell). c. The following also works, because the type on both sides of the assignment operator are the same (both are cells). In fact, this is the length-one array case of vectorized code: for k= 1:4 sd(k)= d(k); % Note parentheses, left and right side have % the same type (cell) end But if you're assigning, say, a number (something that is not contained in a cell array), then you must use the curly brackets instead of parentheses: for k= 1:4 sd{k}= k; % Note curly braces. Here parentheses won't work % because the type on the left and right side end % are different ---------------------------------------------------------------------- STRUCT ARRAYS ---------------------------------------------------------------------- (1) Build a struct array by direct assignment to each component a. Skip initialization of array and increase size during a loop: for k= 1:4 T(k)= struct('x', rand, 'y', rand); end b. To keep Matlab from warning you that your array is growing in size, you can build the array from the last item to the first instead: for k= 4:-1:1 T(k)= struct('x', rand, 'y', rand); end This way, in the first iteration you create a struct array of length 4, with structs of the specified field names (but not values) in the first three components. Assigning to the last component of a struct array is the only way to initialize a struct array to a length greater than 1. (2) Initialize length 0 struct arrays r= struct([]); % r has length 0 and no fields s= struct('x',{},'y',{}); % s is length 0 struct with fields % 'x' and 'y' Note that the "type" of struct array r and struct array s are different: one has no field, the other has fields 'x' and 'y'. (3) Initialize length 1 struct with field names t= struct('x',[],'y',[]); % t has length ONE, not 0 (4) Invalid initialization You cannot initialize an empty array (default type) and then make an indexed assignment of a struct to that array: T= []; % T has type double k= 0; while k<9 k= k+1; T(k)= struct('x', rand, 'y', rand); % ERROR % Error because T has type double whereas the % above statement attempts to change the type of % T(k) to a struct end But the following DOES work in versions after 2014: T= []; % T has type double while length(T)<9 T= [T struct('x', rand, 'y', rand)]; % CORRECT only in % NEW Matlab end