pgfmathsetseed의 시드 값에 제한이 있습니까?

pgfmathsetseed의 시드 값에 제한이 있습니까?

나는 임의의 시험을 만들기 위해 pgf를 사용하고 있습니다. 시드를 설정하기 위해 pgfmathsetseed를 사용하고 있습니다. 이 시스템은 시드에 대해 매우 다른 값을 사용하며 그 범위는 수천에 이를 수 있습니다. pgf 매뉴얼에는 pgfmathsetseed가 정수를 수신한다고 나와 있으며 제한에 대한 언급은 없습니다. 그러나 다른 씨앗에 대해서도 정확히 동일한 결과를 얻고 있습니다. 다음 코드는 문제를 보여줍니다.

\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}

출력은 다음과 같습니다

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

보시다시피, 여러 시드의 값은 동일합니다. pgfmathsetseed에 넣을 수 있는 정수에 제한이 있나요? 아니면 무엇이 문제입니까? 감사합니다.

답변1

난수 생성은 다음의 일부 초기 매개변수에 따라 달라집니다 pgfmathfunctions.random.code.tex.

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

내가 기억하는 것처럼(확인하지 않음) 매개변수 값은 Press et al.의 C, 2판 수치 참조에서 수집되었습니다. 대안이 제안됩니다(의 설명에도 나열되어 있음 pgfmathfunctions.random.code.tex).

예를 들어 이러한 매개변수는 Erich Janka의 매개변수와 동일한 매개변수로 변경될 수 있습니다.LCD 패키지(pgf 무작위 항목의 기반), 이는 더 바람직한 결과를 초래할 수 있습니다(비록 연속된 시드의 시퀀스에서 반복이 여전히 발생할 수 있음)

\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}

여기에 이미지 설명을 입력하세요

답변2

여기에는 뭔가 잘못된 것 같습니다. 분명히 첫 번째 숫자만 중요합니다.

\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}

여기에 이미지 설명을 입력하세요

표를 보면 인수로 시작하는 모든 호출은 1동일한 출력을 생성하며 for 2등도 마찬가지입니다.

반면에 와 관련된 줄을 주석 처리하면 fpu출력은 다음과 같습니다.

여기에 이미지 설명을 입력하세요

무작위 정수는 1, 4, 7만 선택되므로 실제로 그렇게 무작위로 보이지는 않습니다.

expl3다음을 통해 내가 얻은 내용은 다음과 같습니다 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}

여기에 이미지 설명을 입력하세요

답변3

@Mark Wibrow의 답변을 사용하여 무작위 알고리즘(실제로 Numerical Recipies의 두 번째 버전에서 나온 생성기에 대한 새로운 매개변수를 사용하여)을 개선할 수 있었을 뿐만 아니라 pgf의 fpu와의 비호환성도 지적할 수 있었습니다. 그리고 씨앗의 세팅. 참고: 내 응용 프로그램에서는 여러 수량을 계산하기 위해 fpu가 필요하지만 이러한 mwe에는 표시되지 않습니다.

다음 예에서는 /pgf/fpu가 활성화되면 향상된 매개변수를 사용한 후에도 난수 생성기가 예상대로 작동함을 보여줍니다. 로컬에서 비활성화하면 결과가 훨씬 좋아집니다. 이 문제를 정확히 해결하는 방법은 모르겠지만 pgfmathsetseed 함수가 영향을 받아 올바른 데이터를 생성하지 않습니다. 여기에 예가 있습니다

\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}

그리고 출력은

fpu 활성화 및 비활성화 비교

그래서 제 경우에는 fpu를 로컬에서 비활성화해야 합니다. 이 답변은 전적으로 이전 답변을 기반으로 하기 때문에 이전 답변을 답변으로 표시할 것 같습니다.

답변4

나는 lua난수 생성기를 사용하는 것을 선호합니다.

\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}

여기에 이미지 설명을 입력하세요

관련 정보