75 p.setRenderHint(QPainter::Antialiasing,
true);
76 p.setRenderHint(QPainter::TextAntialiasing,
true);
77 p.fillRect(rect(), QColor(14, 17, 22));
79 const double marginL = 58.0;
80 const double marginR = 42.0;
81 const double top = 34.0;
82 const double gap = 42.0;
83 const double bottom = 42.0;
84 const double available = std::max(180.0, height() - top - gap - bottom);
85 const double upperH = available * 0.48;
86 const QRectF pathRect(marginL, top, std::max(100.0, width() - marginL - marginR), upperH);
87 const QRectF echoRect(marginL, pathRect.bottom() + gap, pathRect.width(), available - upperH);
91 p.setPen(QColor(226, 232, 240));
92 p.drawText(QRectF(pathRect.left(), 5.0, pathRect.width(), 22.0), Qt::AlignCenter,
93 QStringLiteral(
"Loschmidt echo — centroid path before and after time reversal"));
94 p.drawText(QRectF(echoRect.left(), pathRect.bottom() + 10.0, echoRect.width(), 22.0), Qt::AlignCenter,
95 QStringLiteral(
"Density echo vs coherent time-reversed-state fidelity"));
98 p.setPen(QColor(205, 214, 224));
99 p.drawText(pathRect, Qt::AlignCenter,
100 QStringLiteral(
"Load Loschmidt Echo / Quantum Time Reversal and press Play"));
101 p.drawText(echoRect, Qt::AlignCenter,
102 QStringLiteral(
"At t = 2T a perfect reversal should reconstruct the initial density"));
106 const std::vector<qpe::QuantumLoschmidtSample2D> &samples =
history_->
samples();
109 double minX = std::numeric_limits<double>::infinity();
110 double maxX = -std::numeric_limits<double>::infinity();
111 double minY = std::numeric_limits<double>::infinity();
112 double maxY = -std::numeric_limits<double>::infinity();
114 minX = std::min(minX, s.meanX);
115 maxX = std::max(maxX, s.meanX);
116 minY = std::min(minY, s.meanY);
117 maxY = std::max(maxY, s.meanY);
119 if (!(maxX > minX)) { minX -= 1.0; maxX += 1.0; }
120 if (!(maxY > minY)) { minY -= 1.0; maxY += 1.0; }
121 const double padX = 0.12 * std::max(1.0, maxX - minX);
122 const double padY = 0.12 * std::max(1.0, maxY - minY);
123 minX -= padX; maxX += padX; minY -= padY; maxY += padY;
125 const auto mxPath = [&](
double x) {
126 return pathRect.left() + (x - minX) / (maxX - minX) * pathRect.width();
128 const auto myPath = [&](
double y) {
129 return pathRect.bottom() - (y - minY) / (maxY - minY) * pathRect.height();
132 QPainterPath outbound;
133 QPainterPath returning;
134 bool outFirst =
true;
135 bool retFirst =
true;
136 QPointF reversalPoint;
137 bool haveReversalPoint =
false;
139 const QPointF pt(mxPath(s.meanX), myPath(s.meanY));
140 if (s.time <= reversalTime + 1.0e-9 && !s.reversalApplied) {
141 if (outFirst) { outbound.moveTo(pt); outFirst =
false; }
142 else outbound.lineTo(pt);
145 if (!haveReversalPoint) {
146 if (!outFirst) returning.moveTo(reversalPoint);
147 else returning.moveTo(pt);
149 haveReversalPoint =
true;
151 if (retFirst) { returning.moveTo(pt); retFirst =
false; }
152 else returning.lineTo(pt);
156 p.setPen(QPen(QColor(79, 220, 255), 2.2));
157 p.drawPath(outbound);
158 p.setPen(QPen(QColor(255, 190, 79), 2.2));
159 p.drawPath(returning);
163 const QPointF startPt(mxPath(first.
meanX), myPath(first.
meanY));
164 const QPointF currentPt(mxPath(last.
meanX), myPath(last.
meanY));
166 p.setBrush(QColor(103, 232, 153));
167 p.drawEllipse(startPt, 5.5, 5.5);
168 if (haveReversalPoint) {
169 p.setBrush(QColor(236, 112, 255));
170 p.drawEllipse(reversalPoint, 6.0, 6.0);
172 p.setBrush(QColor(244, 247, 251));
173 p.drawEllipse(currentPt, 4.5, 4.5);
175 p.setPen(QColor(79, 220, 255));
176 p.drawText(QRectF(pathRect.left() + 8.0, pathRect.top() + 5.0, 180.0, 20.0), Qt::AlignLeft,
177 QStringLiteral(
"cyan: outbound"));
178 p.setPen(QColor(255, 190, 79));
179 p.drawText(QRectF(pathRect.left() + 142.0, pathRect.top() + 5.0, 180.0, 20.0), Qt::AlignLeft,
180 QStringLiteral(
"gold: return"));
181 p.setPen(QColor(202, 211, 221));
182 p.drawText(QRectF(pathRect.right() - 320.0, pathRect.top() + 5.0, 310.0, 20.0), Qt::AlignRight,
183 QStringLiteral(
"t=%1 samples=%2")
184 .arg(last.
time, 0,
'f', 2)
185 .arg(
static_cast<qulonglong
>(samples.size())));
187 const double t0 = 0.0;
188 const double tMax = std::max(2.0 * reversalTime, std::max(reversalTime, last.
time));
189 const auto mx = [&](
double t) {
190 return echoRect.left() + (t - t0) / std::max(1.0e-12, tMax - t0) * echoRect.width();
192 const auto my = [&](
double f) {
193 return echoRect.bottom() - clamp01(f) * echoRect.height();
196 p.setPen(QPen(QColor(65, 72, 82), 1.0));
197 for (
int i = 1; i < 4; ++i) {
198 const double yy = echoRect.bottom() - echoRect.height() *
static_cast<double>(i) / 4.0;
199 p.drawLine(QPointF(echoRect.left(), yy), QPointF(echoRect.right(), yy));
201 p.setPen(QPen(QColor(236, 112, 255), 1.2, Qt::DashLine));
202 p.drawLine(QPointF(mx(reversalTime), echoRect.top()), QPointF(mx(reversalTime), echoRect.bottom()));
203 p.setPen(QPen(QColor(103, 232, 153), 1.2, Qt::DashLine));
204 p.drawLine(QPointF(mx(2.0 * reversalTime), echoRect.top()), QPointF(mx(2.0 * reversalTime), echoRect.bottom()));
206 QPainterPath densityPath;
207 QPainterPath statePath;
208 bool firstDensity =
true;
209 bool firstState =
true;
211 const QPointF pd(mx(s.time), my(s.densityEcho));
212 const QPointF ps(mx(s.time), my(s.stateEcho));
213 if (firstDensity) { densityPath.moveTo(pd); firstDensity =
false; }
214 else densityPath.lineTo(pd);
215 if (firstState) { statePath.moveTo(ps); firstState =
false; }
216 else statePath.lineTo(ps);
218 p.setPen(QPen(QColor(79, 220, 255), 2.0));
219 p.drawPath(densityPath);
220 p.setPen(QPen(QColor(255, 190, 79), 2.0));
221 p.drawPath(statePath);
223 p.setPen(QColor(79, 220, 255));
224 p.drawText(QRectF(echoRect.left() + 8.0, echoRect.top() + 5.0, 210.0, 20.0), Qt::AlignLeft,
225 QStringLiteral(
"cyan: density echo"));
226 p.setPen(QColor(255, 190, 79));
227 p.drawText(QRectF(echoRect.left() + 165.0, echoRect.top() + 5.0, 300.0, 20.0), Qt::AlignLeft,
228 QStringLiteral(
"gold: coherent state echo"));
230 p.setPen(QColor(202, 211, 221));
231 p.drawText(QRectF(4.0, echoRect.top() - 8.0, 48.0, 20.0), Qt::AlignRight, QStringLiteral(
"1"));
232 p.drawText(QRectF(4.0, echoRect.bottom() - 10.0, 48.0, 20.0), Qt::AlignRight, QStringLiteral(
"0"));
233 p.drawText(QRectF(echoRect.left(), echoRect.bottom() + 5.0, 70.0, 20.0), Qt::AlignLeft,
234 QStringLiteral(
"0"));
235 p.drawText(QRectF(mx(reversalTime) - 70.0, echoRect.bottom() + 5.0, 140.0, 20.0), Qt::AlignCenter,
236 QStringLiteral(
"T = %1").arg(reversalTime, 0,
'f', 2));
237 p.drawText(QRectF(mx(2.0 * reversalTime) - 75.0, echoRect.bottom() + 5.0, 150.0, 20.0), Qt::AlignCenter,
238 QStringLiteral(
"2T = %1").arg(2.0 * reversalTime, 0,
'f', 2));
240 p.setPen(QColor(215, 223, 232));
241 p.drawText(QRectF(echoRect.right() - 390.0, echoRect.bottom() - 27.0, 380.0, 20.0), Qt::AlignRight,
242 QStringLiteral(
"current: density=%1 state=%2 norm=%3")
245 .arg(last.
norm, 0,
'f', 5));