0001 function data = fwd_solve(fwd_model, img)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 if ischar(fwd_model) && strcmp(fwd_model,'UNIT_TEST'); do_unit_test; return; end
0035
0036 if nargin == 1
0037 img= fwd_model;
0038 else
0039 warning('EIDORS:DeprecatedInterface', ...
0040 ['Calling FWD_SOLVE with two arguments is deprecated and will cause' ...
0041 ' an error in a future version. First argument ignored.']);
0042 end
0043 ws = warning('query','EIDORS:DeprecatedInterface');
0044 warning off EIDORS:DeprecatedInterface
0045
0046
0047 fwd_model= img.fwd_model;
0048
0049
0050 fwd_model= prepare_model( fwd_model );
0051
0052
0053 if isfield(img,'params_mapping')
0054
0055 mapping_function= img.params_mapping.function;
0056 img= feval(mapping_function,img);
0057 end
0058 if isfield(fwd_model,'coarse2fine') && isfield(img,'elem_data')
0059 c2f= fwd_model.coarse2fine;
0060 if size(img.elem_data,1)==size(c2f,2)
0061
0062 img.elem_data = c2f * img.elem_data;
0063
0064 if isfield(fwd_model,'background')
0065 img.elem_data = img.elem_data + fwd_model.background;
0066 end
0067 end
0068 end
0069
0070 if ~isfield(fwd_model, 'electrode')
0071 error('EIDORS: attempting to solve on model without electrodes');
0072 end
0073 if ~isfield(fwd_model, 'stimulation')
0074 error('EIDORS: attempting to solve on model without stimulation patterns');
0075 end
0076
0077 solver = fwd_model.solve;
0078 if ischar(solver)
0079 solver = str2func(solver);
0080 end
0081
0082 copt.fstr = 'fwd_solve';
0083 n_frames = size(img.elem_data,2);
0084 for frame = 1:n_frames;
0085 imgn = img; imgn.elem_data = imgn.elem_data(:,frame,:,:);
0086 copt.cache_obj = imgn;
0087 copt.boost_priority = -2;
0088 tmp = eidors_cache(solver, {imgn}, copt);
0089 data(frame) = eidors_obj('data',tmp);
0090 end
0091
0092 if isa(fwd_model.solve,'function_handle')
0093 solver = func2str(fwd_model.solve);
0094 else
0095 solver = fwd_model.solve;
0096 end
0097 if strcmp(solver,'eidors_default');
0098 solver = eidors_default('get','fwd_solve');
0099 end
0100 if isfield(fwd_model,'measured_quantity') && ~isfield(data,'measured_quantity')
0101 warning('EIDORS:MeasurementQuantityObliviousSolver',...
0102 ['The solver %s did not handle the requested measurement quantity properly.\n'...
0103 'The results may be incorrect. Please check the code to verify.'], ...
0104 solver);
0105 elseif isfield(fwd_model,'measured_quantity') ...
0106 && isfield(data,'measured_quantity') ...
0107 && ~strcmp(fwd_model.measured_quantity, data.measured_quantity)
0108 error('EIDORS:MeasurementQuantityDisagreement',...
0109 'The solver %s return measurements as %s, while %s was expected.',...
0110 solver, data.measured_quantity, fwd_model.measured_quantity);
0111 end
0112
0113 warning on EIDORS:DeprecatedInterface
0114
0115
0116 function mdl = prepare_model( mdl )
0117 mdl = mdl_normalize(mdl,mdl_normalize(mdl));
0118 if ~isfield(mdl,'elems');
0119 return;
0120 end
0121
0122 mdl.elems = double(mdl.elems);
0123 mdl.n_elem = size(mdl.elems,1);
0124 mdl.n_node = size(mdl.nodes,1);
0125 if isfield(mdl,'electrode');
0126 mdl.n_elec = length(mdl.electrode);
0127 else
0128 mdl.n_elec = 0;
0129 end
0130
0131 function do_unit_test
0132 img = mk_image(mk_common_model('a2c2',4));
0133
0134 img.elem_data([1,5,9,10]) = 2;
0135 A = [1,-1,0,0]; a=A.';
0136 B = [0,0,1,-1]; b=B.';
0137 G = 2;
0138 P = exp(0.1j);
0139 for solv = 1:4; switch solv
0140 case 1; solver = 'fwd_solve_1st_order';
0141 case 2; solver = 'fwd_solve_2p5d_1st_order';
0142 case 3; solver = 'fwd_solve_higher_order';
0143 img.fwd_model.system_mat = @system_mat_higher_order;
0144 img.fwd_model.approx_type = 'tri3';
0145 case 4; break;
0146 end
0147 for test = 1:4; switch test
0148 case 1; str='reciprocity';
0149 mPat = {A,B}; sPat = {b,a};
0150 case 2; str='Gain';
0151 mPat = {A,A*G}; sPat = {b,b/G};
0152 case 3; str='Phase';
0153 mPat = {A,A*P}; sPat = {b,b*P};
0154 case 4; break
0155 end
0156 img.fwd_model.solve = solver;
0157 img.fwd_model.stimulation = struct( ...
0158 'meas_pattern', mPat, 'stim_pattern', sPat );
0159 vv= getfield(fwd_solve(img),'meas');
0160 unit_test_cmp([solver,':',str],diff(vv),0,10*eps)
0161 end
0162 end