Code covered by the BSD License  

Highlights from
functor

image thumbnail

functor

by

 

Automated composition of function handles

function_handle_like
classdef function_handle_like
    
    % Walks and talks like a function_handle. 
    
    properties(GetAccess='protected',SetAccess='protected')
        handle;  % function_handle
    end
    
    methods  % Basic functionality
        
        function f = function_handle_like(h)
            if nargin==0,
               f.handle = [];
            else
               f.handle = h;
            end
        end
        
        function h = to_handle(f)
            h = f.handle;
        end
        
        function B = subsref(f,S)
            switch S(1).type,
                case '.',
                    B = f.(S(1).subs);
                    if length(S)>1,
                        error('Unsupported subsref syntax');
                    end
                otherwise
                    % Allow struct like syntax e.g. (:)
                    h = to_handle(f);
                    B = subsref(h,S);
            end
        end
        
        function s = char(f)
           s = char(f.to_handle); 
        end
        
        function varargout = feval(f,varargin)
            h = f.to_handle;
            varargout = cell(1,nargout);
            if nargout>=1,
                [varargout{:}] = feval(h,varargin{:});
            else
                disp(feval(f,varargin{:}));
            end
        end
        
    end
    
    methods  % Wrappers

        % Some "funfun" s need to be overridden
        % May be performance gains to be had by lengthening this list
        
        function varargout = quadgk(f,varargin) 
             varargout = cell(1,nargout);
             [varargout{:}] = f.handleWrapper('quadgk',varargin{:});
        end
        
        function h = ezplot(f,varargin) 
            h = ezplot(f.to_handle,varargin{:});
        end
        
        function h = ezplot3(f1,f2,f3,varargin) 
            h = ezplot3(f1.to_handle,f2.to_handle,f3.to_handle,varargin{:});
        end
        
    end
    
    methods(Access='private')
        
        function varargout = handleWrapper(f,name,varargin) 
            h = f.to_handle;
            varargout = cell(1,nargout);
            [varargout{:}] = feval(name,h,varargin{:});
        end
            
    end
    
    methods(Static,Access='public') % Testing
        
        function okay = unitTests
            results = [function_handle_like.unitTest_feval;...
                function_handle_like.unitTest_funfun;...
                function_handle_like.unitTest_ode];  % Add more
            okay = all(results);
        end
        
    end
   
    methods (Static,Access='public') % Testing
       
        % As these examples are passed out to external functions, they must be public
        
        function [x,y] = egFun(a,b,c)
            x = a+b;
            y = b+c;
        end
        
        function x = egFun_m(a,b)
           x = a+b;
        end
        
        function y = egFun_f(x)
            y = sin(x)+x.^2;
        end
        
        function y = egFun_g(x)
            y = sin(x(1))+x(2).^2;
        end
        
    end
    
    methods(Static,Access='private') % Testing
        
        function okay = unitTest_feval
            f = function_handle_like(@function_handle_like.egFun);
            a = 1;
            b = 2;
            c = 3;
            [x,y] = feval(f,a,b,c);
            okay = (x==3) && (y==5);
        end
        
        function okay = unitTest_funfun
           % Verify that most funfun's can accept function_handle_like
           f = function_handle_like(@function_handle_like.egFun_f);
           g = function_handle_like(@function_handle_like.egFun_g);
           h = function_handle_like(@function_handle_like.egFun);
           m = function_handle_like(@function_handle_like.egFun_m);
           try
               x1 = fminbnd(f,0,1);
               x2 = fminsearch(g,[0 0]);
               i1 = quad(f,0,1);
               i1 = quadl(f,0,1);
               i3 = quadgk(f,0,1);
               i4 = quadv(f,0,1);
               i5 = triplequad(h,0,1,0,1,0,1);
               i6 = dblquad(m,0,1,0,1);
               ezmesh(m);
               ezmeshc(m);
               ezsurf(m);
               ezsurfc(m);
               ezplot(f);
               ezplot3(f,f,g);
               ezpolar(f);
               ezcontour(m);
               ezcontourf(m);
               fplot(f,[0,2]);
               close all;
               okay = true;
           catch ME
              okay = false;
              disp(['Error: ',ME.message]);
           end
           
        end
       
        function okay = unitTest_ode
           %TODO: Write some tests for ODE functionality
           okay = true; 
        end
        
    end
    
end

Contact us