Update odometer

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
 Other toolboxes required update_odometer Increases a vector subject to limits on how large each entry can be none Helper functions
 This is a helper function that only exists to aid other functions in QETLAB. If you are an end-user of QETLAB, you likely will never have a reason to use this function.

update_odometer is a function that implements an "odometer": that is, it increases the right-most entry of a vector by 1. If that right-most entry is now larger than its maximum allowed value then it "rolls over" to 0 and the second-to-right-most entry increases by 1. Similarly, if this entry is now too larger, it rolls over, and so on.

This function is useful if you are in a situation where you want to nest multiple for loops, but you don't know beforehand exactly how many of them there will be (since it depends on user input, for example).

Syntax

• NEW_IND = update_odometer(OLD_IND,UPPER_LIM)

Argument descriptions

• OLD_IND: The vector to be updated.
• UPPER_LIM: A vector of the same length as OLD_IND with the property that its j-th entry specifies the "roll over" value of the j-th entry of OLD_IND. That is, the j-th value of OLD_IND is constrained to being in the interval from 0 to UPPER_LIM(j)-1 (inclusive).

Examples

The following code loops over all vectors of length 2 with the property that their first entry is 0, 1, or 2, and their second entry is 0 or 1:

```>> v = [0,0]; upper_lim = [3,2];
>> for j = 0:prod(upper_lim)-1
v = update_odometer(v,upper_lim)
end

v =

0     1

v =

1     0

v =

1     1

v =

2     0

v =

2     1

v =

0     0```

Source code

Click on "expand" to the right to view the MATLAB source code for this function.

1. `%%  UPDATE_ODOMETER    Increases a vector subject to limits on how large each entry can be`
2. `%`
3. `%   NEW_IND = update_odometer(OLD_IND,UPPER_LIM) increases the last entry`
4. `%   of the vector OLD_IND by 1, unless that would make it larger than the`
5. `%   last entry of the vector UPPER_LIM. In this case, it sets the last`
6. `%   entry to 0 and instead increases the *second*-last entry of OLD_IND,`
7. `%   unless that would make it larger than the second-last entry of`
8. `%   UPPER_LIM. In this case, it sets the second-last entry to 0 and instead`
9. `%   increases the *third*-last entry of OLD_IND (and so on; it works like`
10. `%   an odometer).`
11. `%`
12. `%   This function is useful when you want to have k nested for loops, but k`
13. `%   isn't specified beforehand. For example, instead for looping over i and`
14. `%   j going from 1 to 3, you could loop over a single variable going from`
15. `%   1 to 3^2, and set [i,j] = update_odometer([i,j],[3,3]) at each step`
16. `%   within the loop.`
17. `%`
18. `%   URL: http://www.qetlab.com/update_odometer`
19. ` `
20. `%   requires: nothing`
21. `%   author: Nathaniel Johnston (nathaniel@njohnston.ca)`
22. `%   package: QETLAB`
23. `%   last updated: December 11, 2014`
24. ` `
25. `function new_ind = update_odometer(old_ind,upper_lim)`
26. `    % Start by increasing the last index by 1.`
27. `    ind_len = length(old_ind);`
28. `    new_ind = old_ind;`
29. `    new_ind(end) = new_ind(end)+1;`
30. ` `
31. `    % Now we work the "odometer": repeatedly set each digit to 0 if it`
32. `    % is too high and carry the addition to the left until we hit a`
33. `    % digit that *isn't* too high.`
34. `    for j = ind_len:-1:1`
35. `        % If we've hit the upper limit in this entry, move onto the next`
36. `        % entry.`
37. `        if(new_ind(j) >= upper_lim(j))`
38. `            new_ind(j) = 0;`
39. `            if(j >= 2)`
40. `                new_ind(j-1) = new_ind(j-1) + 1;`
41. `            else % we're at the left end of the vector; just stop`
42. `                return;`
43. `            end`
44. `        else`
45. `            return; % always return if the odometer doesn't turn over`
46. `        end`
47. `    end`
48. `end`