# A 2-variable steady-state problem.importosimportmatplotlib.pyplotaspltimportnumpyasnpfromscipyimportlinalgfrommiscimportgnuplotsave# A 2-variable steady-state problemlams=[[0.5,0.5],[0.2,0.8],[0.8,0.2],[0.5,0.5]]iters=[10,25,25,25]names=['equal','first','second','swapped']swaps=[False,False,False,True]defnoncoopvscoop(lam,Niter,name,swap=False):"""Simulates non-cooperative vs. cooperative optimization."""# Unstable for about m1 < 0.58, lam1 = lam2 = 0.5m1=0.5m2=-1/m1g=np.array([[-m1,1],[-m2,1]])ifswap:g=np.array([[0,1],[1,0]])@gysp=np.array([[1],[1]])usp=linalg.solve(g,ysp)ude=np.array([[ysp[0,0]/g[0,0]],[ysp[1,0]/g[1,1]]])# Noncooperative problemLnc=np.array([[1-lam[0],-lam[0]*g[0,1]/g[0,0]],[-lam[1]*g[1,0]/g[1,1],1-lam[1]]])Knc=np.diag([lam[0]/g[0,0],lam[1]/g[1,1]])ssnc=np.abs(linalg.eigvals(Lnc))unc=np.zeros((2,Niter+1))unc[:,0]=ude.flatten()foriinrange(Niter):unc[:,i+1]=(Knc@ysp+Lnc@unc[:,i].reshape(-1,1)).flatten()# Cooperative problemQ=np.diag(lam)H=np.block([[Q,np.zeros((2,1))],[np.zeros((1,2)),0]])G1=g[:,0:1]G2=g[:,1:2]D=np.hstack([np.eye(2),-G1])M=np.block([[H,-D.T],[-D,np.zeros((2,2))]])Minv=linalg.inv(M)K1=Minv[2,0:2]@QL1=-Minv[2,3:5]@G2D=np.hstack([np.eye(2),-G2])M=np.block([[H,-D.T],[-D,np.zeros((2,2))]])Minv=linalg.inv(M)K2=Minv[2,0:2]@QL2=-Minv[2,3:5]@G1Kco=np.vstack([lam[0]*K1,lam[1]*K2])Lco=np.array([[1-lam[0],lam[0]*L1[0]],[lam[1]*L2[0],1-lam[1]]])ssco=np.abs(linalg.eigvals(Lco))uco=np.zeros((2,Niter+1))uco[:,0]=ude.flatten()foriinrange(Niter):uco[:,i+1]=(Kco@ysp+Lco@uco[:,i].reshape(-1,1)).flatten()# Make lines for plottingld=np.min(unc,axis=1)ru=np.max(unc,axis=1)lr=max(-ld[0],ru[0])ud=max(-ld[1],ru[1])sslines=np.array([[-lr,lr,np.nan,-ud/m2,ud/m2],[-m1*lr,m1*lr,np.nan,-ud,ud]])sslines=sslines+np.tile(usp,(1,5))ifnotos.getenv('OMIT_PLOTS')=='true':plt.figure()plt.plot(sslines[0,:],sslines[1,:],'-k',unc[0,:],unc[1,:],'-sr',uco[0,:],uco[1,:],'-og')plt.title(f'{name} (lambda = [{lam[0]}, {lam[1]}])')plt.legend(['Steady State','Non-cooperative','Cooperative'])plt.xlabel('u_1')plt.ylabel('u_2')# Package datadata={'ss':sslines.T,'noncoop':unc.T,'coop':uco.T}returndata# Simulate with different values of lambdadata={}foriinrange(len(lams)):data[names[i]]=noncoopvscoop(lams[i],iters[i],names[i],swaps[i])# Save datagnuplotsave('stst.dat',data)