Create a table with calculations of binomial and poisson distribution

The following code shows a solution without the use of external applications.

Binomial distribution

I now have included PGF's own fpu library. Hopefully its setup is correct.
Even n > 8 will compile now (before: ! Dimension too large., this was due to the calculation of the binomial coefficient.)

Packages used:

  • geometry for changing the paper layout,
  • booktabs for nice layout of tables (\top-, \mid- and \toprule)
  • pgf for the calculations,
    • fpu library,
    • pgf/number format,
  • pgffor for the \foreach loops, and
  • etoolbox for the simple composing of the table contents.
  • amsmath's \binom and \frac should be used instead of \choose and \over!

How to use.

There exists one user macro: \binomTable[<zero>]{<start n>}{<end n>}.

The optional <zero> argument decides whether zero cells (0.0000) should be typeset at all (0: 0.0000 is typeset, everything else: 0.0000 is not typeset).
[This is hard-coded, any change to the /pgf/number format/precision key will have to be shadowed there manually.]

The second and third argument define the start and the end n, respectively.

Binomial coefficient

For the bionomial coefficient I used the following formula with i = \j
enter image description here

pgfplotstable?

Yes, please.
I don't know how to use pgfplotstable.

Code

\documentclass[landscape]{article}
\usepackage[landscape, margin=.5cm]{geometry}
\usepackage{booktabs}
\usepackage{pgf,pgffor}
\usepackage{etoolbox}
\usepgflibrary{fpu}
\pgfkeys{/pgf/fpu}
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
\pgfkeys{/pgf/number format/.cd,fixed,fixed zerofill,precision=4}

%%% Defining basic stuff
\def\myHeadList{0.01, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 1/3, 0.35, 0.40, 0.45, 0.49, 0.50}
%\def\startN{9}
%\def\endN{10}

\newif\ifsomanyzeroesshouldbeprinted
\newcommand*{\binomTable}[3][0]{% #1  = 0 => results in the form 0.0000 are typeset
                                % #1 != 0 => results in the form 0.0000 are omitted
                                % #2 = startN
                                % #3 = endN
    \edef\startN{#2}%
    \edef\endN{#3}%
    \expandafter\ifnum#1=0\relax%
        \somanyzeroesshouldbeprintedtrue%
    \else%
        \somanyzeroesshouldbeprintedfalse%
    \fi%
    %
    %%% Building head of table
    \def\myHead{ $n$ & $k$ & $n\choose k$}%
    \foreach \p in \myHeadList {%
        \xappto\myHead{& {$\p$}}%
    }%
    \appto\myHead{\\}%
    %
    %%% Bulding body of table
    \def\myTable{}%
    \def\myN{\startN,...,\endN}%
    \foreach \n in \myN {%
        \foreach \k in {0,...,\n}{%
            \ifnum\k=0\relax%
                \xappto\myTable{\noexpand\midrule\n}%
            \fi%
            \xappto\myTable{& \k}%
            \pgfmathsetmacro{\binomProduct}{1}%
            \xdef\myTempValue{\binomProduct}%
            \ifnum\k=0\relax%
                \xdef\oldK{\k}%
            \else%
                    \foreach \j in {1,...,\k}{%
                        \pgfmathsetmacro{\binomProduct}{\myTempValue*(\n+1-\j)/\j}%
                        \xdef\myTempValue{\binomProduct}%
                    }%
            \fi%
            \pgfmathsetmacro{\myTempValue}{round(\myTempValue)}%
            \xappto\myTable{& \noexpand\pgfmathprintnumber[/pgf/number format/.cd,fixed,precision=0,set thousands separator={\,},min exponent for 1000 sep=4]{\myTempValue}}%
            \foreach \p in \myHeadList {%
                \pgfmathsetmacro{\result}{\myTempValue*\p^(\k)*(1-\p)^(\n-\k)}%
                \ifsomanyzeroesshouldbeprinted%
                    \xappto\myTable{& \noexpand\pgfmathprintnumber{\result}}%
                \else%
                \ifdim\result pt<0.00005pt\relax%
                        \gappto\myTable{&}%
                    \else%
                        \xappto\myTable{& \noexpand\pgfmathprintnumber{\result}}%
                    \fi%
                \fi%
            }%
            \gappto\myTable{\\}%
        }%
    }%
}
\pagestyle{empty}

\def\formulae{%
    \begin{tabular}{@{}l@{}}
        $\displaystyle p(\xi=k)={{n}\choose{k}} p^k q^{n-k}$ \\
        $\displaystyle  {n\choose k}=\prod_{j=1}^k {n+1-j \over j}$
    \end{tabular}%
}
\begin{document}

\binomTable[1]{2}{8}
\begin{tabular}{rrr*{13}{r}}
    \toprule\myHead\myTable\midrule\myHead\bottomrule
\end{tabular}
\hfill\formulae

\binomTable[1]{9}{11}
\begin{tabular}{rrr*{13}{r}}
    \toprule\myHead\myTable\midrule\myHead\bottomrule
\end{tabular}
\hfill\formulae

\binomTable[1]{12}{14}
\begin{tabular}{rrr*{13}{r}}
    \toprule\myHead\myTable\midrule\myHead\bottomrule
\end{tabular}
\hfill\formulae

\binomTable[1]{15}{16}
\begin{tabular}{rrr*{13}{r}}
    \toprule\myHead\myTable\midrule\myHead\bottomrule
\end{tabular}
\hfill\formulae
\end{document}

Output

These are old images, the current code adds another column where n \choose k is given.

enter image description here enter image description here enter image description here

Poisson distribution

Your code looks fine in my eyes.

PGF’s \foreach is known to have precision problems with ... and non-integer values.
My work-around: Use

\foreach \ll in \myLList {%
    \pgfmathsetmacro{\l}{.1*\ll}

and then you can create your tables with

\poissonTable[1]{1,...,40}{12}

Interestingly \pgfmathsetmacor{\l}{\ll/10} won’t work.

In my given example below I used {.1*1,.1*...,.1*40} and parsing that to \l. The macro \poissonTable takes 1, .1* and 40 as separated parameters whereas the macro \poissonTableL expects the list itself.

I added an option to space every _5_th row by testing whether \l is divisible by .5. We could just use a row-counter we can check for divisibility, but that would give us an separate last row in the second example (which is like your professor's).

Testing for the last row works out of the box with \poissonTable but needs a little help for \poissonTable.

This solution is very special and probably will need extra care if the rows differ very much from this scheme.

Maybe you want a more explicit sort of giving the rows like in another answer of mine where you could say {.1,.2,.3,.4,[1].5,.6,.7,.8,.9,[1]1,…} so that rows with [<x>] get <x>ex-spacing …?

Code (without output)

\documentclass[landscape]{article}
\usepackage[landscape,margin=.5cm]{geometry}
\usepackage[table]{xcolor}
\usepackage{booktabs}
\usepackage{pgf,pgffor}
\usepackage{etoolbox}
\usepgflibrary{fpu}
\pgfkeys{/pgf/fpu}
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
\pgfkeys{/pgf/number format/.cd,fixed,fixed zerofill,precision=4}

\edef\mysecondtest{false}%
\def\mc#1{\multicolumn{1}{c}{#1}}
\newif\ifsomanyzeroesshouldbeprinted
\newcommand*{\poissonTable}[5][0]{% #1   = 0 => results in the form 0.0000 are typeset
                                  % #1 != 0 => results in the form 0.0000 are omitted
                                  % #2 = startN
                                  % #3 = midN
                                  % #4 = endN
                                  % #5 = endK
    \edef\startN{#2}\edef\midN{#3}\edef\endN{#4}%
    \edef\myLList{\midN\startN,\midN...,\midN\endN}%
    \edef\lastN{\midN\endN}%
    \poissonTableL[#1]{\myLList}{#5}
}
\newcommand*{\poissonTableL}[3][0]{% #1   = 0 => results in the form 0.0000 are typeset
                                   % #1 != 0 => results in the form 0.0000 are omitted
                                   % #2 = Liste
                                   % #3 = endK
    \edef\myLList{#2}
    \edef\endK{#3}%
    \expandafter\ifnum#1=0\relax%
        \somanyzeroesshouldbeprintedtrue%
    \else%
        \somanyzeroesshouldbeprintedfalse%
    \fi%
    %%% Building head of table
    \def\myLHead{\mc{$\lambda$} }%
    \foreach \k in {0,...,\endK} {%
        \ifnum\k=0\relax%
            \xappto\myLHead{& \noexpand\mc{\llap{$k\to{}$}$\k$}}% or \to replaced by =
        \else%
            \xappto\myLHead{& \noexpand\mc{\k}}%
        \fi
        }%
    \appto\myLHead{\\}%
    %%% Bulding body of table
    \def\myLTable{}%
    \foreach \ll in \myLList {%
        \pgfmathsetmacro{\l}{\ll}%
        \xappto\myLTable{ $\l$}%
        \foreach \k in {0,...,\endK}{%
            \pgfmathsetmacro{\Lresult}{e^(-\l)*((\l)^(\k))/((\k)!)}%
            \ifsomanyzeroesshouldbeprinted%
                \xappto\myLTable{& \noexpand\pgfmathprintnumber{\Lresult}}%
            \else\ifdim\Lresult pt<0.00005pt\relax%
                     \gappto\myLTable{&}%
                \else%
                     \xappto\myLTable{& \noexpand\pgfmathprintnumber{\Lresult}}%
                \fi%
            \fi%
        }%
    \gappto\myLTable{\\}%
    \pgfkeys{/pgf/fpu=false}%
    \pgfmathsetmacro{\lastRow}{\ll==\lastN?"0":"1"}%
    \pgfmathsetmacro{\lastRow}{\mysecondtest?"0":"\lastRow"}%
    \pgfmathparse{mod(\l,.5)==0?"[\lastRow ex]":""}%
    \xappto\myLTable{\pgfmathresult}%
    }%
    \edef\mysecondtest{false}%
}
\pagestyle{empty}

\begin{document}
\poissonTable[1]{1}{.1*}{40}{12}
\begin{tabular}{rr*{13}{r}}
    \toprule\myLHead\midrule\myLTable\midrule\myLHead\bottomrule
\end{tabular}

\edef\lastN{10}%
\def\mysecondtest{mod(\ll,1)==0}%
\poissonTableL[1]{.1*1,.1*...,.1*20,.1*22,.1*24,.1*...,.1*40,5,6,...,10}{12}
\begin{tabular}{rr*{13}{r}}
    \toprule\myLHead\midrule\myLTable\midrule\myLHead\bottomrule
\end{tabular}
\end{document}

It is quite simple. If you are familiar with Matlab or GNU R. I prepared a Matlab example for the first row. It is only semi-automatic -- you need to modify the result manually. But I guess it takes not more than 2 hours until you are satisfied (depending on your experience of course).

Here's the Matlab code:

%% Generate first row
% http://f.cl.ly/items/1z2p0g2H410J3K0v1z32/Binomial_y_Poisson.pdf

n = 2;
for k=0:1:2
    i=1;
    for p=[0.01 0.05 0.15 0.20 0.30 1/3 0.35 0.40 0.45 0.50]
        Result(k+1,i) = binopdf(k,n,p)
        i=i+1
    end
end

%% Save to file
% Problem: Still no \\ at the end of each row
try
delete myResult1File
catch
end

dlmwrite('myResult1File.txt',Result,'delimiter','&','newline','pc','precision','%1.4f')

%% Add \\\r\n to each row

myFileIn = fopen('myResult1File.txt');
myFileOut = fopen('myResult2File.txt','w');

while ~feof(myFileIn)
   s = fgetl(myFileIn); % read line by line
   fprintf(myFileOut,'& & & %s\\\\\r\n',s); % write line by line and add \\ before newline
end

fclose(myFileIn)
fclose(myFileOut)

The result will be stored in myResult2File.txt and will look like this:

& & & 0.9801&0.9025&0.7225&0.6400&0.4900&0.4444&0.4225&0.3600&0.3025&0.2500\\
& & & 0.0198&0.0950&0.2550&0.3200&0.4200&0.4444&0.4550&0.4800&0.4950&0.5000\\
& & & 0.0001&0.0025&0.0225&0.0400&0.0900&0.1111&0.1225&0.1600&0.2025&0.2500\

By the way, myResult1File.txt looks like this:

0.9801&0.9025&0.7225&0.6400&0.4900&0.4444&0.4225&0.3600&0.3025&0.2500
0.0198&0.0950&0.2550&0.3200&0.4200&0.4444&0.4550&0.4800&0.4950&0.5000
0.0001&0.0025&0.0225&0.0400&0.0900&0.1111&0.1225&0.1600&0.2025&0.2500

The LaTeX file could look like this (I recommend using the booktabs package for example):

\documentclass[a4paper]{article}
\usepackage[textwidth=170mm]{geometry}
\begin{document}


\begin{center}
  {\large\textbf{\hspace*{1.0cm}Table of the Binominal Distribution}}
\end{center}

Here you go\ldots

\begin{center}
\small
\begin{tabular}{|r|r|*{11}r|} % *{11}r -> rrrrrrrrrrr
\hline
$n \downarrow$ & $k \downarrow$ & $p \to $ & 0.01 & 0.05 & 0.15 & 0.20 & 0.30 & 1/3 & 0.35 & 0.40 & 0.45 & 0.50\\
\hline
2 & 0 &  & 0.9801&0.9025&0.7225&0.6400&0.4900&0.4444&0.4225&0.3600&0.3025&0.2500\\
  & 1 &  & 0.0198&0.0950&0.2550&0.3200&0.4200&0.4444&0.4550&0.4800&0.4950&0.5000\\
  & 2 &  & 0.0001&0.0025&0.0225&0.0400&0.0900&0.1111&0.1225&0.1600&0.2025&0.2500\\
\hline
\end{tabular}
\end{center}

\end{document}

The PDF file will then look like this:

enter image description here

To compare with the original:

enter image description here

Damn, I now see that I forgot p=0.10 and p=0.49 but you get the idea anyway.

Remark: There seems to be a little rounding error in your professors table (compare n=2,k=0,p=0.1). Or Matlab is wrong.

Another Remark: Why do you need still this kind of table nowadays?! Isn't it outdated like a sin or log table :)?