Skip to content

Commit f8f32c8

Browse files
committed
Added cut_off_observable
1 parent 1c06032 commit f8f32c8

File tree

4 files changed

+33
-10
lines changed

4 files changed

+33
-10
lines changed

lindbladmpo/LindbladMPOSolver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ def verify_parameters(
955955
"Error 410: " + key + " must be a non-negative integer\n"
956956
)
957957
continue
958-
elif (key == "cut_off") or (key == "cut_off_rho"):
958+
elif (key == "cut_off") or (key == "cut_off_rho") or (key == "cut_off_observable"):
959959
if not LindbladMPOSolver.is_float(parameters[key]):
960960
check_msg += "Error 420: " + key + " is not a float\n"
961961
continue

lindbladmpo/examples/simulation_building/LindbladMatrixSolver.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ def solve(self):
394394

395395
if parameters.get("b_save_final_state", False): # Write final state
396396
np.save(self.s_output_path + ".state", sol.y[-1])
397+
cut_off_observable = parameters.get("cut_off_observable", .0)
397398

398399
file_1q = open(self.s_output_path + ".obs-1q.dat", "w")
399400
file_2q = open(self.s_output_path + ".obs-2q.dat", "w")
@@ -419,6 +420,8 @@ def solve(self):
419420
f"Warning: imaginary component {val.imag} in observable "
420421
f"{key[0].upper()}, qubit {key[1] + 1}.\n"
421422
)
423+
if cut_off_observable and (abs(val) < cut_off_observable):
424+
val = .0
422425
file_1q.write(f"{t}\t{key[0].upper()}\t{key[1] + 1}\t{val.real}\n")
423426
file_1q.write("\n")
424427
file_1q.flush()
@@ -431,6 +434,8 @@ def solve(self):
431434
f"Warning: imaginary component {val.imag} in observable "
432435
f"{key[0].upper()}, qubits ({key[1] + 1}, {key[2] + 1}).\n"
433436
)
437+
if cut_off_observable and (abs(val) < cut_off_observable):
438+
val = .0
434439
file_2q.write(
435440
f"{t}\t{key[0].upper()}\t{key[1] + 1}\t{key[2] + 1}\t{val.real}\n"
436441
)
@@ -446,6 +451,8 @@ def solve(self):
446451
f"{key[0].upper()}, qubits ({key[1] + 1}, {key[2] + 1}, "
447452
f"{key[3] + 1}).\n"
448453
)
454+
if cut_off_observable and (abs(val) < cut_off_observable):
455+
val = .0
449456
file_3q.write(
450457
f"{t}\t{key[0].upper()}\t{key[1] + 1}\t{key[2] + 1}\t{key[3] + 1}\t{val.real}\n"
451458
)
@@ -459,6 +466,8 @@ def solve(self):
459466
f"Warning: imaginary component {val.imag} in observable "
460467
f"{obs_cu_name}.\n"
461468
)
469+
if cut_off_observable and (abs(val) < cut_off_observable):
470+
val = .0
462471
file_cu.write(f"{t}\t{obs_cu_name}\t{val.real}\n")
463472
# print(f"{t}\t{obs_cu_name}\t{val.real}")
464473
file_cu.write("\n")

src/SimulationParameters.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ class SimulationParameters : public Parameters
2424
operator[]("trotter_order") = "4"; // Possible choices are 2, 3, 4. 3 or 4 are recommended.
2525
operator[]("max_dim_rho") = "400"; // Maximum bond dimension for density matrices
2626
operator[]("cut_off_rho") =
27-
"1e-16"; // Maximum truncation error for density matrices. The actual
28-
// truncation is done using the most severe condition between cut_off_rho and max_dim_rho.
27+
"1e-16"; // Maximum truncation error for density matrices. The actual truncation is
28+
// done using the most severe condition between cut_off_rho and max_dim_rho.
29+
operator[]("cut_off_observable") = "0"; // If a nonzero value is given, it is the maximum
30+
// (absolute) value of an observable to be written to output files -
31+
// smaller values are truncated to 0.
2932

3033
operator[]("b_force_rho_trace") = "1"; // Whether to force the density matrix trace to 1,
3134
// by substituting rho /= trace{rho} at every time step and every
@@ -41,7 +44,7 @@ class SimulationParameters : public Parameters
4144
"0"; // If nonzero, after reading rho from
4245
// a saved file, perform a re-gauging/compression using ITensor's method orthogonalize().
4346
operator[]("b_quiet") = "0"; // If nonzero, after initialization of the simulation
44-
// avoid the console output at every time step (but write it the log file).
47+
// avoid the console output at every time step (but write it to the log file).
4548

4649
operator[]("init_product_state") =
4750
""; // Initialize a product state. Can be specified

src/lindbladmpo.cc

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,14 @@ int main(int argc, char *argv[])
130130
}
131131

132132
C.ConstructIdentity(); // Construct the density matrix corresponding to infinite temperature
133-
133+
const double cut_off_rho = param.val("cut_off_rho");
134134
// Note on the option below: if we "Normalize=true" (default for fitapplyMPO)
135135
// we would normalize rho such that Tr[rho^2]=1, (norm of the MPS)
136136
// which is of course not appropriate for a density matrix.
137137
auto argsRho = Args();
138138
argsRho.add("Normalize", false);
139139
argsRho.add("MaxDim", param.longval("max_dim_rho"));
140-
argsRho.add("Cutoff", param.val("cut_off_rho"));
140+
argsRho.add("Cutoff", cut_off_rho);
141141

142142
vector<long> init_graph_state = param.longvec("init_graph_state");
143143
vector<long> init_cz_gates = param.longvec("init_cz_gates");
@@ -680,7 +680,7 @@ int main(int argc, char *argv[])
680680

681681
cout2 << "C.rho.orthogonalize...";
682682
cout2.flush();
683-
C.rho.orthogonalize(Args("Cutoff", param.val("cut_off_rho"), "MaxDim", param.longval("max_dim_rho")));
683+
C.rho.orthogonalize(Args("Cutoff", cut_off_rho, "MaxDim", param.longval("max_dim_rho")));
684684
cout2 << "done.\n";
685685
cout2 << "New max bond dimension of rho:" << maxLinkDim(C.rho) << "\n";
686686
cout2.flush();
@@ -912,7 +912,7 @@ int main(int argc, char *argv[])
912912
if (std::abs(z) < _2_N)
913913
cout2 << "\t\tNote: " << "Tr{rho} = " << z << " encountered during collapse projectors, "
914914
<< "this is smaller than 2^(-N)!";
915-
// C.rho /= z;
915+
C.rho /= z;
916916
}
917917
if (i_coll == 0)
918918
rho_c = MPS(C.rho);
@@ -928,16 +928,17 @@ int main(int argc, char *argv[])
928928
cout2 << "\t\tNote: this is smaller than 2^(-N)!"
929929
<< "\n";
930930
// TODO: This is a somewhat arbitrary threshold for the warning.
931-
// C.rho /= z;
931+
C.rho /= z;
932932
auto t_collapse_end = steady_clock::now();
933933
duration_ms = duration_cast<milliseconds>(t_collapse_end - t_collapse_start);
934934
cout2 << "Collapse evaluation terminated. Duration: " << duration_ms.count() / 1000. << "s\n";
935935
}
936936

937937
char buf[100];
938+
const bool b_quiet = param.boolval("b_quiet");
939+
const double cut_off_observable = param.val("cut_off_observable");
938940
const long force_rho_hermitian_step = param.longval("force_rho_hermitian_step");
939941
const long force_rho_hermitian_gates = param.longval("force_rho_hermitian_gates");
940-
const bool b_quiet = param.boolval("b_quiet");
941942
cout2.quiet(b_quiet);
942943
double t = t_0;
943944
for (int n = 0; n <= n_steps; n++)
@@ -1093,6 +1094,8 @@ int main(int argc, char *argv[])
10931094
cout2 << "\tWarning: <S^" << s << "(" << i << ")> = " << expectation_value
10941095
<< "; it should be real, but has an imaginary part > " << IMAGINARY_THRESHOLD
10951096
<< ".\n";
1097+
if (cut_off_observable && (abs(expectation_value) < cut_off_observable))
1098+
expectation_value = .0;
10961099
file_1q << t << "\t" << char(toupper(s[0])) << "\t" << i << "\t" << expectation_value.real()
10971100
<< endl;
10981101
count++;
@@ -1129,6 +1132,8 @@ int main(int argc, char *argv[])
11291132
<< ")> = " << expectation_value
11301133
<< "; it should be real, but has an imaginary part > " << IMAGINARY_THRESHOLD
11311134
<< ".\n";
1135+
if (cut_off_observable && (abs(expectation_value) < cut_off_observable))
1136+
expectation_value = .0;
11321137
file_2q << t << "\t" << char(toupper(s[0])) << char(toupper(s[1])) << "\t" << i << "\t" << j
11331138
<< "\t" << expectation_value.real() << endl;
11341139
count++;
@@ -1165,6 +1170,8 @@ int main(int argc, char *argv[])
11651170
<< k << ")" << expectation_value
11661171
<< "; it should be real, but has an imaginary part > " << IMAGINARY_THRESHOLD
11671172
<< ".\n";
1173+
if (cut_off_observable && (abs(expectation_value) < cut_off_observable))
1174+
expectation_value = .0;
11681175
file_3q << t << "\t" << char(toupper(s[0])) << char(toupper(s[1])) << char(toupper(s[2]))
11691176
<< "\t" << i << "\t" << j << "\t" << k << "\t" << expectation_value.real() << endl;
11701177
count++;
@@ -1192,6 +1199,8 @@ int main(int argc, char *argv[])
11921199
for (MPS &proj : ProjectorList)
11931200
{
11941201
Cplx op_val = innerC(proj, C.rho);
1202+
if (cut_off_observable && (abs(op_val) < cut_off_observable))
1203+
op_val = .0;
11951204
file_custom << t << " \t" << ProjectorNames[c] << "\t" << op_val.real() << endl;
11961205
c++;
11971206
}
@@ -1203,6 +1212,8 @@ int main(int argc, char *argv[])
12031212
for (string &s_op_obs : OperatorObsNames)
12041213
{
12051214
Cplx op_val = C.Expect(OperatorObs[c], OperatorObsQubits[c]);
1215+
if (cut_off_observable && (abs(op_val) < cut_off_observable))
1216+
op_val = .0;
12061217
// cout2 << "\nCalculating: " << OperatorObs[c] << " " << OperatorObsQubits[c];
12071218
file_custom << t << " \t" << s_op_obs << "\t" << op_val.real() << endl;
12081219
c++;

0 commit comments

Comments
 (0)