Code covered by the BSD License  

Highlights from
CounterInBase: Counting in arbitrary base

image thumbnail

CounterInBase: Counting in arbitrary base

by

 

05 Feb 2010 (Updated )

Counter in arbitrary base with a convenient interface. The counter state can be saved to disc.

CounterInBase(inbase)
function cb = CounterInBase(inbase)
% COUNTERINBASE Counter in the base specified as the argument.
% 
% Description:
%   c = CounterInBase(3)
%      Creates a new counter with base 3 and resets its state to 0.
%
%   c.next(), or
%   c.next(1)
%      Returns the state of the counter and increments it by 1.
%
%   c.next(0)
%      Returns the state of the counter and does not change its state.
%
%   c.next(20)
%      Returns a matrix of the next 20 numbers and advances the state of
%      the counter by 20.
%
%   c.save('filename')
%      Saves the counter state to disk. If no filename is given, it uses
%      the default name 'CounterInBaseState'.
%
%   c.load('filename')
%      Loads the previously stored counter state from disk. If no filename
%      is given, it loads from file with the default name
%      'CounterInBaseState'. 
%      NOTE: To be able to call the c.load() method, the counter must first
%      exist: c.load() must be preceded by the call to c=CounterInBase(x),
%      i.e. the c counter may be in any state with any base.
%
% Example:
%
%   >> c = CounterInBase(3);
%   >> c.next()
%   ans =
%        0
%   >> c.next()
%   ans =
%        1
%   >> c.next()
%   ans =
%        2
%   >> c.next()
%   ans =
%        1     0
%   >> c.next(3)
%   ans =
%        1     1
%        1     2
%        2     0
%   >> c.next(4)
%   ans =
%        0     2     1
%        0     2     2
%        1     0     0
%        1     0     1
%   >> c.next(0)
%   ans =
%        1     0     2
%   >> c.next(0)
%   ans =
%        1     0     2

% Filename     : CounterInBase.m
% Author       : Petr Posik (posik#labe.felk.cvut.cz, replace # with @ to get email)
% Created      : 04-Feb-2010 16:25:19
% Modified     : $Date: 2010-02-05 19:34:28 +0100 (pá, 05 II 2010) $
% Revision     : $Revision: 4750 $
% Developed in : 7.5.0.342 (R2007b)
% $Id: CounterInBase.m 4750 2010-02-05 18:34:28Z posik $

    %% Public methods
    cb.next = @next;
    cb.set = @set;
    cb.save = @mysave;
    cb.load = @myload;
    cb.getBase = @getBase;
    %% Public data
    %% Private data
    base = 10;
    numberbase = 0;
    numberdec = 0;
    defaultfname = 'CounterInBaseState';
%% Initialization
    if inbase < 2, 
        error('CounterInBase:WrongArgument', ...
            'The base must be greater or equal to 2.'); 
    end
    base = inbase;
%% Public methods implementation
    function b = getBase()
        b = base;
    end
    function n = next(nextn)
        % Return the 'nextn' states of the counter, advance the counter by
        % 'nextn' states.
        if nargin < 1 || isempty(nextn), nextn = 1; end
        if nextn < 0, 
            error('CounterInBase:WrongArgument',...
                'When calling next(n), n must be nonnegative.'); 
        end
        if nextn == 0, n = numberbase; return; end        
        % Advance the counter by the nextn
        n = zeros(nextn, numel(numberbase));
        for inext = 1:nextn,
            % Update the size of the output matrix if needed
            if numel(numberbase) > size(n,2),
                n = [zeros(nextn,1) n];
            end
            % Assign the counter state to the appropriate output slot 
            n(inext,:) = numberbase;
            % Add 1 to decimal state
            numberdec = numberdec + 1;
            % Add 1 to the state in the base-b
            for i = numel(numberbase):-1:1,
                numberbase(i) = mod(numberbase(i) + 1, base);
                if numberbase(i) ~= 0, break; end
                if i == 1,
                    numberbase = [1 numberbase];
                end
            end
        end
    end
    function set(n)
        % Set the state of the counter
        numberdec = n;
        numberbase = dec2base(n);
    end
    function mysave(fname)
        if nargin < 1 || isempty(fname),
            fname = defaultfname;
        end
        save(fname, 'base', 'numberdec', 'numberbase');
    end
    function myload(fname)
        if nargin < 1 || isempty(fname),
            fname = defaultfname;
        end
        S = load(fname, 'base', 'numberdec', 'numberbase');
        base = S.base;
        numberdec = S.numberdec;
        numberbase = S.numberbase;
    end
%% Private methods implementation
    function nb = dec2base(nd)
        % This is a code snippet from the MATLAB dec2base function,
        % however, it is not its precise copy.
        nd = nd(:);
        ndigits = max(1,round(log(max(nd)+1)/log(base)));
        while any(base.^ndigits <= nd)
            ndigits = ndigits + 1;
        end
        nb = zeros( numel(nd), ndigits );
        for i = ndigits:-1:1,
            nb(:,i) = mod(nd,base);
            nd = floor(nd/base);
        end
    end
end

Contact us