changeset 39:c388f1c70669

Updated documentation and fixed some bugs in function algebra
author samer
date Tue, 29 Jan 2013 17:02:00 +0000
parents 9d24b616bb06
children 62304c930111
files general/funutils/@function_handle/and.m general/funutils/@function_handle/ctranspose.m general/funutils/@function_handle/ge.m general/funutils/@function_handle/gt.m general/funutils/@function_handle/horzcat.m general/funutils/@function_handle/lt.m general/funutils/@function_handle/mpower.m general/funutils/@function_handle/mrdivide.m general/funutils/@function_handle/mtimes.m general/funutils/@function_handle/not.m general/funutils/@function_handle/or.m general/funutils/@function_handle/power.m general/funutils/@function_handle/rdivide.m general/funutils/@function_handle/vertcat.m general/funutils/README.txt general/funutils/groupby.m general/funutils/groupby_ord.m
diffstat 17 files changed, 114 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/general/funutils/@function_handle/and.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/and.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,4 +1,4 @@
-% and - function combinator, f&g (...) = f(...); return g(...)
+% and - sequential call function combinator
 %
 % and ::
 %    (A{:} => B{:}),
@@ -6,11 +6,14 @@
 % -> (A{:} => C{:}).
 %
 % and ::
-%    (A{1:N} => B{:}),
-%    (A{1:N} => C{1:M}),
+%    (A{:} => B{:}),
+%    (A{:} => C{:}),
 %    N:natural,
 %    M:natural
 % -> (A{1:N} => C{1:M}).
+%
+% f&g == and(f,g) is a function which first calls f with given arguments,
+% discarding return values, then calls g with arguments returning result.
 function h=and(f,g,nin,nout)
 	if nargin<4, nout=nargout(g); end
 	if nargin<3, nin=nargin(g); end
--- a/general/funutils/@function_handle/ctranspose.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/ctranspose.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,3 +1,6 @@
+% ctranspose - flip first two function arguments
+%
+% ctranspose :: (A,B,C{:}=>D{:}) -> (B,A,C{:}=>D{:}).
 function h=ctranspose(f,nin,nout)
 	fns = { @q21, @q2n; @qn1, @qnn };
 	if nargin<3, nout=nargout(f); end
--- a/general/funutils/@function_handle/ge.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/ge.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,6 +1,15 @@
+% ge - collect outputs from function into cell array
+%
+% ge :: (A{:}=>B{1:N}), M:[N] -> (A{:}=>cell {B{1:M}}).
+%
+% f>=N is a function which takes the same arguments as f
+% but collects the first N return values into a cell array.
+% eg feval(@eig>=2,X) returns the eigenvalues and eigenvectors
+% of X in a two-element cell array.
+
 function g=ge(f,nout)
-	if nargin<2, nout=nargout(f); end
-	if nout<0, error('function must have a definite number of outputs'); end
+%	if nargin<2, nout=nargout(f); end
+%	if nout<0, error('function must have a definite number of outputs'); end
 	if nargin(f)==1, g=@h1; else g=@hn; end
 	function rets=h1(x), [rets{1:nout}]=f(x); end
 	function rets=hn(varargin), [rets{1:nout}]=f(varargin{:}); end
--- a/general/funutils/@function_handle/gt.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/gt.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,3 +1,12 @@
+% gt - select outputs from function 
+%
+% gt :: (A{:}=>B{1:N}), I:[M]->[N]] -> (A{:}=>B{I}).
+%
+% f>[i,j,k...] is a function which takes the same arguments as f
+% but returns the ith,jth,kth etc return values from f as the 1st, 2nd, 3rd etc
+% return values.
+% eg feval(@eig>2,X) returns the eigenvectors of X.
+
 function g=gt(f,I,nin)
 	if nargin<3, nin=nargin(f); end
 	nout=length(I); MI=max(I);
--- a/general/funutils/@function_handle/horzcat.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/horzcat.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,11 +1,17 @@
 % horzcat - function combinator, 
 %
 % horzcat ::
-%    F:(A{1:N} => B{1:M}),
-%    G:(A{1:N} => C{1:L}),
-%    N:natural,              ~'defaults to nargin(F)'
-%    M:natural               ~'defaults to nargout(F)'
-% -> (A{1:N} => B{1:M}, C{1:L}).
+%    (A{1:N} => B{1}{:}),
+%    (A{1:N} => B{2}{:}),
+%    ...
+% -> (A{1:N} => B{1}{:}, B{2}{:}, ...).
+%
+% [f,g,h,...] is the function which calls f,g,h etc in order
+% with given arguments and returns all their values as multiple
+% return values.
+% eg, [a,b,c]=feval([@zeros,@ones,@eye],2)
+% Returns a=[0,0;0,0], b=[1,1;1,1], c=[1,0;0,1].
+
 function h=horzcat(varargin)
 	funs=varargin;
 	nouts=cell2mat(map(@nargout,varargin));
--- a/general/funutils/@function_handle/lt.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/lt.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,4 +1,12 @@
-function g=le(f,I)
+% lt - select inputs to function
+%
+% lt :: (A{1:N}=>B{:}), I:[[N]->natural] -> (C{:}=>B{:}) :- C(I)==A(1:N).
+%
+% f<[i,j,k...] is a function which takes any number of arguments
+% but passes only the ith,jth,kth etc arguments to f, returning
+% any values from f.
+
+function g=lt(f,I)
 	if nargout(f)==1, g=@q1; else g=@qn; end
 
 	function x=q1(varargin)
--- a/general/funutils/@function_handle/mpower.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/mpower.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,3 +1,6 @@
+% mpower - unary function application
+%
+% mpower :: (A->B{:}), A -> B{:}.
 function varargout=mpower(f,x)
 	[varargout{1:nargout}]=f(x);
 end
--- a/general/funutils/@function_handle/mrdivide.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/mrdivide.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,6 +1,6 @@
-% lt - Bind one argument to a function using Matlab closure
+% mrdivide - Bind one argument to a function using Matlab closure
 %
-% lt :: 
+% mrdivide :: 
 %    (A{1:N}->B{1:L}) ~'func from N inputs to L outputs',
 %    A{1}             ~'first argument'
 % -> (A{2:N}->B{1:L}) ~'func from remaining arguments to returns'.
--- a/general/funutils/@function_handle/mtimes.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/mtimes.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,10 +1,29 @@
-function h=compose(f,g)
+function h=mtimes(f,g)
 % compose - Constructs composition of two functions
 %
-% compose :: (B->C), (A{1:N}->B) -> (A{1:N}->C).
+% compose :: (B{:}->C{:}), (A{:}->B{:}) -> (A{:}->C{:}).
 %
 % returns the function h such that h(...) = f(g(...))
+% If functions have multiple returns and arguments, outputs
+% from g are routed to f.
 
 	h=@fg;
-	function x=fg(varargin), x=f(g(varargin{:})); end
+	n1=nargout(g); if n1<0, n1=inf; end
+	n2=nargin(f); if n2<0, n2=inf; end
+	n3=nargout(f); if n3<0, n3=inf; end
+	nint=min(n1,n2); 
+	if ~isfinite(nint), error('Cannot determine number of intermediate values'); end
+
+	fns = { @q00, @q01, @q0n; @q10, @q11, @q1n; @qn0, @qn1, @qnn };
+	h=fns{ acount(nint,1)+1, acount(n3,1)+1};
+
+	function q00(varargin), g(varargin{:}); f(); end
+	function q10(varargin), f(g(varargin{:})); end
+	function qn0(varargin), [y{1:nint}]=g(varargin{:}); f(y{:}); end
+	function x=q01(varargin), g(varargin{:}); x=f(); end
+	function x=q11(varargin), x=f(g(varargin{:})); end
+	function x=qn1(varargin), [y{1:nint}]=g(varargin{:}); x=f(y{:}); end
+	function varargout=q0n(varargin), g(varargin{:}); [varargout{1:nargout}]=f(); end
+	function varargout=q1n(varargin), [varargout{1:nargout}]=f(g(varargin{:})); end
+	function varargout=qnn(varargin), [y{1:nint}]=g(varargin{:}); [varargout{1:nargout}]=f(y{:}); end
 end
--- a/general/funutils/@function_handle/not.m	Tue Jan 29 15:59:01 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-function g=not(f,nout)
-	if nargin<2, nout=nargout(f); end
-	if nout<0, error('function must have a definite number of outputs'); end
-	if nargin(f)==1, g=@h1; else g=@hn; end
-	function rets=h1(x), [rets{1:nout}]=f(x); end
-	function rets=hn(varargin), [rets{1:nout}]=f(varargin{:}); end
-end
--- a/general/funutils/@function_handle/or.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/or.m	Tue Jan 29 17:02:00 2013 +0000
@@ -6,9 +6,10 @@
 %    N:natural,              ~'defaults to nargin(F)'
 %    M:natural               ~'defaults to nargout(F)'
 % -> (A{1:N} => B{1:M}, C{1:L}).
-function h=and(f,g,nin,nout)
+function h=or(f,g,nin,nout)
 	if nargin<4, nout=nargout(f); end
 	if nargin<3, nin=nargin(f); end
+	noutg=nargout(g);
 	fns = { @q11, @q1n; @qn1, @qnn };
 	h=fns{acount(nin,1),max(acount(nargout(g),1),acount(nout,1))};
 
@@ -16,7 +17,7 @@
 	function [y,z]=qn1(varargin), y=f(varargin{:}); z=g(varargin{:}); end
 	function varargout=q1n(x), [varargout{1:nout}]=f(x); [varargout{nout+1:nargout}]=g(x); end
 	function varargout=qnn(varargin), 
-		[varargin{1:nout}]=f(varargin{:}); 
-		[varargout{1:nargout}]=g(varargin{:}); 
+		[varargout{1:nout}]=f(varargin{:}); 
+		[varargout{nout+(1:noutg)}]=g(varargin{:}); 
 	end
 end
--- a/general/funutils/@function_handle/power.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/power.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,2 +1,5 @@
-function varargout=lt(f,args)
+% mpower - apply function to arguments in cell array
+% 
+% mpower :: (A{:}=>B{:}), A{:} -> B{:}.
+function varargout=mpower(f,args)
 	[varargout{1:nargout}]=f(args{:});
--- a/general/funutils/@function_handle/rdivide.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/rdivide.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,9 +1,9 @@
 % rdivide - Bind arguments to a function using Matlab closure
 %
 % rdivide :: 
-%    func(A{1}, ..., A{N}->B{1:L})   ~'func from N inputs to L outputs',
+%    (A{1:N}=>B{:})
 %    A{1}, ..., A{M}                 ~'M<=N input arguments of the correct types'
-% -> func(A{M+1}, ..., A{N}->B{1:L}) ~'func from remaining arguments to returns'.
+% -> (A{M+1:N}=>B{:}).
 
 function g=rdivide(f,args)
 	g=@(varargin)f(args{:},varargin{:});
--- a/general/funutils/@function_handle/vertcat.m	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/@function_handle/vertcat.m	Tue Jan 29 17:02:00 2013 +0000
@@ -1,17 +1,12 @@
-% vercat - function combinator, f&g (...) = f(...); return g(...)
+% vertcat - function combinator
 %
-% and ::
-%    (A{:} => B{:}),
+% vertcat ::
+%    (A{:} => _),
+%    (A{:} => _),
+%    ...
 %    (A{:} => C{:})
 % -> (A{:} => C{:}).
-%
-% and ::
-%    (A{1:N} => B{:}),
-%    (A{1:N} => C{1:M}),
-%    N:natural,
-%    M:natural
-% -> (A{1:N} => C{1:M}).
-function h=vercat(varargin)
+function h=vertcat(varargin)
 	g=varargin{end};
 	N=length(varargin)-1;
 	fx=varargin(1:N);
--- a/general/funutils/README.txt	Tue Jan 29 15:59:01 2013 +0000
+++ b/general/funutils/README.txt	Tue Jan 29 17:02:00 2013 +0000
@@ -39,4 +39,4 @@
 
   doreturn(f,x,y,...) ==  feval([f<[];@deal],x,y,...)
   nthret(I,f,x,y,...) ==  feval(f>I,x,y,...)
-  returns(N,f,x,y,...) ==  feval(f>I>=max(I), x,y, ...)
+  returns(N,f,x,y,...) ==  feval(f>I>=max(I),x,y,...)
--- a/general/funutils/groupby.m	Tue Jan 29 15:59:01 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-function y=groupby_or(f,x)
-% groupby_or - collect rows of x into equivalence classes based f
-%
-% groupby_or :: ([[1,M]]->A), [[N,M]] -> {[K]->[[L,M]]} :- equality(A).
-%
-% IMPORTANT: this version assumes that data is ordered by f, that is,
-% only consecutive rows will be grouped together.
-
-	N=size(x,1);
-	y={}; 
-	
-	i=1; j=1;
-	while j<=N
-		if i==j, z=f(x(i,:)); end
-		if j==N || any(f(x(j+1,:))~=z)
-			y=vertcat(y,{x(i:j,:)});
-			i=j+1; j=i;
-		else j=j+1; 
-		end
-	end
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/general/funutils/groupby_ord.m	Tue Jan 29 17:02:00 2013 +0000
@@ -0,0 +1,21 @@
+function y=groupby_ord(f,x)
+% groupby_ord - collect rows of x into equivalence classes based f
+%
+% groupby_ord :: ([[1,M]]->A), [[N,M]] -> {[K]->[[L,M]]} :- equality(A).
+%
+% IMPORTANT: this version assumes that data is ordered by f, that is,
+% only consecutive rows will be grouped together.
+
+	N=size(x,1);
+	y={}; 
+	
+	i=1; j=1;
+	while j<=N
+		if i==j, z=f(x(i,:)); end
+		if j==N || any(f(x(j+1,:))~=z)
+			y=vertcat(y,{x(i:j,:)});
+			i=j+1; j=i;
+		else j=j+1; 
+		end
+	end
+