Gibt es eine Grenze für den Startwert in pgfmathsetseed?

Gibt es eine Grenze für den Startwert in pgfmathsetseed?

Ich verwende pgf, um einige zufällige Prüfungen zu erstellen. Um den Seed festzulegen, verwende ich pgfmathsetseed. Dieses System verwendet sehr unterschiedliche Werte für den Seed, deren Bereich bis in die Tausende gehen kann. Im pgf-Handbuch steht, dass pgfmathsetseed eine Ganzzahl empfängt, und es gibt kein Wort über eine Begrenzung. Aber ich erhalte genau die gleichen Ergebnisse für verschiedene Seeds. Der folgende Code veranschaulicht das Problem:

\documentclass[letterpaper,9pt]{article}
\usepackage{tikz} % also for pgfmathparse
\usepackage{pgfmath} % also for pgfmathparse
\usepackage{siunitx} % also for pgfmathparse
\usepgflibrary{fpu}
\pgfkeys{/pgf/fpu}
\pgfkeys{/pgf/fpu/output format=sci}
\pgfkeys{/pgf/number format/.cd, sci, sci e, sci zerofill, precision = 3}

\newcommand{\example}[1]{%
  \pgfmathsetseed{#1}
  \pgfmathsetmacro{\FACTOR}{0.90} % constrol the randomness span
  \pgfmathrandominteger{\NA}{1}{9}
  \pgfmathsetmacro{\LAA}{2.0*(1 + \FACTOR*rand)}
  \begin{tabular}{ccc}
    #1 & \Num{\NA} & \Num{\LAA}
  \end{tabular}
}

\newcommand{\Num}[1]{\pgfmathprintnumberto{#1}{\tmpnum}\ensuremath{\num{\tmpnum}}}

\begin{document}

\example{92}

\example{96}

\example{90}

\example{1}

\example{2}

\end{document}

und die Ausgabe ist wie

92 1.000 1.576
96 1.000 1.576
90 1.000 1.576
1 7.000 2.245
2 4.000 6.891 × 10−1

Wie Sie sehen, sind die Werte für mehrere Seeds gleich. Gibt es eine Grenze für die Ganzzahl, die in pgfmathsetseed eingegeben werden kann? Oder wo liegt das Problem? Danke.

Antwort1

Die Erzeugung von Zufallszahlen hängt von einigen Anfangsparametern ab, die in folgenden Elementen zu finden sind pgfmathfunctions.random.code.tex:

\def\pgfmath@rnd@a{69621}
\def\pgfmath@rnd@r{23902}
\def\pgfmath@rnd@q{30845}

Soweit ich mich erinnere (ich habe es nicht überprüft), wurden die Parameterwerte aus Press et al.s Numerical References in C, 2. Auflage, entnommen. Es werden Alternativen vorgeschlagen (die auch in den Kommentaren in aufgeführt sind pgfmathfunctions.random.code.tex).

Diese Parameter können beispielsweise in die gleichen Parameter wie Erich Jankas geändert werden.lcg-Paket(auf dem das zufällige PGF-Material basierte), was zu wünschenswerteren Ergebnissen führen könnte (obwohl es in Sequenzen aufeinanderfolgender Seeds immer noch zu Wiederholungen kommen kann)

\documentclass{ltxdoc}
\usepackage{geometry}
\parindent=0pt
\usepackage{pgfmath,pgffor,lcg,xcolor,multicol}
\makeatletter
\def\pgfmath@rnd@a{16807}
\def\pgfmath@rnd@r{2836}
\def\pgfmath@rnd@q{127773}
\makeatother
\newcounter{lcgresult}
\newcommand{\example}[1]{%
  \pgfmathsetseed{#1}%
  \reinitrand[seed=#1, counter=lcgresult, first=1, last=9]
  \xdef\pgfseq{}%
  \xdef\lcgseq{}%
  \foreach\s in{0,...,10}{%
    \pgfmathrandominteger{\r}{1}{9}
    \xdef\pgfseq{\pgfseq\space\r}
    \rand
    \xdef\lcgseq{\lcgseq\space\thelcgresult}
  }%
  \begin{tabular}{p{0.5cm}p{4cm}}
    #1\hfil & \textcolor{blue}{\pgfseq} \newline \lcgseq
  \end{tabular}%
}
\begin{document}
\begin{multicols}{3}
\foreach \i in {1,...,60}{\example{\i}}
\end{multicols}
\end{document}

Bildbeschreibung hier eingeben

Antwort2

Hier scheint etwas nicht zu stimmen: Anscheinend ist nur die erste Ziffer von Bedeutung.

\documentclass{article}
\usepackage{geometry}
\usepackage{multicol}
\usepackage{tikz} % also for pgfmathparse
\usepackage{pgfmath} % also for pgfmathparse
\usepackage{siunitx} % also for pgfmathparse
\usepgflibrary{fpu}
\pgfkeys{/pgf/fpu}
\pgfkeys{/pgf/fpu/output format=sci}
\pgfkeys{/pgf/number format/.cd, sci, sci e, sci zerofill, precision = 3}

\newcommand{\example}[1]{%
  \pgfmathsetseed{#1}%
  \pgfmathsetmacro{\FACTOR}{0.90}% constrol the randomness span
  \pgfmathrandominteger{\NA}{1}{9}%
  \pgfmathsetmacro{\LAA}{2.0*(1 + \FACTOR*rand)}%
  #1\quad\Num{\NA}\quad\Num{\LAA}\par
}

\newcommand{\Num}[1]{\pgfmathprintnumberto{#1}{\tmpnum}\ensuremath{\num{\tmpnum}}}

\begin{document}

\begin{multicols}{3}

\count255=0
\loop\ifnum\count255<120
\expandafter\example{\the\count255}
\advance\count255 1
\repeat

\end{multicols}

\end{document}

Bildbeschreibung hier eingeben

Wenn wir uns die Tabelle ansehen, erzeugen alle Aufrufe, deren Argument mit beginnt, 1dieselbe Ausgabe und dasselbe für 2usw.

Wenn ich andererseits die Zeilen im Zusammenhang mit auskommentiere fpu, wird die Ausgabe

Bildbeschreibung hier eingeben

Die zufällige Ganzzahl scheint nicht wirklich so zufällig zu sein, da nur 1, 4 und 7 ausgewählt werden.

Folgendes erhalte ich mit expl3via xfp:

\documentclass{article}
\usepackage{geometry}
\usepackage{multicol}
\usepackage{siunitx,xfp}

\sisetup{round-precision=5,round-mode=figures,scientific-notation=true}

\newcommand{\FACTOR}{0.9}

\newcommand{\example}[1]{%
  \pdfsetrandomseed #1\relax
  #1\quad\num{\fpeval{randint(1,9)}}\quad\num{\fpeval{2*(1+\FACTOR*rand())}}\par
}

\begin{document}

\begin{multicols}{3}

\count255=0
\loop\ifnum\count255<120
\expandafter\example{\the\count255}
\advance\count255 1
\repeat

\end{multicols}

\end{document}

Bildbeschreibung hier eingeben

Antwort3

Mithilfe der Antwort von @Mark Wibrow konnte ich sowohl den Zufallsalgorithmus verbessern (indem ich die neuen Parameter für den Generator verwendete, die eigentlich aus der zweiten Ausgabe von Numerical Recipies stammen), als auch auf die Inkompatibilität mit der FPU von PGF und der Einstellung des Seeds hinweisen. HINWEIS: In meiner Anwendung brauche ich die FPU, um mehrere Mengen zu berechnen, diese MWE zeigt dies nicht an.

Das folgende Beispiel zeigt, dass wenn /pgf/fpu aktiviert ist, der Zufallszahlengenerator auch nach Verwendung der verbesserten Parameter wie erwartet funktioniert. Wenn ich es lokal deaktiviere, sind die Ergebnisse deutlich besser. Ich weiß nicht genau, wie ich das beheben kann, aber irgendwie ist die Funktion pgfmathsetseed betroffen und produziert nicht die richtigen Daten. Hier ist das Beispiel

\documentclass{standalone}
\usepackage{tikz,pgfmath,pgffor,siunitx,multicol} 
\usepgflibrary{fpu}
\pgfkeys{/pgf/fpu/output format=sci}
\pgfkeys{/pgf/number format/.cd, sci, sci e, sci zerofill, precision = 3}

\pgfkeys{/pgf/fpu=true} % this breaks pgfmathsetseed

\makeatletter
\def\pgfmath@rnd@a{16807}
\def\pgfmath@rnd@r{2836}
\def\pgfmath@rnd@q{127773}
\makeatother

\newcommand{\pgfmathsetseednew}[1]{%
  \pgfkeys{/pgf/fpu=false}
  \pgfmathsetseed{#1}
  \pgfkeys{/pgf/fpu=true}
}

\newcommand{\exampleA}[1]{%
  \pgfmathsetseed{#1}%
  \pgfmathrandominteger{\r}{1}{9}
  \pgfmathsetmacro{\LAA}{2.0*(1 + 0.90*rand)}
  #1 \quad \r \quad \Num{\LAA}\par
}
\newcommand{\exampleB}[1]{%
  \pgfmathsetseednew{#1}
  \pgfmathrandominteger{\r}{1}{9}
  \pgfmathsetmacro{\LAA}{2.0*(1 + 0.90*rand)}
  #1 \quad \r \quad \Num{\LAA}\par
}
\newcommand{\Num}[1]{\pgfmathprintnumberto{#1}{\tmpnum}\ensuremath{\num{\tmpnum}}}

\begin{document}
\begin{tabular}{m{0.4\textwidth}m{0.4\textwidth}}
  /pgf/fpu globally activated & /pgf/fpu locally deactivated\\
  \foreach \i in {80,...,99}{\exampleA{\i}}
  &
    \foreach \i in {80,...,99}{\exampleB{\i}}
\end{tabular}
\end{document}

und die Ausgabe ist

Vergleich zwischen FPU aktiviert und deaktiviert

In meinem Fall muss ich die FPU also lokal deaktivieren. Diese Antwort basiert vollständig auf der vorherigen, daher werde ich die vorherige wohl als Antwort markieren.

Antwort4

Ich bevorzuge die Verwendung eines luaZufallszahlengenerators:

\documentclass[letterpaper,9pt]{article}
\usepackage{tikz} % also for pgfmathparse
\usepackage{pgfmath} % also for pgfmathparse
\usepackage{siunitx} % also for pgfmathparse
\usepackage{luacode,multicol}

\usepgflibrary{fpu}
\pgfkeys{/pgf/fpu}
\pgfkeys{/pgf/fpu/output format=sci}
\pgfkeys{/pgf/number format/.cd, sci, sci e, sci zerofill, precision = 3}


\NewDocumentCommand{\Seed}{O{os.time( )}}{%
        \directlua{math.randomseed ( #1 ) ;}%
}

\NewDocumentCommand{\Random}{oom}{%
    % no argument :  real number between 0 and 1
    % upper : integer numbers between 1 and upper (both inclusive).
    % lower and upper : integer numbers between lower and upper
    %                                             (both inclusive).
    \IfNoValueTF{#2}{% not 2 arguments
        \IfNoValueTF{#1}{% no arguments
            \luadirect{
                t = math.random ( ) ;
            }
        }{%
            \luadirect{
                t = math.random ( #1 ) ;
            }
        }
    }{%
        \luadirect{
            t = math.random ( #1 , #2 ) ;
        }
    }
    \bgroup
        \edef\foo{\luadirect{tex.print ( t )}}
        \global\let#3=\foo
    \egroup
}


\newcommand{\example}[1]{%
  \pgfmathsetseed{#1}
  \pgfmathsetmacro{\FACTOR}{0.90} % constrol the randomness span
%  \pgfmathrandominteger{\NA}{1}{9}
  \Random[9]{\NA}
  \Random{\Rand}
  \pgfmathsetmacro{\LAA}{2.0*(1 + \FACTOR*\Rand)}
  \begin{tabular}{ccc}
    #1 & \Num{\NA} & \Num{\LAA}
  \end{tabular}
}

\newcommand{\Num}[1]{\pgfmathprintnumberto{#1}{\tmpnum}\ensuremath{\num{\tmpnum}}}

\begin{document}

\begin{multicols}{3}

\count255=0
\loop\ifnum\count255<120
\expandafter\example{\the\count255}
\advance\count255 1
\repeat

\end{multicols}

\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen