PDF_TARGET = $(TARGET_ROOT).pdf
PS_TARGET = $(TARGET_ROOT).ps
+GS = gs
+PS2PDF = ps2pdf
+PS2PNG = $(GS) -dSAFER -dBATCH -dNOPAUSE -sDEVICE=png16m
+
TEX_OPTIONS = --quiet $(EXTRA_TEX_OPTIONS)
+FIGURES_PNG = $(FIGURES_EPS:.eps=.png)
+FIGURES_PDF = $(FIGURES_EPS:.eps=.pdf)
+
all: $(INFO_TARGET) $(TARGETS)
-$(INFO_TARGET): $(SOURCES)
+$(INFO_TARGET): $(SOURCES) $(FIGURES_PNG)
rm -f $(INFO_TARGET)*
makeinfo --output=$(INFO_TARGET) $(TEXINFO_ROOT).texinfo
-$(HTML_TARGET)/index.html: $(SOURCES)
+$(HTML_TARGET)/index.html: $(SOURCES) $(FIGURES_PNG)
rm -rf $(HTML_TARGET)
makeinfo --html $(TEXINFO_ROOT).texinfo
-$(PDF_TARGET): $(SOURCES)
+$(PDF_TARGET): $(SOURCES) $(FIGURES_PDF)
texi2dvi --pdf $(TEX_OPTIONS) --output=$@ $(TEXINFO_ROOT).texinfo
-$(PS_TARGET): $(SOURCES)
+$(PS_TARGET): $(SOURCES) $(FIGURES_EPS)
-rm -f $(DVI_TARGET)
texi2dvi $(TEX_OPTIONS) --output=$(DVI_TARGET) $(TEXINFO_ROOT).texinfo
dvips -q -o $@ $(DVI_TARGET)
rm -f $(DVI_TARGET)
+.SUFFIXES: .eps
+.SUFFIXES: .pdf
+.SUFFIXES: .png
+
+.eps.pdf:
+ $(PS2PDF) -dEPSCrop -sOutputFile=$@.tmp $< && mv -f $@.tmp $@
+
+.eps.png:
+ $(PS2PNG) -dEPSCrop -sOutputFile=$@.tmp $< && mv -f $@.tmp $@
+
mostlyclean:
clean: mostlyclean
rm -f $(INFO_TARGET)* $(PDF_TARGET) $(PS_TARGET)
+ rm -f $(FIGURES_PDF)
+ rm -f $(FIGURES_PNG)
rm -rf $(HTML_TARGET)
rm -rf $(TEXINFO_ROOT).aux $(TEXINFO_ROOT).log $(TEXINFO_ROOT).toc
rm -rf $(TEXINFO_ROOT).pg $(TEXINFO_ROOT).tp
vectors.texi \
win32-packaging.texi
+FIGURES_EPS = \
+ fig/cn-expm1.eps \
+ fig/cn-log1mexp.eps \
+ fig/cn-log1p.eps \
+ fig/cn-log1pexp.eps \
+ fig/cn-logistic.eps \
+ fig/cn-logistichalf.eps \
+ fig/cn-logit.eps \
+ fig/cn-logitexp.eps \
+ fig/cn-logithalf.eps \
+ fig/cn-loglogistic.eps \
+ fig/expm1.eps \
+ fig/log1mexp.eps \
+ fig/log1p.eps \
+ fig/log1pexp.eps \
+ fig/logistic.eps \
+ fig/logistichalf.eps \
+ fig/logit.eps \
+ fig/logitexp.eps \
+ fig/logithalf.eps \
+ fig/loglogistic.eps \
+ # end of FIGURES_EPS
+
include $(top_srcdir)/make-common
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto
+llx ury lineto
+urx ury lineto
+urx lly lineto
+closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -1.8 def /aymax 2.8 def
+
+% Interpolation parameters.
+/nspline 20 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin axmin a2bb moveto
+ axmax axmax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 2 1 0 tick 2 1 yticklabel
+ 0 1 1 0 tick
+ 0 -1 1 0 tick
+grestore
+
+% Plot another one: expm1 condition number.
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax { % Tx => T(f(x))
+ dup Texpm1 % Tx T(e^x-1)
+ dup Tq 0.0 eq {
+ Texp
+ } {
+ exch dup % T(e^x-1) Tx Tx
+ Texp Tmul % T(e^x-1) T(x*e^x)
+ exch Tdiv % T(x*e^x/(e^x-1))
+ } ifelse
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 0.5 def /aymin -2.8 def /aymax 0.5 def
+
+% Interpolation parameters.
+/nspline 75 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin axmin a2bb moveto
+ axmax axmax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 1 1 0 tick
+ 0 -1 1 0 tick -1 1 yticklabel
+ 0 -2 1 0 tick -2 1 yticklabel
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ 5 dict begin
+ /Tf {
+ dup Texp % Tx T(e^x)
+ dup Tneg Tln1p % Tx T(e^x) T(log(1-e^x))
+ 2 index Texpm1 Tneg % Tx T(e^x) T(log(1-e^x)) T(1-e^x)
+ Tmul % Tx T(e^x) T((1-e^x)*log(1-e^x))
+ Tdiv Tmul Tneg % T((-x*e^x)/((1-e^x)*log(1-e^x)))
+ } def
+ /fxmax -0.0001 def
+ /fxmin axmin def
+ /n nspline def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ nspline axmin -0.0001 {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n axmin -0.0001 {Tf} cubicsplinterpostep curveto } for
+ % Fabricate a final point at the origin with positive
+ % derivative. (Too lazy to compute the limit...)
+ 0.0 0.0 T % Tx0 Ty0 Tx3
+ 0.0 1.0 T % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol
+ 5 index Tq 5 index Tq
+ curveto
+ cubicsplinterpostop
+ stroke
+ end
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -1.2 def /axmax 2.2 def /aymin -1.8 def /aymax 2.8 def
+
+% Interpolation parameters.
+/nspline 20 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll sub % tx y ys -(ury+lly)/2 llx-urx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ -1 aymin a2bb moveto
+ -1 aymax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick
+
+ % y ticks
+ 0 2 1 0 tick 2 1 yticklabel
+ 0 1 1 0 tick
+ 0 -1 1 0 tick
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline -0.9 axmax {
+ dup dup % Tx Tx Tx
+ 1.0 Tconst Tadd % Tx Tx T(1+x)
+ Tdiv % Tx T(x/(1+x))
+ exch Tln1p % T(x/(1+x)) T(log(1+x))
+ Tdiv % T(x/[(1+x)*log(1+x)])
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto
+llx ury lineto
+urx ury lineto
+urx lly lineto
+closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -1.8 def /aymax 2.8 def
+
+% Interpolation parameters.
+/nspline 20 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin axmin a2bb moveto
+ axmax axmax a2bb lineto
+ stroke
+ newpath
+ axmin 1 a2bb moveto
+ axmax 1 a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont % encoding => encoding
+ {
+ dup 45 /minus put % replace hyphen by minus
+ } reencodefont
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 2 -1 0 tick 2 -1 yticklabel
+ 0 1 -1 0 tick
+ 0 -1 -1 0 tick -1 -1 yticklabel
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ nspline axmin axmax { % Tx => T(f(x))
+ dup Texp % Tx T(e^x)
+ dup Tln1p % Tx T(e^x) T(log(1+e^x))
+ 1 index 1.0 Tconst Tadd % Tx T(e^x) T(log(1+e^x)) T(1+e^x)
+ Tmul % Tx T(e^x) T((1+e^x)*log(1+e^x))
+ Tdiv Tmul % T((x*e^x)/((1+e^x)*log(1+e^x)))
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto
+llx ury lineto
+urx ury lineto
+urx lly lineto
+closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -2.5 def /aymax 1.5 def
+
+% Interpolation parameters.
+/nspline 8 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin axmin a2bb moveto
+ axmax axmax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 1 -1 0 tick 1 -1 yticklabel
+ 0 0.5 -0.5 0 tick
+ 0 -0.5 -0.5 0 tick
+ 0 -1 -1 0 tick
+ 0 -1.5 -0.5 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax { % Tx => T(f(x))
+ dup Tneg Texp % Tx T(e^-x)
+ dup 1.0 Tconst Tadd % Tx T(e^-x) T(1 + e^-x)
+ Tdiv % Tx T(e^-x/(1 + e^-x))
+ Tmul % T(x*e^-x/(1 + e^-x))
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto
+llx ury lineto
+urx ury lineto
+urx lly lineto
+closepath
+clip
+
+% Axes.
+/axmin -4.5 def /axmax 4.5 def /aymin -0.5 def /aymax 1.2 def
+
+% Interpolation parameters.
+/nspline 8 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin 1 a2bb moveto
+ axmax 1 a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 4 0 0 -1 tick 4 -1 xticklabel
+ 3 0 0 -1 tick
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1 0 0 -1 tick
+ -1 0 0 -1 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+ -3 0 0 -1 tick
+ -4 0 0 -1 tick -4 -1 xticklabel
+
+ % y ticks
+ 0 1 -1 0 tick 1 -1 yticklabel
+ 0 0.75 -0.5 0 tick
+ 0 0.5 -0.5 0 tick
+ 0 0.25 -0.5 0 tick
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax { % Tx => T(f(x))
+ dup Tneg Texp % Tx T(e^-x)
+ dup dup Tmul % Tx T(e^-x) T(e^-2x)
+ 1.0 Tconst exch Tsub % Tx T(e^-x) T(1-e^-2x)
+ Tdiv % Tx T(e^-x/(1-e^-2x))
+ 2.0 Tconst Tmul Tmul % T(2x*e^-x/(1-e^-2x))
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -0.2 def /axmax 1.2 def /aymin -3.2 def /aymax 6.2 def
+
+% Interpolation parameters.
+/nspline 75 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logistic % x => 1/(1+e^{-x})
+{
+ 0 exch sub 2.718281828 exch exp 1 add 1 exch div
+} def
+
+/logit % p => log(p/(1-p))
+{
+ dup -1.0 logistic lt % p (p<logistic(-1))
+ 1 index 1.0 logistic gt % p (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 exch sub % p 1-p
+ div ln % log(p/(1-p))
+ } {
+ dup 2.0 mul % p 2p
+ 1.0 exch sub % p 1-2p
+ exch div % (1-2p)/p
+ ln1p % log1p((1-2p)/p)
+ 0.0 exch sub % -log1p((1-2p)/p)
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogit % Tp => T(log(p/(1-p)))
+{
+ dup Tq -1.0 logistic lt % Tp (p<logistic(-1))
+ 1 index Tq 1.0 logistic gt % Tp (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 Tconst exch Tsub % Tp T(1-p)
+ Tdiv Tln % T(log(p/(1-p)))
+ } {
+ dup 2.0 Tconst Tmul % Tp T2p
+ 1.0 Tconst exch Tsub % Tp T(1-2p)
+ exch Tdiv % T((1-2p)/p)
+ Tln1p % T(log1p((1-2p)/p))
+ 0.0 Tconst exch Tsub % T(-log1p((1-2p)/p))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+/newton % n x0 Tf => x
+{
+ 0 1 5 -1 roll % x0 Tf start step n
+ {
+ pop % x0 Tf
+ 1 index Tvar % x0 Tf Tx0
+ 1 index % x0 Tf Tx0 Tf
+ exec % x0 Tf Ty0
+ Tqv % x0 Tf y0 dy0
+ dup 0.0 eq { pop pop exit } if
+ div % x0 Tf y0/dy0
+ 2 index exch % x0 Tf x0 y0/dy0
+ sub % x0 Tf x1
+ dup 0.0 ne {
+ dup 3 index sub % x0 Tf x1 x1-x0
+ 1 index div abs % x0 Tf x1 |(x1-x0)/x1|
+ eps le { pop exit } if
+ } if
+ exch % x0 x1 Tf
+ 3 -1 roll % x1 Tf x0
+ pop % x1 Tf
+ } for
+ pop % x
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+/f
+{
+ dup Tlogit exch % T(log(p/(1-p))) Tp
+ 1.0 Tconst exch Tsub % T(log(p/(1-p))) T(1-p)
+ 1.0 Tconst exch Tdiv % T(log(p/(1-p))) T(1/(1-p))
+ exch Tdiv % T((1/(1-p))/(log(p/(1-p))))
+} def
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ 0.5 aymin a2bb moveto
+ 0.5 aymax a2bb lineto
+ stroke
+ newpath
+ 1 aymin a2bb moveto
+ 1 aymax a2bb lineto
+ stroke
+
+ % Find the minimum of the dip.
+ 10 0.75 { % numerator of f'
+ dup dup % Tp Tp Tp
+ 1.0 Tconst exch Tsub % Tp Tp T(1-p)
+ 1.0 Tconst exch Tdiv % Tp Tp T(1/(1-p))
+ Tmul % Tp T(p/(1-p))
+ Tln % Tp T(log(p/(1-p)))
+ Tmul % T(p*log(p/(1-p)))
+ 1.0 Tconst Tsub % T(p*log(p/(1-p))-1)
+ } newton
+ Tvar f Tq
+ newpath
+ axmin 1 index a2bb moveto
+ axmax 1 index a2bb lineto
+ stroke
+ pop
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.875 0 0 -0.25 tick
+ 0.75 0 0 -0.25 tick
+ 0.625 0 0 -0.25 tick
+ 0.5 0 0 -0.5 tick 0.5 -1 xticklabel
+ 0.375 0 0 -0.25 tick
+ 0.25 0 0 -0.25 tick
+ 0.125 0 0 -0.25 tick
+
+ % y ticks
+ 0 5 -0.5 0 tick
+ 0 4 -1 0 tick 4 -1 yticklabel
+ 0 3 -0.5 0 tick
+ 0 2 -1 0 tick 2 -1 yticklabel
+ 0 1 -0.5 0 tick
+ 0 -1 -0.5 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline 0.00001 0.499 {f} cubicsplinterpolate
+ nspline 0.501 0.999 {f} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -3.2 def /axmax 0.5 def /aymin -4.5 def /aymax 4.5 def
+
+% Interpolation parameters.
+/nspline 70 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logistic % x => 1/(1+e^{-x})
+{
+ 0 exch sub 2.718281828 exch exp 1 add 1 exch div
+} def
+
+/logit % p => log(p/(1-p))
+{
+ dup -1.0 logistic lt % p (p<logistic(-1))
+ 1 index 1.0 logistic gt % p (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 exch sub % p 1-p
+ div ln % log(p/(1-p))
+ } {
+ dup 2.0 mul % p 2p
+ 1.0 exch sub % p 1-2p
+ exch div % (1-2p)/p
+ ln1p % log1p((1-2p)/p)
+ 0.0 exch sub % -log1p((1-2p)/p)
+ } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp % Tx => T(e^x)
+{
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1 % Tx => T(e^x-1)
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogit % Tp => T(log(p/(1-p)))
+{
+ dup Tq -1.0 logistic lt % Tp (p<logistic(-1))
+ 1 index Tq 1.0 logistic gt % Tp (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 Tconst exch Tsub % Tp T(1-p)
+ Tdiv Tln % T(log(p/(1-p)))
+ } {
+ dup 2.0 Tconst Tmul % Tp T2p
+ 1.0 Tconst exch Tsub % Tp T(1-2p)
+ exch Tdiv % T((1-2p)/p)
+ Tln1p % T(log1p((1-2p)/p))
+ 0.0 Tconst exch Tsub % T(-log1p((1-2p)/p))
+ } ifelse
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin 1 a2bb moveto
+ axmax 1 a2bb lineto
+ stroke
+ newpath
+ 0.5 ln aymin a2bb moveto
+ 0.5 ln aymax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+ -2.25 0 0 -0.5 tick
+ -2.5 0 0 -0.5 tick
+ -2.75 0 0 -0.5 tick
+ -3 0 0 -1 tick -3 -1 xticklabel
+
+ % y ticks
+ 0 3 -0.5 0 tick
+ 0 2 -1 0 tick 2 0.5 yticklabel
+ 0 1 -0.5 0 tick
+ 0 -1 -0.5 0 tick
+ 0 -2 -1 0 tick -2 0.5 yticklabel
+ 0 -3 -0.5 0 tick
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin -0.694 {
+ dup Texpm1 Tneg % Tx T(1-e^x)
+ 1 index Texp Tlogit % Tx T(1-e^x) T(log(e^x/(1-e^x)))
+ Tmul Tdiv % T(x/((1-e^x)*log((e^x/(1-e^x)))))
+ } cubicsplinterpolate
+ nspline -0.693 -.0001 {
+ dup Texpm1 Tneg % Tx T(1-e^x)
+ 1 index Texp Tlogit % Tx T(1-e^x) T(log(e^x/(1-e^x)))
+ Tmul Tdiv % T(x/((1-e^x)*log((e^x/(1-e^x)))))
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -0.75 def /axmax 0.75 def /aymin -3.2 def /aymax 6.2 def
+
+% Interpolation parameters.
+/nspline 90 def % must be even here to avoid zero
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ -0.5 aymin a2bb moveto
+ -0.5 aymax a2bb lineto
+ stroke
+ newpath
+ 0.5 aymin a2bb moveto
+ 0.5 aymax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 0.5 0 0 -1 tick 0.5 -1 xticklabel
+ 0.375 0 0 -0.25 tick
+ 0.25 0 0 -0.5 tick
+ 0.125 0 0 -0.25 tick
+ -0.125 0 0 -0.25 tick
+ -0.25 0 0 -0.5 tick
+ -0.375 0 0 -0.25 tick
+ -0.5 0 0 -1 tick -0.5 -1 xticklabel
+
+ % y ticks
+ 0 5 -0.5 0 tick
+ 0 4 -1 0 tick 4 -1 yticklabel
+ 0 3 -0.5 0 tick
+ 0 2 -1 0 tick 2 -1 yticklabel
+ 0 1 -0.5 0 tick
+ 0 -1 -0.5 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline -.499 .499 {
+ dup dup % Tx Tx Tx
+ dup Tmul % Tx Tx T(x^2)
+ 4.0 Tconst Tmul % Tx Tx T(4x^2)
+ 1.0 Tconst exch Tsub % Tx Tx T(1-4x^2)
+ Tdiv % Tx T(x/(1-4x^2))
+ exch Tlogithalf % T(x/(1-4x^2)) T(log((1/2+x)/(1/2-x)))
+ Tdiv
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -3.5 def /aymax 1.5 def
+
+% Interpolation parameters.
+/nspline 40 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp % Tx => T(e^x)
+{
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1 % Tx => T(e^x-1)
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin 1 a2bb moveto
+ axmax 1 a2bb lineto
+ stroke
+ newpath
+ axmin 0 axmin sub a2bb moveto
+ axmax 0 axmax sub a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 1 -1 0 tick 1 1 yticklabel
+ 0 -1 -1 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+ 0 -3 -1 0 tick
+grestore
+
+gsave
+ 1 0 0 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax {
+ dup Tneg Texp % Tx T(e^-x)
+ dup 1.0 Tconst Tadd % Tx T(e^-x) T(1+e^-x)
+ 1 index Tln1p % Tx T(e^-x) T(1+e^-x) T(log(1+e^-x))
+ Tmul % Tx T(e^-x) T((1+e^-x)*log(1+e^-x))
+ Tdiv % Tx T(e^-x/((1+e^-x)*log(1+e^-x)))
+ Tmul % T(x*e^-x/((1+e^-x)*log(1+e^-x)))
+ Tneg % T(-x*e^-x/((1+e^-x)*log(1+e^-x)))
+ } cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -1.8 def /aymax 2.8 def
+
+% Interpolation parameters.
+/nspline 20 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logistic % x => 1/(1+e^{-x})
+{
+ 0 exch sub 2.718281828 exch exp 1 add 1 exch div
+} def
+
+/logit % p => log(p/(1-p))
+{
+ dup -1.0 logistic lt % p (p<logistic(-1))
+ 1 index 1.0 logistic gt % p (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 exch sub % p 1-p
+ div ln % log(p/(1-p))
+ } {
+ dup 2.0 mul % p 2p
+ 1.0 exch sub % p 1-2p
+ exch div % (1-2p)/p
+ ln1p % log1p((1-2p)/p)
+ 0.0 exch sub % -log1p((1-2p)/p)
+ } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp % Tx => T(e^x)
+{
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1 % Tx => T(e^x-1)
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogit % Tp => T(log(p/(1-p)))
+{
+ dup Tq -1.0 logistic lt % Tp (p<logistic(-1))
+ 1 index Tq 1.0 logistic gt % Tp (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 Tconst exch Tsub % Tp T(1-p)
+ Tdiv Tln % T(log(p/(1-p)))
+ } {
+ dup 2.0 Tconst Tmul % Tp T2p
+ 1.0 Tconst exch Tsub % Tp T(1-2p)
+ exch Tdiv % T((1-2p)/p)
+ Tln1p % T(log1p((1-2p)/p))
+ 0.0 Tconst exch Tsub % T(-log1p((1-2p)/p))
+ } ifelse
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin -1 a2bb moveto
+ axmax -1 a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 2 1 0 tick 2 1 yticklabel
+ 0 1 1 0 tick
+ 0 -1 1 0 tick
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax {Texpm1} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 0.5 def /aymin -2.8 def /aymax 0.5 def
+
+% Interpolation parameters.
+/nspline 70 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logistic % x => 1/(1+e^{-x})
+{
+ 0 exch sub 2.718281828 exch exp 1 add 1 exch div
+} def
+
+/logit % p => log(p/(1-p))
+{
+ dup -1.0 logistic lt % p (p<logistic(-1))
+ 1 index 1.0 logistic gt % p (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 exch sub % p 1-p
+ div ln % log(p/(1-p))
+ } {
+ dup 2.0 mul % p 2p
+ 1.0 exch sub % p 1-2p
+ exch div % (1-2p)/p
+ ln1p % log1p((1-2p)/p)
+ 0.0 exch sub % -log1p((1-2p)/p)
+ } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp % Tx => T(e^x)
+{
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1 % Tx => T(e^x-1)
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogit % Tp => T(log(p/(1-p)))
+{
+ dup Tq -1.0 logistic lt % Tp (p<logistic(-1))
+ 1 index Tq 1.0 logistic gt % Tp (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 Tconst exch Tsub % Tp T(1-p)
+ Tdiv Tln % T(log(p/(1-p)))
+ } {
+ dup 2.0 Tconst Tmul % Tp T2p
+ 1.0 Tconst exch Tsub % Tp T(1-2p)
+ exch Tdiv % T((1-2p)/p)
+ Tln1p % T(log1p((1-2p)/p))
+ 0.0 Tconst exch Tsub % T(-log1p((1-2p)/p))
+ } ifelse
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 1 1 0 tick
+ 0 -1 1 0 tick -1 1 yticklabel
+ 0 -2 1 0 tick -2 1 yticklabel
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin -.001 {Texp Tneg Tln1p} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -1.2 def /axmax 2.2 def /aymin -3.8 def /aymax 2.8 def
+
+% Interpolation parameters.
+/nspline 70 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logistic % x => 1/(1+e^{-x})
+{
+ 0 exch sub 2.718281828 exch exp 1 add 1 exch div
+} def
+
+/logit % p => log(p/(1-p))
+{
+ dup -1.0 logistic lt % p (p<logistic(-1))
+ 1 index 1.0 logistic gt % p (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 exch sub % p 1-p
+ div ln % log(p/(1-p))
+ } {
+ dup 2.0 mul % p 2p
+ 1.0 exch sub % p 1-2p
+ exch div % (1-2p)/p
+ ln1p % log1p((1-2p)/p)
+ 0.0 exch sub % -log1p((1-2p)/p)
+ } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp % Tx => T(e^x)
+{
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1 % Tx => T(e^x-1)
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogit % Tp => T(log(p/(1-p)))
+{
+ dup Tq -1.0 logistic lt % Tp (p<logistic(-1))
+ 1 index Tq 1.0 logistic gt % Tp (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 Tconst exch Tsub % Tp T(1-p)
+ Tdiv Tln % T(log(p/(1-p)))
+ } {
+ dup 2.0 Tconst Tmul % Tp T2p
+ 1.0 Tconst exch Tsub % Tp T(1-2p)
+ exch Tdiv % T((1-2p)/p)
+ Tln1p % T(log1p((1-2p)/p))
+ 0.0 Tconst exch Tsub % T(-log1p((1-2p)/p))
+ } ifelse
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ -1 aymin a2bb moveto
+ -1 aymax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+
+ % y ticks
+ 0 2 -1 0 tick
+ 0 1 -1 0 tick 1 -1 yticklabel
+ 0 -1 -1 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+ 0 -3 -1 0 tick
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline -0.99 axmax {Tln1p} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto
+llx ury lineto
+urx ury lineto
+urx lly lineto
+closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -1.8 def /aymax 2.8 def
+
+% Interpolation parameters.
+/nspline 20 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin axmin a2bb moveto
+ axmax axmax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont % encoding => encoding
+ {
+ dup 45 /minus put % replace hyphen by minus
+ } reencodefont
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 2 -1 0 tick 2 -1 yticklabel
+ 0 1 -1 0 tick
+ 0 -1 -1 0 tick -1 -1 yticklabel
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ nspline axmin axmax {Texp Tln1p} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto
+llx ury lineto
+urx ury lineto
+urx lly lineto
+closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -0.5 def /aymax 1.2 def
+
+% Interpolation parameters.
+/nspline 20 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogistic % Tx => T(1/(1+e^{-x}))
+{
+ 0.0 Tconst exch Tsub Texp % T(e^{-x})
+ 1.0 Tconst Tadd % T(1+e^{-x})
+ 1.0 Tconst exch Tdiv % T(1/(1+e^{-x}))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin 1 a2bb moveto
+ axmax 1 a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 1 -1 0 tick 1 -1 yticklabel
+ 0 0.75 -0.5 0 tick
+ 0 0.5 -0.5 0 tick
+ 0 0.25 -0.5 0 tick
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax {Tlogistic} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto
+llx ury lineto
+urx ury lineto
+urx lly lineto
+closepath
+clip
+
+% Axes.
+/axmin -4.5 def /axmax 4.5 def /aymin -0.75 def /aymax 0.75 def
+
+% Interpolation parameters.
+/nspline 8 def
+/linearsplinterpoint { linpoint } def % i n => s_{i,n}
+/cubicsplinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ 2.718281828 exch exp 1 sub
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogistic % Tx => T(1/(1+e^{-x}))
+{
+ 0.0 Tconst exch Tsub Texp % T(e^{-x})
+ 1.0 Tconst Tadd % T(1+e^{-x})
+ 1.0 Tconst exch Tdiv % T(1/(1+e^{-x}))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+/linearsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0 1 n {/i exch def
+ i n linearsplinterpoint Tconst
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb Tq exch Tq exch
+ i 0 eq { moveto } { lineto } ifelse
+ } for
+ stroke
+ end
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 6 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ 0.0 0 n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0
+ 1 index Tq % Tx0 Ty0 x0
+ 1 index Tq % Tx0 Ty0 x0 y0
+ moveto % Tx0 Ty0
+ 0 1 n 1 sub {/i exch def % Tx0 Ty0
+ % Construct a cubic curve segment:
+ % c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+ % Note that
+ % c(0) = p0, c'(0) = 3 p1 - 3 p0,
+ % c(1) = p1, c'(1) = 3 p3 - 3 p2,
+ % so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+ % p1 = p0 + c'(0)/3,
+ % p2 = p3 - c'(1)/3.
+ %
+ % Compute Tx3 and Ty3.
+ 1.0 i n cubicsplinter
+ fxwidth Tconst Tmul fxmin Tconst Tadd
+ dup Tf Ta2bb % Tx0 Ty0 Tx3 Ty3
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+ % Draw the curve.
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3
+ 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+ curveto % Tx3 Ty3
+ } for
+ pop pop % ---
+ stroke
+ end
+} def
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/cubicsplinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ cubicsplinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ cubicsplinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin 0.5 a2bb moveto
+ axmax 0.5 a2bb lineto
+ stroke
+ newpath
+ axmin -0.5 a2bb moveto
+ axmax -0.5 a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 4 0 0 -1 tick 4 -1 xticklabel
+ 3 0 0 -1 tick
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1 0 0 -1 tick
+ -1 0 0 1 tick
+ -2 0 0 1 tick -2 1 xticklabel
+ -3 0 0 1 tick
+ -4 0 0 1 tick -4 1 xticklabel
+
+ % y ticks
+ 0 0.5 -1 0 tick 0.5 -1 yticklabel
+ 0 0.25 -0.5 0 tick
+ 0 -0.25 -0.5 0 tick
+ 0 -0.5 -1 0 tick -0.5 -1 yticklabel
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax {Tlogistic 0.5 Tconst Tsub} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -0.2 def /axmax 1.2 def /aymin -4.2 def /aymax 4.2 def
+
+% Interpolation parameters.
+/nspline 75 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logistic % x => 1/(1+e^{-x})
+{
+ 0 exch sub 2.718281828 exch exp 1 add 1 exch div
+} def
+
+/logit % p => log(p/(1-p))
+{
+ dup -1.0 logistic lt % p (p<logistic(-1))
+ 1 index 1.0 logistic gt % p (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 exch sub % p 1-p
+ div ln % log(p/(1-p))
+ } {
+ dup 2.0 mul % p 2p
+ 1.0 exch sub % p 1-2p
+ exch div % (1-2p)/p
+ ln1p % log1p((1-2p)/p)
+ 0.0 exch sub % -log1p((1-2p)/p)
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogit % Tp => T(log(p/(1-p)))
+{
+ dup Tq -1.0 logistic lt % Tp (p<logistic(-1))
+ 1 index Tq 1.0 logistic gt % Tp (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 Tconst exch Tsub % Tp T(1-p)
+ Tdiv Tln % T(log(p/(1-p)))
+ } {
+ dup 2.0 Tconst Tmul % Tp T2p
+ 1.0 Tconst exch Tsub % Tp T(1-2p)
+ exch Tdiv % T((1-2p)/p)
+ Tln1p % T(log1p((1-2p)/p))
+ 0.0 Tconst exch Tsub % T(-log1p((1-2p)/p))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+/newton % n x0 Tf => x
+{
+ 0 1 5 -1 roll % x0 Tf start step n
+ {
+ pop % x0 Tf
+ 1 index Tvar % x0 Tf Tx0
+ 1 index % x0 Tf Tx0 Tf
+ exec % x0 Tf Ty0
+ Tqv % x0 Tf y0 dy0
+ dup 0.0 eq { pop pop exit } if
+ div % x0 Tf y0/dy0
+ 2 index exch % x0 Tf x0 y0/dy0
+ sub % x0 Tf x1
+ dup 0.0 ne {
+ dup 3 index sub % x0 Tf x1 x1-x0
+ 1 index div abs % x0 Tf x1 |(x1-x0)/x1|
+ eps le { pop exit } if
+ } if
+ exch % x0 x1 Tf
+ 3 -1 roll % x1 Tf x0
+ pop % x1 Tf
+ } for
+ pop % x
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 3 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 3 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ 1 aymin a2bb moveto
+ 1 aymax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.875 0 0 -0.25 tick
+ 0.75 0 0 -0.25 tick
+ 0.625 0 0 -0.25 tick
+ 0.5 0 0 -0.5 tick 0.5 -1 xticklabel
+ 0.375 0 0 -0.25 tick
+ 0.25 0 0 -0.25 tick
+ 0.125 0 0 -0.25 tick
+
+ % y ticks
+ 0 3 -0.5 0 tick
+ 0 2 -1 0 tick 2 -1 yticklabel
+ 0 1 -0.5 0 tick
+ 0 -1 -0.5 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+ 0 -3 -0.5 0 tick
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline 0.00001 0.999 {Tlogit} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -3.2 def /axmax 0.5 def /aymin -4.5 def /aymax 4.5 def
+
+% Interpolation parameters.
+/nspline 40 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logistic % x => 1/(1+e^{-x})
+{
+ 0 exch sub 2.718281828 exch exp 1 add 1 exch div
+} def
+
+/logit % p => log(p/(1-p))
+{
+ dup -1.0 logistic lt % p (p<logistic(-1))
+ 1 index 1.0 logistic gt % p (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 exch sub % p 1-p
+ div ln % log(p/(1-p))
+ } {
+ dup 2.0 mul % p 2p
+ 1.0 exch sub % p 1-2p
+ exch div % (1-2p)/p
+ ln1p % log1p((1-2p)/p)
+ 0.0 exch sub % -log1p((1-2p)/p)
+ } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp % Tx => T(e^x)
+{
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1 % Tx => T(e^x-1)
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogit % Tp => T(log(p/(1-p)))
+{
+ dup Tq -1.0 logistic lt % Tp (p<logistic(-1))
+ 1 index Tq 1.0 logistic gt % Tp (p<logistic(-1)) (p>logistic(1))
+ or {
+ dup 1.0 Tconst exch Tsub % Tp T(1-p)
+ Tdiv Tln % T(log(p/(1-p)))
+ } {
+ dup 2.0 Tconst Tmul % Tp T2p
+ 1.0 Tconst exch Tsub % Tp T(1-2p)
+ exch Tdiv % T((1-2p)/p)
+ Tln1p % T(log1p((1-2p)/p))
+ 0.0 Tconst exch Tsub % T(-log1p((1-2p)/p))
+ } ifelse
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin axmin a2bb moveto
+ axmax axmax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+ -2.25 0 0 -0.5 tick
+ -2.5 0 0 -0.5 tick
+ -2.75 0 0 -0.5 tick
+ -3 0 0 -1 tick -3 -1 xticklabel
+
+ % y ticks
+ 0 3 -0.5 0 tick
+ 0 2 -1 0 tick 2 0.5 yticklabel
+ 0 1 -0.5 0 tick
+ 0 -1 -0.5 0 tick
+ 0 -2 -1 0 tick -2 0.5 yticklabel
+ 0 -3 -0.5 0 tick
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin -.001 {Texp Tlogit} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -0.75 def /axmax 0.75 def /aymin -3.2 def /aymax 3.2 def
+
+% Interpolation parameters.
+/nspline 90 def % must be even here to avoid zero
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp {
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptotes.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ -0.5 aymin a2bb moveto
+ -0.5 aymax a2bb lineto
+ stroke
+ newpath
+ 0.5 aymin a2bb moveto
+ 0.5 aymax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 0.5 0 0 -1 tick 0.5 -1 xticklabel
+ 0.375 0 0 -0.25 tick
+ 0.25 0 0 -0.5 tick
+ 0.125 0 0 -0.25 tick
+ -0.125 0 0 -0.25 tick
+ -0.25 0 0 -0.5 tick
+ -0.375 0 0 -0.25 tick
+ -0.5 0 0 -1 tick -0.5 -1 xticklabel
+
+ % y ticks
+ 0 5 -0.5 0 tick
+ 0 4 -1 0 tick 4 -1 yticklabel
+ 0 3 -0.5 0 tick
+ 0 2 -1 0 tick 2 -1 yticklabel
+ 0 1 -0.5 0 tick
+ 0 -1 -0.5 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline -.499 .499 {Tlogithalf} cubicsplinterpolate
+grestore
+
+showpage
--- /dev/null
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 0 0 180 60
+%%BeginProlog
+
+% Bounding box parameters.
+/llx 0 def /lly 0 def /urx 180 def /ury 60 def
+/bbwidth urx llx sub def /bbheight ury lly sub def
+newpath
+llx lly moveto llx ury lineto urx ury lineto urx lly lineto closepath
+clip
+
+% Axes.
+/axmin -2.2 def /axmax 2.2 def /aymin -3.5 def /aymax 0.5 def
+
+% Interpolation parameters.
+/nspline 40 def
+/splinterpoint { chebypoint } def % i n => s_{i,n}
+
+% Derived axis parameters.
+/awidth axmax axmin sub def
+/aheight aymax aymin sub def
+
+% 1pt margin on either side for arrow heads.
+/a2bbx bbwidth 2 sub awidth div def
+/a2bby bbheight 2 sub aheight div def
+
+/a2bb % xa ya => xbb ybb
+{
+ exch a2bbx mul % ya xbb
+ exch a2bby mul % xbb ybb
+} def
+
+/Ta2bb % Txa Tya => Txbb Tybb
+{
+ exch a2bbx Tconst Tmul % Tyf Tx2bb
+ exch a2bby Tconst Tmul % Txbb Tybb
+} def
+
+% Math utilities.
+
+/eps 1.0 { dup 2 div dup 1.0 add 1.0 eq { pop exit } if exch pop } loop def
+/sqrteps eps sqrt def
+/cbrteps eps 1 3 div exp def
+
+/ln1p % x => log(1+x)
+{
+ dup 1.0 add % x 1+x
+ dup 1.0 eq { pop } {
+ dup ln % x 1+x log(1+x)
+ 3 -1 roll % 1+x log(1+x) x
+ mul % 1+x x*log(1+x)
+ exch % x*log(1+x) 1+x
+ 1.0 sub % x*log(1+x) (1+x)-1
+ div % x*log(1+x)/[(1+x)-1]
+ } ifelse
+} def
+
+/expm1
+{
+ dup abs cbrteps gt {
+ % e^x - 1
+ 2.718281828 exch exp 1 sub
+ } { dup abs sqrteps gt {
+ % x + x^2/2 + x^3/3
+ dup dup dup dup % x x x x
+ mul mul 6 div % x x x^3/6
+ exch dup mul 2 div % x x^3/6 x^2/2
+ add add % x+x^2/2+x^3/6
+ } { dup abs eps gt {
+ % x + x^2/2
+ dup dup mul 2 div add
+ } {
+ % nothing
+ } ifelse } ifelse } ifelse
+} def
+
+/logithalf % p => log((1/2+p)/(1/2-p))
+{
+ dup abs 0.5 1.0 3.718281828 div sub le {
+ dup 2 mul % p 2p
+ exch 0.5 exch sub % 2p 1/2-p
+ div ln1p % log(1+2p/(1/2-p))
+ } {
+ dup 0.5 add % p 1/2+p
+ exch 0.5 exch sub % 1/2+p 1/2-p
+ div ln % log((1/2+p)/(1/2-p))
+ } ifelse
+} def
+
+% Automatic differentiation.
+
+/T { 2 array astore } def % x dx => [x dx]
+/Tq { 0 get } def % Tx => x (`position')
+/Tv { 1 get } def % Tx => dx (`velocity')
+/Tqv { dup 0 get exch 1 get } def % [x dx] => x dx
+/Tvar { 1.0 T } def % x => [x 1]
+/Tconst { 0.0 T } def % x => [x 0]
+
+/Tadd % Tx Ty => T(x+y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ exch % y dy dx x
+ 4 -1 roll add % dy dx x+y
+ 3 1 roll add % x+y dx+dy
+ T % T(x+y)
+} def
+
+/Tmul % Tx Ty => T(x*y)
+{
+ Tqv % Tx y dy
+ 3 -1 roll % y dy Tx
+ Tqv % y dy x dx
+ 3 -1 roll % y x dx dy
+ 2 index mul % y x dx x*dy
+ exch % y x x*dy dx
+ 3 index mul % y x x*dy y*dx
+ add % y x y*dx+x*dy
+ 3 1 roll mul % y*dx+x*dy x*y
+ exch % x*y y*dx+x*dy
+ T % T(x*y)
+} def
+
+/Tneg % Tx => T(-x)
+{
+ Tqv % x dx
+ 0 exch sub % x -dx
+ exch % -dx x
+ 0 exch sub % -dx -x
+ exch % -x -dx
+ T % T(-x)
+} def
+
+/Trecip % Tx => T(1/x)
+{
+ Tqv exch % x dx
+ 1 exch div % dx 1/x
+ dup dup % dx 1/x 1/x 1/x
+ 4 1 roll % 1/x dx 1/x 1/x
+ 0 exch sub % 1/x dx 1/x -1/x
+ mul mul % 1/x -dx/x^2
+ T % T(1/x)
+} def
+
+/Tsub { Tneg Tadd } def % Tx Ty => T(x-y)
+/Tdiv { Trecip Tmul } def % Tx Ty => T(x/y)
+
+/Tln % Tx => T(log x)
+{
+ Tqv % x dx
+ exch dup ln % dx x log(x)
+ 3 1 roll % log(x) dx x
+ div % log(x) dx/x
+ T % T(log x)
+} def
+
+/Tln1p % Tx => T(log(1+x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ ln1p % dx x log(1+x)
+ 3 1 roll % log(1+x) dx x
+ 1 add % log(1+x) dx 1+x
+ div % log(1+x) dx/(1+x)
+ T % T(log(1+x))
+} def
+
+/Texp % Tx => T(e^x)
+{
+ Tqv % x dx
+ exch 2.718281828 exch exp exch % e^x dx
+ 1 index mul % e^x e^x*dx
+ T % T(e^x)
+} def
+
+/Texpm1 % Tx => T(e^x-1)
+{
+ Tqv % x dx
+ exch dup expm1 % dx x e^x-1
+ 3 1 roll % e^x-1 dx x
+ 2.718281828 exch exp % e^x-1 dx e^x
+ mul % e^x-1 e^x*dx
+ T % T(e^x-1)
+} def
+
+/Tsin % Tx => T(sin(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ sin exch cos % dx sin(x) cos(x)
+ 3 -1 roll % sin(x) cos(x) dx
+ 0.017453292519943295 mul
+ mul % sin(x) cos(x)*dx
+ T % T(sin(x))
+} def
+
+/Tcos % Tx => T(cos(x))
+{
+ Tqv % x dx
+ exch dup % dx x x
+ cos exch sin % dx cos(x) sin(x)
+ 3 -1 roll % cos(x) sin(x) dx
+ 0.017453292519943295 mul
+ mul 1 exch sub % cos(x) -sin(x)*dx
+ T % T(cos(x))
+} def
+
+/Tlogithalf % Tp => T(log((1/2+p)/(1/2-p)))
+{
+ dup Tq abs 0.5 1.0 3.718281828 div sub le {
+ dup 2.0 Tconst Tmul % Tp T(2p)
+ exch 0.5 Tconst exch Tsub % T(2p) T(1/2-p)
+ Tdiv Tln1p % T(log(1+2p/(1/2-p)))
+ } {
+ dup 0.5 Tconst Tadd % T(p) T(1/2+p)
+ exch 0.5 Tconst exch Tsub % T(1/2+p) T(1/2-p)
+ Tdiv Tln % T(log((1/2+p)/(1/2-p)))
+ } ifelse
+} def
+
+/Tlerp % Tt fxmin fxmax => Tx
+{
+ 1 index sub Tconst % Tt fxmin T(fxmax-fxmin)
+ 3 -1 roll Tmul % fxmin T((fxmax-fxmin)*t)
+ exch Tconst Tadd % T(fxmin+(fxmax-fxmin)*t)
+} def
+
+/Tlogistic % Tx => T(1/(1+e^{-x}))
+{
+ 0.0 Tconst exch Tsub Texp % T(e^{-x})
+ 1.0 Tconst Tadd % T(1+e^{-x})
+ 1.0 Tconst exch Tdiv % T(1/(1+e^{-x}))
+} def
+
+% Interpolation points.
+
+/linpoint { div } def % i n => s_{n,i}
+
+/chebypoint % i n => s_{n,i}
+{
+ exch % n i
+ dup 0 eq {
+ pop pop 0.0
+ } {
+ 2 copy eq {
+ pop pop 1.0
+ } {
+ 2 mul 1 sub % n 2i-1
+ exch 2 mul % 2i-1 2n
+ div % (2i-1)/(2i)
+ 180 mul cos % cos(pi*(2i-1)/(2n))
+ 1 exch sub % 1-cos(pi*(2i-1)/(2n))
+ 2 div % [1-cos(pi*(2i-1)/(2n))]/2
+ } ifelse
+ } ifelse
+} def
+
+% Spline interpolation.
+
+% Compute the tangent vector of a piecewise linear interpolation
+% between two consecutive spline interpolation nodes:
+%
+% c_i(t) := xmin + (xmax - xmin)*(x_i + (x_{i+1} - x_i)*t)
+% c_i(1) = c_{i-1}(0)
+%
+/splinter % t i n => T(c_i(t))
+{
+ 2 copy % t i n i n
+ splinterpoint % t i n x0
+ 3 1 roll % t x0 i n
+ exch 1 add exch % t x0 i+1 n
+ splinterpoint % t x0 x1
+ 1 index sub Tconst % t x0 T(x1-x0)
+ 3 -1 roll Tvar % x0 T(x1-x0) Tt
+ Tmul % x0 T((x1-x0)*t)
+ exch Tconst % T((x1-x0)*t) Tx0
+ Tadd % T(x0+(x1-x0)*t)
+} def
+
+% Evaluate the tangent vector f(fxmin + (fxmax - fxmin)*c_i(t)).
+/splinterpoval % fxmin fxmax Tf t i n => x0 y0
+{
+ splinter % fxmin fxmax Tf Tc
+ 4 2 roll % Tf Tc fxmin fxmax
+ Tlerp % Tf Tx0a
+ dup 3 -1 roll % Tx0a Tx0a Tf
+ exec % Tx0a Ty0a
+ Ta2bb % Tx0 Ty0
+} def
+
+% Compute control points of a cubic spline matching the starting and
+% ending tangent vectors. Pops the starting vectors, keeps the ending.
+%
+% c(t) = (1-t)^3 p0 + 3 t (1-t)^2 p1 + 3 t^2 (1-t) p2 + t^3 p3,
+%
+% Note that
+%
+% c(0) = p0, c'(0) = 3 p1 - 3 p0,
+% c(1) = p1, c'(1) = 3 p3 - 3 p2,
+%
+% so p0 = c(0) = (x0, y0), p3 = c(1) = (x1, y1), and
+%
+% p1 = p0 + c'(0)/3,
+% p2 = p3 - c'(1)/3.
+%
+/cubicsplinterpocontrol % Tx0 Ty0 Tx3 Ty3 => Tx3 Ty3 x1 y1 x2 y2
+{
+ 4 2 roll % Tx3 Ty3 Tx0 Ty0
+ % Compute x1 = x1 + dx1/3.
+ exch Tqv % Tx3 Ty3 Ty0 x0 dx0
+ 3 div add % Tx3 Ty3 Ty0 x1
+ % Compute y1 = y0 + dy0/3.
+ exch Tqv % Tx3 Ty3 x1 y0 dy0
+ 3 div add % Tx3 Ty3 x1 y1
+ % Compute x2 = x3 - dx3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x3 dx3
+ 3 div sub % Tx3 Ty3 x1 y1 x2
+ % Compute y2 = y3 - dy3/3.
+ 3 index Tqv % Tx3 Ty3 x1 y1 x2 y3 dy3
+ 3 div sub % Tx3 Ty3 x1 y1 x2 y2
+} def
+
+/cubicsplinterpostart % n fxmin fxmax Tf => Tx0 Ty0 x0 y0
+{
+ 0.0 0 % n fxmin fxmax Tf t i
+ 6 -1 roll % fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0
+ 1 index Tq 1 index Tq % Tx0 Ty0 x0 y0
+} def
+
+/cubicsplinterpostep % Tx0 Ty0 i n fxmin fxmax Tf
+ % => Tx3 Ty3 x1 y1 x2 y2 x3 y3
+{
+ 1.0 % Tx0 Ty0 i n fxmin fxmax Tf t
+ 6 -2 roll % Tx0 Ty0 fxmin fxmax Tf t i n
+ splinterpoval % Tx0 Ty0 Tx3 Ty3
+ cubicsplinterpocontrol % Tx3 Ty3 x1 y1 x2 y2
+ 5 index Tq 5 index Tq % Tx3 Ty3 x1 y1 x2 y2 x3 y3
+} def
+
+/cubicsplinterpostop % Tx3 Ty3 => ---
+{
+ pop pop
+} def
+
+/cubicsplinterpolate % n fxmin fxmax Tf => ---
+{
+ 5 dict begin
+ /Tf exch def
+ /fxmax exch def
+ /fxmin exch def
+ /n exch def
+ /fxwidth fxmax fxmin sub def
+ newpath
+ n fxmin fxmax {Tf} cubicsplinterpostart moveto % Tx0 Ty0
+ 0 1 n 1 sub { n fxmin fxmax {Tf} cubicsplinterpostep curveto } for
+ cubicsplinterpostop
+ stroke
+ end
+} def
+
+% Graphics.
+
+/arrowhead % x y angle => ---
+{
+ gsave
+ 1 setlinecap
+ newpath
+ 3 1 roll % angle x y
+ moveto rotate
+ -2 2 rmoveto 2 -2 rlineto -2 -2 rlineto
+ stroke
+ grestore
+} def
+
+/ticku 5 def % tick size in pt
+
+/tick % xa ya tx ty => ---
+{
+ exch ticku mul % xa ya ty dxbb
+ exch ticku mul % xa ya dxbb dybb
+ 4 2 roll a2bb % dxbb dybb xbb ybb
+ gsave newpath moveto rlineto stroke grestore
+} def
+
+/ticklabel % v xa ya dxbb dybb => ---
+{
+ 4 2 roll a2bb % v dxbb dybb xbb ybb
+ newpath moveto rlineto show
+} def
+
+/xticklabel % x ty => ---
+{
+ exch dup % ty x x
+ 4 string cvs % ty x xs
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % ty x xs llx lly urx ury
+ grestore
+ 3 -1 roll sub % ty x xs llx urx ury-lly
+ 3 1 roll exch add % ty x xs ury-lly urx+llx
+ 2 div % ty x xs ury-lly (urx+llx)/2
+ 0 exch sub % ty x xs ury-lly -(urx+llx)/2
+ exch % ty x xs -(urx+llx)/2 ury-lly
+ ticku 2 mul add % ty x xs -w/2 h
+ 5 -1 roll mul % x xs -w/2 h*ty
+ 4 -1 roll % xs -w/2 h*ty x
+ 0 % xs -w/2 h*ty x y
+ 4 2 roll % xs x y -w/2 h*ty
+ ticklabel
+} def
+
+/yticklabel % y tx => ---
+{
+ exch dup % tx y y
+ 4 string cvs % tx y ys
+ gsave
+ newpath 0 0 moveto
+ dup true charpath
+ pathbbox % tx y ys llx lly urx ury
+ grestore
+ 3 -1 roll add 2 div % tx y ys llx urx (ury+lly)/2
+ 0 exch sub % tx y ys llx urx -(ury+lly)/2
+ 3 1 roll exch sub % tx y ys -(ury+lly)/2 urx-llx
+ 4 index 0 lt {
+ ticku 2 mul add
+ } {
+ pop ticku 2 mul
+ } ifelse % tx y ys -h/2 w
+ 5 -1 roll mul % y ys -h/2 w*tx
+ exch % y ys w*tx -h/2
+ 4 -1 roll % ys w*tx -h/2 y
+ 0 % ys w*tx -h/2 y x
+ exch % ys w*tx -h/2 x y
+ 4 2 roll % ys x y w*tx -h/2
+ ticklabel
+} def
+
+/reencodefont % name font proc => font'
+{
+ exch dup length dict copy % name proc font'
+ dup /Encoding get % name proc font' encoding
+ dup length array copy % name proc font' encoding'
+ 3 -1 roll exec % name font' encoding'
+ 1 index exch % name font' encoding' font'
+ /Encoding exch put % name font'
+ definefont
+} def
+
+%%EndProlog
+
+% Center coordinates with 1pt margin for arrow heads.
+0 axmin sub 0 aymin sub a2bb 1 add exch 1 add exch translate
+
+% Draw reference asymptote.
+gsave
+ 0.5 setgray
+ 0.25 setlinewidth
+ [2 3] 0 setdash
+ newpath
+ axmin axmin a2bb moveto
+ axmax axmax a2bb lineto
+ stroke
+grestore
+
+% Draw axes.
+gsave
+ 0.125 setlinewidth
+ /Times-Roman-Numeric
+ /Times-Roman findfont
+ { dup 45 /minus put } reencodefont % replace hyphen by minus
+ 10 scalefont setfont
+
+ newpath axmin 0 a2bb moveto axmax 0 a2bb lineto stroke
+ axmax 0 a2bb 0 arrowhead
+ axmin 0 a2bb 180 arrowhead
+ newpath 0 aymin a2bb moveto 0 aymax a2bb lineto stroke
+ 0 aymax a2bb 90 arrowhead
+ 0 aymin a2bb -90 arrowhead
+
+ % x ticks
+ 2 0 0 -1 tick 2 -1 xticklabel
+ 1.75 0 0 -0.5 tick
+ 1.5 0 0 -0.5 tick
+ 1.25 0 0 -0.5 tick
+ 1 0 0 -1 tick 1 -1 xticklabel
+ 0.75 0 0 -0.5 tick
+ 0.5 0 0 -0.5 tick
+ 0.25 0 0 -0.5 tick
+ -0.25 0 0 -0.5 tick
+ -0.5 0 0 -0.5 tick
+ -0.75 0 0 -0.5 tick
+ -1 0 0 -1 tick -1 -1 xticklabel
+ -1.25 0 0 -0.5 tick
+ -1.5 0 0 -0.5 tick
+ -1.75 0 0 -0.5 tick
+ -2 0 0 -1 tick -2 -1 xticklabel
+
+ % y ticks
+ 0 -1 -1 0 tick
+ 0 -2 -1 0 tick -2 -1 yticklabel
+ 0 -3 -1 0 tick
+grestore
+
+gsave
+ 0 0 1 setrgbcolor
+ 0.5 setlinewidth
+ 1 setlinecap
+ nspline axmin axmax {Tlogistic Tln} cubicsplinterpolate
+grestore
+
+showpage
argument.
@end deffn
-@deffn procedure expm1 z
-@deffnx procedure log1p z
+@deffn procedure log1p z
+@deffnx procedure expm1 z
Equivalent to:
@iftex
@tex
-$$\mathop{\rm expm1} z = \exp (z) - 1,$$
-$$\mathop{\rm log1p} z = \log (1 + z).$$
+\eqimage{fig/log1p}{$$\mathop{\rm log1p} z = \log (1 + z).$$}
+\eqimage{fig/expm1}{$$\mathop{\rm expm1} z = \exp (z) - 1,$$}
@end tex
@end iftex
@ifnottex
@example
@group
-expm1 z = exp(z) - 1,
log1p z = log(1 + z).
+expm1 z = exp(z) - 1,
@end group
@end example
+@image{fig/log1p}
+@image{fig/expm1}
+
@end ifnottex
However, for real numbers close to zero, these provide better
-approximations than @code{(- (exp @var{z}) 1)} or @code{(log (+ 1
-@var{z}))}:
+approximations than @code{(log (+ 1 @var{z}))} or @code{(- (exp
+@var{z}) 1)}:
@itemize @bullet
@item
@iftex
@tex
-$$x f'(x)/f(x) = {x/(1 + x) \over \log(1 + x)}.$$
+\eqimage{fig/cn-log1p}
+ {$$x f'(x)/f(x) = {x/(1 + x) \over \log(1 + x)}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = [x/(1 + x)]/log(1 + x).
@end example
+@image{fig/cn-log1p}
+
@end ifnottex
(Conversely, the condition number of log near @math{0} approaches
@math{0}, while the condition number of log1p near @math{-1} is
@iftex
@tex
-$$x f'(x)/f(x) = {x e^x \over e^x - 1}.$$
+\eqimage{fig/cn-expm1}
+ {$$x f'(x)/f(x) = {x e^x \over e^x - 1}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = x e^x/(e^x - 1).
@end example
+@image{fig/cn-expm1}
@end ifnottex
@end itemize
Equivalent to:
@iftex
@tex
-$$\mathop{\rm log1mexp} x = \log (1 - e^x),$$
-$$\mathop{\rm log1pexp} x = \log (1 + e^x).$$
+\eqimage{fig/log1mexp}{$$\mathop{\rm log1mexp} x = \log (1 - e^x),$$}
+\eqimage{fig/log1pexp}{$$\mathop{\rm log1pexp} x = \log (1 + e^x).$$}
@end tex
@end iftex
@ifnottex
@end group
@end example
-@end ifnottex
+@image{fig/log1mexp}
+@image{fig/log1pexp}
+@end ifnottex
Like log1p and expm1, these avoid numerical pathologies with the
intermediate quantities @math{1 - e^x} and @math{1 + e^x} and inputs
to log near @math{1}.
This implementation gives forward relative error bounded by ten times
the forward relative error bound of the system math library's log and
exp, which is usually below 1ulp.
+
+Beware that although the forward relative error of the MIT/GNU Scheme
+@emph{implementations} of these functions is bounded, these
+@emph{functions} are ill-conditioned for large negative inputs:
+@iftex
+@tex
+\nobreak\par\nobreak%
+$$x f'(x)/f(x) = {\pm x e^x \over (1 \pm e^x) \log(1 \pm e^x)}
+ \approx x, \quad\hbox{for $x \ll 0$.}$$
+\nobreak\par\nobreak\leavevmode%
+\begingroup%
+ % Load up the two figures into \box0 and \box1.
+ \setbox0=\hbox{\image{fig/cn-log1pexp}}%
+ \setbox1=\hbox{\image{fig/cn-log1mexp}}%
+ % Compute the width we have to work with here in \dimen0.
+ \dimen0=\hsize%
+ \advance\dimen0 by -\leftskip%
+ \advance\dimen0 by -\hangindent%
+ \advance\dimen0 by -\rightskip%
+ % Create an hbox of that width for the two figures with horizontal
+ % space before, between, and after.
+ \hbox to \dimen0{%
+ \hfill%
+ \vbox{\dimen0=\wd0 \box0 % Save width and dispense with box.
+ \hbox to\dimen0{\hfill Condition number of log1pexp\hfill}}%
+ \hfill%
+ \vbox{\dimen1=\wd1 \box1 % Save width and dispense with box.
+ \hbox to\dimen1{\hfill Condition number of log1mexp\hfill}}%
+ \hfill%
+ }%
+\endgroup
+@end tex
+@end iftex
+@ifnottex
+
+@example
+x f'(x)/f(x) = (+/- x exp(x))/((1 +/- e^x) log(1 +/- e^x)),
+ --> x, for x << 0.
+@end example
+
+@image{fig/cn-log1mexp}
+@image{fig/cn-log1pexp}
+
+@end ifnottex
@end deffn
@deffn procedure logistic x
Equivalent to:
@iftex
@tex
-$$\mathop{\rm logistic} x = {e^x \over 1 + e^x} = {1 \over 1 + e^{-x}} = \mathop{\rm logit}\nolimits^{-1} x,$$
-$$\mathop{\rm logit} p = \log {p \over 1 - p} = \mathop{\rm logistic}\nolimits^{-1} p.$$
+\eqimage{fig/logistic}
+ {$$\mathop{\rm logistic} x = {e^x \over 1 + e^x} = {1 \over 1 + e^{-x}},$$}
+\eqimage{fig/logit}
+ {$$\mathop{\rm logit} p = \log {p \over 1 - p} = \log {1 \over {1\over p} - 1}.$$}
@end tex
@end iftex
@ifnottex
@itemize @bullet
@item
The logistic function is defined on the entire real line, but is
-ill-conditioned for large @var{x}, with condition number
+ill-conditioned for large negative @var{x}, with condition number
@iftex
@tex
-$$x f'(x)/f(x) = {x e^{-x} \over 1 + e^{-x}}.$$
+\eqimage{fig/cn-logistic}
+ {$$x f'(x)/f(x) = {x e^{-x} \over 1 + e^{-x}}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = x exp(-x)/[1 + exp(-x)].
@end example
+@image{fig/cn-logistic}
+
@end ifnottex
The identity
@iftex
condition number
@iftex
@tex
-$$x f'(x)/f(x) = {1/(1 - p) \over \log (p/(1 - p))}.$$
+\eqimage{fig/cn-logit}
+ {$$x f'(x)/f(x) = {1/(1 - p) \over \log (p/(1 - p))}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = 1/[(1 - p) log(p/(1 - p))].
@end example
+@image{fig/cn-logit}
+
@end ifnottex
The identity
@iftex
Equivalent to:
@iftex
@tex
-$$\mathop{\hbox{\rm logistic-1/2}} x = \mathop{\rm logistic}(x) - 1/2,$$
-$$\mathop{\hbox{\rm logit1/2+}} p = \mathop{\rm logit}(1/2 + p).$$
+\eqimage{fig/logistichalf}
+ {$$\mathop{\hbox{\rm logistic-1/2}} x = \mathop{\rm logistic}(x) - 1/2,$$}
+\eqimage{fig/logithalf}
+ {$$\mathop{\hbox{\rm logit1/2+}} p = \mathop{\rm logit}(1/2 + p).$$}
@end tex
@end iftex
@ifnottex
@end group
@end example
+@image{fig/logistichalf}
+@image{fig/logithalf}
+
@end ifnottex
Like @code{logistic} and @code{logit}, these functions are inverses of
one another; unlike @code{logistic} and @code{logit}, their domains
and codomains are both centered at zero.
-
@itemize @bullet
@item
The logistic-1/2 function is well-conditioned on the entire real line,
with maximum condition number @math{1} at @math{0}:
@iftex
@tex
-$$x f'(x)/f(x) = {2x e^{-x} \over 1 - e^{-2x}}.$$
+\eqimage{fig/cn-logistichalf}
+ {$$x f'(x)/f(x) = {2x e^{-x} \over 1 - e^{-2x}}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = 2 x e^-x / (1 - (e^-x)^2).
@end example
+@image{fig/cn-logistichalf}
+
@end ifnottex
This implementation gives forward relative error bounded by 5 times
the forward relative error bound of the system math library's exp,
ill-conditioned near @math{-1/2} and @math{+1/2}:
@iftex
@tex
-$$x f'(x)/f(x) = {x / (1 - 4 x^2) \over \mathop{\rm logit}(1/2 + x)}.$$
+\eqimage{fig/cn-logithalf}
+ {$$x f'(x)/f(x) = {x / (1 - 4 x^2) \over \mathop{\rm logit}(1/2 + x)}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = x/[(1 - 4 x^2) logit(1/2 + x)].
@end example
+@image{fig/cn-logithalf}
+
@end ifnottex
For points near @math{-1/2} or @math{+1/2}, it may be better to
compute logit of a point near @math{0} instead.
Equivalent to:
@iftex
@tex
-$$\mathop{\hbox{\rm log-logistic}} x = \log \mathop{\rm logistic}(x) = \log [1/(1 + e^{-x})],$$
-$$\mathop{\hbox{\rm logit-exp}} x = \mathop{\rm logit}(e^x) = \log [e^x/(1 - e^x)].$$
+\eqimage{fig/loglogistic}
+ {$$\eqalign{\mathop{\hbox{\rm log-logistic}} x &= \log \mathop{\rm logistic}(x) \cr&= \log [1/(1 + e^{-x})],}$$}
+\eqimage{fig/logitexp}
+ {$$\eqalign{\mathop{\hbox{\rm logit-exp}} x &= \mathop{\rm logit}(e^x) \cr&= \log [e^x/(1 - e^x)].}$$}
@end tex
@end iftex
@ifnottex
@item
The log-logistic function maps log-odds on the extended real line to
log-probability on the nonpositive half of the extended real line, and
-is ill-conditioned for positive @var{x}:
+is ill-conditioned for large positive @var{x}:
@iftex
@tex
-$$x f'(x)/f(x) = {-x e^{-x} \over (1 + e^{-x}) \log (1 + e^{-x})}.$$
+\eqimage{fig/cn-loglogistic}
+ {$$x f'(x)/f(x) = {-x e^{-x}/(1 + e^{-x}) \over \log (1 + e^{-x})}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = (-x exp(-x))/[(1 + exp(-x)) log(1 + exp(-x))]
@end example
+@image{fig/cn-loglogistic}
+
@end ifnottex
@item
The logit-exp function maps log-probability on the nonpositive half of
the extended real line to log-odds on the extended real line, and is
-ill-conditioned near zero:
+ill-conditioned near @math{\log(1/2)}:
@iftex
@tex
-$$x f'(x)/f(x) = {x \over (1 - e^x) \log [e^x/(1 - e^x)]}.$$
+\eqimage{fig/cn-logitexp}
+ {$$x f'(x)/f(x) = {x/(1 - e^x) \over \log [e^x/(1 - e^x)]}.$$}
@end tex
@end iftex
@ifnottex
x f'(x)/f(x) = x/[(1 - exp(x)) log(exp(x)/(1 - exp(x)))]
@end example
+@image{fig/cn-logitexp}
+
@end ifnottex
@end itemize
@contents
@tex
-\global\urefurlonlylinktrue
-\global\def\urlcolor{0 0 1} % blue
+\ifx\urefurlonlylinktrue\undefined\else
+ \global\urefurlonlylinktrue
+ \global\def\urlcolor{0 0 1} % blue
+\fi
+
+% \eqimage{foo}{$$f_{a,b}(x) = \int_0^1 e^{-2\pi i t} \,dt.$$}
+%
+% Displays foo.eps to the right of the equation.
+%
+\global\long\def\eqimage#1#2{%
+ \par\leavevmode%
+ % Load up the image into box 0.
+ \setbox0=\hbox{\image{#1}}%
+ % Calculate the width available to us for the pair as \dimen0.
+ \dimen0=\hsize%
+ \advance\dimen0 by -\leftskip%
+ \advance\dimen0 by -\hangindent%
+ \advance\dimen0 by -\rightskip%
+ % Calculate the width available for the display alone as \dimen1.
+ \dimen1=\dimen0 \advance\dimen1 by -\wd0
+ % Set the display into box 1.
+ \setbox1=\vbox{
+ % Narrow ourselves to \dimen1-2em.
+ \hsize\dimen1 \advance\hsize by -2em
+ % Avoid interline skips for displays.
+ \abovedisplayskip=0pt
+ \belowdisplayskip=0pt
+ \abovedisplayshortskip=0pt
+ \belowdisplayshortskip=0pt
+ % Set the display.
+ #2
+ }%
+ % Calculate the higher of the two for the height of our vboxes as
+ % \dimen2.
+ \ifdim\ht0>\ht1 \dimen2=\ht0 \else \dimen2=\ht1 \fi
+ % Set the display (\box1) and figure (\box0) into an hbox as wide as
+ % we can (\dimen0) and as high the higher of the two (\dimen2), with
+ % fill between them and on either side, and vertically centred.
+ \hbox to \dimen0{%
+ \hfill%
+ \vbox to \dimen2{\vss\box1\vss}%
+ \hfill%
+ \vbox to \dimen2{\vss\box0\vss}%
+ \hfill%
+ }%
+}
@end tex
@ifnottex