matlab_-_datatypes
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
matlab_-_datatypes [2012/10/06 02:43] – jochen | matlab_-_datatypes [2012/10/06 15:58] (current) – Indexing jochen | ||
---|---|---|---|
Line 5: | Line 5: | ||
A variable can be thought of as a storage container that has the following properties: | A variable can be thought of as a storage container that has the following properties: | ||
* links a name (identifier) to a value (or list of values) | * links a name (identifier) to a value (or list of values) | ||
- | * is available in a workspace, i.e. when a function is called, variables available in the calling workspace are hidden, unless they are **'' | + | * is available in a workspace, i.e. when a function is called, variables available in the calling workspace are hidden (different function code files can use the same variable names without conflict), unless they are **'' |
* can be assigned a (new) value (or list of values) using the **'' | * can be assigned a (new) value (or list of values) using the **'' | ||
* has a specific datatype, which can change during the course of a program (or command line session) | * has a specific datatype, which can change during the course of a program (or command line session) | ||
Line 82: | Line 82: | ||
A special case is the **'' | A special case is the **'' | ||
- | ===== Character datatype | + | Please note that instead of being keywords (such as in C/C++), datatypes are not " |
+ | |||
+ | ==== Character datatype ==== | ||
Given that Matlab variables can be arrays of arbitrary size, single characters, as well as " | Given that Matlab variables can be arrays of arbitrary size, single characters, as well as " | ||
Line 98: | Line 100: | ||
% is their distance in the alphabet, in this case 3!</ | % is their distance in the alphabet, in this case 3!</ | ||
- | ===== Cell compound data ===== | + | And that also means that a variable |
- | In many situations it is necessary to store data of different types (e.g. a name/string together with a number, such as age) in a " | + | |
- | To define a cell array as well as to address the **content** of a cell, Matlab uses the "curly braces" | + | ==== Compound datatypes ==== |
+ | In many situations it is necessary to store data of different types (e.g. a name/string together with a number, such as age) in a " | ||
+ | |||
+ | These compound datatypes are further sub-divided into two types: one where elements are (mainly) addressed by a numeric (or equivalent) indices, and one where elements are accessed by a field name in a tree-like structure (same rules as identifiers, | ||
+ | |||
+ | === Cell datatype === | ||
+ | The **'' | ||
+ | |||
+ | To define a cell array as well as to address the **content** of a cell, Matlab uses the "curly braces" | ||
name_and_age = {'John Doe', 41}; | name_and_age = {'John Doe', 41}; | ||
Line 113: | Line 122: | ||
Put differently, | Put differently, | ||
+ | |||
+ | Also, please note that if you use a variable (numeric, char, or compound!) when creating a new compound variable or setting one or several elements of a compound variable, the values in the compound variable will be **copies** of the content of the original variable (or rather, if the variable is altered, a copy is created). For instance:< | ||
+ | n = [12, 14, 10]; | ||
+ | s = ' | ||
+ | |||
+ | % store variables in compound variable | ||
+ | c = {s, n}; | ||
+ | |||
+ | % re-assign index 2 of n variable | ||
+ | n(2) = 18; | ||
+ | |||
+ | % and then c still contains [12, 14, 10] in its second cell element!</ | ||
+ | |||
+ | === Struct datatype === | ||
+ | The other compound datatype in Matlab is the **'' | ||
+ | |||
+ | Syntax-wise, | ||
+ | |||
+ | The obvious advantage is that code usually becomes less cryptic, given that instead of using syntax such as **'' | ||
+ | |||
+ | Please note that variables of type struct still can be of arbitrary size! This means that a list of structures (e.g. 5 people' | ||
+ | this_name = people(3).name; | ||
+ | this_age = people(3).age;</ | ||
+ | |||
+ | In turn this means that if the index expression is omitted, the **'' | ||
+ | all_names = {people.name};</ | ||
+ | |||
+ | === Multi-layered compounding === | ||
+ | Each cell and struct field can contain any of Matlab' | ||
+ | main_tree.leaf(3).subfield{4}(11: | ||
+ | |||
+ | If you see such a piece of code this can be translated into | ||
+ | * main_tree is of datatype struct (and must be of size 1x1, i.e. a scalar struct, to be valid) | ||
+ | * one of the field names of main_tree is called leaf, is also of datatype struct with at least field name subfield, and it presumably has at least 3 elements (see comment below) | ||
+ | * the subfield (of the third leaf!) is of type cell with at least 4 elements | ||
+ | * the 4th element of the subfield is a numeric array | ||
+ | * numeric indices 11 through 20 (of this numeric array) are set to 1 | ||
+ | |||
+ | Please be aware that this line of code is also valid if main_tree is not yet defined! In that case, the **'' | ||
+ | |||
+ | As you can see, while Matlab' | ||
+ | |||
+ | ==== Function handles ==== | ||
+ | The **'' | ||
+ | * the type of operation that is to be applied to a variable (or expression) is not fully determinable before code is run, in which case a function handle can be used to call a variable function (instead of using a syntax construction that selects from all possible options, which still could be insufficient if a function can be user defined) | ||
+ | * an argument in a function call itself is "an operation" | ||
+ | * a function is only available in a certain context (private function or sub-function in an M-file), in which case a function handle can be created and returned, allowing functions outside the original scope to use this function after all | ||
+ | |||
+ | Given the fact that this feature is fairly advanced, I won't be giving any in-depth examples at this point. Just be aware that variables can also be of type **'' | ||
+ | |||
+ | ==== User-defined datatypes ==== | ||
+ | Matlab allows users to add functionality by creating text files with the **'' | ||
+ | |||
+ | For this purpose, Matlab allows to define new datatypes (classes) by adding folders with a leading **'' | ||
+ | |||
+ | Again, this is fairly advanced coding and will not be discussed in-depth at this point. There are, however, a few important aspects I want to mention: | ||
+ | * the internal representation of objects is supposed to be of type struct | ||
+ | * indexing operations (incl. the struct syntax of **'' | ||
+ | * NeuroElf makes use of this feature by allowing a more C++/Visual Basic style syntax:< | ||
+ | % load a VMR into an xff object | ||
+ | vmr = xff(' | ||
+ | |||
+ | % call the function in @xff/ | ||
+ | vmr.Browse; | ||
+ | |||
+ | % get xfigure object of the main UI figure | ||
+ | neuroelf_gui; | ||
+ | global ne_gcfg; | ||
+ | mainfig = ne_gcfg.h.MainFig; | ||
+ | |||
+ | % switch to " | ||
+ | mainfig.ShowPage(2);</ | ||
+ | |||
+ | ===== Indexing ===== | ||
+ | It is both a blessing and a curse that Matlab uses the same language elements for passing arguments into a function and indexing into a non-scalar array:< | ||
+ | randvals = randn(3, 3); | ||
+ | |||
+ | % accessing the value at the 3rd row and 2nd column | ||
+ | randvals(3, 2) | ||
+ | |||
+ | % computing the sum along the 2nd dimension | ||
+ | sum(randvals, | ||
+ | |||
+ | In both cases, common parentheses, | ||
+ | * sub-select values (array elements) from a non-scalar variable | ||
+ | * pass arguments (in this case the variable '' | ||
+ | |||
+ | One of the reasons is that even the syntax **'' | ||
+ | |||
+ | The blessing is that, for user defined objects, this can be used to create very elegant code. The curse, on the other hand, is that it cannot be determined if an expression is an indexing operation of a function call, in cases such as<code matlab> | ||
+ | |||
+ | ==== Subscript indexing ==== | ||
+ | Given that, in principle, all of Matlab' | ||
+ | |||
+ | But subscript indexing not only allows to select a single element, but also ranges of elements. For this purpose, each indexing expression can be a list of indices. When a variable is accessed to " | ||
+ | |||
+ | <code matlab>% creating a 5x4, i.e. 5 rows and 4 columns, variable with random values | ||
+ | fivebyfour = randn(5, 4); | ||
+ | |||
+ | % reading the value at row 3, column 1 | ||
+ | fivebyfour(3, | ||
+ | |||
+ | % reading the entire 2nd row | ||
+ | secondrow = fivebyfour(2, | ||
+ | |||
+ | % reading the 4th column | ||
+ | fourthcol = fivebyfour(:, | ||
+ | |||
+ | % reading the 2nd to 4th row, 1st to 3rd column | ||
+ | smaller3x3 = fivebyfour(2: | ||
+ | |||
+ | % reading all uneven rows and columns | ||
+ | unevens = fivebyfour(1: | ||
+ | |||
+ | % reading (in this order) 4th, 1st, and 3rd rows (complete) | ||
+ | r413 = fivebyfour([4, | ||
+ | |||
+ | % repeatedly reading the 2nd column | ||
+ | col2times3 = fivebyfour(:, | ||
+ | |||
+ | All but the last of these expressions are also valid for assignment, in which case the value or array being assigned must either be a scalar (which is then stored in all of the written-to elements) or match in size (i.e. to write into a 3x3 sub-part, only a 1x1 or 3x3 right-hand-side value/array can be used). | ||
+ | |||
+ | In addition to these expressions, | ||
+ | |||
+ | <code matlab>% increase the size to 6-by-6 | ||
+ | fivebyfour(4: | ||
+ | |||
+ | Importantly, | ||
+ | * first, the array is expanded, with all new elements being assigned the " | ||
+ | * for numeric variables this is 0 | ||
+ | * for logical variables this is **'' | ||
+ | * for char variables this is also 0 (which is NOT the blank character)! so this syntax should not be used to extend a string! | ||
+ | * for cell arrays this is an empty double array (empty cell content) | ||
+ | * for struct arrays all fields are empty double arrays | ||
+ | * next, the portion that is specified with the indexing expression is assigned the provided value(s) | ||
+ | |||
+ | This means that in the above example, the first three values of the 5th and 6th columns will be 0! | ||
+ | |||
+ | And finally, this type of indexing also allows to **shrink** an array by a special syntax:< | ||
+ | fivebyfour(2, | ||
+ | |||
+ | % remove 3rd and 4th column | ||
+ | fivebyfour(:, | ||
+ | |||
+ | Please note: for higher dimensional variables (3D/4D), all but one indexing expression **must** be **'':'' | ||
+ | |||
+ | Overall, the idea behind using subscripts is the most " | ||
+ | |||
+ | <code matlab>% assuming that vol3d is a 3D array, getting three slices in the middle | ||
+ | xyslice = vol3d(:, :, 128); | ||
+ | xzslice = vol3d(:, 128, :); | ||
+ | yzslice = vol3d(128, :, : | ||
+ | |||
+ | ==== Single expression indexing ==== | ||
+ | Matlab' | ||
+ | |||
+ | <code matlab>% order of values in a 3x3 variable | ||
+ | ttvar(1, 1) | ||
+ | ttvar(2, 1) | ||
+ | ttvar(3, 1) | ||
+ | ttvar(1, 2) | ||
+ | ttvar(2, 2) | ||
+ | ttvar(3, 2) | ||
+ | ttvar(1, 3) | ||
+ | ttvar(2, 3) | ||
+ | ttvar(3, 3)</ | ||
+ | |||
+ | The total number of values is simply the product of all dimension lengths (size). There are contexts in which, for instance, an operation has to be performed to each individual element of an array, regardless of position. Matlab thus allows to access all elements with a single index expression: | ||
+ | |||
+ | <code matlab>% accessing element ttvar(2, 2) via single index | ||
+ | ttvar(5)</ | ||
+ | |||
+ | Please note that this syntax can be extremely misleading, particularly for people unfamiliar with Matlab index expressions! There is, however, one extremely useful application for this, in which **all** values of an array are considered as a single column: | ||
+ | |||
+ | <code matlab>% computing the total average over a 3D volume | ||
+ | avgslice = mean(vol3d, 3); | ||
+ | avgcolumn = mean(avgslice, | ||
+ | totalavg = mean(avgcolumn); | ||
+ | |||
+ | % alternatively, | ||
+ | totalavg = mean(vol3d(: | ||
+ | |||
+ | Please note that for multi-dimensional arrays, this syntax leads to an error if the index exceeds the total number of elements, i.e. an array cannot be resized with a single index expression! | ||
+ | |||
+ | ==== Variables as indices ==== | ||
+ | Matlab also allows to use (numeric) variables (and return values of functions) to be used in index expressions:< | ||
+ | four_by_four = randn(4, 4); | ||
+ | |||
+ | % select random row | ||
+ | rrowindex = ceil(4 * rand(1, 1)); | ||
+ | rrowdata = four_by_four(rrowindex, | ||
+ | |||
+ | % select random column without variable | ||
+ | rcoldata = four_by_four(:, | ||
+ | |||
+ | % and select a random value from an array without " | ||
+ | randomarrayvalue = four_by_four(ceil(numel(four_by_four) * rand(1, 1)))</ | ||
+ | |||
+ | In this context, the **'' | ||
+ | |||
+ | This can be used, for instance, when an operation has to be applied to a data, say, slice by slice:< | ||
+ | volsize = size(vol3d); | ||
+ | |||
+ | % " | ||
+ | for slice = 1: | ||
+ | |||
+ | % compute critical value | ||
+ | critval = critval_function(vol3d(:, | ||
+ | | ||
+ | % break (leave loop) if threshold is hit | ||
+ | if critval >= 10 | ||
+ | break; | ||
+ | end | ||
+ | end</ | ||
+ | |||
+ | ==== Logical indexing ==== | ||
+ | On top of using numbers (or numeric expressions, | ||
+ | |||
+ | <code matlab>% generate an array with 10 random numbers | ||
+ | r = randn(10, 1); | ||
+ | |||
+ | % sum all numbers that are greater (or equal) 0 | ||
+ | pos_sum = sum(r(r >= 0))</ | ||
+ | |||
+ | The indexing expression **'' | ||
+ | |||
+ | If the comparison operator is used on and then returns a multi-dimensional logical array, the indexing operation automatically converts the result into a column vector (given that arbitrary elements are selected, not allowing the result to be regularly shaped). | ||
+ | |||
+ | Logical indexing can also be used with the subscript notation (more than one expression), | ||
+ | r10x10 = randn(10, 10); | ||
+ | |||
+ | % sub-select some rows and some columns | ||
+ | randompart = r10x10(randn(1, |
matlab_-_datatypes.txt · Last modified: 2012/10/06 15:58 by jochen