Пример #1
0
def pad_matrix(matrix, dim, padding):
    """
    Fills matrix dimensions with zeros or identity.
    """
    if padding == "compsub":
        return matrix
    elif padding == "wzeros":
        zeros = np.zeros([dim, dim])
        matrix = scipy_block_diag(matrix, zeros)
    elif padding == "fulluni":
        identity = np.eye(dim)
        matrix = scipy_block_diag(matrix, identity)
    return matrix
Пример #2
0
 def perform(self, node, inputs, output_storage, params=None):
     dtype = largest_common_dtype(inputs)
     if self.sparse:
         output_storage[0][0] = sp.sparse.block_diag(
             inputs, self.format, dtype)
     else:
         output_storage[0][0] = scipy_block_diag(*inputs).astype(dtype)
Пример #3
0
 def perform(self, node, inputs, output_storage, params=None):
     dtype = largest_common_dtype(inputs)
     if self.sparse:
         output_storage[0][0] = sp.sparse.block_diag(
             inputs, self.format, dtype
         )
     else:
         output_storage[0][0] = scipy_block_diag(*inputs).astype(dtype)
Пример #4
0
def test_block_diag():
    C1 = np.ones((2, 2))
    C2 = np.ones((3, 3)) * 2
    C3 = np.ones((3, 3)) * 3
    C = scipy_block_diag(C1, C2, C3)

    C1 = tt.as_tensor_variable(np.ones((2, 2)))
    C2 = tt.as_tensor_variable(np.ones((3, 3)) * 2)
    C3 = tt.as_tensor_variable(np.ones((3, 3)) * 3)

    assert np.allclose(C, lazy_math.block_diag(C1, C2, C3).eval())
Пример #5
0
 def block_diag(self, *mats):
     if config.lazy:
         N = [mat.shape[0] for mat in mats]
         Nsum = tt.sum(N)
         res = tt.zeros((Nsum, Nsum), dtype=theano.config.floatX)
         n = 0
         for mat in mats:
             inds = slice(n, n + mat.shape[0])
             res = tt.set_subtensor(res[tuple((inds, inds))], mat)
             n += mat.shape[0]
         return res
     else:
         return scipy_block_diag(*mats)
Пример #6
0
def perfect_gate(gates_str: str, index=[0, 1], dims=[2, 2], proj: str = "wzeros"):
    """
    Construct an ideal single or two-qubit gate.

    Parameters
    ----------
    gates_str: str
        Identifier of the gate, i.e. "X90p".
    index : list
        Indeces of the subspace(s) the gate acts on
    dims : list
        Dimension of the subspace(s)
    proj : str
        Option for projection in the case of more than two-level qubits.

    Returns
    -------
    np.array
        Ideal representation of the gate.

    """
    do_pad_gate = True
    # TODO index for now unused
    kron_list = []
    # for dim in dims:
    #     kron_list.append(np.eye(dim))
    kron_gate = 1
    gate_num = 0
    # Note that the gates_str has to be explicit for all subspaces
    # (and ordered)
    for gate_str in gates_str.split(":"):
        lvls = dims[gate_num]
        if gate_str == "Id":
            gate = Id
        elif gate_str == "X90p":
            gate = X90p
        elif gate_str == "X90m":
            gate = X90m
        elif gate_str == "Xp":
            gate = Xp
        elif gate_str == "Y90p":
            gate = Y90p
        elif gate_str == "Y90m":
            gate = Y90m
        elif gate_str == "Yp":
            gate = Yp
        elif gate_str == "Z90p":
            gate = Z90p
        elif gate_str == "Z90m":
            gate = Z90m
        elif gate_str == "Zp":
            gate = Zp
        elif gate_str == "CNOT":
            lvls2 = dims[gate_num + 1]
            NOT = 1j * perfect_gate("Xp", index, [lvls2], proj)
            C = perfect_gate("Id", index, [lvls2], proj)
            gate = scipy_block_diag(C, NOT)
            # We increase gate_num since CNOT is a two qubit gate
            for ii in range(2, lvls):
                pad_matrix(gate, lvls2, proj)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "CZ":
            lvls2 = dims[gate_num + 1]
            Z = 1j * perfect_gate("Zp", index, [lvls2], proj)
            C = perfect_gate("Id", index, [lvls2], proj)
            gate = scipy_block_diag(C, Z)
            # We increase gate_num since CZ is a two qubit gate
            for ii in range(2, lvls):
                pad_matrix(gate, lvls2, proj)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "CR":
            # TODO: Fix the ideal CNOT construction.
            lvls2 = dims[gate_num + 1]
            Z = 1j * perfect_gate("Zp", index, [lvls], proj)
            X = perfect_gate("Xp", index, [lvls2], proj)
            gate = np.kron(Z, X)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "CR90":
            lvls2 = dims[gate_num + 1]
            RXp = perfect_gate("X90p", index, [lvls2], proj)
            RXm = perfect_gate("X90m", index, [lvls2], proj)
            gate = scipy_block_diag(RXp, RXm)
            for ii in range(2, lvls):
                gate = pad_matrix(gate, lvls2, proj)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "iSWAP":
            # TODO make construction of iSWAP work with superoperator too
            lvls2 = dims[gate_num + 1]
            if lvls == 2 and lvls2 == 2:
                gate = iswap
            elif lvls == 3 and lvls2 == 3:
                gate = iswap3
            gate_num += 1
            do_pad_gate = False
        else:
            print("gate_str must be one of the basic 90 or 180 degree gates.")
            print(
                "'Id','X90p','X90m','Xp','Y90p',",
                "'Y90m','Yp','Z90p','Z90m','Zp', 'CNOT'",
            )
            return None
        if do_pad_gate:
            if proj == "compsub":
                pass
            elif proj == "wzeros":
                zeros = np.zeros([lvls - 2, lvls - 2])
                gate = scipy_block_diag(gate, zeros)
            elif proj == "fulluni":
                identity = np.eye(lvls - 2)
                gate = scipy_block_diag(gate, identity)
        kron_list.append(gate)
        gate_num += 1
    return np_kron_n(kron_list)
Пример #7
0
def perfect_gate(  # noqa
        gates_str: str, index=[0, 1], dims=[2, 2], proj: str = "wzeros"):
    """
    Construct an ideal single or two-qubit gate.

    Parameters
    ----------
    gates_str: str
        Identifier of the gate, i.e. "RX90p".
    index : list
        Indeces of the subspace(s) the gate acts on
    dims : list
        Dimension of the subspace(s)
    proj : str
        Option for projection in the case of more than two-level qubits.

    Returns
    -------
    np.array
        Ideal representation of the gate.

    """
    do_pad_gate = True
    # TODO index for now unused
    kron_list = []
    # for dim in dims:
    #     kron_list.append(np.eye(dim))
    # kron_gate = 1
    gate_num = 0
    # Note that the gates_str has to be explicit for all subspaces
    # (and ordered)
    for gate_str in gates_str.split(":"):
        lvls = dims[gate_num]
        if gate_str == "Id":
            gate = Id
        elif gate_str == "RX90p":
            gate = RX90p
        elif gate_str == "RX90m":
            gate = RX90m
        elif gate_str == "RXp":
            gate = RXp
        elif gate_str == "RY90p":
            gate = RY90p
        elif gate_str == "RY90m":
            gate = RY90m
        elif gate_str == "RYp":
            gate = RYp
        elif gate_str == "RZ90p":
            gate = RZ90p
        elif gate_str == "RZ90m":
            gate = RZ90m
        elif gate_str == "RZp":
            gate = RZp
        elif gate_str == "CNOT":
            raise NotImplementedError(
                "A correct implementation of perfect CNOT is pending, use CRXp now"
            )
        elif gate_str == "CRXp":
            # TODO Should this be CNOT?
            lvls2 = dims[gate_num + 1]
            NOT = 1j * perfect_gate("RXp", index, [lvls2], proj)
            C = perfect_gate("Id", index, [lvls2], proj)
            gate = scipy_block_diag(C, NOT)
            # We increase gate_num since CNOT is a two qubit gate
            for ii in range(2, lvls):
                gate = pad_matrix(gate, lvls2, proj)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "CRZp":
            lvls2 = dims[gate_num + 1]
            Z = 1j * perfect_gate("RZp", index, [lvls2], proj)
            C = perfect_gate("Id", index, [lvls2], proj)
            gate = scipy_block_diag(C, Z)
            # We increase gate_num since CRZp is a two qubit gate
            for ii in range(2, lvls):
                gate = pad_matrix(gate, lvls2, proj)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "CR":
            # TODO: Fix the ideal CNOT construction.
            lvls2 = dims[gate_num + 1]
            Z = 1j * perfect_gate("RZp", index, [lvls], proj)
            X = perfect_gate("RXp", index, [lvls2], proj)
            gate = np.kron(Z, X)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "CR90":
            lvls2 = dims[gate_num + 1]
            RXp_temp = perfect_gate("RX90p", index, [lvls2], proj)
            RXm_temp = perfect_gate("RX90m", index, [lvls2], proj)
            gate = scipy_block_diag(RXp_temp, RXm_temp)
            for ii in range(2, lvls):
                gate = pad_matrix(gate, lvls2, proj)
            gate_num += 1
            do_pad_gate = False
        elif gate_str == "iSWAP":
            # TODO make construction of iSWAP work with superoperator too
            lvls2 = dims[gate_num + 1]
            if lvls == 2 and lvls2 == 2:
                gate = iswap
            elif lvls == 3 and lvls2 == 3:
                gate = iswap3
            gate_num += 1
            do_pad_gate = False
        else:
            raise KeyError(
                "gate_str must be one of the basic 90 or 180 degree gates: 'Id','RX90p','RX90m','RXp','RY90p','RY90m','RYp','RZ90p','RZ90m','RZp', 'CNOT', CRXp, CRZp, CR, CR90, iSWAP"
            )
        if do_pad_gate:
            if proj == "compsub":
                pass
            elif proj == "wzeros":
                zeros = np.zeros([lvls - 2, lvls - 2])
                gate = scipy_block_diag(gate, zeros)
            elif proj == "fulluni":
                identity = np.eye(lvls - 2)
                gate = scipy_block_diag(gate, identity)
            else:
                raise KeyError("proj should be wzeros, compsub or fulluni")
        kron_list.append(gate)
        gate_num += 1
    return np_kron_n(kron_list)