0001 function s_mat = system_mat_instrument( 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    if ischar(img) && strcmp(img,'UNIT_TEST'); do_unit_test; return; end
0028 
0029    citeme(mfilename)
0030 
0031    new_c_list = img.fwd_model.system_mat_instrument.connect_list;
0032 
0033 
0034    img.fwd_model = remove_instrument_electrodes(img.fwd_model);
0035    s_mat= system_mat_1st_order(img);
0036    E = s_mat.E;
0037 
0038    n_nodes = num_nodes(img);
0039    if ~isempty(new_c_list);
0040       n_elecs = max([max(new_c_list(:,1:2)),num_elecs(img)]);
0041    else
0042       n_elecs = num_elecs(img);
0043    end
0044    n_max  = n_nodes + n_elecs; 
0045    Eo = sparse(n_max, n_max);
0046    Eo(1:size(E,1),1:size(E,2)) = E;
0047    for i=1:size(new_c_list,1);
0048      x = new_c_list(i,1) + n_nodes;
0049      y = new_c_list(i,2) + n_nodes;
0050      c = new_c_list(i,3);
0051      Eo(x,y) = Eo(x,y) - c;
0052      Eo(y,x) = Eo(y,x) - c;
0053      Eo(x,x) = Eo(x,x) + c;
0054      Eo(y,y) = Eo(y,y) + c;
0055    end
0056    
0057    s_mat.E = Eo;
0058 
0059 function do_unit_test
0060    do_unit_test_x;
0061    do_unit_test_paper
0062    do_unit_test_2d
0063    do_unit_test_3d
0064    do_cache_test
0065 
0066 
0067 function do_cache_test
0068    fmdl = getfield( ...
0069     mk_common_model('a2C2',2),'fwd_model');
0070    fmdl.electrode(end+1) = struct( ...
0071           'nodes','instrument','z_contact',NaN);
0072    fmdl.stimulation = stim_meas_list([1,3,1,3],3);
0073    fmdl.system_mat = @system_mat_instrument;
0074    fmdl.system_mat_instrument.connect_list = ...
0075         [2,3,10];
0076    vA = fwd_solve(mk_image(fmdl,1));
0077    fmdl.system_mat_instrument.connect_list = ...
0078         [2,3,20];
0079    vB = fwd_solve(mk_image(fmdl,1)) ;
0080    unit_test_cmp('check different (cache)', vA.meas > vB.meas, true);
0081 
0082 function do_unit_test_x
0083    
0084    fmdl = mk_circ_tank(1,[],2);
0085    zC = 0.1;
0086    for i=1:num_elecs(fmdl);
0087       fmdl.electrode(i).nodes = num_nodes(fmdl) - 2*i + [1,2];
0088       fmdl.electrode(i).z_contact = zC;
0089    end
0090 
0091    fmdl.system_mat = @system_mat_instrument;
0092    fmdl.system_mat_instrument.connect_list = [];
0093    fmdl.stimulation = stim_meas_list([1,2,1,2], ...
0094                                 num_elecs(fmdl) ); 
0095    img= mk_image(fmdl,1);
0096    s_mat= calc_system_mat(img);
0097    vA = fwd_solve(img);
0098    
0099    unit_test_cmp('square:', vA.meas, 1+sqrt(2)*zC,1e-14);
0100 
0101    NewElectrode = num_elecs(fmdl)+1;
0102    fmdl.electrode(NewElectrode) = struct( ...
0103           'nodes','instrument','z_contact',NaN);
0104    zC = 1000;
0105    fmdl.system_mat_instrument.connect_list = ...
0106         [1,3,1/zC];
0107    fmdl.stimulation = stim_meas_list([1,3,1,3], ...
0108                                 num_elecs(fmdl) ); 
0109    img = mk_image(fmdl,1);
0110 
0111 
0112    vB = fwd_solve(img);
0113    unit_test_cmp('square2:', vB.meas, zC,1e-12);
0114 
0115    img.fwd_model.system_mat_instrument.connect_list = ...
0116         [2,3,2/zC;
0117          1,3,1/zC];
0118    vC = fwd_solve(img);
0119    test = 1/(1/zC + 1/(zC/2 + 1 + 0.1*sqrt(2)));
0120    unit_test_cmp('square3:', vC.meas, test,1e-12);
0121 
0122 function do_unit_test_2d
0123    img = mk_image(mk_common_model('a2C2',2));
0124    s_mat = calc_system_mat(img);
0125    test= zeros(1,num_nodes(img)+2);
0126    test(1,1:5)= [4,-1,-1,-1,-1];
0127    unit_test_cmp('basic',s_mat.E(1,:),test,10*eps);
0128 
0129    img.fwd_model.stimulation = stim_meas_list([1,2,1,2],2);
0130    v0 = fwd_solve(img);
0131    Y12 = 1/10; 
0132    c_list = [ 1,2,Y12];
0133    img.fwd_model.system_mat = @system_mat_instrument;
0134    img.fwd_model.system_mat_instrument.connect_list = c_list;
0135    vv = fwd_solve(img);
0136    test = 1/(1/v0.meas + Y12);
0137    unit_test_cmp('Resistor',vv.meas,test,1e3*eps);
0138   
0139    NewElectrode = num_elecs(img)+1; 
0140    Y13 = 1/ 5; 
0141    c_list = [ 1,2,Y12;
0142               2,NewElectrode,Y13];
0143    img.fwd_model.system_mat_instrument.connect_list = c_list;
0144    
0145    img.fwd_model.electrode(NewElectrode) = ...
0146        struct('nodes','instrument','z_contact',NaN);
0147    img.fwd_model.stimulation = stim_meas_list([1,2,1,3],NewElectrode);
0148    s_mat= calc_system_mat(img);
0149    vv = fwd_solve(img);
0150 
0151 function do_unit_test_paper
0152    
0153    fmdl = eidors_obj('fwd_model','eg', ...
0154        'nodes',[0,0;0,1;2,0;2,1], ...
0155        'elems',[1,2,3;2,3,4], ...
0156        'gnd_node',1);
0157    fmdl = mdl_normalize(fmdl,1);
0158    fmdl.system_mat = @eidors_default;
0159    fmdl.solve      = @eidors_default;
0160    img = mk_image(fmdl,[1,2]);
0161    s_mat= calc_system_mat(img); 
0162    Eok= [ 5,-4,-1, 0;-4, 6, 0,-2;
0163          -1, 0, 9,-8; 0,-2,-8,10]/4;
0164    unit_test_cmp('basic',s_mat.E,Eok);
0165 
0166    img.fwd_model.electrode = [ ...
0167      struct('nodes',[1,2],'z_contact',5/30), ...
0168      struct('nodes',[3,4],'z_contact',5/60)];
0169    s_mat= calc_system_mat(img); 
0170 
0171    Eok(:,5:6) = 0; Eok(5:6,:) = 0;
0172    Eok = Eok + [ ...
0173      2 1 0 0 -3 0; 1 2 0 0 -3 0;
0174      0  0 4 2 0 -6; 0 0  2  4 0 -6
0175     -3 -3 0 0 6  0; 0 0 -6 -6 0 12];
0176    unit_test_cmp('with CEM',s_mat.E,Eok,1e-13);
0177 
0178    img.fwd_model.stimulation = ...
0179       stim_meas_list([1,2,1,2], ...
0180       num_elecs(img) ); 
0181 
0182    imgs = img; imgs.elem_data = [1;1];
0183    vv= fwd_solve(imgs);
0184    Ztest =  2+5/30+5/60;
0185    unit_test_cmp('CEM solve',vv.meas,Ztest,1e-13);
0186 
0187 
0188 
0189    NewElectrode = num_elecs(img)+1;
0190    Y12 = 1/10; 
0191    Y13 = 1/ 5; 
0192    c_list = [ 1,3,Y12;
0193               2,NewElectrode,Y13];
0194    
0195    img.fwd_model.electrode(NewElectrode) = ...
0196        struct('nodes','instrument','z_contact',NaN);
0197    img.fwd_model.stimulation = ...
0198       stim_meas_list([1,3,1,3], ...
0199       num_elecs(img) ); 
0200 
0201    img.fwd_model.system_mat = @system_mat_instrument;
0202    img.fwd_model.system_mat_instrument.connect_list = c_list;
0203    s_mat= calc_system_mat(img); 
0204    save thisimg img
0205 
0206    Eok(:,7) = 0; Eok(7,:) = 0;
0207    Eok = Eok + [ 0 0 0 0 0 0 0;
0208 0 0 0 0   0   0   0; 0 0 0 0   0   0   0; 
0209 0 0 0 0   0   0   0; 0 0 0 0  .1   0 -.1;
0210 0 0 0 0   0  .2 -.2; 0 0 0 0 -.1 -.2  .3];
0211    unit_test_cmp('instrument',s_mat.E,Eok,1e-13);
0212 
0213    imgs = img; imgs.elem_data = [1;1];
0214    vv= fwd_solve(imgs);
0215    Ztest = 1/( Y12 + 1/(Ztest + 1/Y13));
0216    
0217    unit_test_cmp('instrument solve1',vv.meas, Ztest,1e-13);
0218 
0219    
0220    imgs.fwd_model.stimulation = struct( ...
0221       'stim_pattern',[1;0;NaN], ...
0222       'volt_pattern',[0;0;0], ...
0223       'meas_pattern',[1,0,-1;0,1,-1]);
0224    pp = fwd_model_parameters(img.fwd_model);
0225    vv= fwd_solve(imgs);
0226    Ztest2 = 10/(7.25+10)*5;
0227    unit_test_cmp('instrument solve2',vv.meas, [Ztest;Ztest2],1e-13);
0228 
0229    
0230    imgs.fwd_model.stimulation = struct( ...
0231       'stim_pattern',[NaN;0;NaN], ...
0232       'volt_pattern',[10;0;0], ...
0233       'meas_pattern',[1,0,-1;0,1,-1]);
0234    vv= fwd_solve(imgs);
0235    Ztest = 10*[1;5/7.25];
0236    unit_test_cmp('instrument solve3',vv.meas, Ztest,1e-13);
0237 
0238 
0239 
0240 
0241 
0242 function do_unit_test_3d
0243    fmdl = mk_common_model('n3r2',[16,2]);
0244    
0245    fmdl = rmfield(fmdl.fwd_model,'stimulation');
0246    gndE= num_elecs(fmdl) + 1;
0247    fmdl.electrode(gndE) = struct('nodes','instrument','z_contact',NaN);
0248    Zgnd = 1e-3;
0249    VoltIn = 10;
0250    stim.meas_pattern = [eye(gndE-1), -Zgnd*ones(gndE-1,1)];
0251    stim.meas_pattern(1:16,:) = [];
0252 
0253    c_list =  [17:32]'*[1,0,0] + [0,gndE, 1/Zgnd];
0254    fmdl.system_mat = @system_mat_instrument;
0255    fmdl.system_mat_instrument.connect_list = c_list;
0256    for i=1:16
0257       stim.volt_pattern = [zeros(gndE,1)];
0258       stim.stim_pattern = stim.volt_pattern;
0259       stim.volt_pattern(i) = VoltIn;
0260       stim.stim_pattern([i,gndE]) = NaN;
0261       fmdl.stimulation(i) = stim;
0262    end
0263    img = mk_image(fmdl,1);
0264    vv = fwd_solve(img);
0265    unit_test_cmp('3D shape',[max(vv.meas) min(vv.meas)], ...
0266     [ 1.152029995247298e-06, 1.150256267849528e-06], 1e-14);