Как эффективно запрограммировать конкретное унитарное преобразование, работающее с вектором, избегая np.dot - PullRequest
0 голосов
/ 26 января 2019

Я устанавливаю библиотеку квантовых вентилей (унитарных операторов). Я хочу написать их как можно более абстрактно, чтобы использовать их во многих целях.

Например, ворота Адамара.

Представьте, что у нас есть строка из 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).

Спасибо и хорошего!

...