Download Notebook

MProcess and mprocess_typical

[1]:
import numpy as np
np.set_printoptions(linewidth=200)

MProcess (Measurement Process)

MProcess \(M = \{ M_x \}_{x=0,\dots,m-1}\) maps State \(\rho \mapsto \{ \rho_x \}_{x=0,\dots,m-1}\), where \(\rho_x = \frac{M_x(\rho)}{\text{Tr}[M_x(\rho)]}\), with probability \(p(x) = \text{Tr}[M_x(\rho)] = \text{Tr}[\Pi_x\rho]\).
Each \(M_x\) is a linear trace-preserving and completely positive (L-TPCP) map on the space of quantum states.
The Hilbert-Schmidt matrix representations of these L-TPCP maps is denote hss in Quara. hss is a list of 2-dimensional numpy array.
The property mode_sampling of MProcess is whether to sample to determine one Hilbert-Schumidt matrix with compose_qoperations() function.
The property random_seed_or_generator of MProcess is the random seed or numpy.random.Generator to sample.

Generate from mprocess_typical module by specifying CompositeSystem and state mprocess (ex. “z-type1”).

[2]:
from quara.objects.composite_system_typical import generate_composite_system
from quara.objects.mprocess_typical import generate_mprocess_from_name

c_sys = generate_composite_system("qubit", 1)
mprocess = generate_mprocess_from_name(c_sys, "z-type1")
print(mprocess)
Type:
MProcess

Dim:
2

HSs:
[array([[0.5, 0. , 0. , 0.5],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0.5, 0. , 0. , 0.5]]), array([[ 0.5,  0. ,  0. , -0.5],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [-0.5,  0. ,  0. ,  0.5]])]

ModeSampling:
False

Generate MProcess object directly using CompositeSystem and a numpy array.

[3]:
import numpy as np

from quara.objects.composite_system import CompositeSystem
from quara.objects.elemental_system import ElementalSystem
from quara.objects.matrix_basis import get_normalized_pauli_basis
from quara.objects.mprocess import MProcess

basis = get_normalized_pauli_basis(1)
e_sys = ElementalSystem(0, basis)
c_sys = CompositeSystem([e_sys])
hss = [
    np.array([[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0], [0.5, 0, 0, 0.5]]),
    np.array([[0.5, 0, 0, -0.5], [0, 0, 0, 0], [0, 0, 0, 0], [-0.5, 0, 0, 0.5]]),
]
mprocess = MProcess(c_sys, hss)
print(mprocess)
Type:
MProcess

Dim:
2

HSs:
[array([[0.5, 0. , 0. , 0.5],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0.5, 0. , 0. , 0.5]]), array([[ 0.5,  0. ,  0. , -0.5],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [-0.5,  0. ,  0. ,  0.5]])]

ModeSampling:
False

specific properties

The property hss of MProcess is a numpy array specified by the constructor argument hss.

[4]:
mprocess = MProcess(c_sys, hss)
print(f"hss: \n{mprocess.hss}")
hss:
[array([[0.5, 0. , 0. , 0.5],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0.5, 0. , 0. , 0.5]]), array([[ 0.5,  0. ,  0. , -0.5],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [-0.5,  0. ,  0. ,  0.5]])]

The hs() function returns a numpy array specified by the constructor argument hss.

[5]:
mprocess = MProcess(c_sys, hss)
print(f"hs(0): \n{mprocess.hs(0)}")
print(f"hs(1): \n{mprocess.hs(1)}")
hs(0):
[[0.5 0.  0.  0.5]
 [0.  0.  0.  0. ]
 [0.  0.  0.  0. ]
 [0.5 0.  0.  0.5]]
hs(1):
[[ 0.5  0.   0.  -0.5]
 [ 0.   0.   0.   0. ]
 [ 0.   0.   0.   0. ]
 [-0.5  0.   0.   0.5]]

The property dim of MProcess is the size of square matrices hss.

[6]:
print(f"dim: {mprocess.dim}")
print(f"size of square matrices hss: {int(np.sqrt(hss[0].shape[0]))}")
dim: 2
size of square matrices hss: 2

The property num_outcomes of MProcess is the number of hss.

[7]:
print(f"num_outcomes: {mprocess.num_outcomes}")
print(f"number of hss: {len(mprocess.hss)}")
num_outcomes: 2
number of hss: 2

The property mode_sampling of MProcess is the mode of sampling.

[8]:
print(mprocess.mode_sampling)
False

functions to check constraints

The is_eq_constraint_satisfied() function returns True, if and only if the sum of hss is TP(trace-preserving map).

[9]:
print(f"is_eq_constraint_satisfied(): {mprocess.is_eq_constraint_satisfied()}")
print(f"is_sum_tp(): {mprocess.is_sum_tp()}")
is_eq_constraint_satisfied(): True
is_sum_tp(): True

The is_ineq_constraint_satisfied() function returns True, if and only if all matrices of hss are CP(Complete-Positivity-Preserving), i.e. if and only if all Choi matrices of hss are positive semidifinite matrices.

[10]:
print(f"is_ineq_constraint_satisfied(): {mprocess.is_ineq_constraint_satisfied()}")
print(f"is_cp(): {mprocess.is_cp()}")
is_ineq_constraint_satisfied(): True
is_cp(): True

projection functions

calc_proj_eq_constraint() function calculates the projection of MProcess on equal constraint. Let hss of MProcess be \(\{ M_0, \dots, M_{m-1}\}\), where \(m\) is num_outcomes of MProcess. When MProcess object satifies on equal constraint, the first row of \(\sum_{x=0}^{m-1} M_x\) is equal to \([1, 0, \dots, 0]\).
Therefore, calc_proj_eq_constraint() function calculates the projection of MProcess as follows:
  • \(\text{vec} :=\) the first row of \(\sum_{x=0}^{m-1} M_x\)

  • for each \(x\), calculates \(M^{\prime}_x = M_x - \frac{1}{m}\begin{bmatrix} \text{vec} \\ 0 \\ \vdots \\ 0 \end{bmatrix} + \frac{1}{m}\begin{bmatrix} 1 & 0 & \dots & 0 \\ 0 \\ \vdots & & \huge{0} \\ 0 \end{bmatrix}\)

  • The projection of MProcess is \(\{ M^{\prime}_x \}_{x=0}^{m-1}\).

[11]:
hss = [
    np.array(range(16), dtype=np.float64).reshape((4, 4)),
    np.array(range(16, 32), dtype=np.float64).reshape((4, 4)),
]
[12]:
mprocess = MProcess(c_sys, hss, is_physicality_required=False)
proj_mprocess = mprocess.calc_proj_eq_constraint()
print(f"hss: \n{proj_mprocess.hss}")
hss:
[array([[-7.5, -8. , -8. , -8. ],
       [ 4. ,  5. ,  6. ,  7. ],
       [ 8. ,  9. , 10. , 11. ],
       [12. , 13. , 14. , 15. ]]), array([[ 8.5,  8. ,  8. ,  8. ],
       [20. , 21. , 22. , 23. ],
       [24. , 25. , 26. , 27. ],
       [28. , 29. , 30. , 31. ]])]

calc_proj_ineq_constraint() function calculates the projection of MProcess with hss \(\{ M_x \}_{x=0}^{m-1}\) on inequal constraint as follows:

  • For each \(x\), calculate the following:

  • Let \(\text{Choi}_x\) be Choi matrix of \(M_x\)

  • Executes singular value decomposition on \(\text{Choi}_x\), \(\text{Choi}_x = U \Lambda U^{\dagger}\), where \(\Lambda = \text{diag}[\lambda_0, \dots , \lambda_{d-1}]\), and \(\lambda_{i} \in \mathbb{R}\).

  • \(\lambda^{\prime}_{i} := \begin{cases} \lambda_{i} & (\lambda_{i} \geq 0) \\ 0 & (\lambda_{i} < 0) \end{cases}\)

  • \(\Lambda^{\prime} = \text{diag}[\lambda^{\prime}_0, \dots , \lambda^{\prime}_{d-1}]\)

  • \(\text{Choi}^{\prime}_x = U \Lambda^{\prime} U^{\dagger}\)

  • Let \(M^{\prime}_x\) be Hilbert-Schmidt matrix representation of \(\text{Choi}^{\prime}_x\)

  • The projection of MProcess is \(\{ M^{\prime}_x \}_{x=0}^{m-1}\).

[13]:
mprocess = MProcess(c_sys, hss, is_physicality_required=False)
proj_mprocess = mprocess.calc_proj_ineq_constraint()
print(f"hss: \n{proj_mprocess.hss}")
hss:
[array([[15.84558996,  4.43570942,  5.29265833,  6.14960724],
       [ 2.63097854,  2.34702553,  3.08437192,  3.44443746],
       [ 4.98440409,  4.50900796,  4.73510284,  5.71575945],
       [ 7.33782964,  6.29370952,  7.14039548,  7.60980059]]), array([[47.32687829, 20.14755601, 21.1037168 , 22.0598776 ],
       [17.5667235 , 12.54854821, 13.24883203, 13.79656536],
       [20.93808076, 15.04184745, 15.53818711, 16.33962776],
       [24.30943803, 17.3825962 , 18.13264319, 18.73013967]])]

functions to transform parameters

to_stacked_vector() function returns a one-dimensional numpy array of all variables. This is equal to a concatenated vector of flattened matrices of hss.

[14]:
print(f"to_stacked_vector(): \n{mprocess.to_stacked_vector()}")
print(f"hss: \n{mprocess.hss}")
to_stacked_vector():
[ 0.  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.]
hss:
[array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.],
       [12., 13., 14., 15.]]), array([[16., 17., 18., 19.],
       [20., 21., 22., 23.],
       [24., 25., 26., 27.],
       [28., 29., 30., 31.]])]
Let hss of MProcess be \(\{ M_0, \dots, M_{m-1}\}\), where \(m\) is num_outcomes of MProcess. Let \(\text{vec}(M_x) := |M_x\rangle\rangle\). Let $:nbsphinx-math:text{vec}`(:nbsphinx-math:tilde{M}`_x) $ be a flattened vector of the second and subsequent rows of matrix \(M_x\).
If on_para_eq_constraint is True, then the first row of \(\sum_{x=0}^{m-1} M_x\) is equal to \([1, 0, \dots, 0]\).
Therefore, to_var() function returns a concatenated vector of \(\text{vec}(M_0), \dots, \text{vec}(M_{m-2}), \text{vec}(\tilde{M}_{m-1})\), where on_para_eq_constraint is True.
[15]:
# on_para_eq_constraint=True
mprocess = MProcess(c_sys, hss, is_physicality_required=False, on_para_eq_constraint=True)
print(f"to_var(): \n{mprocess.to_var()}")
to_var():
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10. 11. 12. 13. 14. 15. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.]
[16]:
# on_para_eq_constraint=False
mprocess = MProcess(c_sys, hss, is_physicality_required=False, on_para_eq_constraint=False)
print(f"to_var(): \n{mprocess.to_var()}")
to_var():
[ 0.  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.]

functions to generate special objects

[17]:
zero_mprocess = mprocess.generate_zero_obj()
print(f"zero: \n{zero_mprocess.hss}")
origin_mprocess = mprocess.generate_origin_obj()
print(f"origin: \n{origin_mprocess.hss}")
zero:
[array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]]), array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])]
origin:
[array([[0.5, 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ]]), array([[0.5, 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ]])]

supports arithmetic operations

[18]:
hs11 = np.array(range(16), dtype=np.float64).reshape((4, 4))
hs12 = np.array(range(16, 32), dtype=np.float64).reshape((4, 4))
mprocess1 = MProcess(c_sys, [hs11, hs12], is_physicality_required=False)
hs21 = np.array(range(32, 48), dtype=np.float64).reshape((4, 4))
hs22 = np.array(range(48, 64), dtype=np.float64).reshape((4, 4))
mprocess2 = MProcess(c_sys, [hs21, hs22], is_physicality_required=False)

print(mprocess1.hss)
print(mprocess2.hss)
[array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.],
       [12., 13., 14., 15.]]), array([[16., 17., 18., 19.],
       [20., 21., 22., 23.],
       [24., 25., 26., 27.],
       [28., 29., 30., 31.]])]
[array([[32., 33., 34., 35.],
       [36., 37., 38., 39.],
       [40., 41., 42., 43.],
       [44., 45., 46., 47.]]), array([[48., 49., 50., 51.],
       [52., 53., 54., 55.],
       [56., 57., 58., 59.],
       [60., 61., 62., 63.]])]
[19]:
print(f"sum: \n{(mprocess1 + mprocess2).hss}")
print(f"subtraction: \n{(mprocess1 - mprocess2).hss}")
print(f"right multiplication: \n{(2 * mprocess1).hss}")
print(f"left multiplication: \n{(mprocess1 * 2).hss}")
print(f"division: \n{(mprocess1 / 2).hss}")
sum:
[array([[32., 34., 36., 38.],
       [40., 42., 44., 46.],
       [48., 50., 52., 54.],
       [56., 58., 60., 62.]]), array([[64., 66., 68., 70.],
       [72., 74., 76., 78.],
       [80., 82., 84., 86.],
       [88., 90., 92., 94.]])]
subtraction:
[array([[-32., -32., -32., -32.],
       [-32., -32., -32., -32.],
       [-32., -32., -32., -32.],
       [-32., -32., -32., -32.]]), array([[-32., -32., -32., -32.],
       [-32., -32., -32., -32.],
       [-32., -32., -32., -32.],
       [-32., -32., -32., -32.]])]
right multiplication:
[array([[ 0.,  2.,  4.,  6.],
       [ 8., 10., 12., 14.],
       [16., 18., 20., 22.],
       [24., 26., 28., 30.]]), array([[32., 34., 36., 38.],
       [40., 42., 44., 46.],
       [48., 50., 52., 54.],
       [56., 58., 60., 62.]])]
left multiplication:
[array([[ 0.,  2.,  4.,  6.],
       [ 8., 10., 12., 14.],
       [16., 18., 20., 22.],
       [24., 26., 28., 30.]]), array([[32., 34., 36., 38.],
       [40., 42., 44., 46.],
       [48., 50., 52., 54.],
       [56., 58., 60., 62.]])]
division:
[array([[0. , 0.5, 1. , 1.5],
       [2. , 2.5, 3. , 3.5],
       [4. , 4.5, 5. , 5.5],
       [6. , 6.5, 7. , 7.5]]), array([[ 8. ,  8.5,  9. ,  9.5],
       [10. , 10.5, 11. , 11.5],
       [12. , 12.5, 13. , 13.5],
       [14. , 14.5, 15. , 15.5]])]

calc_gradient functions

Calculates gradient of MProcess with variable index.

[20]:
grad_mprocess = mprocess.calc_gradient(0)
print(f"hss: \n{grad_mprocess.hss}")
hss:
[array([[1., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]]), array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])]

convert_basis function

Returns hss converted to the specified basis.

[21]:
from quara.objects.matrix_basis import get_comp_basis

mprocess = generate_mprocess_from_name(c_sys, "z-type1")
converted_hss = mprocess.convert_basis(get_comp_basis())
print(f"hss: \n{converted_hss}")
hss:
[array([[1.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 6.22328532e-19+0.j],
       [0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j],
       [0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j],
       [3.25176795e-17+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 5.97792087e-34+0.j]]), array([[5.97792087e-34+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 3.25176795e-17+0.j],
       [0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j],
       [0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j],
       [6.22328532e-19+0.j, 0.00000000e+00+0.j, 0.00000000e+00+0.j, 1.00000000e+00+0.j]])]

to_choi_matrix

Returns Choi matrix of the specified index of hss.

[22]:
mprocess = generate_mprocess_from_name(c_sys, "z-type1")
print(f"to_choi_matrix(0): \n{mprocess.to_choi_matrix(0)}")
print(f"to_choi_matrix_with_dict(0): \n{mprocess.to_choi_matrix_with_dict(0)}")
print(f"to_choi_matrix(0): \n{mprocess.to_choi_matrix(0)}")
to_choi_matrix(0):
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
to_choi_matrix_with_dict(0):
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]
to_choi_matrix(0):
[[1.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]
 [0.+0.j 0.+0.j 0.+0.j 0.+0.j]]

to_kraus_matrices

Returns Kraus matrices of the specified index of hss.

[23]:
mprocess = generate_mprocess_from_name(c_sys, "z-type1")
print(f"to_kraus_matrices(0): \n{mprocess.to_kraus_matrices(0)}")
to_kraus_matrices(0):
[array([[1.+0.j, 0.+0.j],
       [0.+0.j, 0.+0.j]])]

to_process_matrix

Returns process matrix of the specified index of hss.

[24]:
mprocess = generate_mprocess_from_name(c_sys, "z-type1")
print(f"to_process_matrix(0): \n{mprocess.to_process_matrix(0)}")
to_process_matrix(0):
[[1.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j]
 [0.00000000e+00+0.j 6.22328532e-19+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j]
 [0.00000000e+00+0.j 0.00000000e+00+0.j 3.25176795e-17+0.j 0.00000000e+00+0.j]
 [0.00000000e+00+0.j 0.00000000e+00+0.j 0.00000000e+00+0.j 5.97792087e-34+0.j]]

to_povm

Generates Povm from MProcess.

[25]:
mprocess = generate_mprocess_from_name(c_sys, "z-type1")
print(mprocess.to_povm())
Type:
Povm

Dim:
2

Number of outcomes:
2

Vecs:
[[ 0.70710678  0.          0.          0.70710678]
 [ 0.70710678  0.          0.         -0.70710678]]

some utility functions

[26]:
print(f"is_sum_tp(): {mprocess.is_sum_tp()}")
print(f"is_cp(): {mprocess.is_cp()}")
is_sum_tp(): True
is_cp(): True

mprocess_typical

generate_mprocess_object_from_mprocess_name_object_name() function in mprocess_typical module can easily generate objects related to MProcess.
The generate_mprocess_object_from_mprocess_name_object_name() function has the following arguments:
  • The string that can be specified for mprocess_name can be checked by executing the get_mprocess_names_type1() and get_mprocess_names_type2() functions. The tensor product of state_name “a”, “b” is written “a_b”.

  • object_name can be the following string:

  • “set_pure_state_vectors” - The set of pure state vectors of MProcess.

  • “set_kraus_matrices” - The set of Kraus matrices of MProcess.

  • “hss” - The list of Hilbert-Schmidt matrix representations of MProcess.

  • “mprocess” - MProcess object.

  • c_sys - CompositeSystem of objects related to MProcess. Specify when object_name is “hss” and “mprocess”.

  • is_physicality_required - Whether the generated object is physicality required, by default True.

[27]:
from quara.objects.mprocess_typical import (
    get_mprocess_names_type1,
    get_mprocess_names_type2,
    generate_mprocess_object_from_mprocess_name_object_name,
)

print(f"get_mprocess_names_type1(): \n{get_mprocess_names_type1()}")
print(f"get_mprocess_names_type2(): \n{get_mprocess_names_type2()}")
get_mprocess_names_type1():
['x-type1', 'y-type1', 'z-type1', 'bell-type1', 'z3-type1', 'z2-type1', 'xxparity-type1', 'zzparity-type1']
get_mprocess_names_type2():
['x-type2', 'y-type2', 'z-type2', 'z3-type2', 'z2-type2']

object_name = “set_pure_state_vectors”

[28]:
vecs = generate_mprocess_object_from_mprocess_name_object_name("z-type1", "set_pure_state_vectors")
print(vecs)
[[array([1.+0.j, 0.+0.j])], [array([0.+0.j, 1.+0.j])]]

object_name = “set_kraus_matrices”

[29]:
matrices = generate_mprocess_object_from_mprocess_name_object_name("z-type1", "set_kraus_matrices")
print(matrices)
[[array([[1.+0.j, 0.+0.j],
       [0.+0.j, 0.+0.j]])], [array([[0.+0.j, 0.+0.j],
       [0.+0.j, 1.+0.j]])]]

object_name = “hss”

[30]:
c_sys = generate_composite_system("qubit", 1)
hss = generate_mprocess_object_from_mprocess_name_object_name("z-type1", "hss", c_sys=c_sys)
print(hss)
[array([[0.5, 0. , 0. , 0.5],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0.5, 0. , 0. , 0.5]]), array([[ 0.5,  0. ,  0. , -0.5],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [-0.5,  0. ,  0. ,  0.5]])]

object_name = “mprocess”

[31]:
c_sys = generate_composite_system("qubit", 1)
mprocess = generate_mprocess_object_from_mprocess_name_object_name("z-type1", "mprocess", c_sys=c_sys)
print(mprocess)
Type:
MProcess

Dim:
2

HSs:
[array([[0.5, 0. , 0. , 0.5],
       [0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. ],
       [0.5, 0. , 0. , 0.5]]), array([[ 0.5,  0. ,  0. , -0.5],
       [ 0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ],
       [-0.5,  0. ,  0. ,  0.5]])]

ModeSampling:
False

Download Notebook