Esempio n. 1
0
def Demo():

    #__BLOOD_BANK__##################################################

    # Define Network and Domain
    Network = CreateRandomNetwork(nC=2, nB=2, nD=2, nR=2, seed=0)
    Domain = BloodBank(Network=Network, alpha=2)

    # Set Method
    Method = CashKarp(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-6)

    # Initialize Starting Point
    Start = np.zeros(Domain.Dim)

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000, Tols=[(Domain.gap_rplus, 1e-6 * gap_0)])
    Repo = Reporting(
        Requests=[Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections'])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    BloodBank_Results = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, BloodBank_Results, Method, toc)
def infinity_loss(Domain, Start):
    # Set Method
    Method = HeunEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-3)

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000,
                       Tols=[(Domain.gap_rplus, 1e-6 * gap_0)],
                       verbose=False)
    Repo = Reporting(Requests=[Domain.gap_rplus, 'Data', Domain.F])
    Misc = Miscellaneous(Timer=False)
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Start Solver
    SOI_Results = Solve(Start, Method, Domain, Options)

    # Record X_Star
    Data = SOI_Results.PermStorage['Data']
    dx = np.diff(Data, axis=0)
    F = SOI_Results.PermStorage[Domain.F][:-1]

    return -np.sum(F * dx)
Esempio n. 3
0
def Demo():

    # __MACHINE_LEARNING_NETWORK____#################################################

    # Define Domain
    Network = CreateRandomNetwork()
    Domain = MLN(Network)

    # Set Method
    Method = Euler(Domain=Domain,FixStep=True,P=BoxProjection(lo=Domain.los,hi=Domain.his))

    # Set Options
    Term = Termination(MaxIter=500)
    Repo = Reporting(Requests=['Step', 'F Evaluations',
                               'Projections','Data'])
    Misc = Miscellaneous()
    Init = Initialization(Step=-1e-3)
    Options = DescentOptions(Init,Term,Repo,Misc)

    # Initialize Starting Point
    Start = np.random.rand(Domain.dim)*(Domain.his-Domain.los) + Domain.los
    Start[20:22] = [-.5,.5]
    Start[22:24] = [.5,.5]
    Start[24:26] = [.5,.5]
    Start[26:28] = [1.,0.]
    Start[28:32] = [-.5,-.25,-.75,-.5]

    # Print Stats
    PrintSimStats(Domain,Method,Options)

    # Start Solver
    tic = time.time()
    MLN_Results = Solve(Start,Method,Domain,Options)  # Use same Start
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options,MLN_Results,Method,toc)

    ########################################################
    # Animate Network
    ########################################################

    # Construct MP4 Writer
    fps = 5
    FFMpegWriter = animation.writers['ffmpeg']
    metadata = dict(title='MLN', artist='Matplotlib')
    writer = FFMpegWriter(fps=fps, metadata=metadata)

    # Collect Frames
    Frames = MLN_Results.PermStorage['Data'][::fps]

    # Save Animation to File
    fig, ax = plt.subplots()
    MLN_ani = animation.FuncAnimation(fig, Domain.UpdateVisual,
                                      init_func=Domain.InitVisual,
                                      frames=len(Frames),
                                      fargs=(ax, Frames))
    MLN_ani.save('MLN.mp4', writer=writer)
Esempio n. 4
0
def Demo():

    #__CLOUD_SERVICES__##################################################

    # Define Network and Domain
    Network = CreateNetworkExample(ex=5)
    Domain = CloudServices(Network=Network, gap_alpha=2)

    # Set Method
    eps = 1e-2
    Method = HeunEuler_LEGS(Domain=Domain, P=BoxProjection(lo=eps), Delta0=1e0)

    # Initialize Starting Point
    Start = np.ones(Domain.Dim)

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-3)
    Term = Termination(MaxIter=1e5, Tols=[(Domain.gap_rplus, 1e-12 * gap_0)])
    Repo = Reporting(Requests=[
        Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections', 'Data',
        Domain.eig_stats, 'Lyapunov'
    ])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    CloudServices_Results = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, CloudServices_Results, Method, toc)

    x = CloudServices_Results.PermStorage['Data'][-1]
    print('p,q,Q,pi,Nash?')
    print(x[:Domain.Dim // 2])
    print(x[Domain.Dim // 2:])
    print(Domain.Demand(x)[0])
    print(Domain.CloudProfits(x))
    print(all(Domain.Nash(x)[0]))
Esempio n. 5
0
def Demo():

    #__SUPPLY_CHAIN__##################################################

    # Define Network and Domain
    Network = CreateRandomNetwork(I=2, Nm=2, Nd=2, Nr=1, seed=0)
    Domain = SupplyChain(Network=Network, alpha=2)

    # Set Method
    Method = CashKarp(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-5)

    # Initialize Starting Point
    x = 10 * np.ones(np.product(Domain.x_shape))
    gam = np.ones(np.sum([np.product(g) for g in Domain.gam_shapes]))
    lam = np.zeros(np.sum([np.product(l) for l in Domain.lam_shapes]))
    Start = np.concatenate((x, gam, lam))

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000, Tols=[(Domain.gap_rplus, 1e-3 * gap_0)])
    Repo = Reporting(Requests=[
        Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections', 'Data'
    ])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    SupplyChain_Results = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, SupplyChain_Results, Method, toc)
Esempio n. 6
0
def score_mixturemean(train, test, mask, step=-1e-3, iters=100):
    # Define Domain
    Domain = MixtureMean(Data=train)

    # Set Method
    Method = Euler(Domain=Domain, P=BoxProjection(lo=0., hi=1.))
    # Method = Euler(Domain=Domain,P=EntropicProjection())
    # Method = HeunEuler(Domain=Domain,P=EntropicProjection(),Delta0=1e-5,
    #                    MinStep=-1e-1,MaxStep=-1e-4)

    # Initialize Starting Point
    # Start = np.array([.452,.548])
    Start = np.array([.452])

    # Set Options
    Init = Initialization(Step=step)
    Term = Termination(MaxIter=iters)
    Repo = Reporting(Requests=['Step', 'F Evaluations'])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    Results = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, Results, Method, toc)

    # Retrieve result
    parameters = np.asarray(Results.TempStorage['Data'][-1])
    pred = Domain.predict(parameters)

    return rmse(pred, test, mask)
Esempio n. 7
0
def Demo():

    #__LQ_GAN__##############################################

    # Interpolation between F and RipCurl should probably be nonlinear
    # in terms of L2 norms of matrices if the norms essentially represent the largest eigenvalues

    # what's an example of a pseudomonotone field? stretch vertically linearly a bit? quasimonotone?

    # the extragradient method uses the same step size for the first and second step, as the step size goes
    # to zero, extragradient asymptotes to the projection method
    # modified extragradient methods use different step sizes. if we keep the first step size fixed to some
    # positive value and shrink the second, the dynamics of extragradient remain as desired
    # this is essentially what HE_PhaseSpace is showing
    # HE and HE_PhaseSpace are designed to "simulate" a trajectory - they do not actually change the effective
    # dynamics of the vector field

    # Define Network and Domain
    Domain = LQ(sig=1)

    # Set Method
    lo = [-np.inf, 1e-2]
    # Method = Euler(Domain=Domain,FixStep=True,P=BoxProjection(lo=lo))
    # Method = EG(Domain=Domain,FixStep=True,P=BoxProjection(lo=lo))
    # Method = HeunEuler(Domain=Domain,Delta0=1e-4,P=BoxProjection(lo=lo))
    Method = HeunEuler_PhaseSpace(Domain=Domain,
                                  Delta0=1e-2,
                                  P=BoxProjection(lo=lo))

    # Initialize Starting Point
    # Start = np.random.rand(Domain.Dim)
    scale = 30
    Start = np.array([50., 50.])
    xoff = 0
    yoff = 0
    # no difference between eigenvalues of J at [1.,3.5] and eigenvalues of an outward spiral: a = np.array([[-1,6.92],[-6.92,-1]])
    j = Domain.J(Start)
    print('original evs')
    print(np.linalg.eigvals(j))
    print(np.linalg.eigvals(j + j.T))
    f = Domain.F(Start)
    jsym = j + j.T
    # print(f.dot(jsym.dot(f)))
    tf = Domain.TF(Start)
    print('tf')
    print(tf)
    print(np.linalg.eigvals(tf))
    jrc = Domain.JRipCurl(Start)
    print('jrc')
    print(jrc)
    print(0.5 * (jrc + jrc.T))
    print(np.linalg.eigvals(jrc + jrc.T))
    jreg = Domain.JReg(Start)
    print('jreg')
    print(jreg)
    print(0.5 * (jreg + jreg.T))
    print(np.linalg.eigvals(jreg + jreg.T))
    jasy = j - j.T
    print('exact')
    print(0.5 * np.dot(jasy.T, jasy))

    for gam in np.linspace(0, 1, 20):
        # print(Domain.JRegEV(Start,gam))
        print(Domain.JRCEV(Start, gam))

    jap = approx_jacobian(Domain.F, Start)
    print(jap)
    print(np.linalg.eigvals(0.5 * (jap + jap.T)))

    y = np.array([0, 1])
    x = np.array([1, 1e-1])
    pre = np.dot(Domain.F(y), x - y)
    post = np.dot(Domain.F(x), x - y)
    print(pre)
    print(post)

    d = 2
    W2 = Domain.sym(np.random.rand(d, d))
    w1 = np.random.rand(d)
    A = np.tril(np.random.rand(d, d))
    A[range(d), range(d)] = np.clip(A[range(d), range(d)], 1e-6, np.inf)
    b = np.random.rand(d)
    dmult = np.hstack([W2.flatten(), w1, A.flatten(), b])
    jmult = Domain.Jmult(dmult)
    jskew = (jmult - jmult.T)
    print(np.linalg.matrix_rank(jskew, tol=1e-16))

    W2 = Domain.sym(np.ones((d, d)))
    w1 = np.ones(d)
    A = np.tril(np.ones((d, d)))
    A[range(d), range(d)] = np.clip(A[range(d), range(d)], 0, np.inf)
    b = np.ones(d)
    dmult = np.hstack([W2.flatten(), w1, A.flatten(), b])
    jmult = Domain.Jmult(dmult)
    jskew = (jmult - jmult.T)
    print(np.linalg.matrix_rank(jskew))

    W2 = Domain.sym(np.zeros((d, d)))
    w1 = np.zeros(d)
    A = np.tril(np.ones((d, d)))
    A[range(d), range(d)] = np.clip(A[range(d), range(d)], 0, np.inf)
    b = np.zeros(d)
    dmult = np.hstack([W2.flatten(), w1, A.flatten(), b])
    jmult = Domain.Jmult(dmult)
    jskew = (jmult - jmult.T)
    print(np.linalg.matrix_rank(jskew))

    np.set_printoptions(linewidth=200)

    s = (d**2 + d) // 2
    jskewblock = jskew[:s, s + d:s + d + s]

    embed()

    # Set Options
    Init = Initialization(Step=-1e-5)
    Term = Termination(MaxIter=1000, Tols=[(Domain.dist, 1e-4)])
    Repo = Reporting(
        Requests=['Step', 'F Evaluations', 'Projections', 'Data', Domain.dist])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    LQ_Results = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, LQ_Results, Method, toc)

    data = np.array(LQ_Results.PermStorage['Data'])

    X, Y = np.meshgrid(
        np.arange(-2 * scale + xoff, 2 * scale + xoff, .2 * scale),
        np.arange(1e-2 + yoff, 4 * scale + yoff, .2 * scale))
    U = np.zeros_like(X)
    V = np.zeros_like(Y)
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            vec = -Domain.F([X[i, j], Y[i, j]])
            U[i, j] = vec[0]
            V[i, j] = vec[1]

    fig = plt.figure()
    ax = fig.add_subplot(111)
    Q = plt.quiver(X[::3, ::3],
                   Y[::3, ::3],
                   U[::3, ::3],
                   V[::3, ::3],
                   pivot='mid',
                   units='inches')
    ax.plot(data[:, 0], data[:, 1], '-r')
    ax.plot([data[0, 0]], [data[0, 1]], 'k*')
    ax.plot([data[-1, 0]], [data[-1, 1]], 'b*')
    ax.set_xlim([-2 * scale + xoff, 2 * scale + xoff])
    ax.set_ylim([-.1 * scale + yoff, 4 * scale + yoff])
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    # plt.show()
    # plt.savefig('original.png')
    # plt.savefig('EGoriginal.png')
    # plt.savefig('RipCurl.png')
    # plt.savefig('RipCurl2.png')
    # plt.savefig('EG.png')
    # plt.savefig('GReg.png')
    plt.savefig('Testing.png')
def Demo():

    #__SERVICE_ORIENTED_INTERNET__##############################################
    N = 10  # number of possible maps
    T = 1000  # number of time steps
    eta = 1e-3  # learning rate

    print('Creating Domains')

    # Define Domains and Compute Equilbria
    Domains = []
    X_Stars = []
    CurlBounds = []
    n = 0
    while len(Domains) < N:
        # Create Domain
        Network = CreateRandomNetwork(m=3, n=2, o=2, seed=None)
        Domain = SOI(Network=Network, alpha=2)

        # Initialize Starting Point
        Start = np.zeros(Domain.Dim)

        # Assert PD
        J = approx_jacobian(Domain.F, Start)
        eigs = np.linalg.eigvals(J + J.T)
        if not np.all(eigs > 0):
            continue
        _J = approx_jacobian(Domain.F, Start + 0.5)
        assert np.allclose(J, _J,
                           atol=1e-5)  # assert J is constant (unique for SOI)

        # Record Domain
        Domains += [Domain]

        # Calculate Initial Gap
        gap_0 = Domain.gap_rplus(Start)

        # Calculate Curl Bound
        CurlBounds += [
            np.sqrt(8) *
            svds(J, k=1, which='LM', return_singular_vectors=False).item()
        ]

        # Set Method
        Method = HeunEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-3)

        # Set Options
        Init = Initialization(Step=-1e-10)
        Term = Termination(MaxIter=25000,
                           Tols=[(Domain.gap_rplus, 1e-6 * gap_0)])
        Repo = Reporting(Requests=[Domain.gap_rplus])
        Misc = Miscellaneous()
        Options = DescentOptions(Init, Term, Repo, Misc)

        # Print Stats
        PrintSimStats(Domain, Method, Options)

        # Start Solver
        tic = time.time()
        SOI_Results = Solve(Start, Method, Domain, Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options, SOI_Results, Method, toc)

        # Record X_Star
        X_Star = SOI_Results.TempStorage['Data'][-1]
        X_Stars += [X_Star]
        n += 1
    X_Stars = np.asarray(X_Stars)

    print('Starting Online Learning')

    # Set First Prediction
    X = np.zeros(X_Stars.shape[1])

    # Select First Domain
    idx = np.random.choice(len(Domains))

    # Domain Sequence
    idx_seq = []
    X_seq = []
    F_seq = []

    ts = range(T)
    for t in ts:
        print('t = ' + str(t), end='\r')
        # record prediction
        X_seq += [X]
        # record domain
        idx_seq += [idx]
        # retrieve domain
        Domain = Domains[idx]
        # record F
        FX = Domain.F(X)
        F_seq += [FX]
        # update prediction
        X = BoxProjection(lo=0).P(X, -eta, FX)
        # update domain
        idx = np.random.choice(len(Domains))

    print('Computing Optimal Strategy')

    weights = np.bincount(idx_seq, minlength=len(Domains)) / len(idx_seq)
    print('Weights: ', weights)

    # Compute Equilibrium of Average Domain
    Domain = AverageDomains(Domains, weights=weights)

    # Set Method
    Method = HeunEuler_PhaseSpace(Domain=Domain,
                                  P=BoxProjection(lo=0),
                                  Delta0=1e-5)

    # Initialize Starting Point
    Start = np.zeros(Domain.Dim)

    # Assert PSD - sum of PSD is PSD doesn't hurt to check
    J = approx_jacobian(Domain.F, Start)
    eigs = np.linalg.eigvals(J + J.T)
    assert np.all(eigs > 0)
    sigma = min(eigs)

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000, Tols=[(Domain.gap_rplus, 1e-10 * gap_0)])
    Repo = Reporting(Requests=[Domain.gap_rplus])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    SOI_Results = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, SOI_Results, Method, toc)

    print('Computing Regrets')

    # Record X_Opt
    X_Opt = SOI_Results.TempStorage['Data'][-1]

    # Record constants for bounds
    L = np.sqrt(np.mean(np.linalg.norm(F_seq, axis=1)**2.))
    # B = np.linalg.norm(X_Opt)
    B = 2. * np.max(np.linalg.norm(X_Stars, axis=1))
    eta_opt = B / (L * np.sqrt(2 * T))
    bound_opt = B * L * np.sqrt(2 * T)
    reg_bound = (B**2) / (2 * eta) + eta * T * L**2

    opt_distances = []
    equi_distances = []
    regret_standards = []
    regret_news = []
    Fnorms = []
    stokes_exact = []
    stokes = []
    areas_exact = []
    areas = []
    ts = range(T)
    for t in ts:
        print('t = ' + str(t), end='\r')
        idx = idx_seq[t]
        X = X_seq[t]
        # retrieve domain
        Domain = Domains[idx]
        # retrieve equilibrium / reference vector
        if t > 0:
            equi = X_seq[t - 1]
        else:
            # equi = np.zeros_like(X)
            equi = X
        # calculate distance
        opt_distances += [np.linalg.norm(X_Opt - X)]
        equi_distances += [np.linalg.norm(equi - X)]
        # calculate standard regret
        ci_predict = ContourIntegral(Domain, LineContour(equi, X))
        predict_loss = integral(ci_predict)
        ci_opt = ContourIntegral(Domain, LineContour(equi, X_Opt))
        predict_opt = integral(ci_opt)
        regret_standards += [predict_loss - predict_opt]
        # calculate new regret
        ci_new = ContourIntegral(Domain, LineContour(X_Opt, X))
        regret_news += [integral(ci_new)]
        # calculate bound
        area_exact = herons(X_Opt, X, equi)  # exact area
        area = eta_opt * L * (np.linalg.norm(X) + B)
        areas_exact += [area_exact]
        areas += [area]
        stokes_exact += [CurlBounds[idx] * area_exact]
        stokes += [CurlBounds[idx] * area]
        # stokes += [np.max(CurlBounds[idx]*regret_news[-1]/sigma,0)]
        # calculate Fnorm
        Fnorms += [np.linalg.norm(F_seq[t])]

    ts_p1 = range(1, T + 1)
    opt_distances_avg = np.divide(np.cumsum(opt_distances), ts_p1)
    equi_distances_avg = np.divide(np.cumsum(equi_distances), ts_p1)
    regret_standards_avg = np.divide(np.cumsum(regret_standards), ts_p1)
    regret_news_avg = np.divide(np.cumsum(regret_news), ts_p1)
    areas_exact_avg = np.divide(np.cumsum(areas_exact), ts_p1)
    areas_avg = np.divide(np.cumsum(areas), ts_p1)
    stokes_exact_avg = np.divide(np.cumsum(stokes_exact), ts_p1)
    stokes_avg = np.divide(np.cumsum(stokes), ts_p1)
    Fnorms_avg = np.divide(np.cumsum(Fnorms), ts_p1)

    np.savez_compressed('NoRegret_MLN_new.npz',
                        opt_d_avg=opt_distances_avg,
                        equi_d_avg=equi_distances_avg,
                        rs_avg=regret_standards_avg,
                        rn_avg=regret_news_avg,
                        stokes_exact=stokes_exact_avg,
                        stokes=stokes_avg)

    plt.subplot(2, 1, 2)
    plt.semilogy(ts,
                 opt_distances_avg,
                 'k',
                 label='Average Distance to Optimal')
    plt.semilogy(ts,
                 equi_distances_avg,
                 'r',
                 label='Average Distance to Reference')
    plt.semilogy(ts, areas_exact_avg, 'g-', label='Area (exact)')
    plt.semilogy(ts, areas_avg, 'm-', label='Area')
    plt.semilogy(ts, Fnorms_avg, 'b-', label='Fnorms')
    # plt.title('Demonstration of No-Regret on MLN')
    plt.xlabel('Time Step')
    plt.ylabel('Euclidean Distance')
    # plt.legend()
    lgd1 = plt.legend(bbox_to_anchor=(1.05, 1), loc=2)

    plt.subplot(2, 1, 1)
    plt.plot(ts,
             regret_standards_avg,
             'r--o',
             markevery=T // 20,
             label=r'regret$_{s}$')
    plt.plot(ts, regret_news_avg, 'b-', label=r'regret$_{n}$')
    plt.fill_between(ts,
                     regret_news_avg - stokes,
                     regret_news_avg + stokes,
                     facecolor='c',
                     alpha=0.2,
                     zorder=5,
                     label='Stokes Bound')
    plt.fill_between(ts,
                     regret_news_avg - stokes_exact,
                     regret_news_avg + stokes_exact,
                     facecolor='c',
                     alpha=0.2,
                     zorder=5,
                     label='Stokes Bound (exact)')

    # plt.plot(ts, np.zeros_like(ts), 'w-', lw=1)
    # plt.xlabel('Time Step')
    plt.ylabel('Aggregate System-Wide Loss')
    plt.xlim([0, T])
    plt.ylim([-5000, 5000])
    # plt.legend(loc='lower right')
    lgd2 = plt.legend(bbox_to_anchor=(1.05, 1), loc=2)
    plt.title('Demonstration of No-Regret on MLN')

    plt.savefig('NoRegret_MLN_new.pdf',
                format='pdf',
                additional_artists=[lgd1, lgd2],
                bbox_inches='tight')

    fontsize = 18
    plt.figure()
    plt.subplot(1, 1, 1)
    plt.plot(ts,
             regret_standards_avg,
             'r--o',
             markevery=T // 20,
             label=r'regret$_{s}$')
    plt.plot(ts, regret_news_avg, 'b-', label=r'regret$_{n}$')
    # plt.fill_between(ts, regret_news_avg-stokes, regret_news_avg+stokes,
    #                  facecolor='c', alpha=0.2, zorder=5, label='Stokes Bound')
    plt.fill_between(ts,
                     regret_news_avg - stokes_exact,
                     regret_news_avg + stokes_exact,
                     facecolor='c',
                     alpha=0.2,
                     zorder=5,
                     label='Stokes Bound')

    plt.plot(ts, np.zeros_like(ts), 'w-', lw=1)
    plt.xlabel('Time Step', fontsize=fontsize)
    plt.ylabel('Negative Auto-Welfare', fontsize=fontsize)
    plt.xlim([0, T])
    plt.ylim([0, 5000])
    # plt.legend(loc='lower right')
    lgd = plt.legend(bbox_to_anchor=(1.05, 1), loc=2, fontsize=fontsize)
    plt.title('Demonstration of No-Regret on MLN', fontsize=fontsize)

    plt.savefig('NoRegret_MLN_new2.pdf',
                format='pdf',
                additional_artists=[lgd],
                bbox_inches='tight')

    plt.figure()
    plt.subplot(1, 1, 1)
    plt.plot(ts,
             -regret_standards_avg,
             'r--o',
             markevery=T // 20,
             label=r'regret$_{2}$')
    plt.plot(ts, -regret_news_avg, 'b-', label=r'regret$_{1}$')
    # plt.fill_between(ts, regret_news_avg-stokes, regret_news_avg+stokes,
    #                  facecolor='c', alpha=0.2, zorder=5, label='Stokes Bound')
    plt.fill_between(ts,
                     -regret_news_avg - stokes_exact,
                     -regret_news_avg + stokes_exact,
                     facecolor='c',
                     alpha=0.2,
                     zorder=5,
                     label='Stokes Bound')

    plt.plot(ts, np.zeros_like(ts), 'w-', lw=1)
    plt.xlabel('Time Step', fontsize=fontsize)
    plt.ylabel('Auto-Welfare Regret', fontsize=fontsize)
    plt.xlim([0, T])
    plt.ylim([-5000, 0])
    # plt.legend(loc='lower right')
    lgd = plt.legend(bbox_to_anchor=(1.05, 1), loc=2, fontsize=fontsize)
    plt.title('Demonstration of No-Regret on MLN', fontsize=fontsize)

    plt.savefig('NoRegret_MLN_new3.pdf',
                format='pdf',
                additional_artists=[lgd],
                bbox_inches='tight')

    plt.figure()
    plt.subplot(1, 1, 1)
    plt.plot(ts, regret_news_avg, 'b-')
    # plt.fill_between(ts, regret_news_avg-stokes, regret_news_avg+stokes,
    #                  facecolor='c', alpha=0.2, zorder=5, label='Stokes Bound')
    # plt.fill_between(ts, -regret_news_avg-stokes_exact, -regret_news_avg+stokes_exact,
    #                  facecolor='c', alpha=0.2, zorder=5, label='Stokes Bound')

    plt.plot(ts, np.zeros_like(ts), 'w-', lw=1)
    plt.xlabel('Time Step', fontsize=fontsize)
    plt.ylabel('OMO Path Integral Regret', fontsize=fontsize)
    plt.xlim([0, T])
    plt.ylim([0, 5000])
    # plt.legend(loc='lower right')
    # lgd = plt.legend(bbox_to_anchor=(1.05, 1), loc=2, fontsize=fontsize)
    plt.title('Demonstration of No-Regret on MLN', fontsize=fontsize)

    plt.savefig('NoRegret_MLN_new4.pdf', format='pdf', bbox_inches='tight')

    sat_exact = np.logical_or(
        regret_standards_avg >= regret_news_avg - stokes_exact,
        regret_standards_avg <= regret_news_avg + stokes_exact)
    sat = np.logical_or(regret_standards_avg >= regret_news_avg - stokes,
                        regret_standards_avg <= regret_news_avg + stokes)

    embed()
Esempio n. 9
0
def Demo():

    #__SERVICE_ORIENTED_INTERNET__##############################################
    N = 10  # number of possible maps
    T = 1000  # number of time steps
    eta = 1e-3  # learning rate

    print('Creating Domains')

    # Define Domains and Compute Equilbria
    Domains = []
    X_Stars = []
    CurlBounds = []
    n = 0
    while len(Domains) < N:
        # Create Domain
        Network = CreateRandomNetwork(m=3, n=2, o=2, seed=None)
        Domain = SOI(Network=Network, alpha=2)

        # Initialize Starting Point
        Start = np.zeros(Domain.Dim)

        # Assert PD
        J = approx_jacobian(Domain.F, Start)
        eigs = np.linalg.eigvals(J + J.T)
        eigs_i = np.abs(np.linalg.eigvals(J - J.T))
        if not np.all(eigs > 0):
            continue
        print(eigs.min(), eigs.max())
        print(eigs_i.min(), eigs_i.max())
        _J = approx_jacobian(Domain.F, Start + 0.5)
        assert np.allclose(J, _J,
                           atol=1e-5)  # assert J is constant (unique for SOI)

        # Record Domain
        Domains += [Domain]

        # Calculate Initial Gap
        gap_0 = Domain.gap_rplus(Start)

        # Calculate Curl Bound
        CurlBounds += [
            np.sqrt(18) *
            svds(J, k=1, which='LM', return_singular_vectors=False).item()
        ]

        # Set Method
        Method = HeunEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-3)

        # Set Options
        Init = Initialization(Step=-1e-10)
        Term = Termination(MaxIter=25000,
                           Tols=[(Domain.gap_rplus, 1e-6 * gap_0)])
        Repo = Reporting(Requests=[Domain.gap_rplus])
        Misc = Miscellaneous()
        Options = DescentOptions(Init, Term, Repo, Misc)

        # Print Stats
        PrintSimStats(Domain, Method, Options)

        # Start Solver
        tic = time.time()
        SOI_Results = Solve(Start, Method, Domain, Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options, SOI_Results, Method, toc)

        # Record X_Star
        X_Star = SOI_Results.TempStorage['Data'][-1]
        X_Stars += [X_Star]
        n += 1
    X_Stars = np.asarray(X_Stars)

    print('Starting Online Learning')

    # Set First Prediction
    X = np.zeros(X_Stars.shape[1])
    # X = np.mean(X_Stars,axis=0)
    # X += np.random.rand(*X.shape)*np.linalg.norm(X)

    # Select First Domain
    # idx = np.argmax(np.linalg.norm(X_Stars - X,axis=1))
    idx = np.random.choice(len(Domains))

    # Domain Sequence
    idx_seq = []
    X_seq = []
    F_seq = []

    ts = range(T)
    for t in ts:
        print('t = ' + str(t), end='\r')
        # record prediction
        X_seq += [X]
        # record domain
        idx_seq += [idx]
        # retrieve domain
        Domain = Domains[idx]
        # record F
        FX = Domain.F(X)
        F_seq += [FX]
        # update prediction
        X = BoxProjection(lo=0).P(X, -eta, FX)
        # update domain
        # idx = np.argmax(np.linalg.norm(X_Stars - X,axis=1))
        idx = np.random.choice(len(Domains))

    L = np.sqrt(np.mean(np.linalg.norm(F_seq, axis=1)**2.))

    print('Computing Optimal Strategy')

    weights = np.bincount(idx_seq, minlength=len(Domains)) / len(idx_seq)
    print(weights)

    # Compute Equilibrium of Average Domain
    Domain = AverageDomains(Domains, weights=weights)

    # Set Method
    Method = HeunEuler_PhaseSpace(Domain=Domain,
                                  P=BoxProjection(lo=0),
                                  Delta0=1e-5)

    # Initialize Starting Point
    Start = np.zeros(Domain.Dim)

    # Assert PSD - sum of PSD is PSD doesn't hurt to check
    J = approx_jacobian(Domain.F, Start)
    eigs = np.linalg.eigvals(J + J.T)
    eigs_i = np.abs(np.linalg.eigvals(J - J.T))
    assert np.all(eigs > 0)
    print(eigs.min(), eigs.max())
    print(eigs_i.min(), eigs_i.max())

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000, Tols=[(Domain.gap_rplus, 1e-10 * gap_0)])
    Repo = Reporting(Requests=[Domain.gap_rplus])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    SOI_Results = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, SOI_Results, Method, toc)

    print('Computing Regrets')

    # Record X_Opt
    X_Opt = SOI_Results.TempStorage['Data'][-1]
    # X_Opt = X_Stars[0]
    B = np.linalg.norm(X_Opt)

    eta_opt = B / (L * np.sqrt(2 * T))
    bound_opt = B * L * np.sqrt(2 * T)
    reg_bound = (B**2) / (2 * eta) + eta * T * L**2

    distances = []
    loss_infs = []
    regret_standards = []
    regret_news = []
    stokes = []
    ts = range(T)
    for t in ts:
        print('t = ' + str(t), end='\r')
        idx = idx_seq[t]
        X = X_seq[t]
        # retrieve domain
        Domain = Domains[idx]
        # retrieve equilibrium / reference vector
        equi = X_Stars[idx]
        # equi = np.zeros_like(X_Stars[idx])
        # calculate distance
        distances += [np.linalg.norm(X_Opt - X)]
        # calculate infinity loss
        # loss_infs += [infinity_loss(Domain,X)]
        # calculate standard regret
        ci_predict = ContourIntegral(Domain, LineContour(equi, X))
        predict_loss = integral(ci_predict)
        ci_opt = ContourIntegral(Domain, LineContour(equi, X_Opt))
        predict_opt = integral(ci_opt)
        regret_standards += [predict_loss - predict_opt]
        # calculate new regret
        ci_new = ContourIntegral(Domain, LineContour(X_Opt, X))
        regret_news += [integral(ci_new)]
        # calculate bound
        # area = 0.5*np.prod(np.sort([np.linalg.norm(X_Opt-equi),np.linalg.norm(X-X_Opt),np.linalg.norm(equi-X)])[:2])  # area upper bound
        area = herons(X_Opt, X, equi)  # exact area
        stokes += [CurlBounds[idx] * area]
        # # update prediction
        # X = BoxProjection(lo=0).P(X,-eta,Domain.F(X))
        # # update domain
        # idx = np.argmax(np.linalg.norm(X_Stars - X,axis=1))
    # embed()
    ts_p1 = range(1, T + 1)
    distances_avg = np.divide(np.cumsum(distances), ts_p1)
    # loss_infs_avg = np.divide(np.cumsum(loss_infs),ts_p1)
    regret_standards_avg = np.divide(np.cumsum(regret_standards), ts_p1)
    regret_news_avg = np.divide(np.cumsum(regret_news), ts_p1)
    stokes = np.divide(np.cumsum(stokes), ts_p1)

    # np.savez_compressed('NoRegret_MLN2c.npz',d_avg=distances_avg,
    #                     linf_avg=loss_infs_avg,rs_avg=regret_standards_avg,
    #                     rn_avg=regret_news_avg,stokes=stokes)

    plt.subplot(2, 1, 2)
    plt.plot(ts, distances_avg, 'k', label='Average Distance')
    # plt.title('Demonstration of No-Regret on MLN')
    plt.xlabel('Time Step')
    plt.ylabel('Euclidean Distance')
    plt.legend()

    plt.subplot(2, 1, 1)
    # plt.plot(ts, loss_infs_avg, 'k--', label=r'loss$_{\infty}$')
    plt.plot(ts,
             regret_standards_avg,
             'r--o',
             markevery=T // 20,
             label=r'regret$_{s}$')
    plt.plot(ts, regret_news_avg, 'b-', label=r'regret$_{n}$')
    # plt.fill_between(ts, regret_news_avg-stokes, regret_news_avg+stokes,
    #                  facecolor='c', alpha=0.2, zorder=0, label='Stokes Bound')
    plt.plot(ts, np.zeros_like(ts), 'w-', lw=1)
    # plt.xlabel('Time Step')
    plt.ylabel('Aggregate System-Wide Loss')
    plt.xlim([0, T])
    # plt.ylim([-200,200])
    plt.legend(loc='lower right')
    plt.title('Demonstration of No-Regret on MLN')

    plt.savefig('NoRegret_MLN2c')

    # data = np.load('NoRegret2.npz')
    # distances_avg = data['d_avg']
    # loss_infs_avg = data['linf_avg']
    # regret_standards_avg = data['rs_avg']
    # regret_news_avg = data['rn_avg']
    # stokes = data['stokes']
    # ts = range(len(distances_avg))

    embed()
Esempio n. 10
0
def Demo():

    #__LQ_GAN__##############################################

    # NEED TO WRITE CODE TO GENERATE N LQ-GANS PER DIMENSION FOR M DIMENSIONS
    # THEN RUN EACH ALGORITHM FROM L STARTING POINTS AND MEASURE RUNTIME AND STEPS
    # UNTIL DESIRED DEGREE OF ACCURACY IS MET, MEASURE ACCURACY WITH EUCLIDEAN DISTANCE TO X^*
    # AND KL DIVERGENCE https://stats.stackexchange.com/questions/60680/kl-divergence-between-two-multivariate-gaussians/60699
    # COMPUTE MIN/MAX/AVG/STD RUNTIME OVER N X L RUNS PER DIMENSION

    # Interpolation between F and RipCurl should probably be nonlinear
    # in terms of L2 norms of matrices if the norms essentially represent the largest eigenvalues

    # what's an example of a pseudomonotone field? stretch vertically linearly a bit? quasimonotone?

    # the extragradient method uses the same step size for the first and second step, as the step size goes
    # to zero, extragradient asymptotes to the projection method
    # modified extragradient methods use different step sizes. if we keep the first step size fixed to some
    # positive value and shrink the second, the dynamics of extragradient remain as desired
    # this is essentially what HE_PhaseSpace is showing
    # HE and HE_PhaseSpace are designed to "simulate" a trajectory - they do not actually change the effective
    # dynamics of the vector field

    # Define Network and Domain
    dim = 1
    s = (dim**2 + dim) // 2
    mu = 10 * np.random.rand(dim)
    mu = np.array([0])
    L = 10 * np.random.rand(dim, dim)
    L[range(dim), range(dim)] = np.clip(L[range(dim), range(dim)], 1e-1,
                                        np.inf)
    L = np.tril(L)
    sig = np.dot(L, L.T)
    sig = np.array([[1]])

    np.set_printoptions(linewidth=200)

    print('mu, sig, sig eigs')
    print(mu)
    print(sig)
    print(np.linalg.eigvals(sig))

    # Set Constraints
    loA = -np.inf * np.ones((dim, dim))
    loA[range(dim), range(dim)] = 1e-2
    lo = np.hstack(
        ([-np.inf] * (dim + s), loA[np.tril_indices(dim)], [-np.inf] * dim))
    P = BoxProjection(lo=lo)

    xoff = 0
    yoff = 0
    scale = 30

    datas = []
    dists = []
    methods = ['ccGD', 'simGD', 'preEG', 'conGD', 'regGD', 'EG']
    # methods = ['simGD']
    # methods = ['ccGD']
    for method in methods:

        if method == 'EG':
            Step = -1e-2
            Iters = 10000
            Domain = LQ(mu=mu, sig=sig, method='simGD')
            Method = EG(Domain=Domain, FixStep=True, P=P)
        elif method == 'simGD':
            Step = -1e-3
            Iters = 100000
            Domain = LQ(mu=mu, sig=sig, method='simGD')
            Method = Euler(Domain=Domain, FixStep=True, P=P)
            # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-5,MinStep=-1.,P=P)
        elif method == 'conGD':
            Step = -1e-6
            # Iters = 2750
            Iters = 3000
            Domain = LQ(mu=mu, sig=sig, method=method)
            Method = HeunEuler_PhaseSpace(Domain=Domain, Delta0=1e-5, P=P)
        else:
            Step = -1e-5
            Iters = 10000
            Domain = LQ(mu=mu, sig=sig, method=method)
            Method = HeunEuler_PhaseSpace(Domain=Domain, Delta0=1e-5, P=P)

        # Initialize Starting Point
        Start = np.array([50., 0., 30., 0.])

        # Set Options
        Init = Initialization(Step=Step)
        Term = Termination(MaxIter=Iters, Tols=[(Domain.dist, 1e-4)])
        Repo = Reporting(Requests=[
            'Step', 'F Evaluations', 'Projections', 'Data', Domain.dist
        ])
        Misc = Miscellaneous()
        Options = DescentOptions(Init, Term, Repo, Misc)

        # Print Stats
        PrintSimStats(Domain, Method, Options)

        # Start Solver
        tic = time.time()
        LQ_Results = Solve(Start, Method, Domain, Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options, LQ_Results, Method, toc)

        datas += [np.array(LQ_Results.PermStorage['Data'])]
        dists += [np.array(LQ_Results.PermStorage[Domain.dist])]

    X, Y = np.meshgrid(
        np.arange(-2 * scale + xoff, 2 * scale + xoff, .2 * scale),
        np.arange(1e-2 + yoff, 4 * scale + yoff, .2 * scale))
    U = np.zeros_like(X)
    V = np.zeros_like(Y)
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            vec = -Domain.F(np.array([X[i, j], 0., Y[i, j], 0.]))
            U[i, j] = vec[0]
            V[i, j] = vec[2]

    fig = plt.figure()
    ax = fig.add_subplot(111)
    Q = plt.quiver(X[::3, ::3],
                   Y[::3, ::3],
                   U[::3, ::3],
                   V[::3, ::3],
                   pivot='mid',
                   units='inches')
    colors = ['r', 'gray', 'b', 'k', 'g', 'm']
    # colors = ['gray']
    # colors = ['r']
    for data, color, method in zip(datas, colors, methods):
        if method == 'EG':
            ax.plot(data[:, 0], data[:, 2], '--', color=color, label=method)
        else:
            ax.plot(data[:, 0], data[:, 2], color=color, label=method)
    ax.plot([data[0, 0]], [data[0, 2]], 'k*')
    ax.plot(mu, sig[0], 'c*')
    ax.set_xlim([-2 * scale + xoff, 2 * scale + xoff])
    ax.set_ylim([-.1 * scale + yoff, 4 * scale + yoff])
    ax.set_xlabel(r'$w_2$')
    ax.set_ylabel(r'$a$')
    plt.title('Trajectories for Various Equilibrium Algorithms')
    plt.legend()
    # plt.show()
    # plt.savefig('original.png')
    # plt.savefig('EGoriginal.png')
    # plt.savefig('RipCurl.png')
    # plt.savefig('RipCurl2.png')
    # plt.savefig('EG.png')
    # plt.savefig('GReg.png')
    # plt.savefig('Testing.png')
    # plt.savefig('trajcomp_ccGD.png')
    # plt.savefig('trajcomp.png')
    plt.savefig('trajcomp_test.png')
def Demo():

    #__SUPPLY_CHAIN__##################################################

    #############################################################
    # Example 1 from Nagurney's Paper
    #############################################################

    # Define Network and Domain
    Network = CreateNetworkExample(ex=1)
    Domain = SupplyChain(Network=Network, alpha=2)

    # Set Method
    Method = ABEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-2)

    # Initialize Starting Point
    x = 10 * np.ones(np.product(Domain.x_shape))
    gam = np.ones(np.sum([np.product(g) for g in Domain.gam_shapes]))
    lam = np.zeros(np.sum([np.product(l) for l in Domain.lam_shapes]))
    Start = np.concatenate((x, gam, lam))

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000, Tols=[(Domain.gap_rplus, 1e-3 * gap_0)])
    Repo = Reporting(Requests=[
        Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections', 'Data'
    ])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    SupplyChain_Results_Phase1 = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, SupplyChain_Results_Phase1, Method, toc)

    #############################################################
    # Increased Demand of Firm 2's Product
    #############################################################

    # Define Network and Domain
    Network = CreateNetworkExample(ex=2)
    Domain = SupplyChain(Network=Network, alpha=2)

    # Set Method
    Method = ABEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-2)

    # Initialize Starting Point
    Start = SupplyChain_Results_Phase1.PermStorage['Data'][-1]

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000, Tols=[(Domain.gap_rplus, 1e-3 * gap_0)])
    Repo = Reporting(Requests=[
        Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections', 'Data'
    ])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    SupplyChain_Results_Phase2 = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, SupplyChain_Results_Phase2, Method, toc)

    ########################################################
    # Animate Network
    ########################################################

    # Construct MP4 Writer
    fps = 15
    FFMpegWriter = animation.writers['ffmpeg']
    metadata = dict(title='SupplyChain', artist='Matplotlib')
    writer = FFMpegWriter(fps=fps, metadata=metadata)

    # Collect Frames
    frame_skip = 5
    freeze = 5
    Dyn_1 = SupplyChain_Results_Phase1.PermStorage['Data']
    Frz_1 = [Dyn_1[-1]] * fps * frame_skip * freeze
    Dyn_2 = SupplyChain_Results_Phase2.PermStorage['Data']
    Frz_2 = [Dyn_2[-1]] * fps * frame_skip * freeze
    Frames = np.concatenate((Dyn_1, Frz_1, Dyn_2, Frz_2), axis=0)[::frame_skip]

    # Normalize Colormap by Flow at each Network Level
    Domain.FlowNormalizeColormap(Frames, cm.rainbow)

    # Mark Annotations
    t1 = 0
    t2 = t1 + len(SupplyChain_Results_Phase1.PermStorage['Data']) // frame_skip
    t3 = t2 + fps * freeze
    t4 = t3 + len(SupplyChain_Results_Phase2.PermStorage['Data']) // frame_skip
    Dyn_1_ann = 'Control Network\n(Equilibrating)'
    Frz_1_ann = 'Control Network\n(Converged)'
    Dyn_2_ann = 'Market Increases Demand for Firm 2' 's Product\n(Equilibrating)'
    Frz_2_ann = 'Market Increases Demand for Firm 2' 's Product\n(Converged)'
    anns = sorted([(t1, plt.title, Dyn_1_ann), (t2, plt.title, Frz_1_ann),
                   (t3, plt.title, Dyn_2_ann), (t4, plt.title, Frz_2_ann)],
                  key=lambda x: x[0],
                  reverse=True)

    # Save Animation to File
    fig, ax = plt.subplots()
    SupplyChain_ani = animation.FuncAnimation(fig,
                                              Domain.UpdateVisual,
                                              init_func=Domain.InitVisual,
                                              frames=len(Frames),
                                              fargs=(ax, Frames, anns),
                                              blit=True)
    SupplyChain_ani.save('Videos/SupplyChain.mp4', writer=writer)
Esempio n. 12
0
def Demo():

    #__ONLINE_MONOTONE_EQUILIBRATION_DEMO_OF_A_SERVICE_ORIENTED_INTERNET__######

    # Define Number of Different VIs
    N = 10
    np.random.seed(0)

    # Define Initial Network and Domain
    World = np.random.randint(N)
    Worlds = [World]
    Network = CreateRandomNetwork(m=3, n=2, o=2, seed=World)
    Domain = SOI(Network=Network, alpha=2)

    # Define Initial Strategy
    Strategies = [np.zeros(Domain.Dim)]
    eta = 0.1

    for t in range(1000):

        #__PERFORM_SINGLE_UPDATE

        print('Time ' + str(t))

        # Set Method
        Method = Euler(Domain=Domain, P=BoxProjection(lo=0))

        # Set Options
        Init = Initialization(Step=-eta)
        Term = Termination(MaxIter=1)
        Repo = Reporting(Requests=['Data'])
        Misc = Miscellaneous()
        Options = DescentOptions(Init, Term, Repo, Misc)

        # Run Update
        Result = Solve(Strategies[-1], Method, Domain, Options)

        # Get New Strategy
        Strategy = Result.PermStorage['Data'][-1]
        Strategies += [Strategy]

        #__DEFINE_NEXT_VI

        # Define Initial Network and Domain
        World = np.random.randint(N)
        Worlds += [World]
        Network = CreateRandomNetwork(m=3, n=2, o=2, seed=World)
        Domain = SOI(Network=Network, alpha=2)

    # Scrap Last Strategy / World
    Strategies = np.asarray(Strategies[:-1])
    Worlds = Worlds[:-1]

    # Store Equilibrium Strategies
    Equilibria = dict()

    for w in np.unique(Worlds):

        print('World ' + str(w))

        #__FIND_EQUILIBRIUM_SOLUTION_OF_VI

        # Define Initial Network and Domain
        Network = CreateRandomNetwork(m=3, n=2, o=2, seed=w)
        Domain = SOI(Network=Network, alpha=2)

        # Set Method
        Method = HeunEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-5)

        # Initialize Starting Point
        Start = np.zeros(Domain.Dim)

        # Calculate Initial Gap
        gap_0 = Domain.gap_rplus(Start)

        # Set Options
        Init = Initialization(Step=-1e-10)
        Term = Termination(MaxIter=25000,
                           Tols=[(Domain.gap_rplus, 1e-6 * gap_0)])
        Repo = Reporting(Requests=[Domain.gap_rplus, 'Step', 'Data'])
        Misc = Miscellaneous()
        Options = DescentOptions(Init, Term, Repo, Misc)

        # Print Stats
        PrintSimStats(Domain, Method, Options)

        # Start Solver
        tic = time.time()
        Results = Solve(Start, Method, Domain, Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options, Results, Method, toc)

        # Get Equilibrium Strategy
        Equilibrium = Results.PermStorage['Data'][-1]
        Equilibria[w] = Equilibrium

    # Matched Equilibria & Costs
    Equilibria_Matched = np.asarray([Equilibria[w] for w in Worlds])

    # Compute Mean of Equilibria
    Mean_Equilibrium = np.mean(Equilibria_Matched, axis=0)

    # Compute Strategies Distance From Mean Equilibrium
    Distance_From_Mean = np.linalg.norm(Strategies - Mean_Equilibrium, axis=1)

    # Plot Results
    fig = plt.figure()
    ax1 = fig.add_subplot(1, 1, 1)
    ax1.plot(Distance_From_Mean, label='Distance from Mean')
    ax1.set_title('Online Monotone Equilibration of Dynamic SOI Network')
    ax1.legend()
    ax1.set_xlabel('Time')

    plt.savefig('OMEfast.png')

    embed()
Esempio n. 13
0
def Demo():

    #__CLOUD_SERVICES__##################################################

    # Define Network and Domain
    Network = CreateNetworkExample(ex=2)
    Domain = CloudServices(Network=Network, gap_alpha=2)

    # Set Method
    eps = 1e-2
    Method = HeunEuler_LEGS(Domain=Domain, P=BoxProjection(lo=eps), Delta0=1e0)

    # Set Options
    Init = Initialization(Step=-1e-3)
    Term = Termination(MaxIter=1e5)
    Repo = Reporting(Requests=['Data', 'Step'])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)
    args = (Method, Domain, Options)
    sim = Solve

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Construct grid
    grid = [np.array([.5, 3.5, 6])] * Domain.Dim
    grid = ListONP2NP(grid)
    grid = aug_grid(grid)
    Dinv = np.diag(1. / grid[:, 3])

    # Compute results
    results = MCT(sim,
                  args,
                  grid,
                  nodes=16,
                  limit=40,
                  AVG=0.00,
                  eta_1=1.2,
                  eta_2=.95,
                  eps=1.,
                  L=16,
                  q=8,
                  r=1.1,
                  Dinv=Dinv)
    ref, data, p, iters, avg, bndry_ids, starts = results

    # Save results
    sim_data = [results, Domain, grid]
    np.save('cloud_' + time.strftime("%Y%m%d_%H%M%S"), sim_data)

    # Plot BoAs
    obs = (4, 9)  # Look at new green-tech company
    consts = np.array(
        [3.45, 2.42, 3.21, 2.27, np.inf, .76, .97, .75, 1.03, np.inf])
    txt_locs = [(1.6008064516129032, 1.6015625), (3.2, 3.2), (3.33, 2.53)]
    xlabel = '$p_' + repr(obs[0]) + '$'
    ylabel = '$q_' + repr(obs[1]) + '$'
    title = 'Boundaries of Attraction for Cloud Services Market'
    figBoA, axBoA = plotBoA(ref,
                            data,
                            grid,
                            obs=obs,
                            consts=consts,
                            txt_locs=txt_locs,
                            xlabel=xlabel,
                            ylabel=ylabel,
                            title=title)

    # Plot Probablity Distribution
    figP, axP = plotDistribution(p, grid, obs=obs, consts=consts)
Esempio n. 14
0
def Demo_1dLQGAN(root='figures/'):
    ##############################################################################
    # Compre Trajectories Plot ###################################################
    ##############################################################################

    # Define Network and Domain
    dim = 1
    s = (dim**2+dim)//2
    mu = np.array([0])
    sig = np.array([[1]])

    np.set_printoptions(linewidth=200)

    # Set Constraints
    loA = -np.inf*np.ones((dim,dim))
    loA[range(dim),range(dim)] = 1e-2
    lo = np.hstack(([-np.inf]*(dim+s), loA[np.tril_indices(dim)], [-np.inf]*dim))
    P = BoxProjection(lo=lo)

    xoff = 0
    yoff = 0
    scale = 30

    datas = []
    dists = []
    methods = ['Fcc','Fsim','Feg','Fcon','Freg','EG','Falt','Funr']
    for method in methods:

        if method == 'EG':
            Step = -1e-2
            Iters = 10000
            Domain = LQGAN(mu=mu,sig=sig,preconditioner='Fsim')
            Method = EG(Domain=Domain,FixStep=True,P=P)
        elif method == 'Fsim':
            Step = -1e-3
            Iters = 100000
            Domain = LQGAN(mu=mu,sig=sig,preconditioner='Fsim')
            Method = Euler(Domain=Domain,FixStep=True,P=P)
            # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-5,MinStep=-1.,P=P)
        elif method == 'Fcon':
            Step = -1e-6
            # Iters = 2750
            Iters = 3000
            Domain = LQGAN(mu=mu,sig=sig,preconditioner=method)
            Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-5,P=P)
        elif method == 'Falt' or method == 'Funr':
            Step = -5e-3
            # Iters = 2750
            Iters = 10000
            Domain = LQGAN(mu=mu,sig=sig,preconditioner=method)
            # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-5,P=P)
            Method = Euler(Domain=Domain,FixStep=True,P=P)
        else:
            Step = -1e-5
            Iters = 10000
            Domain = LQGAN(mu=mu,sig=sig,preconditioner=method)
            Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-5,P=P)
        
        # Initialize Starting Point
        Start = np.array([50.,0.,30.,0.])

        # Set Options
        Init = Initialization(Step=Step)
        Term = Termination(MaxIter=Iters,Tols=[(Domain.dist_Euclidean,1e-4)])
        Repo = Reporting(Requests=['Step', 'F Evaluations',
                                   'Projections','Data',Domain.dist_Euclidean])
        Misc = Miscellaneous()
        Options = DescentOptions(Init,Term,Repo,Misc)

        # Print Stats
        PrintSimStats(Domain,Method,Options)

        # Start Solver
        tic = time.time()
        LQ_Results = Solve(Start,Method,Domain,Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options,LQ_Results,Method,toc)

        datas += [np.array(LQ_Results.PermStorage['Data'])]
        dists += [np.array(LQ_Results.PermStorage[Domain.dist_Euclidean])]

    X, Y = np.meshgrid(np.linspace(-2*scale + xoff, 2*scale + xoff, 21), np.arange(1e-2 + yoff, 4*scale + yoff, .2*scale))
    U = np.zeros_like(X)
    V = np.zeros_like(Y)
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            vec = -Domain._F(np.array([X[i,j],0.,Y[i,j],0.]))
            U[i,j] = vec[0]
            V[i,j] = vec[2]

    fs = 18
    fig = plt.figure()
    ax = fig.add_subplot(111)
    Q = plt.quiver(X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3],
                   pivot='mid', units='inches')
    colors = ['r','c','b','k','g','m','gray','orange']
    methods = [r'$F_{cc}$',r'$F$',r'$F_{eg}$',r'$F_{con}$',r'$F_{reg}$',r'$EG$',r'$F_{alt}$',r'$F_{unr}$']
    for data, color, method in zip(datas,colors,methods):
        if method == 'EG' or method == 'Funr':
            ax.plot(data[:,0],data[:,2],'-.',color=color,label=method,zorder=0)
        else:
            ax.plot(data[:,0],data[:,2],color=color,label=method,zorder=0)
    ax.plot([data[0,0]],[data[0,2]],'k*')
    ax.plot(mu,sig[0],'*',color='gold')
    # ax.set_xlim([-2*scale + xoff,2*scale + xoff])
    # ax.set_ylim([-.1*scale + yoff,4*scale + yoff])
    ax.set_xlim([-60., 60.])
    ax.set_ylim([-.1*scale + yoff, 100.])
    ax.set_xlabel(r'$w_2$', fontsize=fs)
    ax.set_ylabel(r'$a$', fontsize=fs)
    for tick in ax.xaxis.get_major_ticks():
        tick.label.set_fontsize(14)
    for tick in ax.yaxis.get_major_ticks():
        tick.label.set_fontsize(14)
    plt.title('Trajectories for Various Equilibrium Algorithms', fontsize=16)
    # plt.legend(fontsize=fs, loc="upper left")

    fs = 24
    # locs = [(15,25),(-35,80),(0,40),(42.5,3.0),(20,2.5),(-30,35),(-40,20),(-20,20)]
    # locs = [(15,25),(-35,80),(2.5,40),(42.5,3.0),(20,2.5),(-45,45),(-42.5,5),(-22.5,5)]
    locs = [(15,25),(-35,75),(2.5,40),(42.5,3.0),(20,2.5),(-45,45),(-42.5,5),(-22.5,5)]
    for method,color,loc in zip(methods,colors,locs):
        ax.annotate(method, xy=loc, color=color, zorder=1, fontsize=fs,
                    bbox=dict(facecolor='white', edgecolor='white', pad=0.0))

    plt.savefig(root+'trajcomp.png',bbox_inches='tight')

    ##############################################################################
    # Euclidean Distance to Equilibrium vs Iterations ############################
    ##############################################################################

    # Old Version of Plot
    # # fig = plt.figure()
    # # ax = fig.add_subplot(111)
    # # colors = ['r','gray','b','k','g']
    # # for dist, color, method in zip(dists,colors,methods):
    # #     ax.plot(dist,color=color,label=method)
    # # ax.set_xlabel('Iterations')
    # # ax.set_ylabel('Distance to Equilibrium')
    # # plt.legend()
    # # plt.title('Iteration vs Distance to Equilibrium for Various Equilibrium Algorithms')
    # # plt.savefig('runtimecomp.png')

    # More Recent Version of Plot
    fig,(ax,ax2) = plt.subplots(1,2,sharey=True, facecolor='w')
    for dist, color, method in zip(dists,colors,methods):
        # if method == 'simGD':
        iters = np.arange(dist.shape[0])/1000
        # print(dist[:5])
        ax.plot(iters,dist,color=color,label=method)
        ax2.plot(iters,dist,color=color,label=method)
        # else:
        #     ax.plot(dist,color=color,label=method)
    ax.set_xlim(-.1,10)
    ax.set_xticks([0,2,4,6,8,10])
    ax2.set_xlim(50,100)
    ax.set_ylim(-5,95)
    ax2.set_ylim(-5,95)

    # hide the spines between ax and ax2
    ax.spines['right'].set_visible(False)
    ax2.spines['left'].set_visible(False)
    ax.yaxis.tick_left()
    ax.tick_params(labelright='off')
    ax2.yaxis.tick_right()
    ax2.set_xticks([75,100])

    d = .015 # how big to make the diagonal lines in axes coordinates
    # arguments to pass plot, just so we don't keep repeating them
    kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
    ax.plot((1-d,1+d), (-d,+d), **kwargs)
    ax.plot((1-d,1+d),(1-d,1+d), **kwargs)

    kwargs.update(transform=ax2.transAxes)  # switch to the bottom axes
    ax2.plot((-d,+d), (1-d,1+d), **kwargs)
    ax2.plot((-d,+d), (-d,+d), **kwargs)

    # ax.set_xlabel('Iterations')
    fig.text(0.5, 0.02, 'Thousand Iterations', ha='center', fontsize=12)
    ax.set_ylabel('Distance to Equilibrium',fontsize=12)
    # ax.legend()
    ax2.legend(fontsize=18)
    plt.suptitle('Iteration vs Distance to Equilibrium for Various Equilibrium Algorithms')
    plt.savefig(root+'runtimecomp.png')

    ##############################################################################
    # Individual Trajectory Plots ################################################
    ##############################################################################

    # Set Constraints
    loA = -np.inf*np.ones((dim,dim))
    loA[range(dim),range(dim)] = 1e-4
    lo = np.hstack(([-np.inf]*(dim+s), loA[np.tril_indices(dim)], [-np.inf]*dim))
    P = BoxProjection(lo=lo)

    xlo, xhi = -5, 5
    ylo, yhi = 0, 2
    methods = ['Fcc','Feg','Fcon','Freg','Falt','Funr']
    colors = ['r','b','k','g','gray','orange']
    for method, color in zip(methods,colors):
        Step = -1e-5
        Iters = 10000
        Domain = LQGAN(mu=mu,sig=sig,preconditioner=method)
        Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-5,P=P)
        # Iters = 10000
        # Method = Euler(Domain=Domain,FixStep=True)
        
        # Initialize Starting Point
        Start = np.array([3.,0.,0.2,0.])

        # Set Options
        Init = Initialization(Step=Step)
        Term = Termination(MaxIter=Iters,Tols=[(Domain.dist_Euclidean,1e-4)])
        Repo = Reporting(Requests=['Step', 'F Evaluations',
                                   'Projections','Data',Domain.dist_Euclidean])
        Misc = Miscellaneous()
        Options = DescentOptions(Init,Term,Repo,Misc)

        # Print Stats
        PrintSimStats(Domain,Method,Options)

        # Start Solver
        tic = time.time()
        LQ_Results = Solve(Start,Method,Domain,Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options,LQ_Results,Method,toc)

        data = np.array(LQ_Results.PermStorage['Data'])
        
        X, Y = np.meshgrid(np.linspace(xlo, xhi, 50), np.linspace(ylo, yhi, 50))
        U = np.zeros_like(X)
        V = np.zeros_like(Y)
        for i in range(X.shape[0]):
            for j in range(X.shape[1]):
                vec = -Domain.F(np.array([X[i,j],0.,Y[i,j],0.]))
                U[i,j] = vec[0]
                V[i,j] = vec[2]

        fig = plt.figure()
        ax = fig.add_subplot(111)
        Q = plt.quiver(X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3],
                       pivot='mid', units='inches')
        ax.plot(data[:,0],data[:,2],color=color,label=method)
        ax.plot([data[0,0]],[data[0,2]],'k*')
        ax.plot(mu,sig[0],'c*')
        ax.set_xlim([xlo, xhi])
        ax.set_ylim([0, yhi])
        ax.set_xlabel(r'$w_2$')
        ax.set_ylabel(r'$a$')
        plt.title('Dynamics for '+method)
        plt.savefig(root+method+'_dyn')
Esempio n. 15
0
def Demo():

    #__AFFINE_GAN__##############################################

    # what happens if we force the diagonal of G to lie in R+?
    # G and -G are both equilibrium solutions -- need to rule one out

    # Define Network and Domain
    mean = np.array([1, 2])
    cov = np.array([[1, 0.5], [0.5, 2]])
    lam, phi = np.linalg.eig(cov)
    mat = np.diag(np.sqrt(lam)).dot(phi)
    # Domain = AffineGAN(u=mean,S=cov,batch_size=1000,alpha=0.,expansion=False)

    # Set Method
    # Method = Euler(Domain=Domain,FixStep=True)
    # Method = EG(Domain=Domain,FixStep=True)

    # Initialize Starting Point
    # Start = np.random.rand(Domain.Dim)
    Start = np.zeros(2 * mean.size + cov.size)
    # d0, G0 = Domain.get_args(Start)
    # u0 = G0[:,-1]
    # S0 = G0[:,:Domain.dim]
    # print(u0)
    # print(S0)

    lo = -np.inf * np.ones_like(Start)
    for d in range(mean.size):
        lo[mean.size + d * (mean.size + 1) + d] = 0.

    iter_schedule = [2000, 4000, 4000]
    step_schedule = [1e-1, 1e-2, 1e-2]
    batch_schedule = [100, 100, 10]
    Vs = []

    for it, step, batch_size in zip(iter_schedule, step_schedule,
                                    batch_schedule):

        Domain = AffineGAN(u=mean,
                           S=cov,
                           batch_size=batch_size,
                           alpha=0.,
                           expansion=False)

        # Set Method
        # Method = Euler(Domain=Domain,FixStep=True,P=BoxProjection(lo=lo))
        Method = EG(Domain=Domain, FixStep=True, P=BoxProjection(lo=lo))

        # Set Options
        Init = Initialization(Step=-step)
        Term = Termination(MaxIter=it)
        Repo = Reporting(Requests=[
            Domain.V, 'Step', 'F Evaluations', 'Projections', 'Data'
        ])
        Misc = Miscellaneous()
        Options = DescentOptions(Init, Term, Repo, Misc)

        # Print Stats
        PrintSimStats(Domain, Method, Options)

        # Start Solver
        tic = time.time()
        AG_Results = Solve(Start, Method, Domain, Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options, AG_Results, Method, toc)

        Vs += AG_Results.PermStorage[Domain.V]
        Start = AG_Results.TempStorage['Data'][-1]

    # d, G = Domain.get_args(data)
    # u = G[:,-1]
    # S = G[:,:Domain.dim]
    # print(u)
    # print(S)
    print(mat)
    # embed()

    for data in AG_Results.PermStorage['Data'][::400]:

        num_samples = 1000
        real, fake = Domain.generate(data, num_samples)

        # u_est = np.mean(fake,axis=0)
        # S_est = np.dot(fake.T,fake)/num_samples
        # print(u_est)
        # print(S_est)

        fig, axs = plt.subplots(2)
        axs[0].scatter(fake[:, 0],
                       fake[:, 1],
                       s=40,
                       facecolors='none',
                       edgecolors='r',
                       label='fake',
                       zorder=1)
        axs[0].scatter(real[:, 0],
                       real[:, 1],
                       s=40,
                       marker='*',
                       facecolors='none',
                       edgecolors='k',
                       label='real',
                       zorder=0)
        axs[0].set_title('Comparing Distributions')
        axs[0].set_xlim([-5, 10])
        axs[0].set_ylim([-5, 10])
        axs[0].legend()
        axs[1].plot(Vs)
        axs[1].set_xlabel('Iteration')
        axs[1].set_ylabel('Minimax Objective (V)')
        plt.show()
Esempio n. 16
0
def Demo_NdLQGAN(root='lqganresults/', Dims=None, Algorithms=None, File=None):
    # Dims = [1]
    Dims = [1,2]
    Nmusigmas = 10
    Lstarts = 10
    Algorithms = dict(zip(['Fsim','EG','Fcon','Freg','Feg','Fcc'],range(6)))
    # Algorithms = dict(zip(['Fcc','Fsim','Feg','Fcon','Freg','EG'],range(6)))
    # Algorithms = dict(zip(['Fcc','Feg','Freg'],range(3)))
    # Algorithms = dict(zip(['Fcc','Feg'],range(2)))
    # Algorithms = dict(zip(['Fcc','Feg','Fccprime','Fegprime'],range(4)))
    # Algorithms = dict(zip(['Fccprime','Fegprime'],range(2)))
    # Algorithms = dict(zip(['Fcc'],range(1)))
    # Algorithms = ['Fcon']
    # Algorithms = dict(zip(['Fcc','Feg','Fcon','Freg','Falt','Funr'],range(6)))

    Iters = 10000

    data = np.empty((len(Dims),Nmusigmas,Lstarts,len(Algorithms),10))

    for i, dim in enumerate(tqdm.tqdm(Dims)):
        Domain = LQGAN(dim=dim, var_only=True)

        # Dimensionality
        s = Domain.s
        pdim = Domain.Dim

        # Set Constraints
        loA = -np.inf*np.ones((dim,dim))
        loA[range(dim),range(dim)] = 1e-2
        lo = np.hstack(([-np.inf]*(dim+s), loA[np.tril_indices(dim)], [-np.inf]*dim))
        P = BoxProjection(lo=lo)

        for musigma in tqdm.tqdm(range(Nmusigmas)):
            # Reset LQGAN to random mu and Sigma
            mu, Sigma = rand_mu_Sigma(dim=dim)
            # print(Sigma.flatten().item())
            mu = np.zeros(dim)
            # Sigma = np.array([[1]])
            # Sigma = np.diag(np.random.rand(dim)*10+1.)
            lams = np.linalg.eigvals(Sigma)
            K = lams.max()/lams.min()
            # print(np.linalg.eigvals(Sigma))
            Domain.set_mu_sigma(mu=mu,sigma=Sigma)
            # print(mu,Sigma)

            for l in tqdm.tqdm(range(Lstarts)):
                # Intialize G and D variables to random starting point
                # should initialize A to square root of random Sigma
                # Start = P.P(10*np.random.rand(pdim)-5.)
                Start = np.zeros(pdim)
                Start[:s] = np.random.rand(s)*10-5
                Start[s:s+dim] = 0.  # set w_1 to zero
                Start[-dim:] = mu  # set b to mu
                Start[-dim-s:-dim] = np.linalg.cholesky(rand_mu_Sigma(dim=dim)[1])[np.tril_indices(dim)]
                Start = P.P(Start)

                # Calculate Initial KL and Euclidean distance
                KL_0 = Domain.dist_KL(Start)
                Euc_0 = Domain.dist_Euclidean(Start)
                norm_F_0 = Domain.norm_F(Start)
                # print(KL_0,Euc_0,norm_F_0)

                for j, alg in enumerate(tqdm.tqdm(Algorithms)):

                    # Step = -1e-3
                    if alg == 'EG':
                        Step = -1e-3
                        Domain.preconditioner = 'Fsim'
                        Method = EG(Domain=Domain,FixStep=True,P=P)
                    elif alg == 'Fsim':
                        Step = -1e-4
                        Domain.preconditioner='Fsim'
                        Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-3,P=P,MinStep=-1e-2)
                        # Method = Euler(Domain=Domain,FixStep=True,P=P)
                    elif alg == 'Fcon':
                        Step = -1e-4
                        Domain.preconditioner = alg
                        Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-3,P=P,MinStep=-1e-2)
                        # Method = Euler(Domain=Domain,FixStep=True,P=P)
                    elif alg == 'Falt' or alg == 'Funr':
                        Step = -5e-3
                        Domain.preconditioner = alg
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-5,P=P)
                        Method = Euler(Domain=Domain,FixStep=True,P=P)
                    elif alg == 'Fccprime' or alg == 'Fegprime':
                        Step = -1e-1
                        Domain.preconditioner = alg
                        Method = Euler(Domain=Domain,FixStep=True,P=P)
                    else:
                        # Step = -1e-1
                        Step = -1e-4
                        Domain.preconditioner = alg
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-0,P=P,MinStep=-10.)  # for 2d+
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-2,P=P,MinStep=-1e-1) # 13 slow
                        Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-3,P=P,MinStep=-1e-2) # slow
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-1,P=P,MinStep=-1e-1) better
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-1,P=P,MinStep=-1e-10) slow
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-1,P=P,MinStep=-1e-2) best so far, Feg is not working well?
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-2,P=P,MinStep=-1e-2) ok
                        # Method = HeunEuler_PhaseSpace(Domain=Domain,Delta0=1e-2,P=P,MinStep=-1e-1)
                        # Delta0=1e-2,MinStep=-1e-1 for speed on 1d, scaled versions are surprisingly worse
                    
                    # Set Options
                    Init = Initialization(Step=Step)
                    Tols = [#(Domain.norm_F,1e-3*norm_F_0),
                            # (Domain.dist_KL,1e-3*KL_0),
                            (Domain.dist_Euclidean,1e-3*Euc_0),
                            (Domain.isNotNaNInf,False)]
                    Term = Termination(MaxIter=Iters,Tols=Tols,verbose=False)
                    Repo = Reporting(Requests=[Domain.norm_F, Domain.dist, 
                                               Domain.dist_KL, Domain.dist_Euclidean,
                                               Domain.isNotNaNInf])
                    # 'Step','Data',
                    Misc = Miscellaneous()
                    Options = DescentOptions(Init,Term,Repo,Misc)

                    # Start Solver
                    tic = time.time()
                    LQ_Results = Solve(Start,Method,Domain,Options)
                    toc = time.time() - tic

                    KL = LQ_Results.PermStorage[Domain.dist_KL][-1]
                    Euc = LQ_Results.PermStorage[Domain.dist_Euclidean][-1]
                    norm_F = LQ_Results.PermStorage[Domain.norm_F][-1]
                    # x = np.array(LQ_Results.PermStorage['Data'])
                    # Steps = np.array(LQ_Results.PermStorage['Step'])
                    runtime = toc
                    steps = LQ_Results.thisPermIndex
                    # embed()

                    data[i,musigma,l,j,:] = np.array([dim,musigma,Algorithms[alg],l,K,KL/KL_0,Euc/Euc_0,norm_F/norm_F_0,runtime,steps])
                    # embed()
            np.save(root+'results15.npy', data)
Esempio n. 17
0
def Demo():

    #__SERVICE_ORIENTED_INTERNET__##############################################
    N = 2  # number of possible maps
    T = 100  # number of time steps
    eta = .01  # learning rate

    # Define Domains and Compute Equilbria
    Domains = []
    X_Stars = []
    CurlBounds = []
    # for n in range(N):
    n = 0
    while len(X_Stars) < N:
        # Create Domain
        Network = CreateRandomNetwork(m=3,n=2,o=2,seed=n)
        Domain = SOI(Network=Network,alpha=2)

        # Record Domain
        Domains += [Domain]

        # Set Method
        Method = HeunEuler(Domain=Domain,P=BoxProjection(lo=0),Delta0=1e-3)

        # Initialize Starting Point
        Start = np.zeros(Domain.Dim)

        # Calculate Initial Gap
        gap_0 = Domain.gap_rplus(Start)

        # Calculate Curl Bound
        J = approx_jacobian(Domain.F,Start)
        if not np.all(np.linalg.eigvals(J+J.T) >= 0):
            pass
        _J = approx_jacobian(Domain.F,Start+0.5)
        assert np.allclose(J,_J,atol=1e-5)
        CurlBounds += [np.sqrt(18)*svds(J,k=1,which='LM',return_singular_vectors=False).item()]

        # Set Options
        Init = Initialization(Step=-1e-10)
        Term = Termination(MaxIter=25000,Tols=[(Domain.gap_rplus,1e-6*gap_0)])
        Repo = Reporting(Requests=[Domain.gap_rplus])
        Misc = Miscellaneous()
        Options = DescentOptions(Init,Term,Repo,Misc)

        # Print Stats
        PrintSimStats(Domain,Method,Options)

        # Start Solver
        tic = time.time()
        SOI_Results = Solve(Start,Method,Domain,Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options,SOI_Results,Method,toc)

        # Record X_Star
        X_Star = SOI_Results.TempStorage['Data'][-1]
        X_Stars += [X_Star]
        n += 1
    X_Stars = np.asarray(X_Stars)

    # Compute Equilibrium of Average Domain
    Domain = AverageDomains(Domains)

    # Set Method
    Method = HeunEuler_PhaseSpace(Domain=Domain,P=BoxProjection(lo=0),Delta0=1e-3)

    # Initialize Starting Point
    Start = np.zeros(Domain.Dim)

    J = approx_jacobian(Domain.F,Start)
    assert np.all(np.linalg.eigvals(J+J.T) >= 0)

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=25000,Tols=[(Domain.gap_rplus,1e-10*gap_0)])
    Repo = Reporting(Requests=[Domain.gap_rplus])
    Misc = Miscellaneous()
    Options = DescentOptions(Init,Term,Repo,Misc)

    # Print Stats
    PrintSimStats(Domain,Method,Options)

    # Start Solver
    tic = time.time()
    SOI_Results = Solve(Start,Method,Domain,Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options,SOI_Results,Method,toc)

    # Record X_Opt
    X_Opt = SOI_Results.TempStorage['Data'][-1]
    # X_Opt = X_Stars[0]

    print('Starting Online Learning')

    # Set First Prediction
    X = np.zeros(X_Stars.shape[1])

    # Select First Domain
    idx = np.argmax(np.linalg.norm(X_Stars - X,axis=1))

    distances = []
    loss_infs = []
    regret_standards = []
    regret_news = []
    stokes = []
    ts = range(T)
    for t in ts:
        print('t = '+str(t))
        # retrieve domain
        Domain = Domains[idx]
        # retrieve equilibrium / reference vector
        # equi = X_Stars[idx]
        equi = np.zeros_like(X_Stars[idx])
        # calculate distance
        distances += [np.linalg.norm(X_Opt-X)]
        # calculate infinity loss
        # loss_infs += [infinity_loss(Domain,X)]
        # calculate standard regret
        ci_predict = ContourIntegral(Domain,LineContour(equi,X))
        predict_loss = integral(ci_predict)
        ci_opt = ContourIntegral(Domain,LineContour(equi,X_Opt))
        predict_opt = integral(ci_opt)
        regret_standards += [predict_loss - predict_opt]
        # calculate new regret
        ci_new = ContourIntegral(Domain,LineContour(X_Opt,X))
        regret_news += [integral(ci_new)]
        # calculate bound
        # area = 0.5*np.prod(np.sort([np.linalg.norm(X_Opt-equi),np.linalg.norm(X-X_Opt),np.linalg.norm(equi-X)])[:2])  # area upper bound
        area = herons(X_Opt,X,equi)  # exact area
        stokes += [CurlBounds[idx]*area]
        # update prediction
        X = BoxProjection(lo=0).P(X,-eta,Domain.F(X))
        # update domain
        idx = np.argmax(np.linalg.norm(X_Stars - X,axis=1))
    # embed()
    ts_p1 = range(1,T+1)
    distances_avg = np.divide(np.cumsum(distances),ts_p1)
    # loss_infs_avg = np.divide(np.cumsum(loss_infs),ts_p1)
    regret_standards_avg = np.divide(np.cumsum(regret_standards),ts_p1)
    regret_news_avg = np.divide(np.cumsum(regret_news),ts_p1)
    stokes = np.divide(np.cumsum(stokes),ts_p1)

    # np.savez_compressed('NoRegret_MLN.npz',d_avg=distances_avg,
    #                     linf_avg=loss_infs_avg,rs_avg=regret_standards_avg,
    #                     rn_avg=regret_news_avg,stokes=stokes)

    plt.subplot(2, 1, 2)
    plt.plot(ts, distances_avg, 'k',label='Average Distance')
    plt.title('Demonstration of No-Regret on MLN')
    plt.ylabel('Euclidean Distance')
    plt.legend()

    plt.subplot(2, 1, 1)
    # plt.plot(ts, loss_infs_avg, 'k--', label=r'loss$_{\infty}$')
    plt.plot(ts, regret_standards_avg, 'r--o', markevery=T//20,
             label=r'regret$_{s}$')
    plt.plot(ts, regret_news_avg, 'b-', label=r'regret$_{n}$')
    # plt.fill_between(ts, regret_news_avg-stokes, regret_news_avg+stokes,
    #                  facecolor='c', alpha=0.2, zorder=0, label='Stokes Bound')
    plt.plot(ts, np.zeros_like(ts), 'w-', lw=1)
    plt.xlabel('Time Step')
    plt.ylabel('Aggregate System-Wide Loss')
    plt.xlim([0,T])
    # plt.ylim([-250,1000])
    plt.legend()
    plt.title('Demonstration of No-Regret on MLN')

    plt.savefig('NoRegret_MLN2')

    # data = np.load('NoRegret2.npz')
    # distances_avg = data['d_avg']
    # loss_infs_avg = data['linf_avg']
    # regret_standards_avg = data['rs_avg']
    # regret_news_avg = data['rn_avg']
    # stokes = data['stokes']
    # ts = range(len(distances_avg))

    embed()
Esempio n. 18
0
def Demo():

    #__SERVICE_ORIENTED_INTERNET__##############################################
    N = 10  # number of possible maps
    T = 1000  # number of time steps
    eta = .01  # learning rate
    Ot = 0  # reference vector will be origin for all maps

    # Define Domains and Compute Equilbria
    Domains = []
    X_Stars = []
    for n in range(N):
        # Create Domain
        Network = CreateRandomNetwork(m=3, n=2, o=2, seed=n)
        Domain = SOI(Network=Network, alpha=2)

        # Record Domain
        Domains += [Domain]

        # Set Method
        Method = HeunEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-3)

        # Initialize Starting Point
        Start = np.zeros(Domain.Dim)

        # Calculate Initial Gap
        gap_0 = Domain.gap_rplus(Start)

        # Set Options
        Init = Initialization(Step=-1e-10)
        Term = Termination(MaxIter=25000,
                           Tols=[(Domain.gap_rplus, 1e-6 * gap_0)])
        Repo = Reporting(Requests=[Domain.gap_rplus])
        Misc = Miscellaneous()
        Options = DescentOptions(Init, Term, Repo, Misc)

        # Print Stats
        PrintSimStats(Domain, Method, Options)

        # Start Solver
        tic = time.time()
        SOI_Results = Solve(Start, Method, Domain, Options)
        toc = time.time() - tic

        # Print Results
        PrintSimResults(Options, SOI_Results, Method, toc)

        # Record X_Star
        X_Star = SOI_Results.TempStorage['Data'][-1]
        X_Stars += [X_Star]
    X_Stars = np.asarray(X_Stars)
    X_Opt = np.mean(X_Stars, axis=0)
    Ot = Ot * np.ones(X_Stars.shape[1])

    print('Starting Online Learning')

    # Set First Prediction
    X = np.zeros(X_Stars.shape[1])

    # Select First Domain
    idx = np.argmax(np.linalg.norm(X_Stars - X, axis=1))

    distances = []
    loss_infs = []
    regret_standards = []
    regret_news = []
    ts = range(T)
    for t in ts:
        print('t = ' + str(t))
        # retrieve domain
        Domain = Domains[idx]
        # retrieve equilibrium
        equi = X_Stars[idx]
        # calculate distance
        distances += [np.linalg.norm(equi - X)]
        # calculate infinity loss
        loss_infs += [infinity_loss(Domain, X)]
        # calculate standard regret
        ci_predict = ContourIntegral(Domain, LineContour(Ot, X))
        predict_loss = integral(ci_predict)
        ci_opt = ContourIntegral(Domain, LineContour(Ot, X_Opt))
        predict_opt = integral(ci_opt)
        regret_standards += [predict_loss - predict_opt]
        # calculate new regret
        ci_new = ContourIntegral(Domain, LineContour(X_Opt, X))
        regret_news += [integral(ci_new)]
        # update prediction
        X = BoxProjection(lo=0).P(X, -eta, Domain.F(X))
        # update domain
        idx = np.argmax(np.linalg.norm(X_Stars - X, axis=1))
    ts_p1 = range(1, T + 1)
    distances_avg = np.divide(distances, ts_p1)
    loss_infs_avg = np.divide(loss_infs, ts_p1)
    regret_standards_avg = np.divide(regret_standards, ts_p1)
    regret_news_avg = np.divide(regret_news, ts_p1)

    np.savez_compressed('NoRegret.npz',
                        d_avg=distances_avg,
                        linf_avg=loss_infs_avg,
                        rs_avg=regret_standards_avg,
                        rn_avg=regret_news_avg)

    plt.subplot(2, 1, 1)
    plt.plot(ts, distances_avg, 'k', label='Average Distance')
    plt.title('Demonstration of No-Regret on MLN')
    plt.ylabel('Euclidean Distance')
    plt.legend()

    plt.subplot(2, 1, 2)
    plt.plot(ts, loss_infs_avg, 'k--', label=r'loss$_{\infty}$')
    plt.plot(ts,
             regret_standards_avg,
             'r--o',
             markevery=T // 20,
             label=r'regret$_{s}$')
    plt.plot(ts, regret_news_avg, 'b-', label=r'regret$_{n}$')
    plt.xlabel('Time Step')
    plt.ylabel('Aggregate System-Wide Loss')
    plt.xlim([0, T])
    plt.ylim([-500, 5000])
    plt.legend()

    plt.savefig('NoRegret')
Esempio n. 19
0
if __name__ == '__main__':
    # Creating a random LQGAN
    dim = 2
    s = (dim**2 + dim) // 2
    mu = np.zeros(dim)
    L = 10 * np.random.rand(dim, dim) - 5 + np.diag(5 * np.ones(dim))
    L[range(dim), range(dim)] = np.clip(L[range(dim), range(dim)], 1e-8,
                                        np.inf)
    L = np.tril(L)
    sig = np.dot(L, L.T)
    # sig = np.diag(np.random.rand(dim)/np.sqrt(2.))
    Domain = LQGAN(mu=mu, sig=sig)

    from VISolver.Projection import BoxProjection
    # Set Constraints
    loA = -np.inf * np.ones((dim, dim))
    loA[range(dim), range(dim)] = 1e-2
    lo = np.hstack(
        ([-np.inf] * (dim + s), loA[np.tril_indices(dim)], [-np.inf] * dim))
    P = BoxProjection(lo=lo)

    mx = -1
    for i in range(10000):
        Start = P.P(100 * np.random.rand(Domain.Dim) - 50.)
        jexact = Domain.J(Start)
        japprox = approx_jacobian(Domain._F, Start)
        newmx = np.max(np.abs(jexact - japprox))
        mx = max(mx, newmx)

    print(mx)
def plotFigure6(saveFig=False):
    print('CloudServices BoA')

    msg = 'This method will run for about a week.\n' +\
        'Email [email protected] for the results .npy file directly.\n' +\
        'Continue? (y/n) '
    cont = input(msg)
    if cont != 'y':
        return

    # Define Network and Domain
    Network = CreateNetworkExample(ex=2)
    Domain = CloudServices(Network=Network,gap_alpha=2)

    # Set Method
    eps = 1e-2
    Method = HeunEuler_LEGS(Domain=Domain,P=BoxProjection(lo=eps),Delta0=1e0)

    # Set Options
    Init = Initialization(Step=-1e-3)
    Term = Termination(MaxIter=1e5)
    Repo = Reporting(Requests=['Data','Step'])
    Misc = Miscellaneous()
    Options = DescentOptions(Init,Term,Repo,Misc)
    args = (Method,Domain,Options)
    sim = Solve

    # Print Stats
    PrintSimStats(Domain,Method,Options)

    # Construct grid
    grid = [np.array([.5,3.5,6])]*Domain.Dim
    grid = ListONP2NP(grid)
    grid = aug_grid(grid)
    Dinv = np.diag(1./grid[:,3])

    # Compute results
    results = MCT(sim,args,grid,nodes=16,limit=40,AVG=0.00,
                  eta_1=1.2,eta_2=.95,eps=1.,
                  L=16,q=8,r=1.1,Dinv=Dinv)
    ref, data, p, iters, avg, bndry_ids, starts = results

    # Save results
    sim_data = [results,Domain,grid]
    np.save('cloud_'+time.strftime("%Y%m%d_%H%M%S"),sim_data)

    # Plot BoAs
    obs = (4,9)  # Look at new green-tech company
    consts = np.array([3.45,2.42,3.21,2.27,np.inf,.76,.97,.75,1.03,np.inf])
    txt_locs = [(1.6008064516129032, 1.6015625),
                (3.2, 3.2),
                (3.33, 2.53)]
    xlabel = '$p_'+repr(obs[0])+'$'
    ylabel = '$q_'+repr(obs[1])+'$'
    title = 'Boundaries of Attraction for Cloud Services Market'
    fig, ax = plotBoA(ref,data,grid,obs=obs,consts=consts,txt_locs=txt_locs,
                      xlabel=xlabel,ylabel=ylabel,title=title)

    if saveFig:
        plt.savefig('BoA.png',bbox_inches='tight')
    return fig, ax
Esempio n. 21
0
def Demo():

    #__BLOOD_BANK__##################################################

    #############################################################
    # Phase 1 - Left hospital has relatively low demand for blood
    #############################################################

    # Define Network and Domain
    Network = CreateNetworkExample(ex=1)
    Domain = BloodBank(Network=Network, alpha=2)

    # Set Method
    Method = ABEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-5)

    # Initialize Starting Point
    Start = np.zeros(Domain.Dim)

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=10000, Tols=[(Domain.gap_rplus, 1e-3 * gap_0)])
    Repo = Reporting(Requests=[
        Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections', 'Data'
    ])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    BloodBank_Results_Phase1 = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, BloodBank_Results_Phase1, Method, toc)

    #########################################################
    # Phase 2 - Left hospital has comparable demand for blood
    #########################################################

    # Define Network and Domain
    Network = CreateNetworkExample(ex=2)
    Domain = BloodBank(Network=Network, alpha=2)

    # Set Method
    Method = ABEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-5)

    # Initialize Starting Point
    Start = BloodBank_Results_Phase1.PermStorage['Data'][-1]

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=10000, Tols=[(Domain.gap_rplus, 1e-3 * gap_0)])
    Repo = Reporting(Requests=[
        Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections', 'Data'
    ])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    BloodBank_Results_Phase2 = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, BloodBank_Results_Phase2, Method, toc)

    ########################################################
    # Phase 3 - Left hospital has excessive demand for blood
    ########################################################

    # Define Network and Domain
    Network = CreateNetworkExample(ex=3)
    Domain = BloodBank(Network=Network, alpha=2)

    # Set Method
    Method = ABEuler(Domain=Domain, P=BoxProjection(lo=0), Delta0=1e-5)

    # Initialize Starting Point
    Start = BloodBank_Results_Phase2.PermStorage['Data'][-1]

    # Calculate Initial Gap
    gap_0 = Domain.gap_rplus(Start)

    # Set Options
    Init = Initialization(Step=-1e-10)
    Term = Termination(MaxIter=10000, Tols=[(Domain.gap_rplus, 1e-3 * gap_0)])
    Repo = Reporting(Requests=[
        Domain.gap_rplus, 'Step', 'F Evaluations', 'Projections', 'Data'
    ])
    Misc = Miscellaneous()
    Options = DescentOptions(Init, Term, Repo, Misc)

    # Print Stats
    PrintSimStats(Domain, Method, Options)

    # Start Solver
    tic = time.time()
    BloodBank_Results_Phase3 = Solve(Start, Method, Domain, Options)
    toc = time.time() - tic

    # Print Results
    PrintSimResults(Options, BloodBank_Results_Phase3, Method, toc)

    ########################################################
    # Animate Network
    ########################################################

    # Construct MP4 Writer
    fps = 15
    FFMpegWriter = animation.writers['ffmpeg']
    metadata = dict(title='BloodBank', artist='Matplotlib')
    writer = FFMpegWriter(fps=fps, metadata=metadata)

    # Collect Frames
    frame_skip = 5
    freeze = 5
    Dyn_1 = BloodBank_Results_Phase1.PermStorage['Data']
    Frz_1 = [Dyn_1[-1]] * fps * frame_skip * freeze
    Dyn_2 = BloodBank_Results_Phase2.PermStorage['Data']
    Frz_2 = [Dyn_2[-1]] * fps * frame_skip * freeze
    Dyn_3 = BloodBank_Results_Phase3.PermStorage['Data']
    Frz_3 = [Dyn_3[-1]] * fps * frame_skip * freeze
    Frames = np.concatenate((Dyn_1, Frz_1, Dyn_2, Frz_2, Dyn_3, Frz_3),
                            axis=0)[::frame_skip]

    # Normalize Colormap by Flow at each Network Level
    Domain.FlowNormalizeColormap(Frames, cm.Reds)

    # Mark Annotations
    t1 = 0
    t2 = t1 + len(BloodBank_Results_Phase1.PermStorage['Data']) // frame_skip
    t3 = t2 + fps * freeze
    t4 = t3 + len(BloodBank_Results_Phase2.PermStorage['Data']) // frame_skip
    t5 = t4 + fps * freeze
    t6 = t5 + len(BloodBank_Results_Phase3.PermStorage['Data']) // frame_skip
    Dyn_1_ann = '$Demand_{1}$ $<$ $Demand_{2}$ & $Demand_{3}$\n(Equilibrating)'
    Frz_1_ann = '$Demand_{1}$ $<$ $Demand_{2}$ & $Demand_{3}$\n(Converged)'
    Dyn_2_ann = '$Demand_{1}$ ~= $Demand_{2}$ & $Demand_{3}$\n(Equilibrating)'
    Frz_2_ann = '$Demand_{1}$ ~= $Demand_{2}$ & $Demand_{3}$\n(Converged)'
    Dyn_3_ann = '$Demand_{1}$ $>$ $Demand_{2}$ & $Demand_{3}$\n(Equilibrating)'
    Frz_3_ann = '$Demand_{1}$ $>$ $Demand_{2}$ & $Demand_{3}$\n(Converged)'
    anns = sorted([(t1, plt.title, Dyn_1_ann), (t2, plt.title, Frz_1_ann),
                   (t3, plt.title, Dyn_2_ann), (t4, plt.title, Frz_2_ann),
                   (t5, plt.title, Dyn_3_ann), (t6, plt.title, Frz_3_ann)],
                  key=lambda x: x[0],
                  reverse=True)

    # Save Animation to File
    fig, ax = plt.subplots()
    BloodBank_ani = animation.FuncAnimation(fig,
                                            Domain.UpdateVisual,
                                            init_func=Domain.InitVisual,
                                            frames=len(Frames),
                                            fargs=(ax, Frames, anns),
                                            blit=True)
    BloodBank_ani.save('BloodBank.mp4', writer=writer)