BraAndKet is a library for numeral calculations of discrete quantum systems.
Project description
BraAndKet
BraAndKet is a library for numeral calculations of discrete quantum systems.
Quickstart
Before Using
Please notice that this library is still actively developing. The stability and compatibility of APIs are NOT guaranteed. Breaking changes are happening every day! Using this library right now, you may take your own risk.
Installation
You can install the latest release from PiPy.
pip install braandket
Then you can import this library with name bnk
import braandket as bnk
KetSpace
Any quantum states can exist in some space called Hilbert space. You can use bnk.KetSpace(n)
to define such a space,
where n
is its dimension. For example, to create a Hilbert space of a qbit:
qbit = bnk.KetSpace(2) print(qbit) # output: KetSpace(2)
You can define a name for a space using named parameter. The name is to describe this space when debugging. The name can
be a str
, or any object to be printed out. When printed, the name of space will be shown, which is very helpful when
debugging.
qbit_a = bnk.KetSpace(2, name="a") print(qbit_a) # output: KetSpace(2, name=a) qbit_b = bnk.KetSpace(2, name="b") print(qbit_b) # output: KetSpace(2, name=b)
You can call these 4 methods on a KetSpace
instance to create ket vectors and operators:
 method
.eigenstate(k)
 to get a ket vector, representing the kth eigenstate  method
.identity()
 to get an identity operator in this Hilbert space  method
.operator(k,b)
 to get an operator  method
.projector(k)
 to get a projector
ket_space = bnk.KetSpace(2) ket_vec = ket_space.eigenstate(0) identity_op = ket_space.identity() increase_op = ket_space.operator(1, 0) zero_proj = ket_space.projector(0)
A KetSpace
is accompanied by a BraSpace
. You can conveniently get it with .ct
property. To avoid confusion, is not
allowed to create any vectors or operations with a BraSpace
. Please do so with its corresponding KetSpace
.
Calling .ct
property, you can get back its KetSpace
.
ket_space = bnk.KetSpace(2) print(ket_space) # output: KetSpace(2) bra_space = ket_space.ct print(bra_space) # output: BraSpace(2) print(bra_space.ct is ket_space) # output: True
QTensors
QTensor
is the basic type of computing elements in this library. A QTensor
instance holds an np.ndarray
as its
values and a tuple of Space
instances. Each Space
corresponds to an axis of the np.ndarray
.
Any vectors, operators and tensors in quantum world are represented by QTensor
. All vectors and operators mentioned
above are all QTensor
instances.
ket_space = bnk.KetSpace(2) ket_vec = ket_space.eigenstate(0) print(ket_vec) # output: QTensor(spaces=(KetSpace(2),), values=[1. 0.]) identity_op = ket_space.identity() print(identity_op) # output: QTensor(spaces=(KetSpace(2), BraSpace(2)), values=[[1. 0.] [0. 1.]]) increase_op = ket_space.operator(1, 0) print(increase_op) # output: QTensor(spaces=(KetSpace(2), BraSpace(2)), values=[[0. 0.] [1. 0.]]) zero_proj = ket_space.projector(0) print(zero_proj) # output: QTensor(spaces=(KetSpace(2), BraSpace(2)), values=[[1. 0.] [0. 0.]])
You can easily get a conjugate transposed QTensor
calling .ct
property. It should be noted that sometimes, such
operation does not affect the values, but spaces.
ket_space = bnk.KetSpace(2) ket_vec = ket_space.eigenstate(0) bra_vec = ket_vec.ct print(bra_vec) # output: QTensor(spaces=(BraSpace(2),), values=[1. 0.]) increase_op = ket_space.operator(1, 0) decrease_op = increase_op.ct print(decrease_op) # output: QTensor(spaces=(BraSpace(2), KetSpace(2)), values=[[0. 0.] [1. 0.]])
QTensor
instances can take tensor product using @
operator. They can automatically inspect which spaces to be
performed the "productsum" (when the bra on the left meets the matching ket on the right), which to be remained.
Example1:
qbit = bnk.KetSpace(2) amp = qbit.eigenstate(0).ct @ qbit.eigenstate(1) print(amp) # output: QTensor(spaces=(), values=0.0)
Example2:
qbit_a = bnk.KetSpace(2, name="a") qbit_b = bnk.KetSpace(2, name="b") ket_vec_ab = qbit_a.eigenstate(0) @ qbit_b.eigenstate(1) print(ket_vec_ab) # output: QTensor(spaces=(KetSpace(2, name=a), KetSpace(2, name=b)), values=[[0. 1.] [0. 0.]])
Example3:
qbit_a = bnk.KetSpace(2, name="a") qbit_b = bnk.KetSpace(2, name="b") tensor_ab = qbit_a.eigenstate(0).ct @ qbit_b.eigenstate(1) print(tensor_ab) # output: QTensor(spaces=(BraSpace(2, name=a), KetSpace(2, name=b)), values=[[0. 1.] [0. 0.]])
Example4:
qbit = bnk.KetSpace(2) ket_vec_0 = qbit.eigenstate(0) ket_vec_1 = qbit.eigenstate(1) increase_op = qbit.operator(1, 0) result = increase_op @ ket_vec_0 print(result) # output: QTensor(spaces=(KetSpace(2),), values=[0. 1.]) print(result == ket_vec_1) # output: True
(todo ...)
Pruning
Sometimes, the space of system can be terribly big, since the space increases exponentially with the increase of the count of components.
But in some cases, we just want to study the evolution of the system under certain conditions, for example from several
specified start points evolves with some certain operators. Then, some states are in fact impossible to be reached. Then
those unreachable states can be dropped out of the computation. Class PrunedKetSpace
is designed for such cases.
The static method PrunedKetSpace.from_seed()
can automatically detect which eigenstates can be dropped, with the given
starting states and evolution operators, and return an instance of PrunedKetSpace
as a "reachable" space. This can
significantly reduce the calculation and memory consumption.
The pruned and original tensors can also be easily converted to each other using method reduce()
and inflate()
.
Evolve functions
(todo ...)
Contribution
This library is completely open source. Any contributions are welcomed. You can fork this repository, make some useful changes and then send a pull request to me on GitHub.
Project details
Release history Release notifications  RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for BraAndKet0.7.3py3noneany.whl
Algorithm  Hash digest  

SHA256  ad3235c95999a2df37f33cb3367a5e66ead6abc5aea240a3174854998c863700 

MD5  bc9bdc57f669bdb601fece6a041efc07 

BLAKE2256  6945f6952e4e3d6747a8a9f700cf84f0d28c82e2a0ac6382cf57b2de61ef87d8 