eidors_default

PURPOSE ^

EIDORS_DEFAULT Default function handler.

SYNOPSIS ^

function varargout = eidors_default(varargin)

DESCRIPTION ^

EIDORS_DEFAULT Default function handler.
  EIDORS_DEFAULT redirects calls to the default implementation of the 
  calling function's functionality, e.g. if called from CALC_JACOBIAN it 
  will call JACOBIAN_ADJOINT. The default implementations are set at 
  startup in EIDORS_STARTUP, and can be manipulated as follows:

  eidors_default('set','caller','implementation')  - set the default
  implementation of 'caller' function to 'implementation'.

  eidors_default('get','caller') - get the current default implementation
  for 'caller'
 
  eidors_default('list') - list all stored defaults

  NOTE: This is an internal function not meant to be called directly other
  than as indicated above. Rather, where the algorithm to be used by a 
  certain function is passed to it as a field on an eidors model
  structure, that field can be set to 'eidors_default'. For example, 
  the inverse solver to be used is in inv_solve is specified in 
  imdl.solve. If imdl.solve = 'eidors_default', a call to inv_solve(imdl)
  will use the default implementation.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function varargout = eidors_default(varargin)
0002 %EIDORS_DEFAULT Default function handler.
0003 %  EIDORS_DEFAULT redirects calls to the default implementation of the
0004 %  calling function's functionality, e.g. if called from CALC_JACOBIAN it
0005 %  will call JACOBIAN_ADJOINT. The default implementations are set at
0006 %  startup in EIDORS_STARTUP, and can be manipulated as follows:
0007 %
0008 %  eidors_default('set','caller','implementation')  - set the default
0009 %  implementation of 'caller' function to 'implementation'.
0010 %
0011 %  eidors_default('get','caller') - get the current default implementation
0012 %  for 'caller'
0013 %
0014 %  eidors_default('list') - list all stored defaults
0015 %
0016 %  NOTE: This is an internal function not meant to be called directly other
0017 %  than as indicated above. Rather, where the algorithm to be used by a
0018 %  certain function is passed to it as a field on an eidors model
0019 %  structure, that field can be set to 'eidors_default'. For example,
0020 %  the inverse solver to be used is in inv_solve is specified in
0021 %  imdl.solve. If imdl.solve = 'eidors_default', a call to inv_solve(imdl)
0022 %  will use the default implementation.
0023 
0024 % (C) Bartlomiej Grychtol, 2012. License: GPL v. 2 or 3.
0025 % $Id: eidors_default.m 5415 2017-04-24 12:49:48Z aadler $
0026 
0027    optargin = size(varargin,2);
0028    s = dbstack;
0029    
0030    % unit test
0031    if numel(s) == 1 && optargin == 1 && ischar(varargin{1}) && strcmp(varargin{1},'UNIT_TEST')
0032        do_unit_test;
0033        return;
0034    end
0035 
0036    % setters and getters
0037    if optargin > 0 && ischar(varargin{1})
0038        switch varargin{1}
0039            case 'get'
0040                varargout{1} = get_default(varargin{2});
0041                return
0042            case 'set'
0043                if optargin ~= 3
0044                    error('Wrong number of inputs');
0045                end
0046                set_default(varargin{2},varargin{3});
0047                return
0048            case 'list'
0049                varargout{1} = list_defaults;
0050                return
0051        end
0052    end
0053    
0054    caller  = get_caller( s );
0055    % This works on a specific version of matlab, and not octave
0056    %varargout{1:nargout} = call_default(caller,varargin{:});
0057    if nargout>0
0058       output = mk_varargout_str(nargout);
0059       cmd= sprintf('%s = %s', output, 'call_default(caller,varargin{:});');
0060       eval(cmd)
0061    else
0062       call_default(caller,varargin{:});
0063    end
0064 
0065 function list = list_defaults
0066     global eidors_objects
0067     try
0068         list = eidors_objects.defaults;
0069     catch
0070         list = [];
0071     end
0072 
0073 function caller = get_caller(s)
0074     caller = s(2).name;
0075     if length(caller) >= 15 && strcmp(caller(end-14:end),'cache_shorthand')
0076         caller = s(4).name;
0077     end
0078 %   caller = octave_caller(caller);
0079     
0080 function caller = octave_caller(caller)
0081     if exist('OCTAVE_VERSION')
0082     % octave gives caller = eidors_default>do_unit_test
0083        ff= find(caller == '>'); 
0084        if length(ff)>=1; ff= ff(end); else ff=0; end
0085        caller = caller(ff+1:end);
0086     end
0087 
0088 
0089 function set_default(caller, default)
0090     global eidors_objects
0091     caller = octave_caller( caller );
0092     eidors_objects.defaults.(caller) = default;
0093 
0094 
0095 function default = get_default(caller)
0096     if exist('OCTAVE_VERSION')
0097     % octave gives caller = eidors_default>do_unit_test
0098        ff= find(caller == '>'); 
0099        if length(ff)>=1; ff= ff(end); else ff=0; end
0100        caller = caller(ff+1:end);
0101     end
0102     global eidors_objects
0103     try
0104         default = eidors_objects.defaults.(caller);
0105     catch
0106         error(['No default implementation of ' caller '.']);
0107     end
0108 
0109 function varargout = call_default(caller,varargin);
0110    default = get_default(caller);
0111    % Octave can't do this, and we don't think matlab can properly either
0112    %  varargout{1:nargout} = feval(default,varargin{:});
0113    if nargout>0
0114       output = mk_varargout_str(nargout);
0115       cmd= sprintf('%s = %s', output, 'feval(default,varargin{:});');
0116       eval(cmd)
0117    else
0118       feval(default,varargin{:});
0119    end
0120 
0121 function output = mk_varargout_str(N)
0122    output = '[';
0123    for i = 1:N
0124       output = [ output sprintf('varargout{%d} ',i)];
0125    end
0126    output = [ output ']' ];
0127 
0128 
0129 function do_unit_test
0130 fid = fopen('test_def.m','w');
0131 fprintf(fid, 'function out = test_def(in);');
0132 fprintf(fid, 'disp(''test_def'');');
0133 fprintf(fid, 'disp(in);');
0134 fprintf(fid, 'out = in;');
0135 fclose(fid);
0136 eidors_default('set','do_unit_test','test_def');
0137 name = eidors_default(5);
0138 unit_test_cmp('dut1', name, 5);
0139 
0140 val = eidors_default(6);
0141 unit_test_cmp('dut2', val, 6);
0142 
0143 name = eidors_default('get','do_unit_test');
0144 unit_test_cmp('dut3', name, 'test_def');
0145 delete('test_def.m');

Generated on Wed 21-Jun-2017 09:29:07 by m2html © 2005