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 4834 2015-03-29 21:36:18Z bgrychtol-ipa $
0026 
0027    optargin = size(varargin,2);
0028 
0029    % unit test
0030    if optargin == 1 && ischar(varargin{1}) && strcmp(varargin{1},'UNIT_TEST')
0031        do_unit_test;
0032        return;
0033    end
0034 
0035    % setters and getters
0036    if optargin > 0 && ischar(varargin{1})
0037        switch varargin{1}
0038            case 'get'
0039                varargout{1} = get_default(varargin{2});
0040                return
0041            case 'set'
0042                if optargin ~= 3
0043                    error('Wrong number of inputs');
0044                end
0045                set_default(varargin{2},varargin{3});
0046                return
0047            case 'list'
0048                varargout{1} = list_defaults;
0049                return
0050        end
0051    end
0052    
0053    caller  = get_caller( dbstack );
0054    % This works on a specific version of matlab, and not octave
0055    %varargout{1:nargout} = call_default(caller,varargin{:});
0056    if nargout>0
0057       output = mk_varargout_str(nargout);
0058       cmd= sprintf('%s = %s', output, 'call_default(caller,varargin{:});');
0059       eval(cmd)
0060    else
0061       call_default(caller,varargin{:});
0062    end
0063 
0064 function list = list_defaults
0065     global eidors_objects
0066     try
0067         list = eidors_objects.defaults;
0068     catch
0069         list = [];
0070     end
0071 
0072 function caller = get_caller(s)
0073     caller = s(2).name;
0074     if length(caller) >= 15 && strcmp(caller(end-14:end),'cache_shorthand')
0075         caller = s(4).name;
0076     end
0077     caller = octave_caller(caller);
0078     
0079 function caller = octave_caller(caller)
0080     if exist('OCTAVE_VERSION')
0081     % octave gives caller = eidors_default>do_unit_test
0082        ff= find(caller == '>'); 
0083        if length(ff)>=1; ff= ff(end); else ff=0; end
0084        caller = caller(ff+1:end);
0085     end
0086 
0087 
0088 function set_default(caller, default)
0089     global eidors_objects
0090     caller = octave_caller( caller );
0091     eidors_objects.defaults.(caller) = default;
0092 
0093 
0094 function default = get_default(caller)
0095     if exist('OCTAVE_VERSION')
0096     % octave gives caller = eidors_default>do_unit_test
0097        ff= find(caller == '>'); 
0098        if length(ff)>=1; ff= ff(end); else ff=0; end
0099        caller = caller(ff+1:end);
0100     end
0101     global eidors_objects
0102     try
0103         default = eidors_objects.defaults.(caller);
0104     catch
0105         error(['No default implementation of ' caller '.']);
0106     end
0107 
0108 function varargout = call_default(caller,varargin);
0109    default = get_default(caller);
0110    % Octave can't do this, and we don't think matlab can properly either
0111    %  varargout{1:nargout} = feval(default,varargin{:});
0112    if nargout>0
0113       output = mk_varargout_str(nargout);
0114       cmd= sprintf('%s = %s', output, 'feval(default,varargin{:});');
0115       eval(cmd)
0116    else
0117       feval(default,varargin{:});
0118    end
0119 
0120 function output = mk_varargout_str(N)
0121    output = '[';
0122    for i = 1:N
0123       output = [ output sprintf('varargout{%d} ',i)];
0124    end
0125    output = [ output ']' ];
0126 
0127 
0128 function do_unit_test
0129 fid = fopen('test_def.m','w');
0130 fprintf(fid, 'function out = test_def(in);');
0131 fprintf(fid, 'disp(''test_def'');');
0132 fprintf(fid, 'disp(in);');
0133 fprintf(fid, 'out = in;');
0134 fclose(fid);
0135 eidors_default('set','do_unit_test','test_def');
0136 name = eidors_default(5);
0137 unit_test_cmp('dut1', name, 5);
0138 
0139 val = eidors_default(6);
0140 unit_test_cmp('dut2', val, 6);
0141 
0142 name = eidors_default('get','do_unit_test');
0143 unit_test_cmp('dut3', name, 'test_def');
0144 %delete('test_def.m');

Generated on Tue 12-May-2015 16:00:42 by m2html © 2005