Mercurial > hg > ishara
view sequences/@seq/seq.m @ 6:0ce3c2070089
Removed duplicate code and fixed doc in timed_action.
author | samer |
---|---|
date | Mon, 14 Jan 2013 14:33:37 +0000 |
parents | 3f77126f7b5f |
children | f0a3d7d7a0e3 |
line wrap: on
line source
% seq - Base class for sequences classdef seq methods (Abstract) x=head(a) % seq(A) -> A. b=next(a) % seq(A) -> seq(A). s=elsize(a) % seq([E->T]) -> E:[[1,D]]. s=tostring(a) % seq(A) -> string. end methods (Sealed=true) function varargout=size(a,n) s=elsize(a); if nargin>1, varargout={s(n)}; elseif nargout<=1, varargout={s}; else varargout=[num2cell(s(1:nargout-1)),{prod(s(nargout:end))}]; end if any(isnan(cell2mat(varargout))) error('seq:Element size indeterminate'); end end function l=length(a,n), l=max(size(a)); end function n=numel(a, varargin), n=prod(size(a)); end function n=end(a,k,m) if m==length(elsize(a)), n=size(a,k); else n=prod(size(a)); end end function display(o) display(sprintf(' %s :: seq([[%s]])\n', tostring(o), ... cat_sep(',',cellmap(@fmt_dim,num2cell(elsize(o)))))); function s=fmt_dim(x), if isnan(x), s='_'; else s=num2str(x); end; end end function y=subsref(a,S) switch S(1).type case '()', y=paren(a,S(1)); case '.', fn=S(1).subs; y=map(@(z)getfield(z,fn),a); end if length(S)>1, y=subsref(y,S(2:end)); end end end methods % decons - head and tail of sequence % decons :: seq(A) -> A, seq(A). function [x,b]=decons(a) x=head(a); b=next(a); end % last - get the last array in a sequence (there must be at least one element) % % last :: seq(A) -> A. function z=last(y) while ~isempty(y), x=y; y=next(x); end z=head(x); end function f=headfn(o), f=@()head(o); end % ------------- WRAPPERS FOR OTHER SEQ CLASSES --------------------------- function y=take(n,x), y=seq.take(n,x); end function y=takewhile(f,x), y=seq.takewhile(f,x); end % drop - Drop the first n alements of sequence % % drop :: natural, seq A -> seq A function s=drop(n,s), for i=1:n, s=next(s); end; end % dropwhile - Drop elements of sequence that satisfy condition % % drop :: (A->bool), seq A -> seq A function s=dropwhile(f,s) while ~isempty(s) && f(head(s)), s=next(s); end end % nth1 - Get nth element of a sequence starting at 1 % % nth1 :: natural, seq X -> X, seq X ~'tail of sequence'. function [x,tail]=nth1(n,X) z=drop(n-1,X); x=head(z); if nargout>=2, tail=next(z); end end % once - equivalent to take(1,...) % % once :: seq A -> seq A. function Y=once(X), Y=cons(head(X),[]); end function x=map(fn,e,varargin), x=seq.map(fn,e,varargin{:}); end function x=mapaccum(fn,s0,y), x=seq.mapaccum(fn,s0,y); end function x=select(fn,y), x=seq.select(fn,y); end function y=cache(x), y=seq.cache(x); end function y=buffer(x,varargin), y=seq.buffer(x,varargin{:}); end % scanl - scanl combinator for sequences % % This function applies an associative operator to a list of arguments, % starting from the left using the given starting element. % % scanl :: % (X,Y->X) ~'associative binary operator', % X ~'initial element', % seq Y ~'a sequence' % -> seq X. function x=scanl(fn,e,y,varargin), x=seq.scanl(fn,e,y,varargin{:}); end % concat - Concatenate sequences % % concat :: % seq(seq(A)) ~ 'sequence of sequences' % -> seq(A) ~ 'resultant sequence'. % % concat :: % {[N]->seq(A)} ~ 'cell array of N sequences', % -> seq(A) ~ 'resultant sequence'. function y=concat(x), y=seq.concat(x); end % append - Append one or more sequences % % append :: seq(A), seq(A), ... -> seq(A). function x=append(varargin), x=seq.concat(cellseq(varargin)); end function z=and(x,y), z=seq.concat(cons(x,cons(y,[]))); end % cycle - cycles through input sequence repeatedly % % cycle :: seq(A) -> seq(A). function y=cycle(x), y=seq.cycle(x); end function y=bindcat(x,f), y=seq.bindcat(x,f); end % bindcat :: seq(A), (A->seq(A)) -> seq(A). function y=subsample(n,x), y=seq.subsample(n,x); end function x=zip(varargin) % zip - combine several sequences into one % % zip :: seq(A), seq(B), ... -> seq(cell {A,B,...}). x=seq.zipwith(@tuple,varargin); function z=rtuple(varargin), z=varargin; end end % zipwith - apply function to several sequences % % zipwith :: % (A,B,...->X), % seq A, seq B, ... % -> seq X. function x=zipwith(fn,varargin), x=seq.zipwith(fn,varargin); end % zipaccum - apply stateful function to several sequences % % zipaccum :: % (A,B,...,S->X,S), % S, % seq(A), seq(B), ... % -> seq(X). function x=zipaccum(fn,s0,varargin), x=seq.zipaccum(fn,s0,varargin); end function xx=unzip(y) % unzip - Separate sequence of tuples into several sequences % % unzip :: % seq({I:[D]->A(I)}). % -> {I:[D]->seq(A(I))}. % % Note: input MUST be a sequence of constant size cell arrays. % Output is a cell array of sequences of the same size and shape. xx=cell(size(y)); for i=1:numel(xx) xx{i}=map(@(a)a{i},y); end end function y=merge(f,varargin), y=seq.merge(f,varargin); end % ------------------ MAPPERS ------------------------------------ % BINOP - Binary operation % % binop :: seq A, seq B, (A,B->C), string -> seq C. % % Three cases % A is seq, B is an array % A is array, B is seq function o=binop(A,B,fn,opstr) o=binfun(A,B,fn,@(a,b)sprintf('(%s%s%s)',a,b,opstr)); end function o=binfun(A,B,fn,fmtstr) if isseq(A), if isseq(B), o=zipwith(fn,A,B); %@(o)fmtstr(tostring(A),tostring(B))); else o=map(@(x)fn(x,B),A); %@(o)fmtstr('.',tostring(B))); end else o=map(@(y)fn(A,y),B); %,@(o)fmtstr(tostring(A),'.')); end end % vecop - apply binary function to different sized array sequences % % vecop :: % ([[D]],[[D]]->[[D]]) ~'some function requiring equal size args', % seq [[DX]] ~'first arg of size DX', % seq [[DY]] ~'second arg of size DY' % -> seq [[DZ]] ~'result of size DZ' :- DZ=max(DX,DY). % % The input sequences must maintain the same size throughout. function Z=vecop(F,X,Y) DX=size(X); DY=size(Y); E=max(length(DX),length(DY)); EDX=pad1s(E,DX); EDY=pad1s(E,DY); if all(EDX>=EDY) S=EDX./EDY; Z=binop(X,Y,@(x,y)F(x,repmat(y,S)),['<' tostring(F) '>']); elseif all(EDY>=EDX) S=EDY./EDX; Z=binop(X,Y,@(x,y)F(repmat(x,S),y),['<' tostring(F) '>']); else DZ=max(EDX,EDY); Z=binop(X,Y,@(x,y)F(repmat(x,DZ./EDX),repmat(y,DZ./EDY)),['<' tostring(F) '>']); end end function h=plot(A,varargin), h=plotseq(@(x)plot(x,varargin{:}),A); end function h=imagesc(A,varargin), h=plotseq(@(x)imagesc(x,varargin{:}),A); end function o=isfinite(A), o=map(@isfinite, A); end function o=isinf(A), o=map(@isinf, A); end function o=isnan(A), o=map(@isnan, A); end function y=powspec(x), y=map(@powspec,x); end function y=magspec(x), y=map(@magspec,x); end function y=phasespec(x), y=map(@phasespec,x); end function o=uminus(A), o=map(@uminus, A); end function y=exp(x), y=map(@exp,x); end function y=cos(x), y=map(@cos,x); end function y=sin(x), y=map(@sin,x); end function y=abs(x), y=map(@abs,x); end function y=sqrt(x), y=map(@sqrt,x); end function y=tanh(x), y=map(@tanh,x); end function y=log(x), y=map(@log,x); end function y=log10(x), y=map(@log10,x); end function y=log2(x), y=map(@log2,x); end function o=ctranspse(A), o=map(@ctranspose,A); end function o=transpse(A), o=map(@transpose,A); end function y=fft(x), y=map(@fft,x); end function y=ifft(x), y=map(@ifft,x); end function o=reshape(source,varargin) % reshape - Map reshape over elements of sequence % % reshape :: seq [Size->A], ... - > seq [Size1->A]. % Works exactly like the usual reshape function but when applied % to a sequence object, returns a new sequence. sz=tosize(varargin{:}); o=map(@(x)reshape(x,varargin{:}),source); function s=charfn(sz,o) s=sprintf('%s >> reshape[%s]',tostring(source(o)),tostring(sz)); end end function y=paren(a,S) % paren - Map application of subsref with parentheses to sequence % % paren :: seq A, subs -> seq B :- (subsref :: A, subs -> B). % NOTE TO SELF: it would be good to work out the size of the % array that will result when the function is evaluated, to % save map evaluating it once on construction. y=map(@(z)subsref(z,S),a); % 'charfn',@(o)charfn(tostring(S.subs{:}),o)); function s=charfn(argstr,o) s=sprintf('%s >> (%s)',tostring(source(o)),argstr); end end function o=plus(A,B), o=binop(A,B,@plus,'+'); end function o=power(A,B), o=binop(A,B,@power,'.^'); end function o=eq(A,B), o=binop(A,B,@eq,'=='); end function o=ge(A,B), o=binop(A,B,@ge,'>='); end function o=gt(A,B), o=binop(A,B,@gt,'>'); end function o=ldivide(A,B), o=binop(A,B,@ldivide,'.\'); end function o=le(A,B), o=binop(A,B,@le,'<='); end function o=lt(A,B), o=binop(A,B,@lt,'<'); end function o=times(A,B), o=binop(A,B,@times,'.*'); end function o=minus(A,B), o=binop(A,B,@minus,'-'); end function o=mldivide(A,B),o=binop(A,B,@mldivide,'\'); end function o=mod(A,B), o=binop(A,B,@mod,'mod'); end function o=mrdivide(A,B),o=binop(A,B,@mrdivide,'/'); end function o=rdivide(A,B), o=binop(A,B,@rdivide,'./'); end function o=mtimes(A,B), o=binop(A,B,@mtimes,'*'); end % max - max mapped over sequence (ie NOT aggregate) function o=cat(dim,varargin) if length(varargin)==2 o=binfun(varargin{1},varargin{2},@(a,b)cat(dim,a,b),@(a,b)sprintf('cat(%d,%s,%s)',dim,a,b)); else o=zipwith(@catdim,varargin{:}); end function x=catdim(varargin), x=cat(dim,varargin); end end function o=vertcat(varargin) if length(varargin)==2 o=binfun(varargin{1},varargin{2},@vertcat,@(a,b)sprintf('[%s;%s]',a,b)); else o=zipwith(@vertcat,varargin{:}); end end function o=horzcat(varargin) if length(varargin)==2 o=binfun(varargin{1},varargin{2},@horzcat,@(a,b)sprintf('[%s,%s]',a,b)); else o=zipwith(@horzcat,varargin{:}); end end end end