No BSD License  

Highlights from
vectorCounter

  • ... Updates an iterator over a variable number of variable length vectors (specified by first and last elements).
  • View all files
image thumbnail
from vectorCounter by michaelB brost
Iteraterates from start vector to finish vector.

...
function [newCountVec, newCount, hitFlag, hitIndex] = ...
    vectorCounter(xEnd, xStart, hitList, oldCountVec, oldCount)
% Updates an iterator over a variable number of variable length vectors (specified by first and last elements).
% it is useful to travel over the vertices of multidimensional lists, flow graphs, hypercubes and so on.
%
% vecCount() updates a counter from an initial vector to a final vector. 
% Optionally, a list of count values can be compared to the current count and if one matches, a flag is set.
% When the current count matches the final count, it is flagged as done.
%
% inputs: (all 5 are required)
%          xEnd        - vector of final values to compare against the current vector count (can be negative)
%          xStart      - initial vector of count values (can be negative)
%          hitList     - optional list of count values (not vectors) to compare against the current count 
%          oldCountVec - vector of the last count vector returned by this function (last values fed back in)
%          oldCount    - old scalar count returned by this function (last values fed back in)
%
% outputs: newCountVec - (required) new vector of count values
%          newCount    - (optional) new scalar count 
%          hitFlag     - (optional) true of scalar count matches any of hitList OR current and end vector counts match
%          hitIndex    - (optional) index of hitList member matching the current count. 0 if function is done.
%
% demo: 
%          vectorCounter; % <== no input arguments
%
% This function does NOT provide an enumerated list of values, rather you call it iteratively 
% from within a loop. If you want such a list, follow the example and wrap this function in a loop
%
% example: 
%                  ---------------- cut and paste --------------
% clc
% doneFlag  = false;          % not done
% lastVec   = [2 3 4];        % end vector
% firstVec  = [1 1 1];        % start vector (default for a 3-element vector)
% thisCount = 0;              % start (scalar) count is usually 0 or 1 (c vs matlab)
% thisVec   = firstVec;       % first vector is usually set to start
% hitList   = [12, 14, 50];   % want to find the 12th, 14th and 50th count elements flagged
%
% while(doneFlag == false) 
%
%   [thisVec, thisCount, hitFlag, hitIndex] = vectorCounter(lastVec, firstVec, hitList, thisVec, thisCount);
%
%   fprintf('[');
%   fprintf('%3d ', thisVec);
%   fprintf(']');
%   if(~isempty(thisCount)), fprintf('%3d ', thisCount); else fprintf(' -- '); end
%   fprintf('%3d ', hitFlag);
%   fprintf('%3d\n', hitIndex); 
%   if(hitFlag == true)
%      if(hitIndex == 0),
%         break;
%      end
%   end
% end
%                  ------------end cut and paste ---------------
%
%
% --- Iterative call results ---
%   thisVec   thisCount  hitFlag  hitIndex 
% ------------------------------------------------
%   [1 1 1]       0         0       
%   [2 1 1]       1         0       
%   [1 2 1]       2         0       
%   [2 2 1]       3         0       
%   [1 3 1]       4         0       
%   [2 3 1]       5         0       
%   [1 1 2]       6         0       
%   [2 1 2]       7         0       
%   [1 2 2]       8         0       
%   [2 2 2]       9         0       
%   [1 3 2]       10        0       
%   [2 3 2]       11        0       
%   [1 1 3]       12        1       1 <- first flag (flag at 12)
%   [2 1 3]       13        0       
%   [1 2 3]       14        1       2 <- second flag (flag at 14) 
%   [2 2 3]       15        0       
%   [1 3 3]       16        0       
%   [2 3 3]       17        0       
%   [1 1 4]       18        0       
%   [2 1 4]       19        0       
%   [1 2 4]       20        0       
%   [2 2 4]       21        0       
%   [1 3 4]       22        0       
%   [2 3 4]       23        1       0 <- done flag (3rd flag at 50 was never encountered)
% ---------------------------------------------------
%
% (C) michaelB brost Feb 2009
%


% algorithm
if(nargin == 0),
    % demo mode?
    doDemo;
    return;
end

% initialize potential outputs for early function termination
newCountVec = [];
newCount    = [];
hitFlag     = true;
hitIndex    = 0;

if(nargin ~= 5),
    error('must have 5 inputs\n');
    return;
end

if(nargout < 1),
    error('must use at least 1 output\n');
    return;
end

%check lengths
if(length(xStart) ~= length(xEnd))
    error('start and end vectors must have same lengths');
end

if(length(xStart) ~= length(oldCountVec))
    error('count, start and end vectors must have same lengths');
end

% check end >= start
for k1=length(xEnd):-1:1,
    if(xStart(k1) > xEnd(k1)),
        error(sprintf('start > end at index %d', k1));
    end
end

% check start <= current count
for k1=length(xStart):-1:1,
    if(oldCountVec(k1) < xStart(k1)),
        error(sprintf('count < start at index %d', k1));
    end
end

% check end >= current count
for k1=length(xEnd):-1:1,
    if(oldCountVec(k1) > xEnd(k1)),
        error(sprintf('count > end at index %d', k1));
    end
end

% increment the counter checking for various conditions
newCountVec = oldCountVec;
newCountVec(1) = newCountVec(1) + 1;
hitFlag  = false;
hitIndex = [];

carryFlag = false;
for k1=1:length(newCountVec),
    if(newCountVec(k1)    > xEnd(k1)),
        newCountVec(k1)   =  xStart(k1);
        if(k1 < length(newCountVec))
            newCountVec(k1+1) =  newCountVec(k1+1) + 1;
            carryFlag = true;
        else,
            carryFlag = true;
            break;
        end
            
    else,
        carryFlag = false;
    end
end

% are we done?
if(carryFlag == true),
    hitFlag = true;
    hitIndex = 0;
    
    % done
    return;
end

% update overall count - assume it is correct
newCount = oldCount + 1;

% check overall count against count list we look for
hitIndex = find(newCount == hitList);

hitFlag = false;
if(~isempty(hitIndex)),
    hitFlag = true;
end


% ------------------------------------- demo -----------------------------------
function doDemo

clc
fprintf('least significant count component is to the left\n');
fprintf('-----------------------------------------\n');
xStart  = [-3  2  -1];
xEnd    = [ 2  3   1 ];
hitList = [ 2 3 5 7 10 12 30 33];

fprintf('start condition: ');
fprintf('%3d ', xStart);
fprintf('\n');

fprintf('end condition:   ');
fprintf('%3d ', xEnd);
fprintf('\n');

fprintf('hit conditions:  ');
fprintf('%3d ', hitList);

fprintf('\n');
fprintf('pseudo code:\n');
fprintf('    do:\n');
fprintf('        [newVec, newCount, doneFlag, hitIndex] = vectorCounter(xEnd, xStart, hitList, oldVec, oldCount)\n');
fprintf('        oldVec     = newVec\n');
fprintf('        oldCount   = newCount\n');
fprintf('\n          do something here ....   \n\n');
fprintf('    until(doneFlag == true)\n');

fprintf('\n-----------------------------------------\n');


% I don't line infinite loops....
maxIter = 1e5;
nIter = 1;

newCountVec = xStart;
newCount    = 0;
fprintf('old (scalar) count----old (vector) count-------hit index\n');
while(nIter < maxIter),
    fprintf('%5d           ', nIter);
    fprintf('         [');
    fprintf('%3d, ', newCountVec(1:(end-1)));
    fprintf('%3d',   newCountVec(end));
    fprintf(']');

    % iterative update of various quantities.....
    [newCountVec, newCount, hitFlag, hitIndex] = vectorCounter(xEnd, xStart, hitList, newCountVec, newCount);

    if(hitFlag == true),
        
        fprintf('          %3d ', hitIndex);

        if(hitIndex == 0),
            fprintf(' <== DONE\n');
            break;
        else,
            fprintf('\n');
        end
    else,
        fprintf('\n');
    end
    
    nIter = nIter + 1;
    
    
end

fprintf('\n-----------------------------------------\n');

return;


Contact us at files@mathworks.com