matlab_-_datatypes
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
matlab_-_datatypes [2012/10/06 04:08] – re-written jochen | matlab_-_datatypes [2012/10/06 15:58] (current) – Indexing jochen | ||
---|---|---|---|
Line 195: | Line 195: | ||
mainfig.ShowPage(2);</ | 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.1349496522.txt.gz · Last modified: 2012/10/06 04:08 by jochen