Skip to content

Commit

Permalink
add test case for mqmatrix method
Browse files Browse the repository at this point in the history
  • Loading branch information
dsdsdshe committed Sep 1, 2023
1 parent aa583d5 commit d8554e9
Show file tree
Hide file tree
Showing 7 changed files with 372 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,11 @@ auto CPUDensityMatrixPolicyBase<derived_, calc_type_>::GetPartialTrace(const qs_
return res;
}


template <typename derived_, typename calc_type_>
auto CPUDensityMatrixPolicyBase<derived_, calc_type_>::PureStateVector(const qs_data_p_t& qs, index_t dim)
-> py_qs_datas_t {
auto p = Purity(qs, dim);
if (std::abs(p - 1) > 1e-8) {
if (1 - p > 1e-6) {
throw(std::runtime_error("PureStateVector(): Cannot transform mixed density matrix to vector."));
}
if (qs == nullptr) {
Expand Down
1 change: 1 addition & 0 deletions mindquantum/core/gates/basicgate.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class UnivMathGate(NoneParamNonHermMat):

def __init__(self, name, matrix_value):
"""Initialize a UnivMathGate object."""
_check_input_type('matrix_value', np.ndarray, matrix_value)
if len(matrix_value.shape) != 2:
raise ValueError(f"matrix_value require shape of 2, but get shape of {matrix_value.shape}")
if matrix_value.shape[0] != matrix_value.shape[1]:
Expand Down
2 changes: 1 addition & 1 deletion mindquantum/core/gates/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ def __init__(self, name: str, kraus_op, **kwargs):
sum_of_mat = np.zeros((2, 2), 'complex128')
for mat in kraus_op:
sum_of_mat += np.dot(mat.T.conj(), mat)
if not np.allclose(sum_of_mat, [[1, 0], [0, 1]]):
if not np.allclose(sum_of_mat, [[1, 0], [0, 1]], atol=1e-6):
raise ValueError(f"kraus_op need to satisfy the completeness condition, but get {sum_of_mat}")
kwargs['name'] = name
kwargs['n_qubits'] = 1
Expand Down
4 changes: 2 additions & 2 deletions mindquantum/simulator/mqsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ def set_qs(self, quantum_state: np.ndarray):
raise ValueError("Wrong quantum state.")
self.sim.set_qs(quantum_state / norm_factor)
elif len(quantum_state.shape) == 2:
if not np.allclose(quantum_state, quantum_state.T.conj()):
if not np.allclose(quantum_state, quantum_state.T.conj(), atol=1e-6):
raise ValueError("density matrix must be hermitian.")
if (quantum_state.diagonal() < 0).any():
raise ValueError("the diagonal terms in density matrix cannot be negative.")
Expand Down Expand Up @@ -528,6 +528,6 @@ def get_pure_state_vector(self) -> np.ndarray:
"""Get the state vector from a pure density matrix."""
if self.name.startswith('mqvector'):
return self.get_qs()
if 1 - self.purity() > 1e-8:
if 1 - self.purity() > 1e-6:
raise ValueError("Cannot transform mixed density matrix to vector.")
return np.array(self.sim.pure_state_vector())
8 changes: 4 additions & 4 deletions mindquantum/simulator/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,21 +679,21 @@ def fidelity(rho: np.ndarray, sigma: np.ndarray):
if np.log2(qs.shape[0]) % 1 != 0:
raise ValueError(f"quantum state size {qs.shape[0]} is not power of 2")
if qs.ndim == 1:
if not np.allclose(np.sum(np.abs(qs) ** 2), 1):
if not np.allclose(np.sum(np.abs(qs) ** 2), 1, atol=1e-6):
raise ValueError("state vector must be normalized.")
elif qs.ndim == 2:
if qs.shape[0] != qs.shape[1]:
raise ValueError("the row of matrix is not equal to column.")
if not np.allclose(qs, qs.T.conj()):
if not np.allclose(qs, qs.T.conj(), atol=1e-6):
raise ValueError("density matrix must be hermitian.")
if (qs.diagonal() < 0).any():
raise ValueError("the diagonal terms in density matrix cannot be negative.")
if not np.allclose(np.real(np.trace(qs)), 1):
if not np.allclose(np.real(np.trace(qs)), 1, atol=1e-6):
raise ValueError("the trace of density matrix must equal to 1.")
else:
raise ValueError(f"input quantum state requires a vector or matrix, but get shape {rho.shape}.")
if rho.ndim == 1 and sigma.ndim == 1:
return np.abs(np.inner(rho, sigma)) ** 2
return np.abs(np.inner(rho.conj().T, sigma)) ** 2
if rho.ndim == 1 and sigma.ndim == 2:
return np.real(rho.conj().T @ sigma @ rho)
if rho.ndim == 2 and sigma.ndim == 1:
Expand Down
Loading

0 comments on commit d8554e9

Please sign in to comment.