Skip to content

Commit aa3890e

Browse files
round for paulistring, and reformat result
1 parent 47e0e4f commit aa3890e

File tree

3 files changed

+84
-48
lines changed

3 files changed

+84
-48
lines changed

mpqp/core/instruction/measurement/pauli_string.py

+34-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ def nb_qubits(self) -> int:
6565
return 0 if len(self._monomials) == 0 else self._monomials[0].nb_qubits
6666

6767
def __str__(self):
68-
return " + ".join(map(str, self._monomials))
68+
return " + ".join(map(str, self.round().simplify()._monomials))
6969

7070
def __repr__(self):
71-
return str(self)
71+
return " + ".join(map(str, self._monomials))
7272

7373
def __pos__(self) -> "PauliString":
7474
return deepcopy(self)
@@ -157,13 +157,15 @@ def simplify(self, inplace: bool = False) -> PauliString:
157157
"""
158158
res = PauliString()
159159
for unique_mono_atoms in {tuple(mono.atoms) for mono in self.monomials}:
160-
coef = sum(
160+
coef = float(sum(
161161
[
162162
mono.coef
163163
for mono in self.monomials
164164
if mono.atoms == list(unique_mono_atoms)
165165
]
166-
)
166+
).real)
167+
if coef == int(coef):
168+
coef = int(coef)
167169
if coef != 0:
168170
res.monomials.append(PauliStringMonomial(coef, list(unique_mono_atoms)))
169171
if len(res.monomials) == 0:
@@ -173,6 +175,34 @@ def simplify(self, inplace: bool = False) -> PauliString:
173175
if inplace:
174176
self._monomials = res.monomials
175177
return res
178+
179+
def round(self, round_off_till: int = 4) -> PauliString:
180+
"""Round the coefficients of the PauliString to a specified number of decimal places.
181+
182+
Example:
183+
>>> ps = 0.6875*I@I + 0.415*I@X + 0.1275*I@Z + 1.0*X@I + 1.0*X@X + 0.0375*Z@I + 0.085*Z@X + -0.2225*Z@Z
184+
>>> rounded_ps = ps.round(1)
185+
>>> print(rounded_ps)
186+
-0.2*Z@Z + 1*X@X + 0.1*I@Z + 1*X@I + 0.1*Z@X + 0.7*I@I + 0.4*I@X
187+
188+
Args:
189+
round_off_till : Number of decimal places to round the coefficients to. Defaults to 5.
190+
191+
Returns:
192+
PauliString: A PauliString with coefficients rounded to the specified number of decimal places.
193+
"""
194+
res = PauliString()
195+
for mono in self.monomials:
196+
coef = float(np.round(float(mono.coef.real), round_off_till))
197+
if coef == int(coef):
198+
coef = int(coef)
199+
if coef != 0:
200+
res.monomials.append(PauliStringMonomial(coef, mono.atoms))
201+
if len(res.monomials) == 0:
202+
res.monomials.append(
203+
PauliStringMonomial(0, [I for _ in range(self.nb_qubits)])
204+
)
205+
return res
176206

177207
def to_matrix(self) -> Matrix:
178208
"""Converts the PauliString to a matrix representation.

mpqp/execution/result.py

+35-32
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ class StateVector:
2828
>>> state_vector.probabilities
2929
array([0.25, 0.25, 0.25, 0.25])
3030
>>> print(state_vector)
31-
State vector: [ 0.5 0.5 0.5 -0.5]
32-
Probabilities: [0.25 0.25 0.25 0.25]
33-
Number of qubits: 2
31+
State vector: [ 0.5 0.5 0.5 -0.5]
32+
Probabilities: [0.25 0.25 0.25 0.25]
33+
Number of qubits: 2
3434
3535
"""
3636

@@ -62,9 +62,10 @@ def amplitudes(self):
6262
def __str__(self):
6363
cleaned_vector = str(self.vector).replace("\n", " ")
6464
cleaned_probas = str(self.probabilities).replace("\n", " ")
65-
return f"""State vector: {cleaned_vector}
66-
Probabilities: {cleaned_probas}
67-
Number of qubits: {self.nb_qubits}"""
65+
return f""" State vector: {cleaned_vector}
66+
Probabilities: {cleaned_probas}
67+
Number of qubits: {self.nb_qubits}
68+
"""
6869

6970

7071
@typechecked
@@ -172,23 +173,23 @@ class Result:
172173
173174
Examples:
174175
>>> print(Result(Job(), StateVector(np.array([1, 1, 1, -1])/2, 2), 0, 0))
175-
State vector: [ 0.5 0.5 0.5 -0.5]
176-
Probabilities: [0.25 0.25 0.25 0.25]
177-
Number of qubits: 2
176+
State vector: [ 0.5 0.5 0.5 -0.5]
177+
Probabilities: [0.25 0.25 0.25 0.25]
178+
Number of qubits: 2
178179
179180
>>> print(Result(Job(), [
180181
... Sample(2, index=0, count=250)
181182
... Sample(2, index=3, count=250)
182183
... ], 0.034, 500))
183-
Counts: [250, 250]
184-
Probabilities: [0.5 0.5]
185-
State: 00, Index: 0, Count: 250, Probability: None
186-
State: 11, Index: 3, Count: 250, Probability: None
187-
Error: 0.034
184+
Counts: [250, 250]
185+
Probabilities: [0.5 0.5]
186+
State: 00, Index: 0, Count: 250, Probability: None
187+
State: 11, Index: 3, Count: 250, Probability: None
188+
Error: 0.034
188189
189190
>>> print(Result(Job(), -3.09834, 0.021, 2048))
190-
Expectation value: -3.09834
191-
Error: 0.021
191+
Expectation value: -3.09834
192+
Error: 0.021
192193
"""
193194

194195
# 3M-TODO: in this class, there is a lot of manual type checking, this is an
@@ -347,21 +348,23 @@ def __str__(self):
347348
header = f"Result: {type(self.device).__name__}, {self.device.name}"
348349

349350
if self.job.job_type == JobType.SAMPLE:
350-
samples_str = "\n".join(map(lambda s: f" {s}", self.samples))
351+
samples_str = "\n".join(map(lambda s: f" {s}", self.samples))
351352
cleaned_probas = str(self._probabilities).replace("\n", " ")
352353
return f"""{header}
353-
Counts: {self._counts}
354-
Probabilities: {cleaned_probas}
354+
Counts: {self._counts}
355+
Probabilities: {cleaned_probas}
355356
{samples_str}
356-
Error: {self.error}"""
357+
Error: {self.error}
358+
"""
357359

358360
if self.job.job_type == JobType.STATE_VECTOR:
359361
return header + "\n" + str(self.state_vector)
360362

361363
if self.job.job_type == JobType.OBSERVABLE:
362364
return f"""{header}
363-
Expectation value: {self.expectation_value}
364-
Error/Variance: {self.error}"""
365+
Expectation value: {self.expectation_value}
366+
Error/Variance: {self.error}
367+
"""
365368

366369
raise NotImplementedError(
367370
f"Job type {self.job.job_type} not implemented for __str__ method"
@@ -402,18 +405,18 @@ class BatchResult:
402405
>>> print(batch_result)
403406
BatchResult: 3 results
404407
Result: ATOSDevice, MYQLM_PYLINALG
405-
State vector: [ 0.5+0.j 0.5+0.j 0.5+0.j -0.5+0.j]
406-
Probabilities: [0.25 0.25 0.25 0.25]
407-
Number of qubits: 2
408+
State vector: [ 0.5+0.j 0.5+0.j 0.5+0.j -0.5+0.j]
409+
Probabilities: [0.25 0.25 0.25 0.25]
410+
Number of qubits: 2
408411
Result: ATOSDevice, MYQLM_PYLINALG
409-
Counts: [250, 0, 0, 250]
410-
Probabilities: [0.5 0. 0. 0.5]
411-
State: 00, Index: 0, Count: 250, Probability: 0.5
412-
State: 11, Index: 3, Count: 250, Probability: 0.5
413-
Error: 0.034
412+
Counts: [250, 0, 0, 250]
413+
Probabilities: [0.5 0. 0. 0.5]
414+
State: 00, Index: 0, Count: 250, Probability: 0.5
415+
State: 11, Index: 3, Count: 250, Probability: 0.5
416+
Error: 0.034
414417
Result: ATOSDevice, MYQLM_PYLINALG
415-
Expectation value: -3.09834
416-
Error/Variance: 0.021
418+
Expectation value: -3.09834
419+
Error/Variance: 0.021
417420
>>> print(batch_result[0])
418421
Result: ATOSDevice, MYQLM_PYLINALG
419422
State vector: [ 0.5+0.j 0.5+0.j 0.5+0.j -0.5+0.j]

tests/execution/test_result.py

+15-12
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ def test_result_right_type(job_type: JobType, data: float | StateVector | list[S
7070
StateVector(np.ones(4, dtype=np.complex64) / 2),
7171
),
7272
"""Result: IBMDevice, AER_SIMULATOR_STATEVECTOR
73-
State vector: [0.5+0.j 0.5+0.j 0.5+0.j 0.5+0.j]
74-
Probabilities: [0.25 0.25 0.25 0.25]
75-
Number of qubits: 2""",
73+
State vector: [0.5+0.j 0.5+0.j 0.5+0.j 0.5+0.j]
74+
Probabilities: [0.25 0.25 0.25 0.25]
75+
Number of qubits: 2
76+
""",
7677
),
7778
(
7879
Result(
@@ -91,19 +92,21 @@ def test_result_right_type(job_type: JobType, data: float | StateVector | list[S
9192
shots=600,
9293
),
9394
"""Result: IBMDevice, AER_SIMULATOR
94-
Counts: [135, 226, 8, 231]
95-
Probabilities: [0.225 0.37666667 0.01333333 0.385 ]
96-
State: 00, Index: 0, Count: 135, Probability: 0.225
97-
State: 01, Index: 1, Count: 226, Probability: 0.37666666666666665
98-
State: 10, Index: 2, Count: 8, Probability: 0.013333333333333334
99-
State: 11, Index: 3, Count: 231, Probability: 0.385
100-
Error: None""",
95+
Counts: [135, 226, 8, 231]
96+
Probabilities: [0.225 0.37666667 0.01333333 0.385 ]
97+
State: 00, Index: 0, Count: 135, Probability: 0.225
98+
State: 01, Index: 1, Count: 226, Probability: 0.37666666666666665
99+
State: 10, Index: 2, Count: 8, Probability: 0.013333333333333334
100+
State: 11, Index: 3, Count: 231, Probability: 0.385
101+
Error: None
102+
""",
101103
),
102104
(
103105
Result(Job(JobType.OBSERVABLE, QCircuit(2), IBMDevice.AER_SIMULATOR), 0.65),
104106
"""Result: IBMDevice, AER_SIMULATOR
105-
Expectation value: 0.65
106-
Error/Variance: None""",
107+
Expectation value: 0.65
108+
Error/Variance: None
109+
""",
107110
),
108111
],
109112
)

0 commit comments

Comments
 (0)