State and state_typical
[1]:
import numpy as np
np.set_printoptions(linewidth=200)
State
Quantum state (density matrix) can be represented by a linear combination of basis. vec represents the coefficients of this linear combination in the form of a numpy array.
vec of \(z_0\) is \([ 1/\sqrt{2}, 0, 0, 1/\sqrt{2} ]\).The methods for generating a State includes the following:
Generate from
state_typicalmoduleGenerate State object directly
Generate from state_typical module by specifying CompositeSystem and state name (ex. “z0”).
[2]:
from quara.objects.composite_system_typical import generate_composite_system
from quara.objects.state_typical import generate_state_from_name
c_sys = generate_composite_system("qubit", 1)
state = generate_state_from_name(c_sys, "z0")
print(state)
Type:
State
Dim:
2
Vec:
[0.70710678 0. 0. 0.70710678]
Generate State object directly using CompositeSystem and a numpy array.
[3]:
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.state import State
basis = get_normalized_pauli_basis(1)
e_sys = ElementalSystem(0, basis)
c_sys = CompositeSystem([e_sys])
vec = np.array([1, 0, 0, 1]) / np.sqrt(2)
state = State(c_sys, vec)
print(state)
Type:
State
Dim:
2
Vec:
[0.70710678 0. 0. 0.70710678]
specific properties
The property vec of State is a numpy array specified by the constructor argument vec.
[4]:
state = State(c_sys, vec)
print(f"vec: {state.vec}")
vec: [0.70710678 0. 0. 0.70710678]
The property dim of State is a square root of the size of element of vec.
[5]:
print(f"dim: {state.dim}")
print(f"square root of the size of element of vec: {int(np.sqrt(len(vec)))}")
dim: 2
square root of the size of element of vec: 2
functions to check constraints
The is_eq_constraint_satisfied() function returns True, if and only if \(\text{Tr}[\rho] = 1\), where \(\rho\) is a density matrix of State.
[6]:
print(f"is_eq_constraint_satisfied(): {state.is_eq_constraint_satisfied()}")
print(f"trace of density matrix: {np.trace(state.to_density_matrix())}")
is_eq_constraint_satisfied(): True
trace of density matrix: (0.9999999999999998+0j)
The is_ineq_constraint_satisfied() function returns True, if and only if \(\rho\) is positive semidifinite matrix, where \(\rho\) is a density matrix of State.
[7]:
print(f"is_eq_constraint_satisfied(): {state.is_eq_constraint_satisfied()}")
print(f"is_positive_semidefinite(): {state.is_positive_semidefinite()}")
is_eq_constraint_satisfied(): True
is_positive_semidefinite(): True
projection functions
calc_proj_eq_constraint() function calculates the projection of State on equal constraint.vec with \(1/\sqrt{d}\), where \(d\) is dim.[8]:
vec = np.array([1.0, 2.0, 3.0, 4.0])
state = State(c_sys, vec, is_physicality_required=False)
proj_state = state.calc_proj_eq_constraint()
print(f"vec: {proj_state.vec}")
vec: [0.70710678 2. 3. 4. ]
calc_proj_ineq_constraint() function calculates the projection of State on inequal constraint as follows:
Executes singular value decomposition on the density matrix \(\rho\) of state, \(\rho = 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}]\)
\(\rho^{\prime} = U \Lambda^{\prime} U^{\dagger}\)
The projection of State is \(|\rho^{\prime} \rangle\rangle\).
[9]:
vec = np.sqrt(2) * np.array([0, 0, 0, 1])
state = State(c_sys, vec, is_physicality_required=False)
print(f"density matrix before projection: \n{state.to_density_matrix()}")
proj_state = state.calc_proj_ineq_constraint()
print(f"density matrix after projection: \n{proj_state.to_density_matrix()}")
print(f"vec after projection: \n{proj_state.vec}")
density matrix before projection:
[[ 1.+0.j 0.+0.j]
[ 0.+0.j -1.+0.j]]
density matrix after projection:
[[1.+0.j 0.+0.j]
[0.+0.j 0.+0.j]]
vec after projection:
[0.70710678 0. 0. 0.70710678]
functions to transform parameters
to_stacked_vector() function returns a one-dimensional numpy array of all variables. This is equal to vec.
[10]:
print(f"to_stacked_vector(): {state.to_stacked_vector()}")
print(f"vec: {state.vec}")
to_stacked_vector(): [0. 0. 0. 1.41421356]
vec: [0. 0. 0. 1.41421356]
on_para_eq_constraint is True, then the first element of vec is equal to \(1/\sqrt{d}\), where \(d\) is dim. Thus, State is characterized by the second and subsequent elements of vec.to_var() function returns the second and subsequent elements of vec, where on_para_eq_constraint is True.[11]:
vec = np.array([1, 0, 0, 1]) / np.sqrt(2)
[12]:
# on_para_eq_constraint=True
state = State(c_sys, vec, on_para_eq_constraint=True)
print(f"to_var(): {state.to_var()}")
to_var(): [0. 0. 0.70710678]
[13]:
# on_para_eq_constraint=False
state = State(c_sys, vec, on_para_eq_constraint=False)
print(f"to_var(): {state.to_var()}")
to_var(): [0.70710678 0. 0. 0.70710678]
functions to generate special objects
[14]:
zero_state = state.generate_zero_obj()
print(f"zero: {zero_state.vec}")
origin_state = state.generate_origin_obj()
print(f"origin: {origin_state.vec}")
zero: [0. 0. 0. 0.]
origin: [0.70710678 0. 0. 0. ]
supports arithmetic operations
[15]:
vec1 = np.array([1.0, 2.0, 3.0, 4.0])
state1 = State(c_sys, vec1, is_physicality_required=False)
vec2 = np.array([5.0, 6.0, 7.0, 8.0])
state2 = State(c_sys, vec2, is_physicality_required=False)
print(f"sum: {(state1 + state2).vec}")
print(f"subtraction: {(state1 - state2).vec}")
print(f"right multiplication: {(2 * state1).vec}")
print(f"left multiplication: {(state1 * 2).vec}")
print(f"division: {(state1 / 2).vec}")
sum: [ 6. 8. 10. 12.]
subtraction: [-4. -4. -4. -4.]
right multiplication: [2. 4. 6. 8.]
left multiplication: [2. 4. 6. 8.]
division: [0.5 1. 1.5 2. ]
calc_gradient functions
Calculates gradient of State with variable index.
[16]:
grad_state = state.calc_gradient(0)
print(f"vec: {grad_state.vec}")
vec: [1. 0. 0. 0.]
convert_basis function
Returns vec converted to the specified basis.
[17]:
from quara.objects.matrix_basis import get_comp_basis
state = generate_state_from_name(c_sys, "z0")
converted_vec = state.convert_basis(get_comp_basis())
print(f"vec: {converted_vec}")
vec: [1.+0.j 0.+0.j 0.+0.j 0.+0.j]
to_density_matrix function
Returns density matrix of State.
[18]:
state = generate_state_from_name(c_sys, "z0")
print(f"to_density_matrix(): \n{state.to_density_matrix()}")
print(f"to_density_matrix_with_sparsity(): \n{state.to_density_matrix_with_sparsity()}")
to_density_matrix():
[[1.+0.j 0.+0.j]
[0.+0.j 0.+0.j]]
to_density_matrix_with_sparsity():
[[1.+0.j 0.+0.j]
[0.+0.j 0.+0.j]]
some utility functions
[19]:
print(f"is_trace_one(): {state.is_trace_one()}")
print(f"is_hermitian(): {state.is_hermitian()}")
print(f"is_positive_semidefinite(): {state.is_positive_semidefinite()}")
print(f"calc_eigenvalues(): {state.calc_eigenvalues()}")
is_trace_one(): True
is_hermitian(): True
is_positive_semidefinite(): True
calc_eigenvalues(): [0.9999999999999998, 0.0]
state_typical
generate_state_object_from_state_name_object_name() function in state_typical module can easily generate objects related to State.generate_state_object_from_state_name_object_name() function has the following arguments:The string that can be specified for
state_namecan be checked by executing theget_state_names()function. The tensor product of state_name “a”, “b” is written “a_b”.object_namecan be the following string:“pure_state_vector” - vector of pure state.
“density_mat” - density matrix.
“density_matrix_vector” - vectorized density matrix.
“state” - State object.
c_sys- CompositeSystem of objects related to State. Specify whenobject_nameis “density_matrix_vector” or “state”.is_physicality_required- Whether the generated object is physicality required, by default True.
[20]:
from quara.objects.state_typical import (
get_state_names,
generate_state_object_from_state_name_object_name,
)
#get_state_names()
object_name = “pure_state_vector”
[21]:
vec = generate_state_object_from_state_name_object_name("z0", "pure_state_vector")
print(vec)
[1.+0.j 0.+0.j]
object_name = “density_mat”
[22]:
density_mat = generate_state_object_from_state_name_object_name("z0", "density_mat")
print(density_mat)
[[1.+0.j 0.+0.j]
[0.+0.j 0.+0.j]]
object_name = “density_matrix_vector”
[23]:
c_sys = generate_composite_system("qubit", 1)
vec = generate_state_object_from_state_name_object_name("z0", "density_matrix_vector", c_sys=c_sys)
print(vec)
[0.70710678 0. 0. 0.70710678]
object_name = “state”
[24]:
c_sys = generate_composite_system("qubit", 1)
state = generate_state_object_from_state_name_object_name("z0", "state", c_sys=c_sys)
print(state)
Type:
State
Dim:
2
Vec:
[0.70710678 0. 0. 0.70710678]