Plot the new math functions and their condition numbers.
authorTaylor R Campbell <campbell@mumble.net>
Mon, 8 Jul 2019 00:57:25 +0000 (00:57 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Mon, 8 Jul 2019 00:57:25 +0000 (00:57 +0000)
Plots are done purely in PostScript, so no additional tools required
on top of the existing PostScript/PDF stack we essentially already
depended on.  Plots are cubic spline interpolations computed by a
little automatic differentiation library in PostScript.

Fix some mistakes in the prose characterizations of the condition
numbers that I had written.

24 files changed:
doc/make-common.in
doc/ref-manual/Makefile.in
doc/ref-manual/fig/cn-expm1.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-log1mexp.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-log1p.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-log1pexp.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-logistic.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-logistichalf.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-logit.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-logitexp.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-logithalf.eps [new file with mode: 0644]
doc/ref-manual/fig/cn-loglogistic.eps [new file with mode: 0644]
doc/ref-manual/fig/expm1.eps [new file with mode: 0644]
doc/ref-manual/fig/log1mexp.eps [new file with mode: 0644]
doc/ref-manual/fig/log1p.eps [new file with mode: 0644]
doc/ref-manual/fig/log1pexp.eps [new file with mode: 0644]
doc/ref-manual/fig/logistic.eps [new file with mode: 0644]
doc/ref-manual/fig/logistichalf.eps [new file with mode: 0644]
doc/ref-manual/fig/logit.eps [new file with mode: 0644]
doc/ref-manual/fig/logitexp.eps [new file with mode: 0644]
doc/ref-manual/fig/logithalf.eps [new file with mode: 0644]
doc/ref-manual/fig/loglogistic.eps [new file with mode: 0644]
doc/ref-manual/numbers.texi
doc/ref-manual/scheme.texinfo

index bcf6ef1fe8f7ea12679ffdb348f99afdc7dd5943..bcf004cc20c637556f4fa019b543d29fbf920cc9 100644 (file)
@@ -75,31 +75,50 @@ DVI_TARGET = $(TARGET_ROOT).dvi
 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
index 40e5a89c607dee88d7ef9718db7afad8d51f1e64..fa0996c848414b93e4bc1eb41af79bb6d80aabb3 100644 (file)
@@ -54,4 +54,27 @@ SOURCES = \
     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
diff --git a/doc/ref-manual/fig/cn-expm1.eps b/doc/ref-manual/fig/cn-expm1.eps
new file mode 100644 (file)
index 0000000..e64e5e7
--- /dev/null
@@ -0,0 +1,459 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-log1mexp.eps b/doc/ref-manual/fig/cn-log1mexp.eps
new file mode 100644 (file)
index 0000000..2fdd6bc
--- /dev/null
@@ -0,0 +1,497 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-log1p.eps b/doc/ref-manual/fig/cn-log1p.eps
new file mode 100644 (file)
index 0000000..cf21a12
--- /dev/null
@@ -0,0 +1,451 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-log1pexp.eps b/doc/ref-manual/fig/cn-log1pexp.eps
new file mode 100644 (file)
index 0000000..06b4e7b
--- /dev/null
@@ -0,0 +1,460 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-logistic.eps b/doc/ref-manual/fig/cn-logistic.eps
new file mode 100644 (file)
index 0000000..0f5a30e
--- /dev/null
@@ -0,0 +1,457 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-logistichalf.eps b/doc/ref-manual/fig/cn-logistichalf.eps
new file mode 100644 (file)
index 0000000..9a8fc47
--- /dev/null
@@ -0,0 +1,448 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-logit.eps b/doc/ref-manual/fig/cn-logit.eps
new file mode 100644 (file)
index 0000000..3061a2f
--- /dev/null
@@ -0,0 +1,568 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-logitexp.eps b/doc/ref-manual/fig/cn-logitexp.eps
new file mode 100644 (file)
index 0000000..a60a525
--- /dev/null
@@ -0,0 +1,557 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-logithalf.eps b/doc/ref-manual/fig/cn-logithalf.eps
new file mode 100644 (file)
index 0000000..45c6cfa
--- /dev/null
@@ -0,0 +1,514 @@
+%!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
diff --git a/doc/ref-manual/fig/cn-loglogistic.eps b/doc/ref-manual/fig/cn-loglogistic.eps
new file mode 100644 (file)
index 0000000..6fb8371
--- /dev/null
@@ -0,0 +1,520 @@
+%!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
diff --git a/doc/ref-manual/fig/expm1.eps b/doc/ref-manual/fig/expm1.eps
new file mode 100644 (file)
index 0000000..5659358
--- /dev/null
@@ -0,0 +1,548 @@
+%!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
diff --git a/doc/ref-manual/fig/log1mexp.eps b/doc/ref-manual/fig/log1mexp.eps
new file mode 100644 (file)
index 0000000..78fdc59
--- /dev/null
@@ -0,0 +1,530 @@
+%!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
diff --git a/doc/ref-manual/fig/log1p.eps b/doc/ref-manual/fig/log1p.eps
new file mode 100644 (file)
index 0000000..b958b29
--- /dev/null
@@ -0,0 +1,546 @@
+%!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
diff --git a/doc/ref-manual/fig/log1pexp.eps b/doc/ref-manual/fig/log1pexp.eps
new file mode 100644 (file)
index 0000000..1bde1cb
--- /dev/null
@@ -0,0 +1,450 @@
+%!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
diff --git a/doc/ref-manual/fig/logistic.eps b/doc/ref-manual/fig/logistic.eps
new file mode 100644 (file)
index 0000000..9ef0612
--- /dev/null
@@ -0,0 +1,457 @@
+%!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
diff --git a/doc/ref-manual/fig/logistichalf.eps b/doc/ref-manual/fig/logistichalf.eps
new file mode 100644 (file)
index 0000000..47e0311
--- /dev/null
@@ -0,0 +1,457 @@
+%!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
diff --git a/doc/ref-manual/fig/logit.eps b/doc/ref-manual/fig/logit.eps
new file mode 100644 (file)
index 0000000..cdcd2f9
--- /dev/null
@@ -0,0 +1,537 @@
+%!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
diff --git a/doc/ref-manual/fig/logitexp.eps b/doc/ref-manual/fig/logitexp.eps
new file mode 100644 (file)
index 0000000..feadeab
--- /dev/null
@@ -0,0 +1,544 @@
+%!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
diff --git a/doc/ref-manual/fig/logithalf.eps b/doc/ref-manual/fig/logithalf.eps
new file mode 100644 (file)
index 0000000..48778cc
--- /dev/null
@@ -0,0 +1,506 @@
+%!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
diff --git a/doc/ref-manual/fig/loglogistic.eps b/doc/ref-manual/fig/loglogistic.eps
new file mode 100644 (file)
index 0000000..4e0b611
--- /dev/null
@@ -0,0 +1,514 @@
+%!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
index f8bf052325b5e50c66681e580a08fa8076865e84..ab13a002d5883f8fb5f38293a6c033ce0d6f7cf9 100644 (file)
@@ -800,29 +800,32 @@ possible these procedures produce a real result from a real
 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
@@ -838,7 +841,8 @@ condition number of log1p near @math{0} is near @math{1}:
 
 @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
@@ -847,6 +851,8 @@ $$x f'(x)/f(x) = {x/(1 + x) \over \log(1 + x)}.$$
 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
@@ -862,7 +868,8 @@ near @math{1}:
 
 @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
@@ -871,6 +878,7 @@ $$x f'(x)/f(x) = {x e^x \over e^x - 1}.$$
 x f'(x)/f(x) = x e^x/(e^x - 1).
 @end example
 
+@image{fig/cn-expm1}
 @end ifnottex
 @end itemize
 
@@ -883,8 +891,8 @@ system's math library, usually below 1ulp.
 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
@@ -896,8 +904,10 @@ log1pexp x = log (1 + e^x).
 @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}.
@@ -918,6 +928,50 @@ only by the sign of the input and the output.
 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
@@ -926,8 +980,10 @@ Logistic and logit functions.
 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
@@ -949,10 +1005,11 @@ maps back from log-odds to probabilities.
 @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
@@ -961,6 +1018,8 @@ $$x f'(x)/f(x) = {x e^{-x} \over 1 + e^{-x}}.$$
 x f'(x)/f(x) = x exp(-x)/[1 + exp(-x)].
 @end example
 
+@image{fig/cn-logistic}
+
 @end ifnottex
 The identity
 @iftex
@@ -989,7 +1048,8 @@ The logit function is defined on the closed unit interval @math{[0,
 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
@@ -998,6 +1058,8 @@ $$x f'(x)/f(x) = {1/(1 - p) \over \log (p/(1 - p))}.$$
 x f'(x)/f(x) = 1/[(1 - p) log(p/(1 - p))].
 @end example
 
+@image{fig/cn-logit}
+
 @end ifnottex
 The identity
 @iftex
@@ -1027,8 +1089,10 @@ library's log, which is usually below 1ulp.
 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
@@ -1040,20 +1104,23 @@ logit1/2+ p = logit(1/2 + p).
 @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
@@ -1062,6 +1129,8 @@ $$x f'(x)/f(x) = {2x e^{-x} \over 1 - e^{-2x}}.$$
 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,
@@ -1072,7 +1141,8 @@ The logit1/2+ function is defined on @math{[-1/2, +1/2]}, and is
 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
@@ -1081,6 +1151,8 @@ $$x f'(x)/f(x) = {x / (1 - 4 x^2) \over \mathop{\rm logit}(1/2 + x)}.$$
 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.
@@ -1095,8 +1167,10 @@ which is usually below 1ulp.
 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
@@ -1117,10 +1191,11 @@ one another.
 @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
@@ -1129,15 +1204,18 @@ $$x f'(x)/f(x) = {-x e^{-x} \over (1 + e^{-x}) \log (1 + e^{-x})}.$$
 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
@@ -1146,6 +1224,8 @@ $$x f'(x)/f(x) = {x \over (1 - e^x) \log [e^x/(1 - e^x)]}.$$
 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
 
index 80cd248e8974ac237f9777fe3b084d9f758a39a8..361e85a9c3f6701ffa62246d060b8517983ab455 100644 (file)
@@ -62,8 +62,52 @@ Documentation License.''
 @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