๐ Python SDK v1.5.2
๊ฐ์ฅ ์ธ๊ธฐ์๋ ์์ ์ปดํจํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ - NumPy, Pandas, Matplotlib์ ์๋ฒฝ ํธํ
๐งช ๊ณผํ ๊ณ์ฐ
NumPy, SciPy์ ๋ค์ดํฐ๋ธ ํตํฉ
๐ ๋ฐ์ดํฐ ๋ถ์
Pandas, Matplotlib ์๋ฒฝ ์ง์
๐ค ๋จธ์ ๋ฌ๋
PyTorch, TensorFlow ์ฐ๋
๐ Jupyter
๋ ธํธ๋ถ์์ ์ธํฐ๋ํฐ๋ธ ์คํ
์ค์น
pip ์ค์น
Bashpip install cqm-quantum
๊ฐ๋ฐ ๋ฒ์ ์ค์น
Bashpip install git+https://github.com/cqmdesk/quantum-sdk-python.git
์์กด์ฑ ํฌํจ ์ค์น
Bashpip install cqm-quantum[visualization,ml]
๋น ๋ฅธ ์์
๊ธฐ๋ณธ ์์
Pythonfrom cqm import QuantumCircuit, Simulator
import numpy as np
# 2ํ๋นํธ Bell ์ํ ์์ฑ
qc = QuantumCircuit(2)
qc.h(0) # Hadamard gate on qubit 0
qc.cx(0, 1) # CNOT gate (control: 0, target: 1)
qc.measure_all()
# ์๋ฎฌ๋ ์ดํฐ ์คํ
sim = Simulator()
result = sim.run(qc, shots=1000)
print(result.get_counts())
# Output: {'00': 502, '11': 498}
Jupyter Notebook์์ ์ฌ์ฉ
Pythonfrom cqm import QuantumCircuit, Simulator
from cqm.visualization import plot_histogram, plot_bloch_multivector
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.h(2)
qc.measure_all()
sim = Simulator()
result = sim.run(qc, shots=1024)
# ๊ฒฐ๊ณผ ์๊ฐํ
plot_histogram(result.get_counts())
plot_bloch_multivector(result.get_statevector())
์ฃผ์ ๊ธฐ๋ฅ
1. ์์ ํ๋ก ์์ฑ
Pythonimport numpy as np
from cqm import QuantumCircuit
qc = QuantumCircuit(4) # 4ํ๋นํธ ํ๋ก
# ๊ธฐ๋ณธ ๊ฒ์ดํธ
qc.h(0) # Hadamard
qc.x(1) # Pauli-X (NOT)
qc.y(2) # Pauli-Y
qc.z(3) # Pauli-Z
# ํ์ ๊ฒ์ดํธ
qc.rx(np.pi/4, 0) # X์ถ ํ์
qc.ry(np.pi/2, 1) # Y์ถ ํ์
qc.rz(np.pi, 2) # Z์ถ ํ์
# ์ ์ด ๊ฒ์ดํธ
qc.cx(0, 1) # CNOT
qc.cz(1, 2) # Controlled-Z
qc.ccx(0, 1, 2) # Toffoli (CCX)
# ๊ธฐํ
qc.swap(0, 1) # SWAP
qc.measure(0, 0) # ์ธก์
2. ์๋ฎฌ๋ ์ด์ ์ต์
Pythonfrom cqm import Simulator, SimulatorOptions
# ๊ธฐ๋ณธ ์๋ฎฌ๋ ์ด์
sim = Simulator()
result = sim.run(qc, shots=1000)
# ๊ณ ๊ธ ์ต์
sim = Simulator(
backend='statevector',
optimization_level=2,
seed_simulator=42
)
result = sim.run(qc, shots=10000, memory=True)
# ๊ฒฐ๊ณผ ํ์ธ
counts = result.get_counts()
statevector = result.get_statevector()
probabilities = result.get_probabilities()
memory = result.get_memory() # ๊ฐ ์ท์ ๊ฐ๋ณ ์ธก์ ๊ฐ
3. NumPy ํตํฉ
Pythonimport numpy as np
from cqm import QuantumCircuit
# NumPy ๋ฐฐ์ด๋ก ํ๋ก ์ ์ด
angles = np.linspace(0, 2*np.pi, 10)
results = []
for angle in angles:
qc = QuantumCircuit(1)
qc.ry(angle, 0)
qc.measure_all()
result = sim.run(qc, shots=1000)
results.append(result.get_counts())
# NumPy ๋ฐฐ์ด๋ก ๋ณํ
prob_0 = np.array([r.get('0', 0)/1000 for r in results])
4. Pandas ๋ฐ์ดํฐ ๋ถ์
Pythonimport pandas as pd
from cqm import QuantumCircuit, Simulator
sim = Simulator()
data = []
# ์ฌ๋ฌ ํ๋ก ์คํ
for n_qubits in range(2, 6):
qc = QuantumCircuit(n_qubits)
for i in range(n_qubits):
qc.h(i)
qc.measure_all()
result = sim.run(qc, shots=1000)
data.append({
'qubits': n_qubits,
'states': len(result.get_counts()),
'entropy': result.get_entropy()
})
df = pd.DataFrame(data)
print(df)
API ๋ ํผ๋ฐ์ค
QuantumCircuit
| ๋ฉ์๋ | ํ๋ผ๋ฏธํฐ | ์ค๋ช |
|---|---|---|
h(qubit) |
qubit: int | Hadamard ๊ฒ์ดํธ ์ ์ฉ |
x(qubit) |
qubit: int | Pauli-X ๊ฒ์ดํธ ์ ์ฉ |
cx(control, target) |
control, target: int | CNOT ๊ฒ์ดํธ ์ ์ฉ |
rx(angle, qubit) |
angle: float, qubit: int | X์ถ ํ์ ๊ฒ์ดํธ |
measure(qubit, cbit) |
qubit, cbit: int | ๋จ์ผ ํ๋นํธ ์ธก์ |
measure_all() |
์์ | ์ ์ฒด ํ๋นํธ ์ธก์ |
Simulator
| ๋ฉ์๋ | ๋ฐํ ํ์ | ์ค๋ช |
|---|---|---|
run(circuit, shots) |
Result | ํ๋ก ์คํ |
run_batch(circuits, shots) |
List[Result] | ์ฌ๋ฌ ํ๋ก ์ผ๊ด ์คํ |
Result
| ๋ฉ์๋ | ๋ฐํ ํ์ | ์ค๋ช |
|---|---|---|
get_counts() |
Dict[str, int] | ์ธก์ ๊ฒฐ๊ณผ ์นด์ดํธ |
get_statevector() |
np.ndarray | ์ํ ๋ฒกํฐ |
get_probabilities() |
np.ndarray | ํ๋ฅ ๋ถํฌ |
๊ณ ๊ธ ์์
์์ ํธ๋ฆฌ์ ๋ณํ (QFT)
Pythonimport numpy as np
from cqm import QuantumCircuit
def qft(circuit, qubits):
"""Quantum Fourier Transform"""
n = len(qubits)
for i in range(n):
circuit.h(qubits[i])
for j in range(i + 1, n):
angle = np.pi / (2 ** (j - i))
circuit.cp(angle, qubits[j], qubits[i])
# Swap qubits
for i in range(n // 2):
circuit.swap(qubits[i], qubits[n - i - 1])
# ์ฌ์ฉ ์์
qc = QuantumCircuit(4)
qft(qc, [0, 1, 2, 3])
qc.measure_all()
Grover ์๊ณ ๋ฆฌ์ฆ
Pythonimport numpy as np
from cqm import QuantumCircuit, Simulator
def grover_oracle(circuit, target):
"""Oracle for Grover's algorithm"""
# target ๋ฌธ์์ด์ ํด๋นํ๋ ์ํ๋ฅผ ๋งํน
for i, bit in enumerate(target):
if bit == '0':
circuit.x(i)
circuit.h(len(target) - 1)
circuit.mcx(list(range(len(target) - 1)), len(target) - 1)
circuit.h(len(target) - 1)
for i, bit in enumerate(target):
if bit == '0':
circuit.x(i)
def grover_diffusion(circuit, n):
"""Diffusion operator"""
for i in range(n):
circuit.h(i)
circuit.x(i)
circuit.h(n - 1)
circuit.mcx(list(range(n - 1)), n - 1)
circuit.h(n - 1)
for i in range(n):
circuit.x(i)
circuit.h(i)
# 2ํ๋นํธ Grover ๊ฒ์
n = 2
target = '11' # ์ฐพ๊ณ ์ ํ๋ ์ํ
qc = QuantumCircuit(n)
# ์ด๊ธฐํ
for i in range(n):
qc.h(i)
# Grover ๋ฐ๋ณต (์ต์ ํ์)
iterations = int(np.pi / 4 * np.sqrt(2**n))
for _ in range(iterations):
grover_oracle(qc, target)
grover_diffusion(qc, n)
qc.measure_all()
sim = Simulator()
result = sim.run(qc, shots=1000)
print(result.get_counts()) # '11'์ด ๋์ ํ๋ฅ ๋ก ๋ํ๋จ
๋ณ๋ถ ์์ ๊ณ ์ ๊ฐ ํ์ด๊ธฐ (VQE)
Pythonimport numpy as np
from cqm import QuantumCircuit, Simulator
from scipy.optimize import minimize
def vqe_circuit(params):
"""Parametrized quantum circuit"""
qc = QuantumCircuit(2)
qc.ry(params[0], 0)
qc.ry(params[1], 1)
qc.cx(0, 1)
qc.ry(params[2], 0)
qc.ry(params[3], 1)
return qc
def compute_expectation(params, hamiltonian):
"""Compute expectation value"""
qc = vqe_circuit(params)
sim = Simulator(backend='statevector')
result = sim.run(qc, shots=1)
statevector = result.get_statevector()
expectation = np.real(
np.conj(statevector) @ hamiltonian @ statevector
)
return expectation
# ํด๋ฐํ ๋์ ์ ์ (์: H2 ๋ถ์)
hamiltonian = np.array([
[-1.0523, 0, 0, 0.3979],
[0, -0.4804, 0.3979, 0],
[0, 0.3979, -0.4804, 0],
[0.3979, 0, 0, -1.0523]
])
# ์ต์ ํ
initial_params = np.random.rand(4) * 2 * np.pi
result = minimize(
compute_expectation,
initial_params,
args=(hamiltonian,),
method='COBYLA'
)
print(f"Ground state energy: {result.fun}")
print(f"Optimal parameters: {result.x}")
์์ ๊ธฐ๊ณํ์ต
Pythonimport numpy as np
from cqm import QuantumCircuit, Simulator
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
class QuantumClassifier:
def __init__(self, n_qubits=4):
self.n_qubits = n_qubits
self.params = np.random.rand(n_qubits * 2) * 2 * np.pi
self.sim = Simulator()
def feature_map(self, x):
"""Encode classical data into quantum state"""
qc = QuantumCircuit(self.n_qubits)
for i in range(self.n_qubits):
qc.ry(x[i % len(x)] * np.pi, i)
return qc
def variational_circuit(self, qc):
"""Variational layer"""
for i in range(self.n_qubits):
qc.ry(self.params[i], i)
for i in range(self.n_qubits - 1):
qc.cx(i, i + 1)
for i in range(self.n_qubits):
qc.ry(self.params[self.n_qubits + i], i)
def predict(self, X):
predictions = []
for x in X:
qc = self.feature_map(x)
self.variational_circuit(qc)
qc.measure_all()
result = self.sim.run(qc, shots=100)
counts = result.get_counts()
# ์ธก์ ๊ฒฐ๊ณผ์ ํจ๋ฆฌํฐ๋ก ๋ถ๋ฅ
prob_0 = sum(v for k, v in counts.items() if k.count('0') > self.n_qubits/2)
predictions.append(1 if prob_0 > 50 else 0)
return np.array(predictions)
# ๋ฐ์ดํฐ ์์ฑ ๋ฐ ํ์ต
X, y = make_classification(n_samples=100, n_features=4, n_classes=2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
qclf = QuantumClassifier(n_qubits=4)
y_pred = qclf.predict(X_test)
accuracy = np.mean(y_pred == y_test)
print(f"Accuracy: {accuracy:.2%}")
๐ก Pro Tip:
%matplotlib inline์ Jupyter์์ ์คํํ๋ฉด ํ๋กฏ์ด ์๋์ผ๋ก ํ์๋ฉ๋๋ค.
โ ๏ธ ์ฃผ์: ๋๊ท๋ชจ ์๋ฎฌ๋ ์ด์
์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๊ธ๊ฒฉํ ์ฆ๊ฐํฉ๋๋ค. 25ํ๋นํธ ์ด์์ HPC ํ๊ฒฝ์ ๊ถ์ฅํฉ๋๋ค.
์๊ฐํ
Pythonfrom cqm.visualization import (
plot_histogram,
plot_bloch_multivector,
plot_state_city,
circuit_drawer
)
# ํ์คํ ๊ทธ๋จ
plot_histogram(result.get_counts())
# ๋ธ๋กํ ๊ตฌ
plot_bloch_multivector(result.get_statevector())
# State city
plot_state_city(result.get_statevector())
# ํ๋ก ๋ค์ด์ด๊ทธ๋จ
circuit_drawer(qc, output='mpl')
๋ฌธ์ ๋ฐ ์ง์
- ๐ ๋ฌธ์: docs.cqmdesk.com/sdk/python
- ๐ฌ Discord: discord.gg/cqmdesk
- ๐ ์ด์: GitHub Issues
- ๐ง ์ด๋ฉ์ผ: sdk@cqmdesk.com
- ๐ฆ PyPI: pypi.org/project/cqm-quantum