function vect = SmartVec(start,slength,step,mode) % vect = SmartVec(start,slength,step,mode) % makes sequence that satisfies certain conditions. % % START is a scalar or vector with starting values of an sequence % SLENGTH is a scalar or vector (with the same length as START) and % indicates the length of all sequences or the length of the % corresponding sequence in START. % STEP is optional and indicates the stepsize of the series. Default is 1 % STEP can be a scalar and indicate the stepsize for all segments, or it % can be the same lenght as START if you want to provide a different % stepsize for each segment % MODE is optional and has two options: % 'neg' : the produced sequence will satisfy : diff([n n+1]) = -1 % 'flat' : the produced sequence will satisfy : diff([n n+1]) = 0 % if no mode, the produced sequence will satisfy : diff([n n+1]) = 1 % MODE can be the third input to the function if you do not wish to % override the default stepsize % % examples: % SmartVec([1 5],3) % ans = % 1 2 3 5 6 7 % SmartVec([1 5],[3 5]) % ans = % 1 2 3 5 6 7 8 9 % SmartVec([1 5],[3 5],'neg') % ans = % 1 0 -1 5 4 3 2 1 % SmartVec([1 5],[3 5],2,'neg') % ans = % 1 -1 -3 5 3 1 -1 -3 % SmartVec([1 5],3,'neg') % ans = % 1 0 -1 5 4 3 % SmartVec([1 5],[3 5],'flat') % ans = % 1 1 1 5 5 5 5 5 % SmartVec([1 5],3,'flat') % ans = % 1 1 1 5 5 5 % DN 2008-04-21 Written it, extention of SmartVec % DN 2008-09-05 Updated engine, no more meshgrid, less transposes needed % DN 2010-08-01 Now supports different stepsize than 1 for vectors % DN 2011-07-23 Now supports different stepsizes for each segment % check input psychassert(length(slength)==1 || length(slength)==length(start),'slength must be a scalar or a vector with the same length as start'); qplat = false; qneg = false; mult = 1; if nargin >= 3 qhavemode = false; % backwards compatibility, mode can be third input as well if nargin==3 && ischar(step) mode = step; qhavemode = true; end if nargin==4 || qhavemode switch mode case 'neg' qneg = true; case 'flat' qplat = true; otherwise error('Mode "%s" not recognized.\nUse "neg" of "flat".',mode) end end if isnumeric(step) && ~isempty(step) mult = step; end end psychassert(length(mult)==1 || length(mult)==length(start),'step must be a scalar or a vector with the same length as start'); maxlen = max(slength); slength = slength(:); % do the work start = start(:)'; startmat = start(ones(maxlen,1),:); if ~qplat vec = [0:maxlen-1]'; vecmat = vec(:,ones(1,length(start))); if any(mult~=1) if ~isscalar(mult) vecmat = bsxfun(@times,mult,vecmat); else vecmat = mult .* vecmat; end end if qneg vecmat = -1*vecmat; end else vecmat = zeros(maxlen,length(start)); end totmat = startmat + vecmat; vect = totmat(:)'; % if slength is a vector, we have to trim parts of the output if ~isscalar(slength) && length(unique(slength))>1 MinInd = cumsum([0 maxlen*ones(1,length(slength)-1)]).'+1; MaxInd = num2cell(MinInd+slength-1); indcell = cellfun(@(a,b)a:b,num2cell(MinInd),MaxInd,'UniformOutput',false); vect = vect([indcell{:}]); end