3.2 Magnetization Square for Any DirectionsΒΆ


Basic UsageΒΆ

a. Import the instancesΒΆ

from qurry import MagnetSquare

experiment_magnetsquare = MagnetSquare()

b. Preparing quantum circuitΒΆ

from qurry.recipe import Cat, TrivialParamagnet
circuits_dict = {
    "trivialPM_2": TrivialParamagnet(2),
    "trivialPM_4": TrivialParamagnet(4),
    "trivialPM_6": TrivialParamagnet(6),
    "trivialPM_8": TrivialParamagnet(8),
    "cat_2": Cat(2),
    "cat_4": Cat(4),
    "cat_6": Cat(6),
    "cat_8": Cat(8),
}
print("| trivial paramagnet and cat in 4 qubits:")
print(circuits_dict["trivialPM_4"])
print(circuits_dict["cat_4"])
| trivial paramagnet and cat in 4 qubits:
     β”Œβ”€β”€β”€β”
q_0: ─ H β”œ
     β”œβ”€β”€β”€β”€
q_1: ─ H β”œ
     β”œβ”€β”€β”€β”€
q_2: ─ H β”œ
     β”œβ”€β”€β”€β”€
q_3: ─ H β”œ
     β””β”€β”€β”€β”˜
     β”Œβ”€β”€β”€β”               
q_0: ─ H β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
     β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”          
q_1: ────── X β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€
          β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”     
q_2: ─────────── X β”œβ”€β”€β– β”€β”€
               β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”
q_3: ──────────────── X β”œ
                    β””β”€β”€β”€β”˜

c. Execute the circuitΒΆ

i. Directly input the circuitΒΆ

After executing, it will return a uuid of experiment. You can use this uuid to get the result of the experiment.

exp1 = experiment_magnetsquare.measure(
    circuits_dict["cat_6"], unitary_operator="z", shots=4096
)
exp1
'114ef3f1-3b7a-4af1-bfa2-d97cf47025cc'

Each experiment result will be stored in a container .exps.

experiment_magnetsquare.exps[exp1]
<MagnetSquareExperiment(exp_id=114ef3f1-3b7a-4af1-bfa2-d97cf47025cc, 
  MagnetSquareArguments(exp_name='experiment.qurmagsq_magnet_square', num_qubits=6, unitary_operator='z'),
  Commonparams(exp_id='114ef3f1-3b7a-4af1-bfa2-d97cf47025cc', target_keys=[0], shots=4096, backend=<AerSimulator('aer_simulator')>, run_args={}, transpile_args={}, tags=(), save_location=PosixPath('.'), serial=None, summoner_id=None, summoner_name=None, datetimes=DatetimeDict({'build': '2025-07-08 16:56:39', 'run.001': '2025-07-08 16:56:39'})),
  unused_args_num=0,
  analysis_num=1))>

For MagnetSquare, its .analyze in MagnetSquareExperiment does not require any arguments, so its post-processing will be executed automatically after .measure.

experiment_magnetsquare.exps[exp1].reports
AnalysisContainer(length=1, {
  0: <MSAnalysis(serial=0, MSAnalysisInput(), MSAnalysisContent(magnet_square=1.0, unitary_operator=z, and others)), unused_args_num=0>})
report01 = experiment_magnetsquare.exps[exp1].reports[0]
report01
<MSAnalysis(
  serial=0,
  MSAnalysisInput(),
  MSAnalysisContent(magnet_square=1.0, unitary_operator=z, and others)),
  unused_args_num=0
  )>
main01, side_product01 = report01.export()
print("| magnetization square", main01["magnet_square"])
for k, v in main01.items():
    if "magnet_square" in k:
        continue
    print(f"| {k}: {v}")
| magnetization square 1.0
| num_qubits: 6
| shots: 4096
| unitary_operator: z
| taking_time: 0.000580088
| input: {}
| header: {'serial': 0, 'datetime': '2025-07-08 16:56:39', 'log': {}}
print("| side product is empty here:", side_product01)
| side product is empty here: {}

main contains another keys "magnet_square_cells" which is a dict, It contains the magnetization square cells they correspond to the magnetization square.

print(main01["magnet_square_cells"])
{10: 1.0, 23: 1.0, 24: 1.0, 9: 1.0, 2: 1.0, 17: 1.0, 4: 1.0, 3: 1.0, 16: 1.0, 22: 1.0, 7: 1.0, 26: 1.0, 27: 1.0, 29: 1.0, 20: 1.0, 28: 1.0, 6: 1.0, 15: 1.0, 5: 1.0, 8: 1.0, 25: 1.0, 13: 1.0, 12: 1.0, 14: 1.0, 18: 1.0, 1: 1.0, 11: 1.0, 19: 1.0, 0: 1.0, 21: 1.0}

ii. Add the circuits to container .waves, then call them later.ΒΆ

Since we have executed an experiment, the circuit we input in exp1 is stored in the container .waves with serial number 0.

experiment_magnetsquare.waves
WaveContainer({ 0: <qurry.recipe.simple.cat.Cat object at 0x76d616e122a0>})

But we can also add the circuit to the container .waves with a custom name. The name should be unique, otherwise it will be overwritten. The method add will return the actual name of the circuit in the container.

for k, v in circuits_dict.items():
    key_of_cirq = experiment_magnetsquare.add(v, k)
    print(f"| {k} added with key: {key_of_cirq}")
print(experiment_magnetsquare.waves["cat_4"])
| trivialPM_2 added with key: trivialPM_2
| trivialPM_4 added with key: trivialPM_4
| trivialPM_6 added with key: trivialPM_6
| trivialPM_8 added with key: trivialPM_8
| cat_2 added with key: cat_2
| cat_4 added with key: cat_4
| cat_6 added with key: cat_6
| cat_8 added with key: cat_8
     β”Œβ”€β”€β”€β”               
q_0: ─ H β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
     β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”          
q_1: ────── X β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€
          β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”     
q_2: ─────────── X β”œβ”€β”€β– β”€β”€
               β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”
q_3: ──────────────── X β”œ
                    β””β”€β”€β”€β”˜

If there is a circuit with the same name, it will be replaced by the new one.

print(experiment_magnetsquare.add(circuits_dict["cat_4"], "cat_4"))
print(experiment_magnetsquare.waves["cat_4"])
cat_4
     β”Œβ”€β”€β”€β”               
q_0: ─ H β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
     β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”          
q_1: ────── X β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€
          β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”     
q_2: ─────────── X β”œβ”€β”€β– β”€β”€
               β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”
q_3: ──────────────── X β”œ
                    β””β”€β”€β”€β”˜

Otherwise, you will need to use replace="duplicate" to prevent it from being replaced.

duplicated_case01 = experiment_magnetsquare.add(
    circuits_dict["cat_4"], "cat_4", replace="duplicate"
)
print(duplicated_case01)
print(experiment_magnetsquare.waves[duplicated_case01])
cat_4.9
     β”Œβ”€β”€β”€β”               
q_0: ─ H β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
     β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”          
q_1: ────── X β”œβ”€β”€β– β”€β”€β”€β”€β”€β”€β”€
          β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”     
q_2: ─────────── X β”œβ”€β”€β– β”€β”€
               β””β”€β”€β”€β”˜β”Œβ”€β”΄β”€β”
q_3: ──────────────── X β”œ
                    β””β”€β”€β”€β”˜

Now we have prepared the circuit and stored it in the container .waves.

experiment_magnetsquare.waves
WaveContainer({
  0: <qurry.recipe.simple.cat.Cat object at 0x76d616e122a0>,
  'trivialPM_2': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x76d616e11b80>,
  'trivialPM_4': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x76d6efb27980>,
  'trivialPM_6': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x76d616e11d00>,
  'trivialPM_8': <qurry.recipe.simple.paramagnet.TrivialParamagnet object at 0x76d617785940>,
  'cat_2': <qurry.recipe.simple.cat.Cat object at 0x76d616e11e80>,
  'cat_4': <qurry.recipe.simple.cat.Cat object at 0x76d616ff33e0>,
  'cat_6': <qurry.recipe.simple.cat.Cat object at 0x76d616e122a0>,
  'cat_8': <qurry.recipe.simple.cat.Cat object at 0x76d616e123f0>,
  'cat_4.9': <qurry.recipe.simple.cat.Cat object at 0x76d616ff33e0>})

Finally, we can execute the circuit and get the result.

exp2 = experiment_magnetsquare.measure("cat_4", unitary_operator="z", shots=4096)
exp2
'755785a0-939a-432a-a678-fc59d8a1d1e0'
experiment_magnetsquare.exps[exp2]
<MagnetSquareExperiment(exp_id=755785a0-939a-432a-a678-fc59d8a1d1e0, 
  MagnetSquareArguments(exp_name='experiment.qurmagsq_magnet_square', num_qubits=4, unitary_operator='z'),
  Commonparams(exp_id='755785a0-939a-432a-a678-fc59d8a1d1e0', target_keys=['cat_4'], shots=4096, backend=<AerSimulator('aer_simulator')>, run_args={}, transpile_args={}, tags=(), save_location=PosixPath('.'), serial=None, summoner_id=None, summoner_name=None, datetimes=DatetimeDict({'build': '2025-07-08 16:56:50', 'run.001': '2025-07-08 16:56:50'})),
  unused_args_num=0,
  analysis_num=1))>
report02 = experiment_magnetsquare.exps[exp2].reports[0]
report02
<MSAnalysis(
  serial=0,
  MSAnalysisInput(),
  MSAnalysisContent(magnet_square=1.0, unitary_operator=z, and others)),
  unused_args_num=0
  )>

d. More direction ConsiderΒΆ

MagnetSquare also can measure on different direction. Except x, y, z have been preset. You can use other single qubit instruction like Gate from qiskit.circuit or Operator from qiskit.quantum_info to set specific direction you wanted.

For example, we use a RZGate on $\phi$ = 0 which is identity and its Operator version.

from qiskit.circuit.library import RZGate
from qiskit.quantum_info import Operator

Preparing RZGate and its Operator version.

rz_0 = RZGate(0)
rz_0_matrix = rz_0.to_matrix()
rz_0_matrix
array([[1.-0.j, 0.+0.j],
       [0.+0.j, 1.+0.j]])
rz_0_op = Operator(rz_0_matrix)
rz_0_op
Operator([[1.-0.j, 0.+0.j],
          [0.+0.j, 1.+0.j]],
         input_dims=(2,), output_dims=(2,))

Executing the experiments

exp_rz_gate = experiment_magnetsquare.measure(
    "cat_4", unitary_operator=rz_0, shots=4096
)
reports_rz_gate = experiment_magnetsquare.exps[exp_rz_gate].reports[0]
main_rz_gate, _side_product_rz_gate = reports_rz_gate.export()
print("| magnetization square using RZGate")
print("|" + "-" * 50)
print("| magnetization square", main_rz_gate["magnet_square"])
for k, v in main_rz_gate.items():
    if "magnet_square" in k:
        continue
    print(f"| {k}: {v}")
reports_rz_gate
| magnetization square using RZGate
|--------------------------------------------------
| magnetization square 1.0
| num_qubits: 4
| shots: 4096
| unitary_operator: [[1.-0.j 0.+0.j]
 [0.+0.j 1.+0.j]]
| taking_time: 0.001787938
| input: {}
| header: {'serial': 0, 'datetime': '2025-07-08 16:57:02', 'log': {}}
<MSAnalysis(
  serial=0,
  MSAnalysisInput(),
  MSAnalysisContent(magnet_square=1.0, unitary_operator=[[1.-0.j 0.+0.j]
 [0.+0.j 1.+0.j]], and others)),
  unused_args_num=0
  )>
exp_rz_op = experiment_magnetsquare.measure(
    "cat_4", unitary_operator=rz_0_op, shots=4096
)
reports_rz_op = experiment_magnetsquare.exps[exp_rz_op].reports[0]
main_rz_op, _side_product_rz_op = reports_rz_op.export()
print("| magnetization square using RZGate Operator")
print("|" + "-" * 50)
print("| magnetization square", main_rz_op["magnet_square"])
for k, v in main_rz_op.items():
    if "magnet_square" in k:
        continue
    print(f"| {k}: {v}")
reports_rz_op
| magnetization square using RZGate Operator
|--------------------------------------------------
| magnetization square 1.0
| num_qubits: 4
| shots: 4096
| unitary_operator: [[1.-0.j 0.+0.j]
 [0.+0.j 1.+0.j]]
| taking_time: 0.000266527
| input: {}
| header: {'serial': 0, 'datetime': '2025-07-08 16:57:13', 'log': {}}
<MSAnalysis(
  serial=0,
  MSAnalysisInput(),
  MSAnalysisContent(magnet_square=1.0, unitary_operator=[[1.-0.j 0.+0.j]
 [0.+0.j 1.+0.j]], and others)),
  unused_args_num=0
  )>

e. Export them after allΒΆ

exp1_id, exp1_files_info = experiment_magnetsquare.exps[exp1].write(
    save_location=".",  # where to save files
)
exp1_files_info
{'folder': 'experiment.qurmagsq_magnet_square.002',
 'qurryinfo': 'experiment.qurmagsq_magnet_square.002/qurryinfo.json',
 'args': 'experiment.qurmagsq_magnet_square.002/args/experiment.qurmagsq_magnet_square.002.id=114ef3f1-3b7a-4af1-bfa2-d97cf47025cc.args.json',
 'advent': 'experiment.qurmagsq_magnet_square.002/advent/experiment.qurmagsq_magnet_square.002.id=114ef3f1-3b7a-4af1-bfa2-d97cf47025cc.advent.json',
 'legacy': 'experiment.qurmagsq_magnet_square.002/legacy/experiment.qurmagsq_magnet_square.002.id=114ef3f1-3b7a-4af1-bfa2-d97cf47025cc.legacy.json',
 'reports': 'experiment.qurmagsq_magnet_square.002/reports/experiment.qurmagsq_magnet_square.002.id=114ef3f1-3b7a-4af1-bfa2-d97cf47025cc.reports.json'}

Post-Process Availablities and Version InfoΒΆ

from qurry.process import AVAIBILITY_STATESHEET

AVAIBILITY_STATESHEET
 | Qurrium version: 0.13.0
---------------------------------------------------------------------------
 ### Qurrium Post-Processing
   - Backend Availability ................... Python Cython Rust   JAX   
 - randomized_measure
   - entangled_entropy.entropy_core_2 ....... Yes    Depr.  Yes    No    
   - entangle_entropy.purity_cell_2 ......... Yes    Depr.  Yes    No    
   - entangled_entropy_v1.entropy_core ...... Yes    Depr.  Yes    No    
   - entangle_entropy_v1.purity_cell ........ Yes    Depr.  Yes    No    
   - wavefunction_overlap.echo_core_2 ....... Yes    Depr.  Yes    No    
   - wavefunction_overlap.echo_cell_2 ....... Yes    Depr.  Yes    No    
   - wavefunction_overlap_v1.echo_core ...... Yes    Depr.  Yes    No    
   - wavefunction_overlap_v1.echo_cell ...... Yes    Depr.  Yes    No    
 - hadamard_test
   - purity_echo_core ....................... Yes    No     Yes    No    
 - magnet_square
   - magnsq_core ............................ Yes    No     Yes    No    
 - string_operator
   - strop_core ............................. Yes    No     Yes    No    
 - classical_shadow
   - rho_m_core ............................. Yes    No     No     Yes   
 - utils
   - randomized ............................. Yes    Depr.  Yes    No    
   - counts_process ......................... Yes    No     Yes    No    
   - bit_slice .............................. Yes    No     Yes    No    
   - dummy .................................. Yes    No     Yes    No    
   - test ................................... Yes    No     Yes    No    
---------------------------------------------------------------------------
   + Yes ...... Working normally.
   + Error .... Exception occurred.
   + No ....... Not supported.
   + Depr. .... Deprecated.
---------------------------------------------------------------------------
by <Hoshi>