-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc_performance_loop.m
213 lines (175 loc) · 6.07 KB
/
calc_performance_loop.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
%% loop for calculating peformance data (delta_bar)
% SPDX-FileCopyrightText: Copyright (C) 2023 S Shermer <lw1660@gmail.com>, Swansea University
% SPDX-FileCopyrightText: Copyright (C) 2023 Sean P O'Neil <seanonei@usc.edu>, University of Southern California
%
% SPDX-License-Identifier: CC-BY-SA-4.0
function out_data = calc_performance_loop(ind,results,delta,epsilon,tol,prob,tf,K,ss,algorithm,control)
% input
% ind - controller index
% results - results structure output by calc_sens__bounds.m
% delta - step size for incrementing perturbation
% epsilon - performance limit on fidelity error
% tol - tolerance to determine when fidelity error exceeds \epsilon
% prob - problem index
% tf - read-out time
% K - number of control pulses
% ss - step-size string
% algorithm - algorithm string
% output
% error_f - array of fidelity error evaluated at \delta_bar for each
% principal uncertainty structure and for the maximum sensitivity
% direction
% delta_bar - minimum perturbation that violates the performance threshold
% load problem data
intag = sprintf('problems/problem%d',prob);
load(intag);
% extract system and controller data
M = length(problem.H)-1;
temp = control; % extract control
f = reshape(temp,M,K); % reshape control array
H = problem.H; % drift and interaction hamiltonian matrices
dH = problem.dH; % extract uncertainty structure matrices
M2 = length(dH);
dHindex = results.dHindex; % extact association of structure with Hamiltonian matrices
Uf = problem.UT; % target unitary
dt = tf/K; % length of each control pulse
N = max(size(H{1})); % system size
H_0 = H{1};
sens = results.sens(ind,:); % differential sensitivity
Z = (-1/N)*results.X{ind};
%delta = 0
% establish array of directions for \delta_bar search
for ell = 1:K
direction(ell,:) = Z(ell,:)/norm(Z(ell,:));
end
% create optimized hamiltonian
for k = 1:K
Htot{k} = H_0;
for m = 1:M
Htot{k} = Htot{k} + f(m,k)*H{m+1};
end
end
% create perturbed hamiltonian about \delta = 0
Htot_p = Htot;
for k = 1:K
for p = 1:M2
mu = dHindex(1,p);
if mu == M+1
Htot_p{k} = Htot_p{k}+dH{p}*delta*direction(k,p);
else
Htot_p{k} = Htot_p{k} + delta*f(mu,k)*dH{p}*direction(k,p);
end
end
end
% calculate exact perturbed state transition matrix
for k = 1:K
[Phi_p{k}] = expm(-i*(Htot_p{k})*dt);
end
% produce total perturbed state transition matrix from ordered product
Phi_tot_p{1} = Phi_p{1};
for k = 2:K
Phi_tot_p{k} = Phi_p{k}*Phi_tot_p{k-1};
end
% initialize index for iteration on \delta
c = 1;
phi = trace(transpose(Uf)*conj(Phi_tot_p{K}))/abs(trace(Uf'*Phi_tot_p{K}));
fid_p = (1/N)*abs(trace(Uf'*Phi_tot_p{K}));
err_p(c,1) = 1-fid_p;
clear Phi_p Phi_tot_p ell p k;
% loop to determine \delta_bar
while (epsilon-err_p(c,1)) >= tol
z = zeros(K,M2);
% loop to compute matrix exponential derivative evaluated at c*\delta for each uncertainty structure
for p = 1:M2
mu = dHindex(1,p);
for k = 1:K
if mu == M+1
[Phi_p{k},dPhi_p{k}] = dexpma(-i*(Htot_p{k})*dt,-i*dH{p}*dt);
else
[Phi_p{k},dPhi_p{k}] = dexpma(-i*(Htot_p{k})*dt,-i*f(mu,k)*dH{p}*dt);
end
end
% produce total perturbed state transition matrix at c*\delta
Phi_tot_p{1} = Phi_p{1};
for k = 2:K
Phi_tot_p{k} = Phi_p{k}*Phi_tot_p{k-1};
end
phi = trace(transpose(Uf)*conj(Phi_tot_p{K}))/abs(trace(Uf'*Phi_tot_p{K}));
% compute Z matrix at c*\delta
for k = 1:K
if k == 1
z(k,p) = real(phi*trace(Uf'*Phi_tot_p{K}*Phi_tot_p{k}'*dPhi_p{k}));
else
z(k,p) = real(phi*trace( Phi_tot_p{k-1}*Uf'*Phi_tot_p{K}*Phi_tot_p{k}'*dPhi_p{k} ));
end
end
clear Phi_p Phi_tot_p
end
% increment step size index
c = c+1;
temp = (-1*z/N);
for k = 1:length(temp)
dir(k,:) = temp(k,:)/norm(temp(k,:));
end
% create perturbed hamiltonian at next step of \delta
for k = 1:K
for ell = 1:M2
mu = dHindex(1,ell);
if mu == M+1
Htot_p{k} = Htot_p{k}+dH{ell}*delta*dir(k,ell);
else
Htot_p{k} = Htot_p{k} + delta*f(mu,k)*dH{ell}*dir(k,ell);
end
end
end
% calculate exact perturbed state transition matrix at new \delta
for k = 1:K
[Phi_p{k}] = expm(-i*(Htot_p{k})*dt);
end
% produce total perturbed state transition matrix at new \delta
Phi_tot_p{1} = Phi_p{1};
for k = 2:K
Phi_tot_p{k} = Phi_p{k}*Phi_tot_p{k-1};
end
% evalute fidelity error at new value of \delta
phi = trace(Uf*Phi_tot_p{K}')/abs(trace(Uf*Phi_tot_p{K}'));
fid_p = (1/N)*abs(trace(Uf'*Phi_tot_p{K}));
err_p(c,1) = 1-fid_p;
clear Phi_p Phi_tot_p z
end
delta_bar = delta*(c-1);
clear Htot_p Phi_p Phi_tot_p dir
% recalculate err_p at delta_bar in each basis direction for comparison
% create perturbed hamiltonian at \delta_bar in principal directions
for p = 1:M2
mu = dHindex(1,p);
for k = 1:K
if mu == M+1
Htot_f{k} = Htot{k} + dH{p}*delta_bar;
else
Htot_f{k} = Htot{k} + delta_bar*f(mu,k)*dH{p};
end
end
% produced state transision matrix at each time step - perturbed at
% \delta_bar
for k = 1:K
[Phi_f{k}] = expm(-i*(Htot_f{k})*dt);
end
% produce total perturbed state transition matrix at \delta_bar in
% given uncertainty direction
Phi_tot_f{1} = Phi_f{1};
for k = 2:K
Phi_tot_f{k} = Phi_f{k}*Phi_tot_f{k-1};
end
% compute perturbed fidelity error in each principal direction at
% \delta_bar for comparison
fid_f(1,p) = (1/N)*abs(trace(Uf'*Phi_tot_f{K}));
err_f(1,p) = 1-fid_f(1,p);
clear Phi_tot_f;
clear Htot_f;
clear Phi_f;
end
error_f(1,:) = [err_f(1,:) err_p(c-1,1)];
out_data = [delta_bar error_f];
outfile = sprintf('results/temp/problem%d_tf%d_K%d_%s_%d_%s',prob,tf,K,ss,ind,algorithm);
save(outfile,'out_data');