# Source code for oqupy.operators

```# Copyright 2022 The TEMPO Collaboration
#
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# Unless required by applicable law or agreed to in writing, software
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
"""
Shorthand for commonly used operators.
"""

from typing import Text

import numpy as np
from numpy import ndarray

from oqupy.config import NpDtype

SIGMA = {"id":[[1, 0], [0, 1]],
"x":[[0, 1], [1, 0]],
"y":[[0, -1j], [1j, 0]],
"z":[[1, 0], [0, -1]],
"+":[[0, 1], [0, 0]],
"-":[[0, 0], [1, 0]]}

SPIN_DM = {"up":[[1, 0], [0, 0]],
"down":[[0, 0], [0, 1]],
"z+":[[1, 0], [0, 0]],
"z-":[[0, 0], [0, 1]],
"x+":[[0.5, 0.5], [0.5, 0.5]],
"x-":[[0.5, -0.5], [-0.5, 0.5]],
"y+":[[0.5, -0.5j], [0.5j, 0.5]],
"y-":[[0.5, 0.5j], [-0.5j, 0.5]],
"mixed":[[0.5, 0.0], [0.0, 0.5]]}

[docs]def identity(n: int) -> ndarray:
"""
Identity matrix of dimension `n` x `n`.

Parameters
----------
n: int
Dimension of the square matrix.

Returns
-------
identity : ndarray
Identity matrix of dimension `n` x `n`.
"""
return np.identity(n, dtype=NpDtype)

[docs]def sigma(name: Text) -> ndarray:
"""
Spin matrix sigma of type `name`.

Parameters
----------
name: str{ ``'id'``, ``'x'``, ``'y'``, ``'z'``, ``'+'``, ``'-'``}

Returns
-------
sigma : ndarray
Spin matrix of type `name`.
"""
return np.array(SIGMA[name], dtype=NpDtype)

[docs]def spin_dm(name: Text) -> ndarray:
"""
Spin 1/2 state of type `name`.

Parameters
----------
name: str{ ``'up'``/``'z+'``, ``'down'``/``'z-'``, ``'x+'``, ``'x-'``, \
``'y+'``, ``'y-'``, ``mixed``}

Returns
-------
density_matrix : ndarray
Spin density matrix.
"""
return np.array(SPIN_DM[name], dtype=NpDtype)

[docs]def create(n: int) -> ndarray:
"""
Bosonic creation operator of dimension `n` x `n`.

Parameters
----------
n: int
Dimension of the Hilbert space.

Returns
-------
create : ndarray
Creation operator matrix of dimension `n` x `n`.
"""
return destroy(n).T

[docs]def destroy(n: int) -> ndarray:
"""
Bosonic annihilation operator of dimension `n` x `n`.

Parameters
----------
n: int
Dimension of the Hilbert space.

Returns
-------
create : ndarray
Annihilation operator matrix of dimension `n` x `n`.
"""
return np.diag(np.sqrt(range(1, n), dtype=NpDtype), 1)

# -- superoperators ----------------------------------------------------------

[docs]def commutator(operator: ndarray) -> ndarray:
"""Construct commutator superoperator from operator. """
dim = operator.shape[0]
return np.kron(operator, np.identity(dim)) \
- np.kron(np.identity(dim), operator.T)

[docs]def acommutator(operator: ndarray) -> ndarray:
"""Construct anti-commutator superoperator from operator. """
dim = operator.shape[0]
return np.kron(operator, np.identity(dim)) \
+ np.kron(np.identity(dim), operator.T)

[docs]def left_super(operator: ndarray) -> ndarray:
"""Construct left acting superoperator from operator. """
dim = operator.shape[0]
return np.kron(operator, np.identity(dim))

[docs]def right_super(operator: ndarray) -> ndarray:
"""Construct right acting superoperator from operator. """
dim = operator.shape[0]
return np.kron(np.identity(dim), operator.T)

[docs]def left_right_super(
left_operator: ndarray,
right_operator: ndarray) -> ndarray:
"""Construct left and right acting superoperator from operators. """
return np.kron(left_operator, right_operator.T)

[docs]def preparation(
density_matrix: ndarray) -> ndarray:
"""Construct the super operator that prepares the state. """
dim = density_matrix.shape[0]
identity_matrix = np.identity(dim, dtype=NpDtype)
return np.outer(density_matrix.flatten(), identity_matrix.flatten())

# -- two site superoperators --------------------------------------------------

[docs]def cross_commutator(
operator_1: ndarray,
operator_2: ndarray) -> ndarray:
"""Construct commutator of cross term (acting on two Hilbert spaces). """
id1 = np.identity(operator_1.shape[1])
id2 = np.identity(operator_2.shape[1])
op1_id = np.kron(operator_1, id1)
op2_id = np.kron(operator_2, id2)
id_op1 = np.kron(id1, operator_1.T)
id_op2 = np.kron(id2, operator_2.T)
return np.kron(op1_id, op2_id) - np.kron(id_op1, id_op2)

[docs]def cross_acommutator(
operator_1: ndarray,
operator_2: ndarray) -> ndarray:
"""
Construct anit-commutator of cross term (acting on two Hilbert spaces).
"""
id1 = np.identity(operator_1.shape[1])
id2 = np.identity(operator_2.shape[1])
op1_id = np.kron(operator_1, id1)
op2_id = np.kron(operator_2, id2)
id_op1 = np.kron(id1, operator_1.T)
id_op2 = np.kron(id2, operator_2.T)
return np.kron(op1_id, op2_id) + np.kron(id_op1, id_op2)

[docs]def cross_left_right_super(
operator_1_l: ndarray,
operator_1_r: ndarray,
operator_2_l: ndarray,
operator_2_r: ndarray) -> ndarray:
"""
Contruct map from rho to [(op1l x op2l) rho (op1r x op2r)].
"""
op1l_op1r = np.kron(operator_1_l, operator_1_r.T)
op2l_op2r = np.kron(operator_2_l, operator_2_r.T)
return np.kron(op1l_op1r, op2l_op2r)
```