Rate-level model of TCP (2 routes)

Graphics commands

AllZero[x_,opts___] := And @@ Thread[Chop[x,opts]==0]

Needs["Splines`"]

Midpoints[c_,x_] := With[{y=(x/(Plus @@ x))},
c (Drop[FoldList[Plus,0,y],1]-(y/2)) - (c/2)] /;  ((c≥Plus @@ x) && !AllZero[x])

Midpoints[c_,x_] := Drop[FoldList[Plus,0,x],1]-(x/2)-(c/2)-((-c+Plus @@ x)/2) /; c<Plus @@ x

Midpoints[c_,{}] := {};
Midpoints[c_,x_] := Table[0,{Length[x]}] /; AllZero[x]

DrawLink[link[C_,xy_ : {.5,0} ,L_ : 1,name_ : "link",opts___]] := 
If[C==0,{},With[{x=xy[[1]],y=xy[[2]]},
Graphics[{
{GrayLevel[.8],Opacity[.5],
Rectangle[{x-L/2,y+C/2},{x+L/2,y-C/2}],
Disk[{x-L/2,y},{.1 L,C/2},{Pi/2,3Pi/2}] ,
Disk[{x+L/2,y},{.1 L,C/2},{-Pi/2,Pi/2}]},
Circle[{x-L/2,y},{.1 L,C/2}] ,
Circle[{x+L/2,y},{.1 L,C/2},{-Pi/2,Pi/2}],
Line[{{x-L/2,y+C/2},{x+L/2,y+C/2}}],
Line[{{x-L/2,y-C/2},{x+L/2,y-C/2}}]
}] ]]

DrawLinkLabel[link[C_,xy_ : {.5,0},L_:1,name_:"link",opts___],load_] := Module [ {label},
labelfunc = Label /. {opts} /. {Label->None};
If[labelfunc===None,{},labelfunc[C,load,xy]]
]

LinkName[link[C_,xy_ : {.5,0}, L_ : 1, name_ : "link",rest___]] := name

LinkCapacity[link[C_,rest___]] := C

LinkLength[link[C_,xy_ : {.5,0},L_:1,rest___]] := L

LinkCoord[link[C_,xy_:{.5,0},rest___]] := xy

FlowName[flow[rate_,waypoints_,name_]] := name

FlowRate[flow[rate_,rest___]] := rate

LinksUsed[flow[rate_,waypoints_,name_]] := Cases[waypoints, _String ]

Waypoints[flow[rate_,waypoints_,rest___]] := waypoints

Second[x_] := x[[2]]

Indicator[True] = 1;
Indicator[False] = 0;

(* Spline from start to link, line through link, spline through midpoint to next link, line through link, spline to end *)
(* Spline from start to link, line through link, spline to end *)

DrawFlow[{point[p1_],uselink[{p2_,len_},mp_],path__}] := {
Spline[{p1,p2+{-len/2-.2,mp},p2+{-len/2,mp}},Bezier],
DrawFlow[{uselink[{p2,len},mp],path}]}

DrawFlow[{uselink[{p1_,len1_},mp1_],uselink[{p2_,len2_},mp2_],path__}] :=
{Line[{p1+{-len1/2,mp1},p1+{len1/2,mp1}}],
Spline[{p1+{len1/2,mp1},p1+{len1/2+.2,mp1},(p1+{len1/2+.2,mp1}+p2+{-len2/2-.2,mp2})/2,p2+{-len2/2-.2,mp2},p2+{-len2/2,mp2}},CompositeBezier],
DrawFlow[{uselink[{p2,len2},mp2],path}]}

DrawFlow[{uselink[{p1_,len_},mp_],point[p2_]}] := {
Line[{p1+{-len/2,mp},p1+{len/2,mp}}],
Spline[{p1+{len/2,mp},p1+{len/2+.2,mp},p2},Bezier]}

DrawFlow[{uselink[{p1_,len1_},mp1_],uselink[{p2_,len2_},mp2_]}] := {
Line[{p1+{-len1/2,mp1},p1+{len1/2,mp1}}],
Spline[{p1+{len1/2,mp1},p1+{len1/2+.2,mp1},(p1+{len1/2+.2,mp1}+p2+{-len2/2-.2,mp2})/2,p2+{-len2/2-.2,mp2},p2+{-len2/2,mp2}},CompositeBezier],
Line[{p2+{-len2/2,mp2},p2+{len2/2,mp2}}] }

CleanLine[line_] := Module [ {s,a,b,cleansegment,res,inds},
cleansegment[s_Spline] := Table[s[[3]][x],{x,0,Length[First[s]]-1,1/10}];
cleansegment[Line[{a_,b_}]] := {a,b};
res = Flatten[cleansegment /@ line,1];
inds = Prepend[Select[Range[Length[res]],res[[#]]≠res[[#-1]]&],1];
Line[Part[res,inds]]
]

Rep[x_,n_] := Take[Flatten[Table[x,{n}],1],n]

ShowNetwork[objects_,opts___] := Module [ {links,flows,linknames,linkdefs,flownames,linksused,adjacency,midpoints,GetMidpoints,flowdesc,flowpaths,cols,thicks,plotrange,loads},
links = Cases[objects,_link];
flows = Cases[objects,_flow];
linknames = Thread[Rule[LinkName /@ links,Range@Length@links]];
linkdefs = Thread[Rule[LinkName /@ links,{LinkCoord[#],LinkLength[#]}& /@ links]];
flownames = Thread[Rule[FlowName /@ flows, Range@Length@flows]];
linksused = LinksUsed /@ flows;
adjacency = Function[{linkname},Indicator@MemberQ[#,linkname]& /@ linksused] /@ (First /@ linknames);
(* What are the midpoints at each link? *)
midpoints = Thread[Midpoints[LinkCapacity /@ links,(FlowRate /@ flows #)& /@ adjacency]];
(* For each flow, what is its midpoint at each link it passes through? *)
GetMidpoints[links_List,flownum_] := If[!StringQ[#],#,uselink[#,midpoints[[# /. linknames,flownum]]]]& /@ links;
(* What is the load at each link? *)
loads = (FlowRate /@ flows #)& /@ adjacency;
(* Now, draw *)
flowdesc = MapThread[GetMidpoints,{Waypoints /@ flows, Range@Length@flows}] /. linkdefs;
flowpaths = CleanLine@Flatten@DrawFlow[#] & /@ flowdesc;
cols = FlowStyle /. {opts} /. {FlowStyle->FlowColours[Length@flows]};
cols = Rep[cols,Length@flows];
plotrange = PlotRange /. {opts} /. {PlotRange->{{Min[First /@ (LinkCoord /@ links) - (LinkLength /@ links)/2]-1,
Max[First /@ (LinkCoord /@ links) + (LinkLength /@ links)/2]+1},
{Min[Second /@ (LinkCoord /@ links) - (LinkCapacity /@ links)/2-1],
Max[Second /@ (LinkCoord /@ links) + (LinkCapacity /@ links)/2]+1}}};
thicks = Thickness /@ ((FlowRate /@ flows)/(plotrange[[1,2]]-plotrange[[1,1]]));
Show[{Graphics@Transpose[{cols, thicks,flowpaths}],
DrawLink /@ links,
Graphics@MapThread[DrawLinkLabel,{links,loads}]},
PlotRange->plotrange,Sequence @@ FilterRules[FilterRules[{opts},Options[Graphics]],Except[PlotRange]]]
]

FlowColours[n_] := Table[ColorData["Pastel"][i],{i,0,1,1/(n-1)}];

FormatCapacity[x_,suffix_:""] := ToString[NumberForm[x,{3,0},NumberPadding->" ",NumberPoint->""]]<>suffix

FormatWnd[w_,suffix_:""] := ToString[NumberForm[w,{3,2},NumberPadding->" ",NumberPoint->"."]] <>suffix

FormatTime[x_] := ToString[NumberForm[1000 x,{3,0},NumberPadding->" ",NumberPoint->""]]<>" ms"

ShowLoad[C_,loads_,xy_] := Style[Text[NumberForm[100 (Plus @@ loads),{3,1}],xy,{1,0}],"Legend"]

ShowCapacity[C_,loads_,xy_] := Style[Text[NumberForm[N[100 C],{3,1}],xy,{0,0}],"Legend"]

ShowEachLoad[C_,loads_,xy_] := Style[Text[NumberForm[100 #,{3,1}]& /@ Reverse@loads,xy,{-1,0}],"Legend"]

ShowDrop[p_][C_,loads_,xy_] := Style[Text[ToString@NumberForm[100 p[C,Plus@@loads],{3,1}]<>"%",xy,{0,0}],"Legend"]

ShowVal[v_][C_,loads_,xy_] := Style[Text[ToString@NumberForm[100. v,{3,2}]<>"%",xy,{0,0}],"Legend"]

PressedIf[pressed_] = If[pressed,{"DialogBox","Pressed"},"DialogBox"];

General setup

drop[C_,y_] = Max[0,1-C/y];

updatemodel[fm_,topo_,pars_,x0_] := Module [ {res,subs,Vars,eqs,eqsi,n,terms,drifts,d0},
n = Length[fm];
terms = fm[[All,1]]; drifts=fm[[All,2]];
d0 = drifts /. topo /. Thread[terms->x0] /. pars;
If[AllZero[d0,(10^(-5))],
None,
subs = Table[terms[[i]]->Vars[i][t],{i,n}];
eqs = Table[Vars[i]'[t]==drifts[[i]],{i,n}];
eqsi = Table[Vars[i][0]==x0[[i]],{i,n}];
res = First@NDSolve[
Join[eqs,eqsi]/. topo /. subs /. pars,
Table[Vars[i],{i,n}],
{t,0,10}];
terms /. subs /. {t->10} /. res ]]

{cola1,cola2,colb1,colb2,colc1,colc2} = {RGBColor[0.76,.47,.94],Lighter[RGBColor[.76,.47,.94],.5],RGBColor[.94,.79,.59],Lighter[RGBColor[.94,.79,.59],.3],RGBColor[0.79,0.89,0.83],Darker[RGBColor[0.79,0.89,0.83],.1]};

cold = Lighter[Blue,.6];

Code

linear2a= {
y0->(rtt0^2)(y0^2)((2/((y0^2)(rtt0^2)))-p1-p2),
y1->(rtt1^2)(y1^2)((2/((y1^2)(rtt1^2)))-p1) };

linear2atopo = {p1->drop[c1,y0+y1],p2->drop[c2 ,y0]};

linear2apars = {rtt0->.1,rtt1->.1,c1->50,c2->30};

X={20,20};

X = updatemodel[linear2a,linear2atopo,linear2apars,X]

{col2,col2b,col1,col1b ,col0,col0b,col3}={Hue[.582,.08,.836],Hue[.582,.03,.632],
Hue[.582,.28,.7],Hue[.582,.28,.636],
Hue[.284,.27,.65],Hue[.284,.27,.682],
Hue[0,.776,.882]};
{Style["(Subscript[col, 0])",col0b],Style["(Subscript[col, 1])",col1b],Style["(Subscript[col, 2])",col2b]}

ShowCaption[cap_,size_,adj_:{0,0}][C_,loads_,xy_] := Inset[cap,xy,adj,size]

feas2a[pars_,x0_] := Module [ {vals,Y0,Y1,C1,C2,P1,P2},
{Y0,Y1}=x0;
C1 = c1 /. pars;
C2 = c2 /. pars;
P1 = p1/.linear2atopo/.pars/.{y0->Y0,y1->Y1};
P2=p2/.linear2atopo/.pars/.{y0->Y0,y1->Y1};
Show[Graphics[{
FaceForm[Lighter[Blue,.8]],EdgeForm[Blue],
Polygon[{{0,0},{0,Min[C1,C2]},{Max[C1-C2,0],Min[C1,C2]},{C1,0},{0,0}}],
Locator[{Y1(1-P1),Y0(1-P1)(1-P2)}]
}],
Axes->True,AxesLabel->{"(Subscript[y, A])","(Subscript[y, B])"},AxesOrigin->{0,0}
]
];
feas2a[linear2apars,X]

linear2aplot[pars_,topo_,x0_] := Module[{vals},
vals = Thread[{y0,y1}->x0];
ShowNetwork[{
link[0,{-2,3.5},1,"src0",Label->ShowLoad],
link[0,{-2,6},1,"src1",Label->ShowLoad],
link[0,{6,4.8},1,"dst0"],
link[0,{2,6},1,"dst1"],
link[c1/100 /. pars,{0,5},1,"link1",Label->ShowDrop[drop]],
link[c2/100 /. pars,{4,5},1,"link2",Label->ShowDrop[drop]],
flow[y0/100 /. vals /. pars,{"src0","link1","link2","dst0"},"flow0"],
flow[y1/100 /. vals /. pars,{"src1","link1","dst1"},"flow1"],
},PlotRange->{{-3,7},{2.5,7.5}}, 
FlowStyle->{col0,col1,col2}]
]
linear2aplot[linear2apars,linear2atopo,X]

Manipulate[
DynamicModule[{X={20,20},Xnew},
Dynamic[Refresh[
With[{pars={c1->cap1,c2->cap2,rtt0->RTT0/100,rtt1->RTT1/100}},
If[(Xnew=updatemodel[linear2a,linear2atopo,pars,X])===None,,  X=Xnew];
Row[{Show[linear2aplot[pars,linear2atopo,X],ImageSize->{Automatic,200}],Show[feas2a[pars,X],ImageSize->{Automatic,200}]}]
],
TrackedSymbols:>{cap1,cap2,RTT0,RTT1,X}] ]],
Row[{"(Subscript[C, 1]) ",Control[{{cap1,50,""},0,100,5}],Dynamic@FormatCapacity[cap1 // N," pkt/s"]}],
Row[{"(Subscript[C, 2]) ",Control[{{cap2,50,""},0,100,5}],Dynamic@FormatCapacity[cap2 // N," pkt/s"]}],
Row[{Style["(Subscript[RTT, B]) ",col0b],Control[{{RTT0,100,""},0,250,10}],Dynamic@FormatCapacity[RTT0 // N," ms"]}],
Row[{Style["(Subscript[RTT, A]) ",col1b],Control[{{RTT1,100,""},0,250,10}],Dynamic@FormatCapacity[RTT1 // N," ms"]}],
ControlPlacement->Top,
SaveDefinitions->True,
SynchronousUpdating->False
]

Rate-level model of TCP (3 routes)

Graphics commands

AllZero[x_,opts___] := And @@ Thread[Chop[x,opts]==0]

Needs["Splines`"]

Midpoints[c_,x_] := With[{y=(x/(Plus @@ x))},
c (Drop[FoldList[Plus,0,y],1]-(y/2)) - (c/2)] /;  ((c≥Plus @@ x) && !AllZero[x])

Midpoints[c_,x_] := Drop[FoldList[Plus,0,x],1]-(x/2)-(c/2)-((-c+Plus @@ x)/2) /; c<Plus @@ x

Midpoints[c_,{}] := {};
Midpoints[c_,x_] := Table[0,{Length[x]}] /; AllZero[x]

DrawLink[link[C_,xy_ : {.5,0} ,L_ : 1,name_ : "link",opts___]] := 
If[C==0,{},With[{x=xy[[1]],y=xy[[2]]},
Graphics[{
{GrayLevel[.8],Opacity[.5],
Rectangle[{x-L/2,y+C/2},{x+L/2,y-C/2}],
Disk[{x-L/2,y},{.1 L,C/2},{Pi/2,3Pi/2}] ,
Disk[{x+L/2,y},{.1 L,C/2},{-Pi/2,Pi/2}]},
Circle[{x-L/2,y},{.1 L,C/2}] ,
Circle[{x+L/2,y},{.1 L,C/2},{-Pi/2,Pi/2}],
Line[{{x-L/2,y+C/2},{x+L/2,y+C/2}}],
Line[{{x-L/2,y-C/2},{x+L/2,y-C/2}}]
}] ]]

DrawLinkLabel[link[C_,xy_ : {.5,0},L_:1,name_:"link",opts___],load_] := Module [ {label},
labelfunc = Label /. {opts} /. {Label->None};
If[labelfunc===None,{},labelfunc[C,load,xy]]
]

LinkName[link[C_,xy_ : {.5,0}, L_ : 1, name_ : "link",rest___]] := name

LinkCapacity[link[C_,rest___]] := C

LinkLength[link[C_,xy_ : {.5,0},L_:1,rest___]] := L

LinkCoord[link[C_,xy_:{.5,0},rest___]] := xy

FlowName[flow[rate_,waypoints_,name_]] := name

FlowRate[flow[rate_,rest___]] := rate

LinksUsed[flow[rate_,waypoints_,name_]] := Cases[waypoints, _String ]

Waypoints[flow[rate_,waypoints_,rest___]] := waypoints

Second[x_] := x[[2]]

Indicator[True] = 1;
Indicator[False] = 0;

(* Spline from start to link, line through link, spline through midpoint to next link, line through link, spline to end *)
(* Spline from start to link, line through link, spline to end *)

DrawFlow[{point[p1_],uselink[{p2_,len_},mp_],path__}] := {
Spline[{p1,p2+{-len/2-.2,mp},p2+{-len/2,mp}},Bezier],
DrawFlow[{uselink[{p2,len},mp],path}]}

DrawFlow[{uselink[{p1_,len1_},mp1_],uselink[{p2_,len2_},mp2_],path__}] :=
{Line[{p1+{-len1/2,mp1},p1+{len1/2,mp1}}],
Spline[{p1+{len1/2,mp1},p1+{len1/2+.2,mp1},(p1+{len1/2+.2,mp1}+p2+{-len2/2-.2,mp2})/2,p2+{-len2/2-.2,mp2},p2+{-len2/2,mp2}},CompositeBezier],
DrawFlow[{uselink[{p2,len2},mp2],path}]}

DrawFlow[{uselink[{p1_,len_},mp_],point[p2_]}] := {
Line[{p1+{-len/2,mp},p1+{len/2,mp}}],
Spline[{p1+{len/2,mp},p1+{len/2+.2,mp},p2},Bezier]}

DrawFlow[{uselink[{p1_,len1_},mp1_],uselink[{p2_,len2_},mp2_]}] := {
Line[{p1+{-len1/2,mp1},p1+{len1/2,mp1}}],
Spline[{p1+{len1/2,mp1},p1+{len1/2+.2,mp1},(p1+{len1/2+.2,mp1}+p2+{-len2/2-.2,mp2})/2,p2+{-len2/2-.2,mp2},p2+{-len2/2,mp2}},CompositeBezier],
Line[{p2+{-len2/2,mp2},p2+{len2/2,mp2}}] }

CleanLine[line_] := Module [ {s,a,b,cleansegment,res,inds},
cleansegment[s_Spline] := Table[s[[3]][x],{x,0,Length[First[s]]-1,1/10}];
cleansegment[Line[{a_,b_}]] := {a,b};
res = Flatten[cleansegment /@ line,1];
inds = Prepend[Select[Range[Length[res]],res[[#]]≠res[[#-1]]&],1];
Line[Part[res,inds]]
]

Rep[x_,n_] := Take[Flatten[Table[x,{n}],1],n]

ShowNetwork[objects_,opts___] := Module [ {links,flows,linknames,linkdefs,flownames,linksused,adjacency,midpoints,GetMidpoints,flowdesc,flowpaths,cols,thicks,plotrange,loads},
links = Cases[objects,_link];
flows = Cases[objects,_flow];
linknames = Thread[Rule[LinkName /@ links,Range@Length@links]];
linkdefs = Thread[Rule[LinkName /@ links,{LinkCoord[#],LinkLength[#]}& /@ links]];
flownames = Thread[Rule[FlowName /@ flows, Range@Length@flows]];
linksused = LinksUsed /@ flows;
adjacency = Function[{linkname},Indicator@MemberQ[#,linkname]& /@ linksused] /@ (First /@ linknames);
(* What are the midpoints at each link? *)
midpoints = Thread[Midpoints[LinkCapacity /@ links,(FlowRate /@ flows #)& /@ adjacency]];
(* For each flow, what is its midpoint at each link it passes through? *)
GetMidpoints[links_List,flownum_] := If[!StringQ[#],#,uselink[#,midpoints[[# /. linknames,flownum]]]]& /@ links;
(* What is the load at each link? *)
loads = (FlowRate /@ flows #)& /@ adjacency;
(* Now, draw *)
flowdesc = MapThread[GetMidpoints,{Waypoints /@ flows, Range@Length@flows}] /. linkdefs;
flowpaths = CleanLine@Flatten@DrawFlow[#] & /@ flowdesc;
cols = FlowStyle /. {opts} /. {FlowStyle->FlowColours[Length@flows]};
cols = Rep[cols,Length@flows];
plotrange = PlotRange /. {opts} /. {PlotRange->{{Min[First /@ (LinkCoord /@ links) - (LinkLength /@ links)/2]-1,
Max[First /@ (LinkCoord /@ links) + (LinkLength /@ links)/2]+1},
{Min[Second /@ (LinkCoord /@ links) - (LinkCapacity /@ links)/2-1],
Max[Second /@ (LinkCoord /@ links) + (LinkCapacity /@ links)/2]+1}}};
thicks = Thickness /@ ((FlowRate /@ flows)/(plotrange[[1,2]]-plotrange[[1,1]]));
Show[{Graphics@Transpose[{cols, thicks,flowpaths}],
DrawLink /@ links,
Graphics@MapThread[DrawLinkLabel,{links,loads}]},
PlotRange->plotrange,Sequence @@ FilterRules[FilterRules[{opts},Options[Graphics]],Except[PlotRange]]]
]

FlowColours[n_] := Table[ColorData["Pastel"][i],{i,0,1,1/(n-1)}];

FormatCapacity[x_,suffix_:""] := ToString[NumberForm[x,{3,0},NumberPadding->" ",NumberPoint->""]]<>suffix

FormatWnd[w_,suffix_:""] := ToString[NumberForm[w,{3,2},NumberPadding->" ",NumberPoint->"."]] <>suffix

FormatTime[x_] := ToString[NumberForm[1000 x,{3,0},NumberPadding->" ",NumberPoint->""]]<>" ms"

ShowLoad[C_,loads_,xy_] := Style[Text[NumberForm[100 (Plus @@ loads),{3,1}],xy,{1,0}],"Legend"]

ShowCapacity[C_,loads_,xy_] := Style[Text[NumberForm[N[100 C],{3,1}],xy,{0,0}],"Legend"]

ShowEachLoad[C_,loads_,xy_] := Style[Text[NumberForm[100 #,{3,1}]& /@ Reverse@loads,xy,{-1,0}],"Legend"]

ShowDrop[p_][C_,loads_,xy_] := Style[Text[ToString@NumberForm[100 p[C,Plus@@loads],{3,1}]<>"%",xy,{0,0}],"Legend"]

ShowVal[v_][C_,loads_,xy_] := Style[Text[ToString@NumberForm[100. v,{3,2}]<>"%",xy,{0,0}],"Legend"]

PressedIf[pressed_] = If[pressed,{"DialogBox","Pressed"},"DialogBox"];

General setup

drop[C_,y_] = Max[0,1-C/y];

updatemodel[fm_,topo_,pars_,x0_] := Module [ {res,subs,Vars,eqs,eqsi,n,terms,drifts,d0},
n = Length[fm];
terms = fm[[All,1]]; drifts=fm[[All,2]];
d0 = drifts /. topo /. Thread[terms->x0] /. pars;
If[AllZero[d0,(10^(-5))],
None,
subs = Table[terms[[i]]->Vars[i][t],{i,n}];
eqs = Table[Vars[i]'[t]==drifts[[i]],{i,n}];
eqsi = Table[Vars[i][0]==x0[[i]],{i,n}];
res = First@NDSolve[
Join[eqs,eqsi]/. topo /. subs /. pars,
Table[Vars[i],{i,n}],
{t,0,10}];
terms /. subs /. {t->10} /. res ]]

{cola1,cola2,colb1,colb2,colc1,colc2} = {RGBColor[0.76,.47,.94],Lighter[RGBColor[.76,.47,.94],.5],RGBColor[.94,.79,.59],Lighter[RGBColor[.94,.79,.59],.3],RGBColor[0.79,0.89,0.83],Darker[RGBColor[0.79,0.89,0.83],.1]};

cold = Lighter[Blue,.6];

Code

linear2= {
y0->(rtt0^2)(y0^2)((2/((y0^2)(rtt0^2)))-p1-p2),
y1->(rtt1^2)(y1^2)((2/((y1^2)(rtt1^2)))-p1),
y2->(rtt2^2)(y2^2)((2/((y2^2)(rtt2^2)))-p2) };

linear2topo = {p1->drop[c1,y0+y1],p2->drop[c2 ,y0+y2]};

linear2pars = {rtt0->.1,rtt1->.1,rtt2->.1,c1->50,c2->30};

X={20,20,20};

X = updatemodel[linear2,linear2topo,linear2pars,X]

{col2,col2b,col1,col1b ,col0,col0b,col3}={Hue[.582,.08,.836],Hue[.582,.03,.632],
Hue[.582,.28,.7],Hue[.582,.28,.636],
Hue[.284,.27,.65],Hue[.284,.27,.682],
Hue[0,.776,.882]};
{Style["(Subscript[col, 0])",col0b],Style["(Subscript[col, 1])",col1b],Style["(Subscript[col, 2])",col2b]}

ShowCaption[cap_,size_,adj_:{0,0}][C_,loads_,xy_] := Inset[cap,xy,adj,size]

feas[pars_,x0_] := Module [ {vals,y0,y1,y2,C1,C2},
{y0,y1,y2}=x0;
C1  = c1 /. pars;
C2 = c2 /. pars;
cc = Min[C1,C2];
Graphics3D[{
Text["(Subscript[C, 1])",{C1,-2,0}],Text["(Subscript[C, 2])",{-2,C2,0}],Text["Min((Subscript[C, 1]),(Subscript[C, 2]))",{-2,-2,cc}],
{GrayLevel[.5],Line[{{0,y2,y0},{y1,y2,y0}}],
Line[{{y1,0,y0},{y1,y2,y0}}],
Line[{{y1,y2,0},{y1,y2,y0}}]},
{Dashing[{.01,.01}],Thickness[.01],
Line[{{C1,0,0},{C1,1.2 C2,0}}],
Line[{{0,C2,0},{1.2 C1,C2,0}}]},
FaceForm[Opacity[.5]],EdgeForm[Black],
Polygon[{{0,0,0},{0,C2,0},{0,C2-cc,cc},{0,0,cc}}],
Polygon[{{0,0,0},{C1,0,0},{C1-cc,0,cc},{0,0,cc}}],
Polygon[{{C1,C2,0},{C1-cc,C2-cc,cc},{C1-cc,0,cc},{C1,0,0}}],
Polygon[{{C1,C2,0},{C1-cc,C2-cc,cc},{0,C2-cc,cc},{0,C2,0}}]
},
Boxed->False,AxesLabel->{"(Subscript[y, 1])","(Subscript[y, 2])","(Subscript[y, 0])"},Axes->True,AxesEdge->{{-1,-1},{-1,-1},{-1,-1}},AxesOrigin->{0,0,0},BoxRatios->Automatic]
]
feas[linear2pars,X]

linear2plot[pars_,topo_,x0_] := Module[{vals},
vals = Thread[{y0,y1,y2}->x0];
ShowNetwork[{
link[0,{-2,3.5},1,"src0",Label->ShowLoad],
link[0,{-2,6},1,"src1",Label->ShowLoad],
link[0,{2.5,6.5},1,"src2",Label->ShowLoad],
link[0,{6,3.5},1,"dst0"],
link[0,{2,6},1,"dst1"],
link[0,{6,6},1,"dst2"],
link[c1/100 /. pars,{0,5},1,"link1",Label->ShowDrop[drop]],
link[c2/100 /. pars,{4,5},1,"link2",Label->ShowDrop[drop]],
flow[y0/100 /. vals /. pars,{"src0","link1","link2","dst0"},"flow0"],
flow[y1/100 /. vals /. pars,{"src1","link1","dst1"},"flow1"],
flow[y2/100 /. vals /. pars,{"src2","link2","dst2"},"flow2"]
},PlotRange->{{-3,7},{2.5,7.5}}, 
FlowStyle->{col0,col1,col2}]
]
linear2plot[linear2pars,linear2topo,X]

Manipulate[
DynamicModule[{X={20,20,20},Xnew},
Dynamic[Refresh[
With[{pars={c1->cap1,c2->cap2,rtt0->RTT0/100,rtt1->RTT1/100,rtt2->RTT2/100}},
If[(Xnew=updatemodel[linear2,linear2topo,pars,X])===None,,  X=Xnew];
Row[{linear2plot[pars,linear2topo,X],feas[pars,X]}]
],
TrackedSymbols:>{cap1,cap2,RTT0,RTT1,RTT2,X}] ]],
Row[{"(Subscript[C, 1]) ",Control[{{cap1,50,""},0,100,5}],Dynamic@FormatCapacity[cap1 // N," pkt/s"]}],
Row[{"(Subscript[C, 2]) ",Control[{{cap2,50,""},0,100,5}],Dynamic@FormatCapacity[cap2 // N," pkt/s"]}],
Row[{Style["(Subscript[RTT, 0]) ",col0b],Control[{{RTT0,100,""},0,250,10}],Dynamic@FormatCapacity[RTT0 // N," ms"]}],
Row[{Style["(Subscript[RTT, 1]) ",col1b],Control[{{RTT1,100,""},0,250,10}],Dynamic@FormatCapacity[RTT1 // N," ms"]}],
Row[{Style["(Subscript[RTT, 2]) ",col2b],Control[{{RTT2,100,""},0,250,10}],Dynamic@FormatCapacity[RTT2 // N," ms"]}],
ControlPlacement->Top,
SaveDefinitions->True,
SynchronousUpdating->False
]

Rate-level model of wireless throughput

Code

jointjoint[r_,β_] := r[[1]]<Log[2,1+Min[β[[1,All]]]] && r[[2]]<Log[2,1+Min[β[[2,All]]]] && r[[1]]+r[[2]]≤Log[1+Min[β[[1,1]]+β[[2,1]],β[[2,1]]+β[[2,2]]]]

sepsep[r_,β_] := Max[((2^(r[[1]]))-1)(β[[2,2]]+β[[2,1]]((2^(r[[2]]))-1)),((2^(r[[2]]))-1)(β[[1,1]]+β[[1,2]]((2^(r[[1]]))-1))]≤β[[1,1]]β[[2,2]]-((2^(r[[1]]))-1)((2^(r[[2]]))-1)β[[1,2]]β[[2,1]]

jointsep[r_,β_]:=(((2^(r[[2]]))-1)/(β[[2,1]]))≤1 && Max[(((2^(r[[1]]))-1)/(β[[1,1]])),(((2^(r[[1]]+r[[2]]))-1-β[[2,1]])/(β[[1,1]]))]≤Min[1,(((β[[2,2]])/((2^(r[[2]]))-1))-1)/β[[1,2]]]

sepjoint[r_,β_]:=(((2^(r[[1]]))-1)/(β[[1,2]]))≤1 && Max[(((2^(r[[2]]))-1)/(β[[2,2]])),(((2^(r[[1]]+r[[2]]))-1-β[[1,2]])/(β[[2,2]]))]≤Min[1,(((β[[1,1]])/((2^(r[[1]]))-1))-1)/β[[2,1]]]

apA={0,0}; apB={10,0};src1={2,.8};src2={15,.5};
Manipulate[
snr1=100;snr2=100;
g1 = LocatorPane[Dynamic[{apA,apB,src1,src2}],
Dynamic@Graphics[{
Arrow[{src1,apA}],Arrow[{src2,apB}],
Opacity[.2],Pink,Disk[src1,(((snr1 (10^(-#/10))))^(1/2))]& /@ {5,10,15,20},
Lighter[Blue,.5],Disk[src2,(((snr2 (10^(-#/10))))^(1/2))]& /@ {5,10,15,20}
},
PlotRange->{{-10,20},{-5,15}},ImageSize->Medium]
];
g2 = With[{β=(({{(snr1/((Norm[src1-apA])^2)), (snr2/((Norm[src1-apB])^2))}, {(snr2/((Norm[src2-apA])^2)), (snr2/((Norm[src2-apB])^2))}}) )},
RegionPlot[{sepsep[{(Subscript[r, 1]),(Subscript[r, 2])},β] && MemberQ[coding,"separate"],(jointjoint[{(Subscript[r, 1]),(Subscript[r, 2])},β] || jointsep[{(Subscript[r, 1]),(Subscript[r, 2])},β] || sepjoint[{(Subscript[r, 1]),(Subscript[r, 2])},β]) && MemberQ[coding,"joint"]},
{(Subscript[r, 1]),0,4},{(Subscript[r, 2]),0,4},ImageSize->Medium,AxesLabel->{"(Subscript[y, 0])","(Subscript[y, 1])"},Axes->True,Frame->False]
];
Row[{g1,g2}],
{coding,{"separate","joint"},CheckboxBar},
SynchronousUpdating->False,TrackedSymbols:>{src1,src2,apA,apB,coding},
SaveDefinitions->True]

Rate-level model of multipath TCP

Code

Manipulate[
reg1[y1_,y2_,{Ca_,Cb_,Cc_}] = y1≤Ca && y2≤Cb;
reg2[y1_,y2_,{Ca_,Cb_,Cc_}] = y2≤Cb && y1≤Ca+Min[Cb,Cc] && y1+y2≤Ca+Cb;
reg3[y1_,y2_,{Ca_,Cb_,Cc_}] = y1≤Ca+Min[Cb,Cc] && y2≤Cb+Cc && 2y1+y2≤2Ca+Cb+Cc;
p = {Ca,Cb,Cc};
Row[{RegionPlot[{reg1[y1,y2,p],reg2[y1,y2,p],reg3[y1,y2,p]},{y1,0,200},{y2,0,200},PlotPoints->ControlActive[8,32],ImageSize->Medium],
Column[{,,}]}],
Row[{"(Subscript[C, a]) ",Control[{{Ca,50,""},0,100,5}],Dynamic@FormatCapacity[Ca // N," Mb/s"]}],
Row[{"(Subscript[C, b]) ",Control[{{Cb,50,""},0,100,5}],Dynamic@FormatCapacity[Cb // N," Mb/s"]}],
Row[{"(Subscript[C, c]) ",Control[{{Cc,50,""},0,100,5}],Dynamic@FormatCapacity[Cc // N," Mb/s"]}],
TrackedSymbols:>{Ca,Cb,Cc},
SynchronousUpdating->Automatic
]