Cookbook

From Octave
Jump to navigation Jump to search

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 others. The following example returns the contaminated state from all test cases older than 34

 [cases([cases(:).age] > 34).contaminated]

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.

Plotting

User input