diff --git a/docs/api_python/core/operators/mindquantum.core.operators.FermionOperator.rst b/docs/api_python/core/operators/mindquantum.core.operators.FermionOperator.rst index 9b362337c..bee2954d8 100644 --- a/docs/api_python/core/operators/mindquantum.core.operators.FermionOperator.rst +++ b/docs/api_python/core/operators/mindquantum.core.operators.FermionOperator.rst @@ -126,12 +126,18 @@ mindquantum.core.operators.FermionOperator 返回: FermionOperator,从字符串加载的FermionOperator。 - .. py:method:: matrix(n_qubits: int = None) + .. py:method:: matrix(n_qubits: int = None, pr=None) 将此费米子运算符转换为jordan_wigner映射下的csr_matrix。 参数: - **n_qubits** (int) - 结果矩阵的总量子比特数。如果是None,则该值将是最大局域量子比特数。默认值: ``None``。 + - **pr** (ParameterResolver, dict, numpy.ndarray, list, numbers.Number) - 含参费米子算符的参数。默认值: ``None``。 + + .. py:method:: params_name + :property: + + 获取费米子算符的所有参数。 .. py:method:: normal_ordered() diff --git a/docs/api_python/core/operators/mindquantum.core.operators.QubitOperator.rst b/docs/api_python/core/operators/mindquantum.core.operators.QubitOperator.rst index d897bd2fc..1afc58f76 100644 --- a/docs/api_python/core/operators/mindquantum.core.operators.QubitOperator.rst +++ b/docs/api_python/core/operators/mindquantum.core.operators.QubitOperator.rst @@ -130,12 +130,18 @@ mindquantum.core.operators.QubitOperator 返回: QubitOperator,从字符串加载的QubitOperator。 - .. py:method:: matrix(n_qubits: int = None) + .. py:method:: matrix(n_qubits: int = None, pr=None) 将此玻色子算符转换为csr_matrix。 参数: - **n_qubits** (int) - 结果矩阵的量子比特数目。如果是None,则该值将是最大局域量子比特数。默认值: ``None``。 + - **pr** (ParameterResolver, dict, numpy.ndarray, list, numbers.Number) - 含参玻色子算符的参数。默认值: ``None``。 + + .. py:method:: params_name + :property: + + 获取玻色子算符的所有参数。 .. py:method:: parameterized :property: diff --git a/mindquantum/core/operators/fermion_operator.py b/mindquantum/core/operators/fermion_operator.py index 89b18be33..77593b027 100644 --- a/mindquantum/core/operators/fermion_operator.py +++ b/mindquantum/core/operators/fermion_operator.py @@ -31,7 +31,11 @@ from mindquantum.dtype.dtype import str_dtype_map from mindquantum.mqbackend import EQ_TOLERANCE from mindquantum.third_party.interaction_operator import InteractionOperator -from mindquantum.utils.type_value_check import _check_int_type, _require_package +from mindquantum.utils.type_value_check import ( + _check_and_generate_pr_type, + _check_int_type, + _require_package, +) @lru_cache() @@ -537,20 +541,27 @@ def hermitian(self) -> "FermionOperator": """ return FermionOperator(FermionOperator_.hermitian_conjugated(self), internal=True) - def matrix(self, n_qubits: int = None): # pylint: disable=too-many-branches + def matrix(self, n_qubits: int = None, pr=None): # pylint: disable=too-many-branches """ Convert this fermion operator to csr_matrix under jordan_wigner mapping. Args: n_qubits (int): The total qubit of final matrix. If None, the value will be the maximum local qubit number. Default: None. + pr (ParameterResolver, dict, numpy.ndarray, list, numbers.Number): The parameter + resolver for parameterized FermionOperator. Default: None. """ - if self.parameterized: - raise RuntimeError("Cannot convert a parameterized fermion operator to matrix.") + if pr is None: + pr = ParameterResolver() + pr = _check_and_generate_pr_type(pr, self.params_name) np_type = mq.to_np_type(self.dtype) + ops = self + if self.parameterized: + ops = copy.copy(self) + ops = ops.subs(pr) if not self.terms: raise ValueError("Cannot convert empty fermion operator to matrix") - n_qubits_local = self.count_qubits() + n_qubits_local = ops.count_qubits() if n_qubits_local == 0 and n_qubits is None: raise ValueError("You should specific n_qubits for converting a identity fermion operator.") if n_qubits is None: @@ -561,7 +572,7 @@ def matrix(self, n_qubits: int = None): # pylint: disable=too-many-branches f"Given n_qubits {n_qubits} is small than qubit of fermion operator, which is {n_qubits_local}." ) out = 0 - for term, coeff in self.terms.items(): + for term, coeff in ops.terms.items(): coeff = coeff.const if not term: out += csr_matrix(np.identity(2**n_qubits, dtype=np_type)) * coeff @@ -583,6 +594,14 @@ def matrix(self, n_qubits: int = None): # pylint: disable=too-many-branches out += tmp * coeff return out + @property + def params_name(self): + """Get all parameters of this operator.""" + names = [] + for pr in self.terms.values(): + names.extend([i for i in pr.params_name if i not in names]) + return names + def normal_ordered(self) -> "FermionOperator": """ Return the normal ordered form of the Fermion Operator. diff --git a/mindquantum/core/operators/qubit_operator.py b/mindquantum/core/operators/qubit_operator.py index 0b73bf7b9..8adb3f27c 100644 --- a/mindquantum/core/operators/qubit_operator.py +++ b/mindquantum/core/operators/qubit_operator.py @@ -28,7 +28,11 @@ from mindquantum.core.parameterresolver import ParameterResolver, PRConvertible from mindquantum.dtype.dtype import str_dtype_map from mindquantum.mqbackend import EQ_TOLERANCE -from mindquantum.utils.type_value_check import _check_int_type, _require_package +from mindquantum.utils.type_value_check import ( + _check_and_generate_pr_type, + _check_int_type, + _require_package, +) # pylint: disable=too-many-public-methods @@ -495,23 +499,40 @@ def hermitian(self) -> "QubitOperator": """ return QubitOperator(QubitOperator_.hermitian_conjugated(self), internal=True) - def matrix(self, n_qubits: int = None): + def matrix(self, n_qubits: int = None, pr=None): """ Convert this qubit operator to csr_matrix. Args: n_qubits (int): The total qubits of final matrix. If ``None``, the value will be the maximum local qubit number. Default: ``None``. + pr (ParameterResolver, dict, numpy.ndarray, list, numbers.Number): The parameter + resolver for parameterized QubitOperator. Default: None. """ + if pr is None: + pr = ParameterResolver() + pr = _check_and_generate_pr_type(pr, self.params_name) + ops = self + if self.parameterized: + ops = copy.copy(self) + ops = ops.subs(pr) if n_qubits is None: n_qubits = -1 _check_int_type('n_qubits', n_qubits) - csr = QubitOperator_.sparsing(self, n_qubits) + csr = QubitOperator_.sparsing(ops, n_qubits) data = np.array(csr.data, copy=False) indptr = np.array(csr.get_indptr(), copy=False) indices = np.array(csr.get_indices(), copy=False) return csr_matrix((data, indices, indptr), (csr.n_row, csr.n_col)) + @property + def params_name(self): + """Get all parameters of this operator.""" + names = [] + for pr in self.terms.values(): + names.extend([i for i in pr.params_name if i not in names]) + return names + def relabel(self, logic_qubits: typing.List[int]) -> "QubitOperator": """ Relabel the qubit according to the given logic qubits order. diff --git a/mindquantum/io/qasm/openqasm.py b/mindquantum/io/qasm/openqasm.py index 0df8d6eea..4e20152e8 100644 --- a/mindquantum/io/qasm/openqasm.py +++ b/mindquantum/io/qasm/openqasm.py @@ -91,7 +91,7 @@ def h_related(gate): def i_related(gate): """Convert mindquantum gate to qasm.""" - return f"id {gate.obj_qubits[0]};" + return f"id q[{gate.obj_qubits[0]}];" def phase_related(gate): diff --git a/tests/st/test_core/test_operators/test_fermion_ops.py b/tests/st/test_core/test_operators/test_fermion_ops.py index 0e2bed5de..36339e733 100644 --- a/tests/st/test_core/test_operators/test_fermion_ops.py +++ b/tests/st/test_core/test_operators/test_fermion_ops.py @@ -18,6 +18,7 @@ import os import pickle +import numpy as np import pytest from mindquantum.core.operators import FermionOperator @@ -244,3 +245,16 @@ def test_relabel(): f_op = FermionOperator('3^ 2 1 0') f_op = f_op.relabel([1, 3, 0, 2]) assert f_op == -FermionOperator('3 2^ 1 0') + + +@pytest.mark.level0 +@pytest.mark.platform_x86_cpu +def test_get_matrix(): + """ + Description: Test get matrix of fermion operator. + Expectation: success. + """ + a = FermionOperator('0', 'a') + with pytest.raises(ValueError, match="Parameter a not in given parameter resolver."): + a.matrix() + assert np.allclose(a.matrix(pr={'a': 1}).toarray(), FermionOperator('0').matrix().toarray()) diff --git a/tests/st/test_core/test_operators/test_qubit_ops.py b/tests/st/test_core/test_operators/test_qubit_ops.py index 9e7997c46..f2cbfd9ac 100644 --- a/tests/st/test_core/test_operators/test_qubit_ops.py +++ b/tests/st/test_core/test_operators/test_qubit_ops.py @@ -266,3 +266,16 @@ def test_relabel(): q_op = QubitOperator('Z0 Y1 X2 Z3') q_op = q_op.relabel([1, 3, 0, 2]) assert q_op == QubitOperator('X0 Z1 Z2 Y3') + + +@pytest.mark.level0 +@pytest.mark.platform_x86_cpu +def test_get_matrix(): + """ + Description: Test get matrix of qubit operator. + Expectation: success. + """ + a = QubitOperator('X0', 'a') + with pytest.raises(ValueError, match="Parameter a not in given parameter resolver."): + a.matrix() + assert np.allclose(a.matrix(pr={'a': 1}).toarray(), QubitOperator('X0').matrix().toarray())