Skip to content

Commit fc70e7b

Browse files
authored
Merge pull request #15 from tsipkens/developer
Developer
2 parents 3167101 + e1db908 commit fc70e7b

33 files changed

+395
-306
lines changed

+invert/tikhonov_lpr.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11

22
% TIKHONOV_LPR Generates Tikhonov smoothing operators/matrix, L.
33
% Author: Timothy Sipkens, 2020-02-05
4-
%-------------------------------------------------------------------------%
4+
%
55
% Inputs:
66
% order Order of the Tikhonov operator
77
% n_grid Length of first dimension of solution or Grid for x
8-
% x_length Length of x vector (only used if a Grid is not
9-
% specified for n_grid)
8+
% x_length Length of x vector
9+
% (only used if a Grid is not specified for n_grid)
1010
%
1111
% Outputs:
1212
% Lpr0 Tikhonov matrix
@@ -47,7 +47,7 @@
4747

4848
%== GENL1 ================================================================%
4949
% Generates Tikhonov matrix for 1st order Tikhonov regularization.
50-
%-------------------------------------------------------------------------%
50+
%
5151
% Inputs:
5252
% n Length of first dimension of solution
5353
% x_length Length of x vector
@@ -84,7 +84,7 @@
8484

8585
%== GENL2 ================================================================%
8686
% Generates Tikhonov matrix for 2nd order Tikhonov regularization.
87-
%-------------------------------------------------------------------------%
87+
%
8888
% Inputs:
8989
% n Length of first dimension of solution
9090
% x_length Length of x vector

+kernel/gen.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
A = bsxfun(@times,K,dr_log'); % multiply kernel by element area
108108
A = sparse(A); % exploit sparse structure
109109

110-
disp('Completed computing A matrix.');
110+
disp('Completed computing kernel matrix, <strong>A</strong>.');
111111
disp(' ');
112112

113113
end

+kernel/gen_grid.m

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,16 @@
8181

8282
%== STEP 2: Evaluate PMA transfer function ===============================%
8383
disp('Computing PMA contribution:');
84-
pname = varargin{1}; % name of field for additional PMA field
85-
pval = varargin{2}; % value of field for current setpoint
86-
if length(pval)==1; pval = pval.*ones(n_b(2),1); end % stretch if scalar
8784

8885
tools.textbar(0); % initiate textbar
89-
Lambda_mat = cell(1,n_z); % pre-allocate for speed
90-
% one cell entry per charge state
86+
Lambda_mat = cell(1,n_z); % pre-allocate for speed, one cell entry per charge state
87+
sp = tfer_pma.get_setpoint(prop_pma,...
88+
'm_star',grid_b.edges{1}.*1e-18,varargin{:}); % get PMA setpoints
89+
9190
for kk=1:n_z % loop over the charge state
9291
Lambda_mat{kk} = sparse(n_b(1),N_i);% pre-allocate for speed
9392

9493
for ii=1:n_b(1) % loop over m_star
95-
sp(ii) = tfer_pma.get_setpoint(...
96-
prop_pma,'m_star',grid_b.edges{1}(ii).*1e-18,pname,pval(ii));
9794
Lambda_mat{kk}(ii,:) = kernel.tfer_pma(...
9895
sp(ii),m.*1e-18,...
9996
d.*1e-9,z_vec(kk),prop_pma)';
@@ -124,7 +121,7 @@
124121
A = bsxfun(@times,K,dr_log'); % multiply kernel by element area
125122
A = sparse(A); % exploit sparse structure
126123

127-
disp('Completed computing A matrix.');
124+
disp('Completed computing kernel matrix, <strong>A</strong>.');
128125
disp(' ');
129126

130127

+kernel/gen_grid_c2.m

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,16 @@
8585

8686
%== STEP 2: Evaluate PMA transfer function ===============================%
8787
disp('Computing PMA contribution:');
88-
pname = varargin{1}; % name of field for additional PMA field
89-
pval = varargin{2}; % value of field for current setpoint
90-
if length(pval)==1; pval = pval.*ones(n_b(2),1); end % stretch if scalar
9188

9289
tools.textbar(0); % initiate textbar
93-
Lambda_mat = cell(1,n_z); % pre-allocate for speed
94-
% one cell entry per charge state
90+
Lambda_mat = cell(1,n_z); % pre-allocate for speed, one cell entry per charge state
91+
sp = tfer_pma.get_setpoint(prop_pma,...
92+
'm_star',grid_b.edges{2}.*1e-18,varargin{:}); % get PMA setpoints
93+
9594
for kk=1:n_z % loop over the charge state
9695
Lambda_mat{kk} = sparse(n_b(1),N_i);% pre-allocate for speed
9796

9897
for ii=1:n_b(2) % loop over m_star
99-
sp(ii) = tfer_pma.get_setpoint(...
100-
prop_pma,'m_star',grid_b.edges{2}(ii).*1e-18,pname,pval(ii));
10198
Lambda_mat{kk}(ii,:) = kernel.tfer_pma(...
10299
sp(ii),m.*1e-18,d.*1e-9,...
103100
z_vec(kk),prop_pma)';
@@ -129,7 +126,7 @@
129126
A = bsxfun(@times,K,dr_log'); % multiply kernel by element area
130127
A = sparse(A); % exploit sparse structure
131128

132-
disp('Completed computing A matrix.');
129+
disp('Completed computing kernel matrix, <strong>A</strong>.');
133130
disp(' ');
134131

135132

+kernel/tfer_charge.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
% Author: Timothy Sipkens, 2018-12-27
44
% Based on code from Buckley et al., J. Aerosol Sci. (2008) and Olfert
55
% laboratory at the University of Alberta.
6-
%-------------------------------------------------------------------------%
6+
%
77
% Inputs:
88
% d Particle diameter [m]
99
% z Integer particle charge state (optional, default = 0:6)

+optimize/bayesf.m

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,18 @@
99
lx = size(A,2); % n in Thompson and Kay
1010
lb = size(A,1); % s in Thompson and Kay
1111

12-
F = -1/2*(norm(A*x-b)^2 + norm(lambda.*Lpr0*x)^2);
13-
14-
% Gpo_inv = (A')*A+(Lpr')*Lpr;
15-
% C = tools.logdet(Lpr'*Lpr)/2 - tools.logdet(Gpo_inv)/2;
12+
F = -1/2*(norm(A*x-b)^2 + norm(lambda.*Lpr0*x)^2); % fit
1613

1714
[~,~,~,S1,S2] = gsvd(full(A),full(Lpr0));
1815
h = max(S1,[],2); % picks off diagonal elements of each row
1916
the = diag(S2);
2017

21-
% ct = 2*sum(log(the((lx-r+1):lb)));
22-
% % cp = 2*tools.logdet(P); % term cancels out between |Lpr| and |Gpo|
23-
% det_po = sum(log(h((lx-r+1):lb).^2 + the((lx-r+1):lb).^2));
24-
% C = det_pr/2 - det_po/2;
25-
2618
ct = 2*sum(log(the((lx-r+1):lb))); % contributes to the constant term
27-
% cp = 2*tools.logdet(P); % term cancels out between |Lpr| and |Gpo|
2819
det_po = sum(log(h((lx-r+1):lb).^2 + lambda^2.*the((lx-r+1):lb).^2));
2920

3021
C = (r+lb-lx)*log(lambda) - det_po/2 + ct/2;
22+
% measurement credence
23+
% ignores det_b contributions
3124

3225
B = F+C;
3326

+optimize/bayesf_b.m

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
% BAYESF_B Evaluate the Bayes factor given Lpr0, lambda, and evolving A matrix.
3+
% Author: Timothy Sipkens, 2020-02-27
4+
%=========================================================================%
5+
6+
function [B,F,C] = bayesf_b(A,b,x,Lpr0,lambda)
7+
8+
r = length(x);
9+
lx = size(A,2); % n in Thompson and Kay
10+
lb = size(A,1); % s in Thompson and Kay
11+
12+
F = -1/2*(norm(A*x-b)^2 + norm(lambda.*Lpr0*x)^2); % fit
13+
14+
%-- Depreciated code ----------------------%
15+
% Gpo_inv = (A')*A+(Lpr')*Lpr;
16+
% C = tools.logdet(Lpr'*Lpr)/2 - tools.logdet(Gpo_inv)/2;
17+
%------------------------------------------%
18+
19+
[~,~,P,S1,S2] = gsvd(full(A),full(Lpr0));
20+
h = max(S1,[],2); % picks off diagonal elements of each row
21+
the = diag(S2);
22+
23+
%-- Depreciated code ----------------------%
24+
% ct = 2*sum(log(the((lx-r+1):lb)));
25+
% % cp = 2*tools.logdet(P); % term cancels out between |Gpr| and |Gpo|
26+
% det_po = sum(log(h((lx-r+1):lb).^2 + the((lx-r+1):lb).^2));
27+
% C = det_pr/2 - det_po/2;
28+
%------------------------------------------%
29+
30+
ct = 2*sum(log(the((lx-r+1):lb))); % contributes to the constant term
31+
det_po = sum(log(h((lx-r+1):lb).^2 + lambda^2.*the((lx-r+1):lb).^2));
32+
33+
cp = 2*tools.logdet(P); % contributes due to presence of |Gb|
34+
det_b = cp + 2.*sum(log(h(1:lb)));
35+
36+
C = (r+lb-lx)*log(lambda) - det_po/2 + ct/2 + det_b/2;
37+
% measurement credence, including |Gb| contribution
38+
39+
B = F+C;
40+
41+
end
42+

+optimize/bayesf_precomp.m

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,17 @@
2121
[~,~,~,S1,S2] = gsvd(full(A),full(Lpr0));
2222
end
2323

24-
F = -1/2*(norm(A*x-b)^2 + norm(lambda.*Lpr0*x)^2);
25-
26-
% Gpo_inv = (A')*A+lambda^2.*(Lpr')*Lpr;
27-
% C = (length(x)-order)*log(lambda) - tools.logdet(Gpo_inv)/2;
24+
F = -1/2*(norm(A*x-b)^2 + norm(lambda.*Lpr0*x)^2); % fit
2825

2926
h = max(S1,[],2); % picks off diagonal elements of each row
3027
the = diag(S2);
3128

3229
ct = 2*sum(log(the((lx-r+1):lb))); % contributes to the constant term
33-
% cp = 2*tools.logdet(P); % term cancels out between |Lpr| and |Gpo|
3430
det_po = sum(log(h((lx-r+1):lb).^2 + lambda^2.*the((lx-r+1):lb).^2));
3531

3632
C = (r+lb-lx)*log(lambda) - det_po/2 + ct/2;
33+
% measurement credence
34+
% ignores det_b contributions
3735

3836
B = F+C;
3937

+optimize/exp_dist_op.m

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
%
1616
% Outputs:
1717
% x Regularized estimate
18+
% lambda Semi-optimal regularization parameter
19+
% (against exact solution if x_ex is specified or using Bayes factor)
20+
% output Output structure with information for a range of the regularization parameter
1821
%=========================================================================%
1922

20-
function [x,lambda,out] = exp_dist_op(A,b,span,Gd,d_vec,m_vec,x_ex,xi,solver,n)
23+
function [x,lambda,output] = exp_dist_op(A,b,span,Gd,d_vec,m_vec,x_ex,xi,solver,n)
2124

2225

2326
%-- Parse inputs ---------------------------------------------%
@@ -45,35 +48,35 @@
4548
tools.textbar(0);
4649
for ii=length(lambda):-1:1
4750
%-- Store case parameters ----------------------%
48-
out(ii).lambda = lambda(ii);
49-
out(ii).lm = sqrt(Gd(1,1));
50-
out(ii).ld = sqrt(Gd(2,2));
51-
out(ii).R12 = Gd(1,2)/sqrt(Gd(1,1)*Gd(2,2));
51+
output(ii).lambda = lambda(ii);
52+
output(ii).lm = sqrt(Gd(1,1));
53+
output(ii).ld = sqrt(Gd(2,2));
54+
output(ii).R12 = Gd(1,2)/sqrt(Gd(1,1)*Gd(2,2));
5255

5356
%-- Perform inversion --------------------------%
54-
out(ii).x = invert.exp_dist(...
57+
output(ii).x = invert.exp_dist(...
5558
A,b,lambda(ii),Gd,d_vec,m_vec,xi,solver);
5659

5760
%-- Store ||Ax-b|| and Euclidean error ---------%
58-
if ~isempty(x_ex); out(ii).chi = norm(out(ii).x-x_ex); end
59-
out(ii).Axb = norm(A*out(ii).x-b);
61+
if ~isempty(x_ex); output(ii).chi = norm(output(ii).x-x_ex); end
62+
output(ii).Axb = norm(A*output(ii).x-b);
6063

6164
%-- Compute credence, fit, and Bayes factor ----%
62-
[out(ii).B,out(ii).F,out(ii).C] = ...
63-
optimize.bayesf_precomp(A,b,out(ii).x,Lpr,out(ii).lambda,S1,S2,0);
65+
[output(ii).B,output(ii).F,output(ii).C] = ...
66+
optimize.bayesf_precomp(A,b,output(ii).x,Lpr,output(ii).lambda,S1,S2,0);
6467
% bypass exp_dist_bayesf, because GSVD is pre-computed
6568
% optimize.exp_dist_bayesf(A,b,lambda(ii),Lpr,out(ii).x);
6669

6770
tools.textbar((length(lambda)-ii+1)/length(lambda));
6871
end
6972

7073
if ~isempty(x_ex)
71-
[~,ind_min] = min([out.chi]);
74+
[~,ind_min] = min([output.chi]);
7275
else
73-
[~,ind_min] = max([out.B]);
76+
[~,ind_min] = max([output.B]);
7477
end
75-
lambda = out(ind_min).lambda;
76-
x = out(ind_min).x;
78+
lambda = output(ind_min).lambda;
79+
x = output(ind_min).x;
7780

7881
end
7982

+optimize/exp_dist_op1d.m

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
% EXP_DIST_OP1D Single parameter sensitivity study for exponential distance regularization.
33
%=========================================================================%
44

5-
function [out] = exp_dist_op1d(A,b,lambda,Gd,d_vec,m_vec,x_ex,xi,solver,type)
5+
function [output] = exp_dist_op1d(A,b,lambda,Gd,d_vec,m_vec,x_ex,xi,solver,type)
66

77
%-- Parse inputs ---------------------------------------------%
88
if ~exist('solver','var'); solver = []; end
@@ -39,33 +39,33 @@
3939

4040
%-- Evaluate Gd/parameters for current vector entry ------%
4141
if strcmp(type,'lmld') % lm/ld scaling
42-
out(ii).alpha = beta_vec(ii);
42+
output(ii).alpha = beta_vec(ii);
4343
Gd_alt = Gd.*beta_vec(ii);
4444

4545
elseif strcmp(type,'corr') % corr. scaling
46-
out(ii).R12 = 1-beta_vec(ii);
46+
output(ii).R12 = 1-beta_vec(ii);
4747
Gd_12_alt = sqrt(Gd(1,1)*Gd(2,2))*beta_vec(ii);
4848
Gd_alt = diag(diag(Gd))+[0,Gd_12_alt;Gd_12_alt,0];
4949
end
5050
%---------------------------------------------------------%
5151

5252
%-- Store other case parameters --%
53-
out(ii).lambda = lambda;
54-
out(ii).lm = sqrt(Gd_alt(1,1));
55-
out(ii).ld = sqrt(Gd_alt(2,2));
56-
out(ii).R12 = Gd_alt(1,2)/sqrt(Gd_alt(1,1)*Gd_alt(2,2));
53+
output(ii).lambda = lambda;
54+
output(ii).lm = sqrt(Gd_alt(1,1));
55+
output(ii).ld = sqrt(Gd_alt(2,2));
56+
output(ii).R12 = Gd_alt(1,2)/sqrt(Gd_alt(1,1)*Gd_alt(2,2));
5757

5858
%-- Perform inversion --%
59-
[out(ii).x,~,Lpr] = invert.exp_dist(...
59+
[output(ii).x,~,Lpr] = invert.exp_dist(...
6060
A,b,lambda,Gd_alt,d_vec,m_vec,xi,solver);
6161

6262
%-- Store ||Ax-b|| and Euclidean error --%
63-
if ~isempty(x_ex); out(ii).chi = norm(out(ii).x-x_ex); end
64-
out(ii).Axb = norm(A*out(ii).x-b);
63+
if ~isempty(x_ex); output(ii).chi = norm(output(ii).x-x_ex); end
64+
output(ii).Axb = norm(A*output(ii).x-b);
6565

6666
%-- Compute credence, fit, and Bayes factor --%
67-
[out(ii).B,out(ii).F,out(ii).C] = ...
68-
optimize.bayesf(A,b,out(ii).x,Lpr,lambda);
67+
[output(ii).B,output(ii).F,output(ii).C] = ...
68+
optimize.bayesf(A,b,output(ii).x,Lpr,lambda);
6969

7070
tools.textbar((length(beta_vec)-ii+1)/length(beta_vec));
7171
end

+optimize/exp_dist_opbf.m

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

2-
% EXP_DIST_OPBF Approximates optimal lambda for exponential distance solver by brute force method.
2+
% EXP_DIST_OPBF Approximates optimal prior parameter set using the brute force method.
33
% Author: Timothy Sipkens, 2019-12
4-
%-------------------------------------------------------------------------%
4+
%
55
% Inputs:
66
% A Model matrix
77
% b Data
@@ -15,9 +15,12 @@
1515
%
1616
% Outputs:
1717
% x Regularized estimate
18+
% lambda Semi-optimal regularization parameter
19+
% (against exact solution if x_ex is specified or using Bayes factor)
20+
% output Output structure with information for a range of the prior parameters
1821
%=========================================================================%
1922

20-
function [x,lambda,out] = exp_dist_opbf(A,b,d_vec,m_vec,x_ex,xi,solver)
23+
function [x,lambda,output] = exp_dist_opbf(A,b,d_vec,m_vec,x_ex,xi,solver)
2124

2225

2326
%-- Parse inputs ---------------------------------------------%
@@ -44,30 +47,30 @@
4447
vec_corr = vec_corr(:);
4548

4649
tools.textbar(0);
47-
out(length(vec_lambda)).chi = [];
50+
output(length(vec_lambda)).chi = [];
4851
for ii=1:length(vec_lambda)
4952
y = [vec_lambda(ii),vec_ratio(ii),vec_ld(ii),vec_corr(ii)];
5053

51-
out(ii).x = invert.exp_dist(...
54+
output(ii).x = invert.exp_dist(...
5255
A,b,y(1),Gd_fun(y),d_vec,m_vec,xi,solver);
53-
out(ii).chi = norm(out(ii).x-x_ex);
56+
output(ii).chi = norm(output(ii).x-x_ex);
5457

55-
out(ii).lambda = vec_lambda(ii);
56-
out(ii).ratio = vec_ratio(ii);
57-
out(ii).ld = vec_ld(ii);
58-
out(ii).corr = vec_corr(ii);
58+
output(ii).lambda = vec_lambda(ii);
59+
output(ii).ratio = vec_ratio(ii);
60+
output(ii).ld = vec_ld(ii);
61+
output(ii).corr = vec_corr(ii);
5962

60-
[out(ii).B,out(ii).F,out(ii).C] = ...
61-
optimize.bayesf(A,b,out(ii).x,Lpr,out(ii).lambda);
63+
[output(ii).B,output(ii).F,output(ii).C] = ...
64+
optimize.bayesf(A,b,output(ii).x,Lpr,output(ii).lambda);
6265

6366
tools.textbar(ii/length(vec_lambda));
6467
end
6568

6669
tools.textbar(1);
6770

68-
[~,ind_min] = min([out(ii).chi]);
69-
x = [];%out(ind_min).x;
70-
lambda = [];%out(ind_min).lambda;
71+
[~,ind_min] = min([output(ii).chi]);
72+
x = out(ind_min).x;
73+
lambda = out(ind_min).lambda;
7174

7275
end
7376

0 commit comments

Comments
 (0)