----------------------------------------------------------------------------- Advanced MATLAB + want to model multiple and related info + Tedious way: use many variables ex) model people fn1 = 'gene'; ln1 = 'demaitre'; id1 = 1234; fn2 = 'ben'; ln2 = 'stein'; id2 = 4321; % assume even more people! + Notes: - different types causes weird behavior: A = [1 'aa'] outputs just $aa$ (weird) - even if use all strings, strings diff lengths (each char = 1 col) A = ['a' 'bb' ; 'ccc' 'd'] causes error message because row 1 needs 3 cols and row 2 needs 4 cols + Want to: - reduce redundant code - clearly model "multiple" constructs (many parts make whole) + But how? use - cell arrays - structure arrays + exploring these leads into OOP! ----------------------------------------------------------------------------- CELL ARRAYS (CAs) ================= General: + most "general" MATLAB data structure + special kind of array + holds arrays (including CAs) inside elements + arrays may be different types! + no math operations allowed (ML would get too confused) + cells called CONTAINERS ----------------------------------------------------------------------------- Creating CAs: + Preallocation with $cell$ + using {} notation ----------------------------------------------------------------------------- Creating CA: Preallocation: help cell Portion of help file: CELL Create cell array. CELL(N) is an N-by-N cell array of empty matrices. CELL(M,N) or CELL([M,N]) is an M-by-N cell array of empty matrices. ex) create an empty 2x2 cell array cell(2) gives 4 empty matrices: ans = [] [] [] [] ----------------------------------------------------------------------------- Creating CA: Using {} notation + three ways: - using {} directly: {row stuff ; more row stuff ; etc } - cell indexing: array(indicies) = {stuff} - content indexing: array{indicies} = stuff + all methods identical for results! Direct ====== A = {'ben' 'stein' ; 4321 [] } A = 'ben' 'stein' [4321] [] Cell indexing ============= A(1,1) = {'ben'}; A(1,2) = {'stein'}; A(2,1) = {4321}; A(2,2) = {[]}; A A = 'ben' 'stein' [4321] [] Content indexing ================ A{1,1} = 'ben'; A{1,2} = 'stein'; A{2,1} = 4321; A{2,2} = []; A A = 'ben' 'stein' [4321] [] See? Same results Related ops: - extending cell arrays: see Chapman p264 (ex: B=A; B{3,3} = 'hello') - deleting elements: see Chapman 266 (ex: B(1,:) = [] deletes 1st row) - reshape: see $help reshape$ (ex: reshape(A,1,4)) - combining: ex) C = [A A] creates a new cell array with twice A ----------------------------------------------------------------------------- CA: Displaying all contents + entering variable (see above examples) A + $celldisp$ celldisp(A) A{1,1} = ben A{2,1} = 4321 A{1,2} = stein A{2,2} = [] + $cellplot$ boxes indicate the number of items in each cell cellplot(A) ----------------------------------------------------------------------------- CA: Displaying some contents () -> refers to contents that a cell points to -> () index the cells directly {} -> refers to the actual contents pointed to by a cell -> {} retrieve the data directly ex) B={'ira!' [1 2;3 4]) B(2) % gives $[2x2 double]$ % $B(2)$ is really a POINTER to a data structure % The pointer is an address that gives the location in computer memory % for the contents referred to by the cell. B(1), B(2) % could also just enter $B$ ans = 'ira' ans = [2x2 double] B{2} % gives [1 2;3 4] % $B(2)$ extracts the CONTENTS of the data structure % referred to by $B(2)$ B{1}, B{2} ans = 'ira' ans = 1 2 3 4 Notes: - individual values and strings are extracted in both cases (because they are scalars) - extract individual elements of a structure inside a cell ex) B{2}(1:4) ans = 1 3 2 4 (pretty cool, huh?) ----------------------------------------------------------------------------- Application of CA: cell array of strings + strings are arrays of characters + storing unequal length strings in array sickens ML + you could pad strings with blanks, but... + Cell arrays to the rescue! S{1} = 'I'; S{2} = 'love'; S{3} = 'MATLAB!'; S S = 'I' 'love' 'MATLAB!' Shortcuts: + $help cellstr$ + S = {'I' 'love' 'MATLAB!}; Related functions: $iscellstr$, $ischar$ ----------------------------------------------------------------------------- STRUCTURE ARRAYS (SAs) ====================== General: + special kind of array + holds arrays inside elements + arrays may be different types! + addresses elements by names called FIELDS (CAs address elements by numerical indicies) + SAs usually 1-D but can be multi-dim ----------------------------------------------------------------------------- Creating SAs ============ + Just make assignments + to store values use the $.$ operator syntax: name.field=value A.fn = 'ben'; A.ln = 'stein'; A.id = 4321 pause A = fn: 'ben' ln: 'stein' id: 4321 Note: + ML will display a reference if the field is not 1-D + Try $A.x = [1:3;3:5]$ and then displaying $A$ A.x = [1:3;3:5] pause ----------------------------------------------------------------------------- Retrieve values A.fn ans = ben ----------------------------------------------------------------------------- Fields can be any other data structure, including another SA Create a new SA B.tests = [99 88] B.projects = [10 10 10]; B pause B = tests: [99 88] projects: [10 10 10] Create new field of A called $scores$ Assign scores in $B$ to $A$ A.scores = B A = fn: 'ben' ln: 'stein' id: 4321 x: [2x3 double] % for 9:05am, this is supposed to be 2x3, not 2x2 scores: [1x1 struct] % this is indeed correct! Notes: + $scores$ and $x$ values NOT 1-D, so ML uses pointers + But, values are still there! + Access particular value name.(substructure access) means name.name.field A.scores.tests ans = 99 88 ----------------------------------------------------------------------------- Additional Things: help struct help rmfield help getfield help setfield Preallocation SA1 = struct('x',0,'y',1) SA1 = x: 0 y: 1 Removing fields + ML's SAs have a feature not common to other languages + Entering $rmfield$ will remove the NAME and CONTENTS of a field A = rmfield(A,'x') pause A = fn: 'ben' ln: 'stein' id: 4321 scores: [1x1 struct] ----------------------------------------------------------------------------- Array of Structures + can create an array of SAs by "adding" another SA - start with initial SA and make another - give 1 or more fields a value - ML automatically creates a new SA - empty fields represented as empty array $[]$ A(2).fn = 'gene'; A(2) ans = fn: 'gene' ln: [] id: [] x: [] scores: [] + What's an array of SAs??? A A = 1x2 struct array with fields: fn ln id x scores + to get individual SAs, enter $A(1),A(2)$ pause ----------------------------------------------------------------------------- Cell Arrays and Structure Arrays + Store info with $struct$ s = struct('colors',{'blue','red','yellow'}) s = 1x3 struct array with fields: colors + $struct2cell$ and $cell2struct$ help cell2struct CELL2STRUCT Convert cell array to structure array. S = CELL2STRUCT(C,FIELDS,DIM) converts the cell array C into the structure S by folding the dimension DIM of C into fields of S. SIZE(C,DIM) must match the number of field names in FIELDS. FIELDS can be a character array or a cell array of strings. Huh? -> the number of columns of C must match the number of elements of FIELDS -> FIELDS is going to be 1-D array A = {'ben' 'stein' ; 4321 []}; use $reshape$ (takes elements from cols) A = cell2struct(reshape(CA,1,4),{'fn','id','ln','blank'},2) SA = fn: 'ben' id: 4321 ln: 'stein' blank: [] Get lost? Check type: class(SA) % struct class(CA) % cell ----------------------------------------------------------------------------- Do structure array fields know about changes to another structure array? No. See below: clear echo on clc Create an SA sa2.y=2; pause store $sa2$ as a field of $sa1$ sa1.x=sa2; pause Check output sa1 % x: [1x1 struct] sa1.x % y: 2 sa1.x.y % 2 pause Now, change value inside $sa2$ sa2.y=3; pause What happened to $sa1$ and $sa2$? sa2 % y: 3 sa2.y % 3 pause % sa1 % x: [1x1 struct] sa1.x % y: 2 sa1.x.y % 2 Yes, the values inside x do NOT change. This behavior is different in Java, where the values change. $sa1.x$ still points to an array, but that array does not change when $sa2$ changes. -----------------------------------------------------------------------------