Japanese

English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

# qiskit.quantum_info.operators.scalar_op のソースコード

```# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2020.
#
# obtain a copy of this license in the LICENSE.txt file in the root directory
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
ScalarOp class
"""

import copy
from numbers import Number
import numpy as np

from qiskit.exceptions import QiskitError
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.quantum_info.operators.linear_op import LinearOp
from qiskit.quantum_info.operators.operator import Operator
from qiskit.quantum_info.operators.mixins import generate_apidocs

[ドキュメント]class ScalarOp(LinearOp):
"""Scalar identity operator class.

This is a symbolic representation of an scalar identity operator on
multiple subsystems. It may be used to initialize a symbolic scalar
multiplication of an identity and then be implicitly converted to other
kinds of operator subclasses by using the :meth:`compose`, :meth:`dot`,
:meth:`tensor`, :meth:`expand` methods.
"""

def __init__(self, dims=None, coeff=1):
"""Initialize an operator object.

Args:
dims (int or tuple): subsystem dimensions.
coeff (Number): scalar coefficient for the identity
operator (Default: 1).

Raises:
QiskitError: If the optional coefficient is invalid.
"""
if not isinstance(coeff, Number):
QiskitError(f"coeff {coeff} must be a number.")
self._coeff = coeff
super().__init__(input_dims=dims, output_dims=dims)

def __array__(self, dtype=None):
if dtype:
return np.asarray(self.to_matrix(), dtype=dtype)
return self.to_matrix()

def __repr__(self):
return f"ScalarOp({self.input_dims()}, coeff={self.coeff})"

@property
def coeff(self):
"""Return the coefficient"""
return self._coeff

[ドキュメント]    def conjugate(self):
ret = self.copy()
ret._coeff = np.conjugate(self.coeff)
return ret

[ドキュメント]    def transpose(self):
return self.copy()

[ドキュメント]    def is_unitary(self, atol=None, rtol=None):
"""Return True if operator is a unitary matrix."""
if atol is None:
atol = self.atol
if rtol is None:
rtol = self.rtol
return np.isclose(np.abs(self.coeff), 1, atol=atol, rtol=rtol)

[ドキュメント]    def to_matrix(self):
"""Convert to a Numpy matrix."""
dim, _ = self.dim
iden = np.eye(dim, dtype=complex)
return self.coeff * iden

[ドキュメント]    def to_operator(self):
"""Convert to an Operator object."""
return Operator(
self.to_matrix(), input_dims=self.input_dims(), output_dims=self.output_dims()
)

[ドキュメント]    def compose(self, other, qargs=None, front=False):
if qargs is None:
qargs = getattr(other, "qargs", None)
if not isinstance(other, BaseOperator):
other = Operator(other)

new_shape = self._op_shape.compose(other._op_shape, qargs, front)

# If other is also an ScalarOp we only need to
# update the coefficient and dimensions
if isinstance(other, ScalarOp):
ret = copy.copy(self)
ret._coeff = self.coeff * other.coeff
ret._op_shape = new_shape
return ret

# If we are composing on the full system we return the
# other operator with reshaped dimensions
if qargs is None:
ret = copy.copy(other)
ret._op_shape = new_shape
# Other operator might not support scalar multiplication
# so we treat the identity as a special case to avoid a
# possible error
if self.coeff == 1:
return ret
return self.coeff * ret

# For qargs composition we initialize the scalar operator
# as an instance of the other BaseOperators subclass. We then
# perform subsystem qargs composition using the BaseOperator
# subclasses compose method.
# Note that this will raise an error if the other operator does
# not support initialization from a ScalarOp or the ScalarOps
# `to_operator` method).
return other.__class__(self).compose(other, qargs=qargs, front=front)

[ドキュメント]    def power(self, n):
"""Return the power of the ScalarOp.

Args:
n (float): the exponent for the scalar op.

Returns:
ScalarOp: the ``coeff ** n`` ScalarOp.
"""
ret = self.copy()
ret._coeff = self.coeff**n
return ret

[ドキュメント]    def tensor(self, other):
if not isinstance(other, BaseOperator):
other = Operator(other)

if isinstance(other, ScalarOp):
ret = copy.copy(self)
ret._coeff = self.coeff * other.coeff
ret._op_shape = self._op_shape.tensor(other._op_shape)
return ret

return other.expand(self)

[ドキュメント]    def expand(self, other):
if not isinstance(other, BaseOperator):
other = Operator(other)

if isinstance(other, ScalarOp):
ret = copy.copy(self)
ret._coeff = self.coeff * other.coeff
ret._op_shape = self._op_shape.expand(other._op_shape)
return ret

return other.tensor(self)

"""Return the operator self + other.

If ``qargs`` are specified the other operator will be added
assuming it is identity on all other subsystems.

Args:
other (BaseOperator): an operator object.
qargs (None or list): optional subsystems to subtract on
(Default: None)

Returns:
ScalarOp: if other is an ScalarOp.
BaseOperator: if other is not an ScalarOp.

Raises:
QiskitError: if other has incompatible dimensions.
"""
if qargs is None:
qargs = getattr(other, "qargs", None)

if not isinstance(other, BaseOperator):
other = Operator(other)

# Next if we are adding two ScalarOps we return a ScalarOp
if isinstance(other, ScalarOp):
return ScalarOp(self.input_dims(), coeff=self.coeff + other.coeff)

# If qargs are specified we have to pad the other BaseOperator
# with identities on remaining subsystems. We do this by
# composing it with an identity ScalarOp.

# First we check the special case where coeff=0. In this case
# we simply return the other operator reshaped so that its
# subsystem dimensions are equal to the current operator for the
# case where total dimensions agree but subsystem dimensions differ.
if self.coeff == 0:
return other.reshape(self.input_dims(), self.output_dims())

# Finally if we are adding another BaseOperator subclass
# we use that subclasses `_add` method and reshape the
# final dimensions.

def _multiply(self, other):
"""Return the ScalarOp other * self.

Args:
other (Number): a complex number.

Returns:
ScalarOp: the scaled identity operator other * self.

Raises:
QiskitError: if other is not a valid complex number.
"""
if not isinstance(other, Number):
raise QiskitError(f"other ({other}) is not a number")
ret = self.copy()
ret._coeff = other * self.coeff
return ret

@staticmethod

Args:
current (BaseOperator): current operator.
other (BaseOperator): other operator.
qargs (None or list): qargs

Returns: