# HG changeset patch # User samer # Date 1358338354 0 # Node ID 03694e5c8365da8f4d655f709b4a9147e809d8ec # Parent fbc0540a92080f6fdb26536336db0c0275a45793 Reorganised some high order list functions to correct class-based method dispatch; fixed some docs. diff -r fbc0540a9208 -r 03694e5c8365 general/algo/iterate.m --- a/general/algo/iterate.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/algo/iterate.m Wed Jan 16 12:12:34 2013 +0000 @@ -12,23 +12,21 @@ % (A->(A | empty)) ~'function to iterate, can return [] to terminate', % A ~'initial state' % } ~'iterated system as a cell array', -% options iterate_timed_options +% options iterate_options % -> A ~'final state'. % -% iterate_timed_options = { +% iterate_options = { % its :: natural /inf ~'Iteration limit'; -% quiet :: bool /1 ~'controls console display'; -% drawnow :: bool /1 ~'controls graphics updating'; +% quiet :: bool /1 ~'controls verbosity'; % pre :: A=>void ~'something to do before each iteration'; % post :: A=>void ~'something to do after each iteration'; % save :: natural /0 ~'iterations between state saving (0=off)'; % id :: string /'iterstate@' ~'name of mat file to save to'; -% recover :: bool /0 ~'recover from saved state' +% recover :: bool /0 ~'recover from saved state'; +% drawnow :: bool /1 ~'controls graphics updating'; +% pause :: natural /0 ~'pause between iterations (in ms) or 1 for indefinite' % }. % -% Plus the usual OPTPAUSE options. -% -% NOTE: old termination by throwing an exception is no longer supported. % The function must return an empty array to force termination. if iscell(varargin{1}) @@ -67,7 +65,6 @@ fprintf('Will save every %d iterations to %s.mat\n',opts.save,opts.id); end - % how cunning is this... if isfinite(opts.its), itformat=sprintf('%%%dd. ',ceil(log10(opts.its))); else itformat='%d. '; end diff -r fbc0540a9208 -r 03694e5c8365 general/algo/optpause.m --- a/general/algo/optpause.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/algo/optpause.m Wed Jan 16 12:12:34 2013 +0000 @@ -2,8 +2,8 @@ % optpause - Optionally pause and/or update graphics % % optpause :: struct { -% pause :: natural/0 ~'0-nopause, 1-pause, N-timed pause in ms'; -% drawnow :: bool/0 ~'flush graphics before pausing' +% pause :: nonneg/0 ~'0-nopause, 1-pause, N-timed pause in ms'; +% drawnow :: bool/0 ~'flush graphics if not pausing' % } => void. ps=getparam(opt,'pause',0); diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/.DS_Store Binary file general/arrutils/.DS_Store has changed diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/chunk.m --- a/general/arrutils/chunk.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/arrutils/chunk.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,9 +1,11 @@ function B=chunk(A,n,step) -% CHUNK: return chunk from inside matrix -% B=chunk(A,n,hop): returns nth block of rows of size hop from A -% A: source matrix -% n: index of chunk -% hop: size of chunk +% chunk - return chunk from inside matrix +% +% chunk :: +% [[N,M]] ~'source array', +% K:natural ~'index of chunk', +% L:natural ~'chunk size' +% -> [[L,M]] ~'K block of L rows'. i=n*step+1; B=A(i:i+step-1,:); diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/defmat.m --- a/general/arrutils/defmat.m Mon Jan 14 22:21:11 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -function X=defmat(I,w,D) -% defmat - specify matrix as a list of non-zero elements -% -% defmat :: -% [[N,E]->natural] ~'N E-dim array subscripts, 1 per row', -% [[N]] ~'values to place at positions specified by subs', -% D:[[1,E]] ~'size of target array' -% -> [[D]] ~'array of size D'. - -X=accumarray(I,w); -if any(size(X)[[prod(size)]] - -X=reshape(X,numel(X),1); +function X=flatten(X), X=X(:); end diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/foldrcols.m --- a/general/arrutils/foldrcols.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/arrutils/foldrcols.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,4 +1,6 @@ -% foldcols :; +% foldrcols - fold array columns from the right +% +% foldrcols :; % ([[M]], [[N]] -> [[M]]) ~'folding function', % [[M]] ~'initial value', % [[N,L]] ~'data to scan, sequence of length L' diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/forels.m --- a/general/arrutils/forels.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/arrutils/forels.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,19 +1,16 @@ -function forels(f,X,varargin) % forels - do an action for each element of an array in order % % forels :: % (A->action) ~'action to apply to each element', % [[Size]->A] ~'array of elements of type', -% options { -% pause :: bool/0 -% drawnow :: bool/1 -% } ~'see ITERATE for more options' -% -> action. +% options iterate_options +% => void. % % Note, the array can be multidimensional - the standard order % cycles through the earlier indices before the later ones, eg % rows, then columns, then slices etc. +function forels(f,X,varargin) N=numel(X); iterate(@g,1,varargin{:}); diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/interleave.m --- a/general/arrutils/interleave.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/arrutils/interleave.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,5 +1,11 @@ +% interleave - interleave elements of an array +% +% interleave :: [[1,N]], [[1,M]] -> [[1,N+M]]. +% +% interleave(A,B) interleaves the elements of A and B until there are +% no elements left in one of them. The remaining elements of the other +% are then appending. function z=interleave(x,y) -% interleave - interleave elements of an array x=x(:); y=y(:); diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/reverse.m --- a/general/arrutils/reverse.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/arrutils/reverse.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,3 +1,7 @@ -function y=reverse(x) -% reverse a vector -y = x(length(x):-1:1); +% reverse - reverse a vector +% +% reverse :: [[N]] -> [[N]]. +% reverse :: [[1,N]] -> [[1,N]]. +% +% Works on row or column vectors, preserving orientation. +function y=reverse(x), y = x(length(x):-1:1); end diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/shiftl.m --- a/general/arrutils/shiftl.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/arrutils/shiftl.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,9 +1,13 @@ +% shiftl - shift a column vector up one +% +% shift :: [[N,M]] -> [[N,M]]. +% +% Shift array elements back one, padding end with zeros. +% eg [ 1 2 3 4 ] --> [ 2 3 4 0] function y=shiftl(x) -% shiftl - shift a column vector up one -% maintaining original length -% eg [ 1 2 3 4 ] --> [ 2 3 4 0] -if isvector(x) - y = [ x(2:length(x)); 0]; -else - y = [ x(:,2:size(x,2)), zeros(size(x,1),1) ]; + if isvector(x) + y = [ x(2:end); 0]; + else + y = [ x(:,2:size(x,2)), zeros(size(x,1),1) ]; + end end diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/shiftr.m --- a/general/arrutils/shiftr.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/arrutils/shiftr.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,5 +1,13 @@ +% shiftr - shift array columns right one +% +% shiftr :: [[N,M]] -> [[N,M]]. +% +% Shift array elements right one, padding start with zeros. +% eg [ 1 2 3 4 ] --> [ 0 1 2 3 ] function y=shiftr(x) -% shiftr - shift a column vector down one -% maintaining original length -% eg [ 1 2 3 4 ] --> [ 0 1 2 3 ] -y = [0; x(1:length(x)-1) ]; + if isvector(x) + y = [ 0; x(1:end-1) ]; + else + y = [ zeros(size(x,1),1), x(:,1:size(x,2)-1) ]; + end +end diff -r fbc0540a9208 -r 03694e5c8365 general/arrutils/tween.m --- a/general/arrutils/tween.m Mon Jan 14 22:21:11 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -function I=tween(a,b) -% tween - all indices in a given range (like interval to set) -% -% tween :: interger, integer -> [[N]->integer]. -% tween :: [[2]->interger] -> [[N]->integer]. -% -% tween([A,B])=tween(A,B). - -if nargin<2, b=a(2); a=a(1); end -if b>=a, I=a:b; else I=a:-1:b; end - diff -r fbc0540a9208 -r 03694e5c8365 general/cellutils/cellmap.m --- a/general/cellutils/cellmap.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/cellutils/cellmap.m Wed Jan 16 12:12:34 2013 +0000 @@ -1,7 +1,7 @@ function Y=cellmap(fn,X) % cellmap - Map a function over a cell array % -% cellmap :: (A->B, {[Size]->A}) -> {[Size]->B} +% cellmap :: (A->B, {[Size]->A}) -> {[Size]->B}. % preallocate to fix size Y=cell(size(X)); diff -r fbc0540a9208 -r 03694e5c8365 general/cellutils/cfoldl.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/cellutils/cfoldl.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,9 @@ +function X=cfoldl(fn,e,args) +% cfoldl - Fold fom the left combinator for cell arrays +% +% foldl :: (X,Y->X), X, cells(Y) -> X. +% +% This function applies a folding function to cell array, +% starting from the left using the given starting element. +% eg cfoldl(@plus,0,{1,2,3,4}) = ((((0+1)+2)+3)+4). +X=e; for i=1:length(args), X=fn(X,args{i}); end diff -r fbc0540a9208 -r 03694e5c8365 general/cellutils/cfoldr.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/cellutils/cfoldr.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,13 @@ +function X=foldr(fn,e,args) +% foldr - Fold from the right for cell arrays +% +% This function applies an operator to a list of arguments, +% starting from the right, eg +% elements, eg foldr(@plus,0,{1,2,3,4}) = (1+(2+(3+(4+0)))). +% +% foldr :: +% (Y,X->X) ~'associative binary operator', +% Y ~'initial element', +% {[N]->Y} ~'list (cell array) of arguments' +% -> Y. +X=e; for i=length(args):-1:1, X=fn(args{i},X); end diff -r fbc0540a9208 -r 03694e5c8365 general/cellutils/cforeach.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/cellutils/cforeach.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,8 @@ +function foreach(f,X,varargin) +% foreach - do an action for each element in a cell array in order +% +% foreach :: (A=>void), {[N]->A} => void. +% + +if nargin>2, error('Options for foreach no longer supported'); end +for i=1:numel(X), f(x{i}); end diff -r fbc0540a9208 -r 03694e5c8365 general/cellutils/cmapaccum.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/cellutils/cmapaccum.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,10 @@ +function [Y,s]=cmapaccum(fn,s,X) +% cmapaccum - Map a function over a cell array +% +% cmapaccum :: (A,S->B,S), S, {[Size]->A}) -> {[Size]->B}, S. + +% preallocate to fix size +Y=cell(size(X)); +for i=1:numel(X) + [Y{i},s]=fn(X{i},s); +end diff -r fbc0540a9208 -r 03694e5c8365 general/cellutils/cscanl.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/cellutils/cscanl.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,24 @@ +% cscanl - scanl for cell arrays +% +% cscanl :: +% (S,X->S) ~'scannning function', +% S ~'initial value', +% {[N]->X} ~'data to scan, sequence of length L' +% -> {[N]->S}. + +function Y=cscanl(f,y,X,varargin) + Y=cell(size(X)); + if nargin>3 + opts=prefs('draw',0,varargin{:}); + for i=1:size(X,2) + y1=f(y,X{i}); + Y{i}=y1; + if opts.draw, opts.plotfn(i,y,X{i},y1); end + optpause(opts); + y=y1; + end + else + for i=1:size(X,2), y=f(y,X{i}); Y{i}=y; end + end + + diff -r fbc0540a9208 -r 03694e5c8365 general/cpfields.m --- a/general/cpfields.m Mon Jan 14 22:21:11 2013 +0000 +++ b/general/cpfields.m Wed Jan 16 12:12:34 2013 +0000 @@ -7,5 +7,6 @@ % -> struct union(B,C) ~'struct with fields B union C' :- % subset(C,A) ~'target fields must be in A'. function B=cpfields(fields,A,B) +keyboard B=foldl(@(b,fn)setfield(b,fn,getfield(A,fn)),B,fields); diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/decorate.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/decorate.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,23 @@ +% decorate - Decorate function with pre and post operations and optional pausing +% +% decorate :: +% (A->B{:}) ~'function from 1 argument to any number of returns', +% options { +% pre :: (A=>void)/@nop ~'action to perform before calling function'; +% post :: (A=>void)/@nop ~'action to perform after calling function' +% } +% -> (A->B{:}) ~'new function incorporating pre and post actions'. +function f1=decorate(f,varargin) + opts=prefs(varargin{:}); + pf=pauser(opts); + if isfield(opts,'pre') || isfield(opts,'post') + pre=getparam(opts,'pre',@nop); + post=getparam(opts,'post',@nop); + f1=@f_bracket; + else + f1=@f_simple; + end + + function x=f_simple(x), x=f(x); pf(); end + function x=f_bracket(x), pre(x); x=f(x); post(x); pf(); end +end diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/foldl.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/foldl.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,5 @@ +function X=foldl(fn,e,args) +% foldl - Fold fom the left combinator +% +% foldl :: (X,Y->X), X, cells(Y) -> X. +X=e; for i=1:length(args), X=fn(X,args{i}); end diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/foldr.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/foldr.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,9 @@ +function X=foldr(fn,e,args) +% foldr - Fold from the right combinator +% +% foldr :: (Y,X->X), Y, cells(Y) -> Y. +% +% This function applies an associative operator to a list of arguments, +% starting from the right, eg +% elements, eg foldr(@plus,0,{1,2,3,4}) = (1+(2+(3+(4+0)))). +X=e; for i=length(args):-1:1, X=fn(args{i},X); end diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/foreach.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/foreach.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,7 @@ +function foreach(f,X,varargin) +% foreach - do an action for each element in a cell array in order +% +% foreach :: (A=>void), cells(A) => void. + +if nargin>2, error('Options for foreach no longer supported'); end +for i=1:numel(X), f(x{i}); end diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/map.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/map.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,4 @@ +% map - Map a function over a cell array +% +% map :: (A->B, {[Size]->A}) -> {[Size]->B} +function Y=map(fn,X), Y=cellmap(fn,X); end diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/scanl.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/scanl.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,8 @@ +% scanl - scanl for cell arrays +% +% scanl :: +% (S,X->S) ~'scannning function', +% S ~'initial value', +% {[N]->X} ~'data to scan, sequence of length L' +% -> {[N]->S}. +function Y=scanl(f,y,X), Y=cscanl(f,y,X); end diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/select.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/select.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,7 @@ +% select - Filter cell array with boolean test +% +% select :: (A->bool), {[N]->A} -> {[M]->A}. +% select :: (A->bool), {[1,N]->A} -> {[1,M]->A}. +% +% eg, select(@iseven,{1,2,3,4}) = {2,4} +function Y=select(fn,X), Y=cellfilt(fn,X); diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/@function_handle/zipwith.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/funutils/@function_handle/zipwith.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,11 @@ +function Y=zipwith(fn,varargin) +% zipwith - Zip cell arrays with a function +% +% zipwith :: ( +% (D1,...,Dn)->R ~ function of n arguments, +% {[size]->D1}, ..., {[size]->Dn} ~ n cell arrays of appropriate types +% ) -> {[size]->R} ~ cell array of results + +Y=cellzip(fn,varargin{:}); + + diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/TODO --- a/general/funutils/TODO Mon Jan 14 22:21:11 2013 +0000 +++ b/general/funutils/TODO Wed Jan 16 12:12:34 2013 +0000 @@ -13,4 +13,8 @@ folder: X,S->S accum: Y,S->X,S +Current special cases: + scanner_add_plotter + decorate + Also what about actions? (Function with side-effects or dependence on global state) diff -r fbc0540a9208 -r 03694e5c8365 general/funutils/foreach.m --- a/general/funutils/foreach.m Mon Jan 14 22:21:11 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -function foreach(f,x), if ~isempty(x), error('foreach not supported for this class'); end diff -r fbc0540a9208 -r 03694e5c8365 general/pair.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/general/pair.m Wed Jan 16 12:12:34 2013 +0000 @@ -0,0 +1,1 @@ +function p=pair(a,b), p={a,b}; diff -r fbc0540a9208 -r 03694e5c8365 sched/pair.m --- a/sched/pair.m Mon Jan 14 22:21:11 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -function p=pair(a,b), p={a,b}; diff -r fbc0540a9208 -r 03694e5c8365 sequences/@seq/foldl.m --- a/sequences/@seq/foldl.m Mon Jan 14 22:21:11 2013 +0000 +++ b/sequences/@seq/foldl.m Wed Jan 16 12:12:34 2013 +0000 @@ -10,6 +10,7 @@ % seq(Y) ~'a lazy sequence' % -> X. +if iscell(y), x=cfoldl(fn,e,y); return; end if nargin<4, x=e; while ~isempty(y) diff -r fbc0540a9208 -r 03694e5c8365 sequences/@seq/seq.m --- a/sequences/@seq/seq.m Mon Jan 14 22:21:11 2013 +0000 +++ b/sequences/@seq/seq.m Wed Jan 16 12:12:34 2013 +0000 @@ -91,12 +91,16 @@ % 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=map(fn,y), x=seq.map(fn,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 + function x=mapaccum(fn,s0,y) + if iscell(y), x=cmapaccum(fn,s0,y); + else x=seq.mapaccum(fn,s0,y); end + end + % scanl - scanl combinator for sequences % % This function applies an associative operator to a list of arguments, @@ -107,7 +111,10 @@ % X ~'initial element', % seq Y ~'a sequence' % -> seq X. - function x=scanl(fn,e,y,varargin), x=seq.scanl(fn,e,y,varargin{:}); end + function x=scanl(fn,e,y,varargin), + if iscell(y), x=cscanl(fn,e,y,varargin{:}); + else x=seq.scanl(fn,e,y,varargin{:}); end + end % concat - Concatenate sequences % @@ -160,7 +167,13 @@ % S, % seq(A), seq(B), ... % -> seq(X). - function x=zipaccum(fn,s0,varargin), x=seq.zipaccum(fn,s0,varargin); end + function x=zipaccum(fn,s0,varargin), + if isseq(s0) && any(map(@iscell,varargin)) % catch dispatching errors + z=czipcaccum(fn,s0,varargin{:}); + else + x=seq.zipaccum(fn,s0,varargin); + end + end function xx=unzip(y) % unzip - Separate sequence of tuples into several sequences