diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx new file mode 100644 index 00000000000..e2708e193fc --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx @@ -0,0 +1,266 @@ +% \iffalse meta-comment +% +%% File: l3fp-random.dtx Copyright (C) 2016 The LaTeX3 Project +%% +%% It may be distributed and/or modified under the conditions of the +%% LaTeX Project Public License (LPPL), either version 1.3c of this +%% license or (at your option) any later version. The latest version +%% of this license is in the file +%% +%% http://www.latex-project.org/lppl.txt +%% +%% This file is part of the "l3kernel bundle" (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +% +%<*driver> +\documentclass[full]{l3doc} +\GetIdInfo$Id: l3fp-random.dtx 6750 2016-11-21 01:24:26Z bruno $ + {L3 Floating-point random numbers} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{l3fp-random} package\thanks{This file +% has version number \ExplFileVersion, last +% revised \ExplFileDate.}\\ +% Floating point random numbers} +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% \date{Released \ExplFileDate} +% +% \maketitle +% +% \begin{documentation} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3fp-random} Implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<@@=fp> +% \end{macrocode} +% +% \subsection{Random floating point} +% +% \begin{macro}[EXP, int]{\@@_rand_o:Nw} +% \begin{macro}[EXP, aux]{\@@_rand_o:} +% Check that |random| was called without argument. Random numbers are +% only available if the engine defines a primitive equivalent to +% \pdfTeX{}'s \tn{pdfuniformdeviate}. A random floating point number +% in $[0,1)$, uniformly distributed with equal-spaced steps of +% $10^{-16}$ is obtained by combining two integers in $[0,10^8-1]$. +% \begin{macrocode} +\cs_new:Npn \@@_rand_o:Nw ? #1 @ + { + \tl_if_empty:nTF {#1} + { \@@_rand_o: } + { + \__msg_kernel_expandable_error:nnnnn + { kernel } { fp-num-args } { rand() } { 0 } { 0 } + \exp_after:wN \c_nan_fp + } + } +\cs_if_exist:NTF \pdftex_uniformdeviate:D + { + \cs_new:Npn \@@_rand_o: + { + \@@_parse_o:n + { + . + \exp_after:wN \use_none:n + \__int_value:w \__int_eval:w 1 0000 0000 + + \pdftex_uniformdeviate:D 1 0000 0000 \__int_eval_end: + \exp_after:wN \use_none:n + \__int_value:w \__int_eval:w 1 0000 0000 + + \pdftex_uniformdeviate:D 1 0000 0000 \__int_eval_end: + } + } + } + { + \cs_new:Npn \@@_rand_o: + { + \__msg_kernel_expandable_error:nn { kernel } { fp-no-random } + \exp_after:wN \c_nan_fp + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Random integer} +% +% \begin{macro}[EXP, int]{\@@_randint_o:Nw} +% \begin{macro}[EXP, aux] +% { +% \@@_randint_badarg:w, +% \@@_randint_e:w, +% \@@_randint_narrow_e:nn, +% \@@_randint_wide_e:nn, +% \@@_randint_wide_e:nnn, +% \@@_randint_wide_e:nnnn, +% } +% Enforce that there is one argument (then add first argument~$1$) +% or two arguments. Enforce that they are integers in +% $(-10^{16},10^{16})$ and ordered. +% +% When the range is narrow (less than $2\times 10^9$) we can +% directly use the primitive. Otherwise we use the primitive twice. +% To ensure a uniform distribution we combine two uniformly +% distributed integers into a total range greater or equal to our +% target range and try again if the random number ended up being too +% big. +% +% The strange |+\c_six| ensures that the first argument of +% \cs{@@_randint_wide_e:nnn} is larger than $10^{-8}$ times the +% difference between the end-points even if these are near +% $-10^{16}$ and $+10^{16}$ (their difference is rounded to sixteen +% digits). Note that we cannot just concatenate the two random +% numbers provided by the engine as that may give an integer up to +% (almost) $2\times 10^{16}$ which incurs rounding. +% \begin{macrocode} +\cs_new:Npn \@@_randint_o:Nw ? #1 @ + { + \if_case:w + \__int_eval:w \@@_array_count:n {#1} - \c_one \__int_eval_end: + \exp_after:wN \@@_randint_e:w \c_one_fp #1 + \or: \@@_randint_e:w #1 + \else: + \__msg_kernel_expandable_error:nnnnn + { kernel } { fp-num-args } { randint() } { 1 } { 2 } + \exp_after:wN \c_nan_fp \exp:w + \fi: + \exp_after:wN \exp_end: + } +\cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3; + { + \@@_int:wTF \s_@@ \@@_chk:w #1#2#3; + { + \if_meaning:w 1 #1 + \if_int_compare:w + \use_i_delimit_by_q_stop:nw #3 \q_stop > \c_sixteen + \exp_after:wN \c_one + \fi: + \fi: + } + { \c_one } + } +\cs_new:Npn \@@_randint_e:w #1; #2; + { + \if_case:w + \@@_randint_badarg:w #1; + \@@_randint_badarg:w #2; + \fp_compare:nNnTF { #1; } > { #2; } { \c_one } { \c_zero } + \fp_compare:nNnTF { #1; + 2e9 } < { #2; } + { \@@_randint_wide_e:nn } + { \@@_randint_narrow_e:nn } + { #1; } { #2; } + \or: + \@@_invalid_operation_tl_o:ff + { randint } { \@@_array_to_clist:n { #1; #2; } } + \exp:w + \fi: + } +\cs_if_exist:NTF \pdftex_uniformdeviate:D + { + \cs_new:Npn \@@_randint_narrow_e:nn #1#2 + { + \@@_parse_o:n + { + #1 + + \pdftex_uniformdeviate:D + \int_eval:n { \fp_to_int:n { #2 - #1 } + \c_one } + } + \exp:w + } + \cs_new:Npn \@@_randint_wide_e:nn #1 #2 + { + \exp_args:Nf \@@_randint_wide_e:nnn + { \fp_to_int:n { ceil ( ( #2 - #1 + \c_six ) * 1e-8 ) } } + {#1} {#2} + } + \cs_new:Npn \@@_randint_wide_e:nnn #1#2#3 + { + \exp_args:Nf \@@_randint_wide_e:nnnn + { + \@@_parse:n + { + #2 + + \pdftex_uniformdeviate:D #1 e 8 + + \pdftex_uniformdeviate:D 1 0000 0000 + } + } + {#1} {#2} {#3} + } + \cs_new:Npn \@@_randint_wide_e:nnnn #1#2#3#4 + { + \fp_compare:nNnTF {#1} > {#4} + { \@@_randint_wide_e:nnn {#2} {#3} {#4} } + { \@@_exp_after_o:w #1 \exp:w } + } + } + { + \cs_new:Npn \@@_randint_narrow_e:nn #1#2 + { + \__msg_kernel_expandable_error:nn { kernel } { fp-no-random } + \exp_after:wN \c_nan_fp \exp:w + } + \cs_new:Npn \@@_randint_wide_e:nn #1#2 + { + \__msg_kernel_expandable_error:nn { kernel } { fp-no-random } + \exp_after:wN \c_nan_fp \exp:w + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +\__msg_kernel_new:nnn { kernel } { fp-no-random } + { Random~numbers~unavailable } +% \end{macrocode} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintChanges +% +% \PrintIndex |