示例#1
0
    def add_memory_qchan(self, edge=None, **kwargs):
        """
        Add a temporal Qchan to the graph to show time-connection of nodes with quantum memory.

        The only difference with add_qchan() is that if either of the node types are Satellites, the airCosts
        will be not be updated since the memory costs are inherent properties of the nodes themselves and
        hence, are time independent.

        :param list edge: Array-like object of two qnodes to be connected
        :param float kwargs: Other costs or qualifying attributes
        :return: None
        """

        # Assert edge is valid
        assert (edge !=
                None), "\'edge\' must be an array-like object of two qnodes"
        assert (len(edge) == 2
                ), "\'edge\' must be an array-like object of two qnodes"

        u = self.getNode(str(edge[0]))
        v = self.getNode(str(edge[1]))

        if u is None:
            u = QNET.Ground(self, name=str(edge[0]))
            self.add_node(u)
        if v is None:
            v = QNET.Ground(self, name=str(edge[1]))
            self.add_node(v)

        cost_vector = QNET.make_cost_vector(self, **kwargs)
        self.add_edge(u, v, **cost_vector)
示例#2
0
    def add_qchan(self, edge=None, key=None, **kwargs):
        """
        Add a Qchan to the graph.

        If either of the node types are Satellites, the costs of the edge will be automatically calculated with
        the Node class method "airCost"

        Parameters
        ----------
        edge: (qnode, qnode)
            A pair of nodes to be connected. Order does not matter.

        key: int
            Optional
            A key specifying a specific edge

        kwargs:
            Key word arguments for the edge cost

        Returns
        -------
        None

        Warnings
        --------
        Additional costs specified in **kwargs that are not in self.cost_vector will not be added. This is because
        such costs do not have an associated range or additive conversion method.
        """
        # Assert edge is valid
        assert (edge !=
                None), "\'edge\' must be an array-like object of two qnodes"
        assert (len(edge) == 2
                ), "\'edge\' must be an array-like object of two qnodes"

        u = self.getNode(str(edge[0]))
        v = self.getNode(str(edge[1]))

        if u is None:
            u = QNET.Ground(self, name=str(edge[0]))
            self.add_node(u)
        if v is None:
            v = QNET.Ground(self, name=str(edge[1]))
            self.add_node(v)

        # If either of the nodes are satellites, get air costs
        if isinstance(u, QNET.Satellite):
            e, f = u.airCost(v)
            kwargs.update({'e': e, 'f': f})
        elif isinstance(v, QNET.Satellite):
            e, f = v.airCost(u)
            kwargs.update({'e': e, 'f': f})

        # Pass it through make_cost_vector to ensure that
        cost_vector = QNET.make_cost_vector(self, **kwargs)
        self.add_edge(u, v, key=key, **cost_vector)
示例#3
0
def regularLatticeGen(x, y, xspacing, yspacing=[0, 0, 0], e=1, f=1):
    '''
    Constructs a 2D Regular Lattice with end Qnodes A and B, and alternating Swapper and Ground nodes in the middle.


    Parameters
    ----------
    x : int
        Number of columns in the regular lattice.
    y : int
        Number of rows in the regular lattice.
    xspacing : 3x1 Array of float
        Distance between two consecutive columns in 2D regular lattice in [x,0,0] format.
    yspacing : 3x1 Array of float
        Distance between two consecutive rows in 2D regular lattice in [0,y,0] format. The default is [0,0,0].
    eVal : float
        Efficiency of a single channel in the regular lattice. The default is 1.
    pxVal : float
        Probability of state not undergoing X-flip in the regular lattice. The default is 0.
    pyVal : float
        Probability of state not undergoing Y-flip in the regular lattice. The default is 0.
    pzVal : float
        Probability of state not undergoing Z-flip in the regular lattice. The default is 0.

    Returns
    -------
    Q : QNET Graph
        A y*x 2D regular lattice.

    '''

    assert (x > 0)
    assert (y > 0)

    if yspacing == [0, 0, 0]:
        yspacing[1] = xspacing[0]

    Q = QNET.Qnet()

    firstNode = QNET.Qnode(Q, name='A', coords=[0, 0, 0])
    lastNode = QNET.Qnode(Q,
                          name='B',
                          coords=np.add(np.multiply(x - 1, xspacing),
                                        np.multiply(y - 1, yspacing)))

    previousNode = QNET.Qnode(Q)
    currentNode = QNET.Qnode(Q)

    ChannelList = []

    # Constructing the nodes in the Regular Lattice
    for i in range(x):
        for j in range(y):

            GroundNode = QNET.Ground(Q,
                                     name=('G(' + str(i + 1) + ',' +
                                           str(j + 1) + ')'),
                                     coords=np.add(np.multiply(i, xspacing),
                                                   np.multiply(j, yspacing)))
            SwapNode = QNET.Swapper(Q,
                                    name=('T(' + str(i + 1) + ',' +
                                          str(j + 1) + ')'),
                                    coords=np.add(np.multiply(i, xspacing),
                                                  np.multiply(j, yspacing)))

            # Swap nodes at odd positions and Ground nodes at even positions in a Regular Lattice
            if x >= 1 and y >= 1:
                if (i + j) % 2 == 0:
                    currentNode = GroundNode
                else:
                    currentNode = SwapNode

            # Linear chain of length 3 exception
            if (x == 3 and y == 1) or (x == 1 and y == 3):
                currentNode = GroundNode

            # 2*2 2D lattice exception
            if x == 2 and y == 2:
                currentNode = GroundNode

            # Initialising the first node as A
            if i == 0 and j == 0:
                currentNode = firstNode

            # Initialising the last node as B
            if i == (x - 1) and j == (y - 1):
                currentNode = lastNode

            Q.add_node(currentNode)

            previousNode = currentNode

    # Constructing the vertical edges in the Regular Lattice
    for i in range(x):
        previousNode = list(Q.nodes)[i * y]
        for j in range(y - 1):
            currentNode = list(Q.nodes)[j + 1 + (i * y)]
            ChannelList.append({
                'edge': (previousNode.name, currentNode.name),
                'e': e,
                'f': f
            })
            previousNode = currentNode

    # Constructing the horizontal edges in the Regular Lattice
    for j in range(y):
        previousNode = list(Q.nodes)[j]
        for i in range(x - 1):
            currentNode = list(Q.nodes)[j + (i + 1) * y]
            ChannelList.append({
                'edge': (previousNode.name, currentNode.name),
                'e': e,
                'f': f
            })
            previousNode = currentNode

    Q.add_qchans_from(ChannelList)
    # Q.print_qchans()

    return Q
示例#4
0
def altLinSatGen(n, spacing, e=1, f=1, startTime=0, Line1='', Line2='', *args):
    '''
    Constructs a linear chain with end Qnodes A and B, and alternating Swapper and Ground nodes in the middle.

    A satellite is connected to end nodes A and B, and all swapper nodes.

    Parameters
    ----------
    n : int
        Total number of nodes in the chain, including end nodes A and B.
    spacing : Array of float
        Distance between two consecutive nodes in [x,y,z] format.
    eVal : float
        Efficiency of a single channel in the regular lattice. The default is 1.
    pxVal : float
        Probability of state not undergoing X-flip in the regular lattice. The default is 0.
    pyVal : float
        Probability of state not undergoing Y-flip in the regular lattice. The default is 0.
    pzVal : float
        Probability of state not undergoing Z-flip in the regular lattice. The default is 0.
    startTime : int
        Time in seconds from now (current time) starting which the satellite should be tracked. The default is 0.
    Line1 : String
        Line 1 of satellite TLE. The deault is ''.
    Line2 : String
        Line 2 of satellite TLE. The deault is ''.

    Returns
    -------
    Q : QNET Graph
        A linear chain of length n consisting of alternating Bell pair generator and swappers.
        End nodes A and B, and all swapper nodes are connected to a satellite.

    '''

    Q = QNET.Qnet()

    if n > 0:
        firstNode = QNET.Qnode(Q, name='A', coords=spacing)
        Q.add_node(firstNode)

    previousNode = QNET.Qnode(Q)
    currentNode = QNET.Qnode(Q)

    ChannelList = []

    if n > 2:
        for i in range(n - 2):
            GroundNode = QNET.Ground(Q,
                                     name=('G' + str(i + 1)),
                                     coords=np.multiply(i + 2, spacing))
            SwapNode = QNET.Swapper(Q,
                                    name=('T' + str(i + 1)),
                                    coords=np.multiply(i + 2, spacing))

            if n > 3:
                if (i) % 2 == 0:
                    currentNode = SwapNode
                else:
                    currentNode = GroundNode
            else:
                currentNode = GroundNode

            Q.add_node(currentNode)

            if i > 0:
                ChannelList.append({
                    'edge': (previousNode.name, currentNode.name),
                    'e':
                    e,
                    'f':
                    f
                })

            previousNode = currentNode

    if n > 1:
        lastNode = QNET.Qnode(Q, name='B', coords=np.multiply(n, spacing))
        Q.add_node(lastNode)

        ChannelList.append({
            'edge': (firstNode.name, list(Q.nodes)[1].name),
            'e': e,
            'f': f
        })
        ChannelList.append({
            'edge': (list(Q.nodes)[n - 2].name, lastNode.name),
            'e': e,
            'f': f
        })

    S = QNET.Satellite(Q,
                       name='S',
                       t=startTime,
                       line1=Line1,
                       line2=Line2,
                       cartesian=False)
    Q.add_node(S)

    nodeList = Q.nodes()
    for node in nodeList:
        if type(node) != QNET.Ground and type(node) != QNET.Satellite:
            ChannelList.append({'edge': (node.name, S.name)})

    Q.add_qchans_from(ChannelList)

    return Q
示例#5
0
def altLinGen(n, spacing, e=1, f=1):
    '''
    Constructs a linear chain with end Qnodes A and B, and alternating Swapper and Ground nodes in the middle.

    Parameters
    ----------
    n : int
        Total number of nodes in the chain, including end nodes A and B.
    spacing : Array of float
        Distance between two consecutive nodes in [x,y,z] format.
    e : float
        Efficiency of a single channel in the regular lattice. The default is 1.

    Returns
    -------
    Q : QNET Graph
        A linear chain of length n consisting of alternating Bell pair generator and swappers.

    '''

    Q = QNET.Qnet()

    if n > 0:
        firstNode = QNET.Qnode(Q, name='A', coords=spacing)
        Q.add_node(firstNode)

    previousNode = QNET.Qnode(Q)
    currentNode = QNET.Qnode(Q)

    ChannelList = []

    if n > 2:
        for i in range(n - 2):
            GroundNode = QNET.Ground(Q,
                                     name=('G' + str(i + 1)),
                                     coords=np.multiply(i + 2, spacing))
            SwapNode = QNET.Swapper(Q,
                                    name=('T' + str(i + 1)),
                                    coords=np.multiply(i + 2, spacing))

            if n > 3:
                if (i) % 2 == 0:
                    currentNode = SwapNode
                else:
                    currentNode = GroundNode
            else:
                currentNode = GroundNode

            Q.add_node(currentNode)

            if i > 0:
                ChannelList.append({
                    'edge': (previousNode.name, currentNode.name),
                    'e':
                    e,
                    'f':
                    f
                })

            previousNode = currentNode

    if n > 1:
        lastNode = QNET.Qnode(Q, name='B', coords=np.multiply(n, spacing))
        Q.add_node(lastNode)

        ChannelList.append({
            'edge': (firstNode.name, list(Q.nodes)[1].name),
            'e': e,
            'f': f
        })
        ChannelList.append({
            'edge': (list(Q.nodes)[n - 2].name, lastNode.name),
            'e': e,
            'f': f
        })

    Q.add_qchans_from(ChannelList)

    return Q