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
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.
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}
Best Answer
Here's a LuaLaTeX-based implementation. It employs Lua code both to calculate the cdf values and to tabulate them in an
array
environment with 11 columns and 42 rows (including 1 header row).The algorithm that calculates the cdf at
x
(for a positive value ofx
) is based on an approximation proposed in Abramovitz and Stegun, "Handbook of Mathematical Functions" (1964). For more information on this algorithm, see also Abramowitz and Stegun approximation for cumulative normal distribution. The maximum absolute error may be shown to be less than7.5×10^{−8}
. Since the numbers in the table show only 5 digits, the approximation error is negligible for the present use case.Addendum: If you wanted to use
,
(comma) as the decimal marker, all you would need to do in the code shown below is (a) add the instructionsin the preamble and (b) change the specification of the
array
environment from*{11}{l}
toT{1.1} *{10}{T{1.5}}
.