Epsilon-Delta Plots

The cells in this group define the function EDPlot.  This command makes a plot to illustrate the ϵ-δ definition of the statement “the limit of f(x) as x approaches c is L.”  The syntax is:
EDPlot[f[x], {x, c, maxdelta}, {L, maxepsilon}]
The parameters maxdelta and maxepsilon are the largest values of δ and ϵ that you want the graph to illustrate.  For example, to illustrate that the limit of sin(2x) as x approaches π is 0, you might use the command:
EDPlot[Sin[2x], {x, Pi, 2}, {0, 1}]
This command specifies that the largest value of δ to be used is δ = 2, and the largest value of ϵ will be ϵ = 1.

You can give an optional argument to specify a formula for δ in terms of ϵ.  For example, in the case of sin(2x), you can take δ to be ϵ/2.  To use this choice of δ, you would use the command:
EDPlot[Sin[2x], {x, Pi, 2}, {0, 1}, DeltaFunction -> epsilon/2]

Evaluate the initialization cells, and then try the examples below.  Drag the sliders to try out different values of δ and ϵ.

interpy[p_,q_,y_]:=If[p[[2]]==q[[2]],p,{(y-p[[2]])/(q[[2]]-p[[2]])(q[[1]]-p[[1]])+p[[1]],y}]

sll[state_,linelist_]:=If[state==3,{AbsoluteThickness[1],Hue[.67,.6,.6],Line[linelist]},If[state==1,{AbsoluteThickness[2],Hue[.67],Line[linelist]},{AbsoluteThickness[2],Hue[1],Line[linelist]}]]

search[points_,start_,end_,x_]:=Module[{a,b,c},
a=start;
b=end;
While[b>a+1,
c=Quotient[a+b,2];
If[points[[c]][[1]]<x,
a=c,
b=c
]
];
b
]

st[p_,l_,r_,b_,t_]:=(If[p[[2]]>t,Return[2]];
If[p[[2]]<b,Return[0]];
If[p[[1]]==l,Return[1]];
If[p[[1]]==r,Return[1]];
If[p[[2]]==t,Return[2]];
If[p[[2]]==b,Return[0]];
1)

EDPlot[func_,{var_,c_,deltamax_},{L_,epsilonmax_},OptionsPattern[{DeltaFunction->None}]]:=DynamicModule[{left,right,bottom,top,graphlines,numlines,df},
left=c-deltamax;
right=c+deltamax;
bottom = L-epsilonmax;
top=L+epsilonmax;
graphlines=Cases[Plot[func,{var,left,right},PlotRange->{bottom,top}],Line[_],Infinity];
numlines=Length[graphlines];
df=OptionValue[DeltaFunction];
Manipulate[Module[{g,works,leftline,rightline,bottomline,topline,i,nextline,numpoints,leftpt,rightpt,midpiece,j,j0,p,in,in2,state,newstate,nextpiece},
If[!MatchQ[df,None],
del=df/.epsilon->eps;
If[del>deltamax,del=deltamax,If[del≤0,del=deltamax/100]]
];
works=True;
leftline=c-del;
rightline=c+del;
bottomline=L-eps;
topline = L+eps;
g=Flatten[Reap[
Do[nextline=graphlines[[i]][[1]];   (*for i=1 to numlines*)
numpoints=Length[nextline];
leftpt=search[nextline,0,numpoints+1,leftline];
If[leftpt>numpoints,Sow[nextline,3],
rightpt=search[nextline,leftpt-1,numpoints+1,rightline];
If[rightpt==1,Sow[nextline,3],
If[leftpt==rightpt,
midpiece={},
midpiece=Take[nextline,{leftpt,rightpt-1}]
];
If[leftpt>1,
in={leftline,Max[Min[func/.var->leftline,top],bottom]};
Sow[Append[Take[nextline,leftpt-1],in],3];
PrependTo[midpiece,in]
];
If[rightpt≤numpoints,
in={rightline,Max[Min[func/.var->rightline,top],bottom]};
Sow[Prepend[Take[nextline,{rightpt,numpoints}],in],3];
AppendTo[midpiece,in]
];
numpoints=Length[midpiece];
p=midpiece[[1]];
state=st[p,leftline,rightline,bottomline,topline];
If[state≠1,works=False];
j0=1;
Do[p=midpiece[[j]];   (*for j = 2 to numpoints*)
newstate=st[p,leftline,rightline,bottomline,topline];
If[state≠newstate,
works=False;
If[j0==1,
nextpiece=Take[midpiece,j-1],
nextpiece=Prepend[Take[midpiece,{j0,j-1}],in]
];
Which[((state==0)&&(newstate==1))||((state==1)&&(newstate==0)),
in=interpy[midpiece[[j-1]],p,bottomline];
Sow[Append[nextpiece,in],state],
((state==1)&&(newstate==2))||((state==2)&&(newstate==1)),
in=interpy[midpiece[[j-1]],p,topline];
Sow[Append[nextpiece,in],state],
(state==0)&&(newstate==2),
in2=interpy[midpiece[[j-1]],p,bottomline];
in=interpy[in2,p,topline];
Sow[Append[nextpiece,in2],0];
Sow[{in2,in},1],
True,
in2=interpy[midpiece[[j-1]],p,topline];
in=interpy[in2,p,bottomline];
Sow[Append[nextpiece,in2],2];
Sow[{in2,in},1]
];
j0=j;
state=newstate
],
{j,2,numpoints}]; (*end Do*)
If[j0==1,
Sow[midpiece,state],
Sow[Prepend[Take[midpiece,{j0,numpoints}],in],state]
]
]
],
{i,1,numlines}]; (* end Do*)
,{0,1,2,3},sll][[2]]];  (*end Reap*)
Graphics[Join[
{Hue[1,.1,1],
Rectangle[{leftline,bottom},{rightline,bottomline}],
Rectangle[{leftline,topline},{rightline,top}],
AbsoluteThickness[1],GrayLevel[0],Line[{{{leftline,bottom},{leftline,top}},
{{rightline,bottom},{rightline,top}},
{{left,bottomline},{right,bottomline}},
{{left,topline},{right,topline}}}],AbsoluteDashing[5],Line[{{{c,bottom},{c,top}},{{left,L},{right,L}}}],AbsoluteDashing[{}]},g],
{Axes->True,PlotLabel->works,AspectRatio->1}]],
{{eps,N[epsilonmax/2],Style["ϵ", FontSize->16]},epsilonmax/100,epsilonmax,Appearance->"Labeled"},{{del,N[deltamax/2],Style["δ",FontSize->16]},If[MatchQ[df,None],deltamax/100,0],deltamax,Appearance->"Labeled"}]
]

EDPlot[Sin[2x],{x,Pi,2},{0,1}]

EDPlot[Sin[2x],{x,Pi,2},{0,1},DeltaFunction->epsilon/2]

EDPlot[x Sin[1/x],{x,0,.5},{0,.5}]

EDPlot[Sin[1/x],{x,0,.5},{0,1.5}]

EDPlot[x^2,{x,2,2},{4,8}]

EDPlot[x^2,{x,2,2},{4,8},DeltaFunction->epsilon/5]

EDPlot[x^2,{x,2,2},{4,8},DeltaFunction->Min[1,epsilon/5]]