Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
azimonti committed May 11, 2024
1 parent 95e976e commit 2563f39
Show file tree
Hide file tree
Showing 6 changed files with 1,291 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
ignore=E741,E743
64 changes: 62 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,62 @@
# quantum-entanglement-simulation
Simulate an entangled state of a quantum computer
# Quantum mechanics spin simulation

Welcome to the Quantum Mechanics Spin Simulation repository. This Python-based project is designed to simulate quantum spin dynamics, providing an interactive platform to explore the fundamental principles of quantum mechanics through computational methods. Whether you're a student, educator, or researcher, this repository offers valuable tools to simulate and analyze the behavior of quantum spins under various conditions.

## Single spin simulation

The single spin simulation script allows users to simulate the quantum mechanics of a single spin system. Users can specify the orientation of a measurement apparatus in three-dimensional space and observe the behavior of a quantum spin subjected to this configuration. The simulation outputs include the probabilities of the spin aligning in either the up or down state and can be visualized in real-time to aid in understanding quantum superposition and measurement collapse.

### Features:

- **Dynamic Apparatus Orientation:** Users can input coordinates to align the measurement apparatus in any arbitrary direction.
- **Randomized Spin Measurement:** Utilizes a random number generator to simulate the probabilistic nature of quantum measurements.
- **Measurement Repeatability:** Simulate consecutive measurements to observe the quantum mechanical property of state collapse.

## Two spin simulation

The two spin simulation script extends the capabilities of the single spin simulator by introducing interactions between two spins. This script includes various predefined states such as entangled states and product states, allowing users to simulate complex quantum phenomena like entanglement and spin correlation.

### Simulation types:

- **Product States:** Simulate two independent spins in various configurations.
- **Entangled States:** Explore the intriguing properties of entangled spins with several types of entangled states available, including the singlet and triplet states.
- **Measurement Options:** Perform measurements on both spins individually or simultaneously to observe correlations directly resulting from quantum entanglement.

### Output:

- **Statistical Analysis:** The script provides detailed statistics on spin states and their correlations after multiple measurements, essential for understanding entanglement.

## Getting Started

To get started with these simulations:
1. Clone the repository:
```
git clone https://github.com/azimonti/quantum-entanglement-simulation.git
```
2. Navigate to the repository directory:
```
cd quantum-entanglement-simulation
```
3. Install required dependencies:
```
pip install -r requirements.txt
```
4. Run the simulation scripts:
```
python single_spin_sim.py
python two_spin_sim.py
```

## Contributing

Contributions to the Quantum Mechanics Spin Simulation project are welcome. Whether it's through submitting bug reports, proposing new features, or contributing to the code, your help is appreciated. For major changes, please open an issue first to discuss what you would like to change.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details.

## Contact

If you have any questions or want to get in touch regarding the project, please open an issue or contact the repository maintainers directly through GitHub.

Thank you for exploring the quantum mechanics of spins with us!
215 changes: 215 additions & 0 deletions mod_spin_operators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
#!/usr/bin/env python3
'''
/************************/
/* mod_spin_operators */
/* Version 1.0 */
/* 2024/05/11 */
/************************/
'''
import cmath
import math
import numpy as np
import sys


class SingleSpin:

def __init__(self, basis: str = 'ud'):
self.__basis = basis
self.__state = None
if (basis == 'ud'):
self.__u = np.array([[1], [0]], dtype=complex)
self.__d = np.array([[0], [1]], dtype=complex)
self.__r = np.array(
[[1 / np.sqrt(2)], [1 / np.sqrt(2)]], dtype=complex)
self.__l = np.array(
[[1 / np.sqrt(2)], [-1 / np.sqrt(2)]], dtype=complex)
self.__i = np.array(
[[1 / np.sqrt(2)], [1j / np.sqrt(2)]], dtype=complex)
self.__o = np.array(
[[1 / np.sqrt(2)], [-1j / np.sqrt(2)]], dtype=complex)
self.__sz = np.array([[1, 0], [0, -1]], dtype=complex)
self.__sx = np.array([[0, 1], [1, 0]], dtype=complex)
self.__sy = np.array([[0, -1j], [1j, 0]], dtype=complex)
elif (basis == 'rl'):
self.__u = np.array(
[[1 / np.sqrt(2)], [1 / np.sqrt(2)]], dtype=complex)
self.__d = np.array(
[[1 / np.sqrt(2)], [-1 / np.sqrt(2)]], dtype=complex)
self.__r = np.array([[1], [0]], dtype=complex)
self.__l = np.array([[0], [1]], dtype=complex)
self.__i = np.array(
[[(1 + 1j) / 2], [(1 - 1j) / 2]], dtype=complex)
self.__o = np.array(
[[(1 - 1j) / 2], [(1 + 1j) / 2]], dtype=complex)
elif (basis == 'io'):
self.__u = np.array(
[[1 / np.sqrt(2)], [1 / np.sqrt(2)]], dtype=complex)
self.__d = np.array(
[[1j / np.sqrt(2)], [-1j / np.sqrt(2)]], dtype=complex)
self.__r = np.array(
[[(1 + 1j) / 2], [(1 - 1j) / 2]], dtype=complex)
self.__l = np.array(
[[(1 - 1j) / 2], [(1 + 1j) / 2]], dtype=complex)
self.__o = np.array([[1], [0]], dtype=complex)
self.__i = np.array([[0], [1]], dtype=complex)
else:
raise NotImplementedError(
"Basis " + basis + "not Implemented")

@property
def u(self):
return self.__u

@property
def d(self):
return self.__d

@property
def r(self):
return self.__r

@property
def l(self):
return self.__l

@property
def i(self):
return self.__i

@property
def o(self):
return self.__o

@property
def s_z(self):
if (self.__basis != 'ud'):
raise NotImplementedError(
"S_z for basis " + self.__basis + "not Implemented")
return self.__sz

@property
def s_x(self):
if (self.__basis != 'ud'):
raise NotImplementedError(
"S_x for basis " + self.__basis + "not Implemented")
return self.__sx

@property
def s_y(self):
if (self.__basis != 'ud'):
raise NotImplementedError(
"S_y for basis " + self.__basis + "not Implemented")
return self.__sy

@property
def psi(self):
return self.__state

@psi.setter
def psi(self, value):
# check that length is unitary
assert math.isclose(np.linalg.norm(value), 1)
self.__state = value

def theta(self):
assert self.__state
return 2 * np.arccos(np.linalg.norm(self.__state[0][0]))

def phi(self):
assert self.__state
if self.__state[1][0] != 0:
return cmath.phase(self.__state[1][0])
else:
return 0

def angles(self):
return [self.theta(), self.phi()]


class TwolSpins:

def __init__(self, basis: str = 'ud'):
self.__basis = basis
self.__state = None
if (basis == 'ud'):
u = np.array([[1], [0]], dtype=complex)
d = np.array([[0], [1]], dtype=complex)
self.__b = [
np.kron(u, u), np.kron(u, d),
np.kron(d, u), np.kron(d, d)
]
self.__bmap = {'uu': 0, 'ud': 1, 'du': 2, 'dd': 3}
self.__s = [
np.array([[1, 0], [0, -1]], dtype=complex),
np.array([[0, 1], [1, 0]], dtype=complex),
np.array([[0, -1j], [1j, 0]], dtype=complex),
np.array([[1, 0], [0, 1]], dtype=complex)
]
self.__smap = {'z': 0, 'x': 1, 'y': 2, 'I': 3}
else:
raise NotImplementedError(
"Basis " + basis + "not Implemented")

@property
def psi(self):
return self.__state

@ psi.setter
def psi(self, value):
# check that length is unitary
assert math.isclose(np.linalg.norm(value), 1)
self.__state = value

def BasisVector(self, s):
return self.__b[self.__bmap[s]]

def Sigma(self, sA: str, sB: str):
return np.kron(
self.__s[self.__smap[sA]], self.__s[self.__smap[sB]])

def Sigma_A(self, s: str):
return np.kron(self.__s[self.__smap[s]], self.__s[3])

def Sigma_B(self, s: str):
return np.kron(self.__s[3], self.__s[self.__smap[s]])

def Expectation(self, sA: str, sB: str):
if (sA == 'I'):
# expectation of System B
return np.linalg.multi_dot([
self.__state.conj().T, self.Sigma_B(sB), self.__state])[0, 0]
elif (sB == 'I'):
# expectation of System A
return np.linalg.multi_dot([
self.__state.conj().T, self.Sigma_A(sA), self.__state])[0, 0]
else:
# expectation of the composite system
return np.linalg.multi_dot([
self.__state.conj().T, self.Sigma(sA, sB), self.__state])[0, 0]

def ProductState(self, A: np.array, B: np.array):
# check that length is unitary
assert math.isclose(np.linalg.norm(A), 1)
assert math.isclose(np.linalg.norm(B), 1)
self.psi = np.kron(A, B)

def Singlet(self):
self.psi = 1 / np.sqrt(2) * (self.__b[1] - self.__b[2])

def Triplet(self, i: int):
match i:
case 1:
self.psi = 1 / np.sqrt(2) * (self.__b[1] + self.__b[2])
case 2:
self.psi = 1 / np.sqrt(2) * (self.__b[0] + self.__b[3])
case 3:
self.psi = 1 / np.sqrt(2) * (self.__b[0] - self.__b[3])
case _:
raise ValueError("Incorrect index " + str(i))


if __name__ == '__main__':
if sys.version_info[0] < 3:
raise 'Must be using Python 3'
pass
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pyqt6==6.5.2
numpy==1.25.2
Loading

0 comments on commit 2563f39

Please sign in to comment.