示例#1
0
def test_fidelity_invalid_dim():
    """Tests for invalid dim."""
    rho = np.array([[1 / 2, 0, 0, 1 / 2], [0, 0, 0, 0], [0, 0, 0, 0],
                    [1 / 2, 0, 0, 1 / 2]])
    sigma = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    with np.testing.assert_raises(ValueError):
        fidelity(rho, sigma)
示例#2
0
def test_fidelity_non_identical_states_2():
    """Test the fidelity between two non-identical states."""
    e_0, e_1 = basis(2, 0), basis(2, 1)
    rho = 3 / 4 * e_0 * e_0.conj().T + 1 / 4 * e_1 * e_1.conj().T
    sigma = 1 / 8 * e_0 * e_0.conj().T + 7 / 8 * e_1 * e_1.conj().T
    np.testing.assert_equal(
        np.isclose(fidelity(rho, sigma), 0.774, rtol=1e-03), True)
示例#3
0
def test_sub_fidelity_lower_bound_2():
    """Test sub_fidelity is lower bound on fidelity for rho and pi."""
    e_0, e_1 = basis(2, 0), basis(2, 1)
    rho = 3 / 4 * e_0 * e_0.conj().T + 1 / 4 * e_1 * e_1.conj().T
    sigma = 1 / 8 * e_0 * e_0.conj().T + 7 / 8 * e_1 * e_1.conj().T

    res = sub_fidelity(rho, sigma)
    np.testing.assert_array_less(res, fidelity(rho, sigma))
示例#4
0
def test_fidelity_default():
    """Test fidelity default arguments."""
    rho = np.array([[1 / 2, 0, 0, 1 / 2], [0, 0, 0, 0], [0, 0, 0, 0],
                    [1 / 2, 0, 0, 1 / 2]])
    sigma = rho

    res = fidelity(rho, sigma)
    np.testing.assert_equal(np.isclose(res, 1), True)
示例#5
0
def test_fidelity_cvx():
    """Test fidelity for cvx objects."""
    rho = cvxpy.bmat([[1 / 2, 0, 0, 1 / 2], [0, 0, 0, 0], [0, 0, 0, 0],
                      [1 / 2, 0, 0, 1 / 2]])
    sigma = rho

    res = fidelity(rho, sigma)
    np.testing.assert_equal(np.isclose(res, 1), True)
示例#6
0
def bures_distance(rho_1: np.ndarray, rho_2: np.ndarray, decimals: int = 10) -> float:
    r"""
    Compute the Bures distance of two density matrices [WikBures]_.

    Calculate the Bures distance between two density matrices :code:`rho_1` and :code:`rho_2`
    defined by:

    .. math::
        \sqrt{2 (1 - F(\rho_1, \rho_2))},

    where :math:`F(\cdot)` denotes the fidelity between :math:`\rho_1` and :math:`\rho_2`. The
    return is a value between :math:`0` and :math:`\sqrt{2}`,with :math:`0` corresponding to
    matrices: :code:`rho_1 = rho_2` and :math:`\sqrt{2}` corresponding to the case: :code:`rho_1`
    and :code:`rho_2` with orthogonal support.

    Examples
    ==========

    Consider the following Bell state

    .. math::
        u = \frac{1}{\sqrt{2}} \left( |00 \rangle + |11 \rangle \right) \in \mathcal{X}.

    The corresponding density matrix of :math:`u` may be calculated by:

    .. math::
        \rho = u u^* = \frac{1}{2} \begin{pmatrix}
                         1 & 0 & 0 & 1 \\
                         0 & 0 & 0 & 0 \\
                         0 & 0 & 0 & 0 \\
                         1 & 0 & 0 & 1
                       \end{pmatrix} \in \text{D}(\mathcal{X}).

    In the event where we calculate the Bures distance between states that are identical, we
    should obtain the value of :math:`0`. This can be observed in :code:`toqito` as follows.

    >>> from toqito.state_metrics import bures_distance
    >>> import numpy as np
    >>> rho = 1 / 2 * np.array(
    >>>     [[1, 0, 0, 1],
    >>>      [0, 0, 0, 0],
    >>>      [0, 0, 0, 0],
    >>>      [1, 0, 0, 1]]
    >>> )
    >>> sigma = rho
    >>> bures_distance(rho, sigma)
    0

    References
    ==========
    .. [WikBures] Wikipedia: Bures metric
        https://en.wikipedia.org/wiki/Bures_metric

    :param rho_1: Density operator.
    :param rho_2: Density operator.
    :param decimals: Number of decimal places to round to (default 10).
    :return: The Bures distance between :code:`rho_1` and :code:`rho_2`.
    """
    # Perform some error checking.
    if not np.all(rho_1.shape == rho_2.shape):
        raise ValueError("InvalidDim: `rho_1` and `rho_2` must be matrices of the same size.")
    # Round fidelity to only 10 decimals to avoid error when :code:`rho_1 = rho_2`.
    return np.sqrt(2.0 * (1.0 - np.round(fidelity(rho_1, rho_2), decimals)))
def graph(nbPlayers,
          sym,
          delta=0.01,
          start=0,
          end=2,
          seeSawRepeatLow=10,
          seeSawRepeatHigh=3,
          treshold=0.4,
          dimension=2):

    operatorsP1 = [0, 1, 2]
    operatorsP2 = [0, 3, 4]
    operatorsP3 = [0, 5, 6]
    operatorsP4 = [0, 7, 8]
    operatorsP5 = [0, 9, 10]
    P3 = [operatorsP1, operatorsP2, operatorsP3]
    P5 = [operatorsP1, operatorsP2, operatorsP3, operatorsP4, operatorsP5]
    if nbPlayers == 5: P = P5
    else: P = P3
    points = int(np.round((end - start) / delta)) + 1
    x = np.linspace(start, end, points)

    paramV0 = cp.Parameter()
    v1 = 2 - paramV0

    game = Game(nbPlayers, paramV0, v1, sym)
    prob = Hierarchie(game, P)

    print("GraphState & deviated strat & classical strat")
    QSW_GraphState = []
    SW_classical = []
    # QSW_dev = []
    xGraphState = []
    xClassical = []
    # xDev = []

    for idx, v0 in enumerate(x):
        print("iteration {}".format(idx))
        game.v0.value = v0

        SWGraph = quantumStrategies.graphStateStrategy(game)
        if SWGraph is not None:
            QSW_GraphState.append(SWGraph)
            xGraphState.append(game.v0.value)

        SW_classical.append(bestClassicalStrategy(game))
        print(bestClassicalStrategy(game))
        xClassical.append(game.v0.value)

        # # QSW for deviated strat
        # if quantumStrategies.devStratIsNashEq(game):
        #     dev = quantumStrategies.QSW(game, quantumStrategies.optimalTheta(game))
        #     xDev.append(v0)
        #     QSW_dev.append(dev)

    # try:
    #     QSW_NotNash = readFile('data/{}Players_{}Points_Sym{}_HierarchieNoNash.txt'.format(nbPlayers, points, sym))
    #     print("Chargement hierarchie sans contrainte de Nash")

    # except:
    #     print("Hierarchie Sans contrainte de Nash")
    #     QSW_NotNash = []
    #     for idx, v0 in enumerate(x):
    #         print("iteration {}".format(idx))
    #         paramV0.value = v0
    #         qsw = prob.optimize(verbose=False, warmStart=True, solver="MOSEK")
    #         QSW_NotNash.append(qsw)

    #     with open('data/{}Players_{}Points_Sym{}_HierarchieNoNash.txt'.format(nbPlayers, points, sym), 'w') as f:
    #         for item in QSW_NotNash:
    #             f.write("%s\n" % item)

    try:
        QSW_Nash = readFile(
            'data/{}Players_{}Points_Sym{}_HierarchieNash.txt'.format(
                nbPlayers, points, sym))
        print("Chargement hierarchie avec contrainte de Nash")

    except:
        print("Hierarchie avec contrainte de Nash")
        QSW_Nash = []

        prob.setNashEqConstraints()

        for idx, v0 in enumerate(x):
            print("iteration {}".format(idx))
            paramV0.value = v0
            qsw = prob.optimize(verbose=False, warmStart=True, solver="MOSEK")
            QSW_Nash.append(qsw)

        with open(
                'data/{}Players_{}Points_Sym{}_HierarchieNash.txt'.format(
                    nbPlayers, points, sym), 'w') as f:
            for item in QSW_Nash:
                f.write("%s\n" % item)

    try:
        QSW_SeeSaw = readFile(
            'data/{}Players_{}Points_Sym{}_SeeSaw.txt'.format(
                nbPlayers, points, sym))
        Winrate_SeeSaw = readFile(
            'data/{}Players_{}Points_Sym{}_SeeSaw_Winrate.txt'.format(
                nbPlayers, points, sym))
        print("Chargement SeeSaw")

    except:
        print("SeeSaw")
        graphStateMatrix = graphState(nbPlayers)
        game = Game(nbPlayers, 0, 0, sym)

        lastGraphStateInit = (graphStatePOVMS(nbPlayers), graphStateMatrix)
        lastInit = (graphStatePOVMS(nbPlayers), graphStateMatrix)

        QSW_SeeSaw = []
        Winrate_SeeSaw = []

        #If one of them exist, we remove the file.
        if os.path.exists('data/{}Players_{}Points_Sym{}_SeeSaw.txt'.format(
                nbPlayers, points, sym)):
            os.remove('data/{}Players_{}Points_Sym{}_SeeSaw.txt'.format(
                nbPlayers, points, sym))

        if os.path.exists(
                'data/{}Players_{}Points_Sym{}_SeeSaw_Winrate.txt'.format(
                    nbPlayers, points, sym)):
            os.remove(
                'data/{}Players_{}Points_Sym{}_SeeSaw_Winrate.txt'.format(
                    nbPlayers, points, sym))

        prevMax = 1

        for it, v0 in enumerate(reversed(x)):
            game.v0 = v0
            game.v1 = 2 - v0

            print("\nGlobal Iteration {} v0 {}".format(it, v0))
            maxQsw = 0

            nbRepeat = seeSawRepeatLow * (v0 < treshold) + seeSawRepeatHigh * (
                v0 >= treshold)
            #On pourrait couper si on est proche de la borne de la hierarchie

            for r in range(nbRepeat):
                print("nbRepeat {}".format(r))

                if r == 0:
                    # Following strat with POVMs near graphstate ones
                    qsw, seeSaw = fullSeeSaw(game,
                                             dimension=dimension,
                                             init=lastGraphStateInit)
                    lastGraphStateInit = (seeSaw.POVM_Dict, seeSaw.genRho())
                if r == 1:
                    #Takes best init for last value of v0
                    qsw, seeSaw = fullSeeSaw(game,
                                             dimension=dimension,
                                             init=lastInit)

                if r == 2:
                    initClassical = (classicalStratPOVM(game),
                                     genRhoClassic(game.nbPlayers))
                    qsw, seeSaw = fullSeeSaw(game,
                                             dimension=dimension,
                                             init=initClassical)

                else:
                    #Random init
                    init = (seeSaw.genPOVMs(), seeSaw.genRho())
                    qsw, seeSaw = fullSeeSaw(game,
                                             dimension=dimension,
                                             init=init)

                maxQsw = max(maxQsw, qsw)

                ###UNCOMMENT TO HAVE RANDOM INIT.
                #First repetition take best POVMs for last V0 value. After it takes random POVMs.

                # If it's the best result we encoutered yet for this v0's value, we save the strategy.
                if maxQsw == qsw:
                    bestSeeSaw = seeSaw
                    maxDiff = abs(prevMax - maxQsw)

            # If huge diff, we do another cyle on a strategy which as already been optimized.
            # Otherwise we have "holes" where the qsw collapse when we shift of strategy class
            # (i.e when we go from quantum strat to classicals)
            iter = 0
            while maxDiff >= 0.05 and v0 != 0 and iter <= 1:
                print("another cycle")
                #
                #Best of last iteration
                if iter == 0:
                    init = (bestSeeSaw.genPOVMs(), seeSaw.genRho())
                    qsw, seeSaw = fullSeeSaw(game,
                                             dimension=dimension,
                                             init=init)
#
#                #GraphState povms
                if iter == 1:
                    qsw, seeSaw = fullSeeSaw(game,
                                             dimension=dimension,
                                             init=lastGraphStateInit)
#
#                else:
#                    init = (seeSaw.genPOVMs(), seeSaw.genRho())
#                    qsw, seeSaw = fullSeeSaw(nbPlayers, v0, v1, init=init,  sym=sym)
#                    init = (seeSaw.POVM_Dict, seeSaw.genRho())
#                    qsw, seeSaw = fullSeeSaw(nbPlayers, v0, v1, init=init,  sym=sym)
#
#
                maxQsw = max(maxQsw, qsw)

                if maxQsw == qsw:
                    bestSeeSaw = seeSaw
                    maxDiff = abs(prevMax - maxQsw)
#
                iter += 1


#
            prevMax = maxQsw
            QSW_SeeSaw.append(maxQsw)
            Winrate_SeeSaw.append(bestSeeSaw.winrate)

            lastInit = (
                bestSeeSaw.POVM_Dict, seeSaw.genRho()
            )  #If we keep old rho, we often (always ?) stay on the same equilibrium.

            printPOVMS(bestSeeSaw)
            print("Rho:")
            print(bestSeeSaw.rho)
            print("Trace of rho squared:",
                  np.trace(np.dot(bestSeeSaw.rho, bestSeeSaw.rho)))
            print("Fidelity with graphState",
                  fidelity(bestSeeSaw.rho, graphStateMatrix))

        with open(
                'data/{}Players_{}Points_Sym{}_SeeSaw.txt'.format(
                    nbPlayers, points, sym), 'w') as f:
            for item in QSW_SeeSaw:
                f.write("%s\n" % item)

        with open(
                'data/{}Players_{}Points_Sym{}_SeeSaw_Winrate.txt'.format(
                    nbPlayers, points, sym), 'w') as f:
            for item in Winrate_SeeSaw:
                f.write("%s\n" % item)

    fig, axs = plt.subplots(1, constrained_layout=True, figsize=(10, 10))
    fig.suptitle("Graph for {} players with {} points, sym: {}".format(
        nbPlayers, points, sym))

    axs.plot([v / 2 for v in xGraphState], QSW_GraphState, label="GraphState")
    axs.plot(x / 2, QSW_Nash, label="HierarchieNash")
    # axs.plot(x/2, QSW_NotNash, label="HierarchieNotNash")
    axs.plot(x / 2, list(reversed(QSW_SeeSaw)), label="SeeSaw")
    # axs.plot(x, list(reversed(Winrate_SeeSaw)), label="Winrate Seesaw")
    axs.plot([v / 2 for v in xClassical],
             SW_classical,
             label="SW best classical strat")
    # axs.plot([v/2 for v in xDev], QSW_dev, label="SW of deviated strat")

    axs.set_title("Quantum social welfare")
    axs.set_xlabel("v0/(v0+v1)")
    axs.set_ylabel("QSW")
    axs.set_ylim([0, 2])
    axs.legend(loc="upper right")

    plt.show()