Cookbook: Difference between revisions
Carandraug (talk | contribs) |
Carandraug (talk | contribs) (→Retrieve a field value from all entries in a struct array: strcmpi for indexing) |
||
Line 32: | Line 32: | ||
{cases(:).name} | {cases(:).name} | ||
You are also not limited to return all elements, you may use logical indexing from other fields to get values from others | You are also not limited to return all elements, you may use logical indexing from other fields to get values from the others: | ||
[cases([cases(:).age] > 34).contaminated] | [cases([cases(:).age] > 34).contaminated] ## return contaminated state from all cases older than 34 | ||
[cases(strcmp({cases(:).protein}, "CDK2").tube] ## return all tube numbers with protein CDK2 | |||
== Input/output == | == Input/output == |
Revision as of 18:29, 21 August 2012
An Octave cookbook. Each entry should go in a separate section and have the following subsection: problem, solution, discussion and maybe a see also.
Structures
Retrieve a field value from all entries in a struct array
Problem
You have a struct array with multiple fields, and you want to acess the value from a specific field from all elements. For example, you want to return the age from all pacients in the following case:
cases(1).name = "Bob"; cases(1).age = 45; cases(1).contaminated = true; cases(2).name = "Andrew"; cases(2).age = 21; cases(2).contaminated = true; cases(2).name = "Kevin"; cases(2).age = 24; cases(2).contaminated = false;
Solution
Indexing the struct returns a comma separated list so use them to create a matrix.
[cases(:).age]
This however does not keep the original structure of the data, instead returning all values in a single column. To fix this, use reshape()
.
reshape ([cases(:).age], size (cases))
Discussion
Returning all values in a comma separated lists allows you to make anything out of them. If numbers are expected, create a matrix by enclosing them in square brackets. But if strings are to be expected, a cell array can also be easily generated with curly brackets
{cases(:).name}
You are also not limited to return all elements, you may use logical indexing from other fields to get values from the others:
[cases([cases(:).age] > 34).contaminated] ## return contaminated state from all cases older than 34 [cases(strcmp({cases(:).protein}, "CDK2").tube] ## return all tube numbers with protein CDK2
Input/output
Mathematics
Find if a number is even/odd
Problem
You have a number, or an array or matrix of them, and want to know if any of them is an odd or even number, i.e., their parity.
Solution
Check the remainder of a division by two. If the remainder is zero, the number is odd.
mod (value, 2) ## 1 if odd, zero if even
Since mod()
acceps a matrix, the following can be done:
any (mod (values, 2)) ## true if at least one number in values is even all (mod (values, 2)) ## true if all numbers in values are odd any (!logical (mod (values, 2))) ## true if at least one number in values is even all (!logical (mod (values, 2))) ## true if all numbers in values are even
Discussion
Since we are checking for the remainder of a division, the first choice would be to use rem()
. However, in the case of negative numbers mod()
will still return a positive number making it easier for comparisons. Another alternative is to use bitand (X, 1)
or bitget (X, 1)
but those are a bit slower.
Note that this solution applies to integers only. Non-integers such as 1/2 or 4.201 are neither even nor odd. If the source of the numbers are unknown, such as user input, some sort of checking should be applied for NaN, Inf, or non-integer values.
See also
Find if a number is an integer.