%------------------------------------------------------------------------------ % 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 CA = {'ben' 'stein' ; 4321 []}; % use $reshape$ (takes elements from cols) SA = 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. %------------------------------------------------------------------------------