Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 87 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,103 @@
name: CI

on: [push]
on:
push:
pull_request:
workflow_dispatch:

jobs:
test:
test-quantum-simulator:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: pip install torch matplotlib scikit-learn
- name: Run quantum simulator tests
run: python -m unittest discover -s tests -p "test_quantum_simulator.py" -v

test-qnn-layers:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: pip install torch matplotlib scikit-learn
- name: Run QNN layers tests
run: python -m unittest discover -s tests -p "test_qnn_layers.py" -v

test-qml-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: pip install torch matplotlib scikit-learn
- name: Run QML run tests
run: python -m unittest discover -s tests -p "test_qml_run.py" -v

test-qml-parallel-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: pip install torch matplotlib scikit-learn
- name: Run QML parallel run tests
run: python -m unittest discover -s tests -p "test_qml_parallel_run.py" -v

test-run-experiments:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: pip install torch matplotlib scikit-learn
- name: Run experiments tests
run: python -m unittest discover -s tests -p "test_run_experiments.py" -v

test-state-encoding:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: pip install torch matplotlib scikit-learn
- name: Run state encoding tests
run: python -m unittest discover -s tests -p "test_state_encoding.py" -v

run-training:
runs-on: ubuntu-latest
needs: [test-quantum-simulator, test-qnn-layers, test-qml-run, test-qml-parallel-run, test-run-experiments, test-state-encoding]
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install torch matplotlib scikit-learn

- name: Run tests
run: |
python -m unittest test_quantum_simulator.py && python -m unittest test_qnn_layers.py

- name: Run qnn_training
run: |
python qml_training.py

- name: Run qnn_training-parallel
run: |
python qml_training_parallel.py
run: pip install torch matplotlib scikit-learn
- name: Run qml_training
run: python qml_training.py
- name: Run qml_training_parallel
run: python qml_training_parallel.py


4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,6 @@ dmypy.json
*.code-workspace

data/*
plots/*
plots/*
*.lock
.vscode/*
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# COMPSCI 648 - Quantum Machine Learning Project

Quantum machine learning for binary classification using variational quantum circuits, built with PyTorch.

## Project Structure

```
quantum_simulator.py # States, gates, measurements
qml_training.py # VQC training pipelines
run_experiments.py # CLI experiment runner
error_kraus.py # T1/T2 noise via Kraus operators
metrics.py # Accuracy, F1, ROC-AUC
visualizer.py # Training curve plots
demos/circuit_visualization.ipynb
data/ # Output CSVs
tests/
```

## Encoding

- **Angle**: Feature θ → RY(θ) rotation. N features use N qubits.
- **Amplitude**: Features as state amplitudes. 2^N values use N qubits.

## Noise Model

T1/T2 thermal relaxation applied after each gate:
- T1: amplitude damping (|1⟩ → |0⟩ decay)
- T2: phase damping (coherence loss)

Circuit error-adding functionality:
- Time-based idle noise between gates via `gate_durations` (μs)
- Optional decoherence during gates using `gate_noise_fraction` (0–1, default to 1)
- Kraus-based simulation with `T_φ` derived from `T1,T2`; enforces `T2 ≤ 2·T1`
- Units: all times in microseconds; typical: H≈0.025 μs, CNOT≈0.2 μs
- Relaxation model based on superconducting transmon qubit

## Models

**Deep VQC**: Multi-layer variational circuit with RY, RZ, CNOT layers.

**Noise-Aware VQC**: Same architecture, trained with simulated T1/T2 noise using density matrix evolution.

## Usage

```bash
# Default run
python run_experiments.py

# Custom parameters
python run_experiments.py --epochs 50 --T1 50 --T2 100

# Specific configuration
python run_experiments.py --models deep_vqc --encodings angle --datasets moons --plot
```

| Arg | Default | Options |
|-----|---------|---------|
| `--epochs` | 25 | |
| `--T1` | 100 | T1 relaxation (μs) |
| `--T2` | 200 | T2 dephasing (μs) |
| `--models` | all | `deep_vqc`, `noise_aware` |
| `--encodings` | all | `angle`, `amplitude` |
| `--datasets` | all | `real`, `moons` |
| `--plot` | off | Save comparison plots |

## Datasets

- **real**: Breast cancer (UCI), PCA to 2-4 features
- **moons**: Synthetic two-moons, 2D

## Demo Notebook

`demos/circuit_visualization.ipynb` shows encoding comparisons, kernel matrices, and noise effects on fidelity.

## Install

```bash
pip install -e .
```

Requires Python ≥3.8, PyTorch ≥2.0, NumPy, Matplotlib, scikit-learn.
4 changes: 4 additions & 0 deletions metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@ def binary_predictions(scores):
return torch.where(scores >= 0, 1.0, -1.0)

def accuracy(y_true, y_pred):
"""Binary accuracy for {-1,+1} labels."""
return (y_true == y_pred).float().mean().item()

def precision(y_true, y_pred):
"""Positive predictive value for {-1,+1} labels."""
tp = ((y_pred == 1) & (y_true == 1)).sum().item()
fp = ((y_pred == 1) & (y_true == -1)).sum().item()
return tp / (tp + fp + 1e-9)

def recall(y_true, y_pred):
"""True positive rate for {-1,+1} labels."""
tp = ((y_pred == 1) & (y_true == 1)).sum().item()
fn = ((y_pred == -1) & (y_true == 1)).sum().item()
return tp / (tp + fn + 1e-9)

def f1_score(y_true, y_pred):
"""Harmonic mean of precision and recall."""
p = precision(y_true, y_pred)
r = recall(y_true, y_pred)
return 2 * p * r / (p + r + 1e-9)
Expand Down
32 changes: 32 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "compsci648-qml"
version = "0.1.0"
description = "Quantum Machine Learning Project for COMPSCI648"
requires-python = ">=3.8"
dependencies = [
"torch>=2.0.0,<2.3.0",
"numpy>=1.24.0,<2.0.0",
"matplotlib",
"scikit-learn",
]

[tool.setuptools]
py-modules = [
"quantum_simulator",
"qml_training",
"qml_training_parallel",
"run_experiments",
"metrics",
"error_kraus",
"visualizer",
]

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
torch>=2.0.0
numpy>=1.24.0
torch>=2.0.0,<2.3.0
numpy>=1.24.0,<2.0.0
matplotlib>=3.7.0
scikit-learn>=1.3.0
pandas>=2.0.0
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Test package for COMPSCI648 Quantum ML Project
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.