Я устанавливаю библиотеку квантовых вентилей (унитарных операторов).
Я хочу написать их как можно более абстрактно, чтобы использовать их во многих целях.
Например, ворота Адамара.
Представьте, что у нас есть строка из n битов: | abc ... n>.
Эти строки представляют числа от 0 до 2 ^ n и служат для вычисления элементов | 00 ... 0>, | 00 ... 1>, ..., | 11 ... 1>.
Допустим, наше состояние является линейной комбинацией некоторых битовых строк, и мы выражаем его как вектор из 2 ^ n компонентов:
state = [a00...0, ..., a11...1]
Ворота Адамара принимают в качестве аргументов текущее состояние и целое число m <= n.
Мы говорим, что Ворота Адамара действуют на m-м кубите. </p>
На практическом примере предположим, что мы работаем с 3 кубитами.
Наша вычислительная база:
|000>, |001>, |010>, |011>,
|100>, |101>, |110>, |111>
И наши состояния будут сложными 8-мерными массивами.
state = [a000, a001, a010, a011, a100, a101, a110, a111]
Врата Адамара на 1-м кубите:
H(state) = [b000, b001, b010, b011, b100, b101, b110, b111]
с
b0XY = 1/sqrt(2) * (a0XY + a1XY)
b1XY = 1/sqrt(2) * (a0XY - a1XY)
для любых X и Y.
И, например, то же самое произошло бы, если бы мы применили Ворота Адамара к третьему кубиту 4-кубитной системы:
state = [a0000, a0001, ..., a1111]
H(state) = [b0000, b0001, ..., b1111]
с
bXX0X = 1/sqrt(2) (aXX0X + aXX1X)
bXX1X = 1/sqrt(2) (aXX0X - aXX1X)
Это мой код, где `` размер '- это размерность, количество кубитов.
Начальное состояние a00 ... 0 = 1 и 0 в другом месте, но это не так уж важно, это может быть что угодно.
from itertools import product
import numpy as np
import math
state = np.zeros(2**size, dtype=complex)
state[0] = 1.
def ii (self,i):
"""Computes a double index.
Args.
i (vector): array of bits with value 1 or 0.
Rets.
ii (int): base 10 representation of the bits array.
"""
l = len(i)
return np.dot(i,[2**(l-j-1) for j in range(l)])
def H(state, m):
"""Apply the Hadamard Gate to the m'th qubit.
Args.
state (dim=2**size vector): initial state.
m (int): what qubit are we applying our gate on.
Rets.
state (dim=2**n vector): new final state.
"""
for i in product([0,1], repeat=self.size):
# can improve, just looking for a working model
j = np.array(i)
j[m] ^= 1
if(j[m]):
state[ii(i)] += state[ii(j)]
else:
state[ii(i)] = state[ii(j)] - 2*state[ii(i)]
state /= math.sqrt(2)
return state
Что я могу сделать, чтобы повысить эффективность?
Вывод в порядке прямо сейчас.
Я хотел бы более элегантно разобраться с тремя строками под комментарием.
Я также хотел бы знать, как обращаться с векторным преобразованием, используя дескрипторы, чтобы не тратить память и время. (Я пришел из скромного C-фона и до сих пор не знаю, что такое эквивалент дескрипторов в Python).
Спасибо и хорошего!