KTUG마당은 KTUG를 방문하는 모든 이용자가 대화를 나누고 소식을 전하는 곳입니다.
- 로그인 없이 자유롭게 글을 읽고 쓸 수 있는 철학은 처음과 같이 계속됩니다.
- Team Blog의 글을 이곳 게시판의 "정보글"로 모았습니다. Team blog는 기고자가 올린 글에 질문을 받는 부담을 줄이기 위하여 댓글을 허용하지 않았습니다. 그러나 이곳 게시판으로 모으면서 댓글을 달 수 있습니다. 게시물을 작성하실 때 댓글을 원하지 않으시면 댓글을 허용하시지 않으시기를 바랍니다. 또한 불필요한 소모성 댓글을 달지 않도록 주의하여 주시기를 바랍니다.
- TeX과 관련된 질문이나 답변은 QnA 마당을 이용하십시오. TeX과 관련된 질문은 지웁니다
- MathJax를 이용한 수식조판을 사용하실 수 있습니다. 여기를 참조하세요.
- 스팸 글을 막기 위하여 짧은 시간 내에 다시 글이 등록되는 IP를 막거나, 광고 글을 막기 위하여 금지어로 .com, .net 등을 설정하고 있습니다. 다소간의 불편함이 있으시더라도 양해 바랍니다.
- 금지어에서 stackexchange, stackoverflow, ctan, overleaf, , github, google.com, gmail.com, .org, .io, sil.org, wiki.com, tistory.com등은 해제하였습니다.
- 사용하는 편집기는 CKeditor입니다. 편집기에서 [enter]를 누르면 <p> 태그가 들어가고, 문단으로 생각하고 한줄을 비웁니다. 글줄만 바꾸려면 shift-enter 를 누르시면 <BR>가 들어가므로 용도에 맞게 나누어 쓸 수 있습니다.
자유글 [exp3] 조합(combination) <연분수보다 말도 못하게 쉬운>
2018.10.26 15:19
로또 확률이 어케 구해지는지 알아보다가 만들어봤습니다. 여기에서 유념할 것은 한 가지 뿐입니다. 10! 이상 되면 값이 너무 커지므로, 정수(int)가 아닌 실수(fp)를 사용해야 합니다.
\documentclass{article}
\usepackage{xparse, expl3}
\newcommand\NchooseR[2]{$_{#1}C_{#2}$~=~}
\ExplSyntaxOn
\NewDocumentCommand \combination { s m m }
{
\int_set:Nn \l_tmpa_int { #2 - #3 + 1}
\combination_factorial:Nnn \l_tmpa_fp { #2 }{ \l_tmpa_int }
\combination_factorial:Nnn \l_tmpb_fp { #3 }{ 1 }
\IfBooleanT { #1 }{ \NchooseR{ #2 }{ #3 } }
\fp_eval:n { \l_tmpa_fp / \l_tmpb_fp }
}
\cs_new:Npn \combination_factorial:Nnn #1 #2 #3
{
\fp_set:Nn #1 { 1 }
\int_step_inline:nnnn { #2 }{ -1 }{ #3 }
{
\fp_set:Nn #1 { #1 * ##1 }
}
}
\NewDocumentCommand \factorial { s m }
{
\combination_factorial:Nnn \l_tmpa_fp { #2 }{ 1 }
\IfBooleanT { #1 }{ #2!~=~ }
\fp_use:N \l_tmpa_fp
}
\ExplSyntaxOff
\begin{document}
\factorial{5} \factorial*{5} \\
\combination{45}{6} \combination*{45}{6}
\end{document}
댓글 7
-
yihoze
2018.10.26 17:22
-
noname
2018.11.01 16:01
파스칼의 삼각형으로 구해볼 수 없을까 싶어서 한번 해봤는데요, Pascal's rule에 의하여
\[
\binom{n}{k}=\binom{n-1}{k-1} + \binom{n-1}{k}
\]이고, \(\binom{n}{0}=1, \binom{n}{n}=1\) 임을 이용하면 재귀적인 덧셈으로 이항계수를 구할 수 있을 거라고 추측했습니다.
expl3에서 재귀함수를 정의하는 게 가능하다고는 하지만 속도를 떨어뜨리는 건 어쩔 수 없을테니 되도록 재귀되는 횟수를 줄이고 싶어서 다음 몇 가지 규칙을 더 적용했습니다.
(1) \( \binom{n}{k} = \binom{n}{n-k} \)
(2) \( \binom{n}{1} = n \)
(3) \( \binom{n}{2} = \sum_{i=1}^{n-1} i \)이상을 expl3로 고대로 옮겨쓰면:
\ExplSyntaxOn \NewDocumentCommand \simplecombination { m m } { \simple_comb:nn { #1 } { #2 } } \cs_new:Npn \simple_comb:nn #1 #2 { \int_compare:nTF { #2 < #1 - #2 } { \simp_comb_fn:nn { #1 } { #2 } } { \simp_comb_fn:nn { #1 } { \int_eval:n { #1 - #2 } } } } \cs_new:Npn \simp_comb_fn:nn #1 #2 { \int_case:nnF { #2 } { { 0 } { 1 } { 1 } { #1 } { 2 } { \sum_to:n { #1 - 1 } } { #1 } { 1 } } { \int_eval:n { \simple_comb:nn { \int_eval:n { #1 - 1 } } { \int_eval:n { #2 - 1 } } + \simple_comb:nn { \int_eval:n { #1 - 1 } } { \int_eval:n { #2 } } } } } \cs_new:Npn \sum_to:n #1 { \int_compare:nTF { #1 <= 1 } { 1 } { \int_eval:n { #1 + \sum_to:n { \int_eval:n { #1 - 1 } } } } } \ExplSyntaxOff
그런데 아무래도 효율적이지는 못해서 30 정도만 돼도 꽤 오래 기다려야 하더군요. 그냥 이런 게 되더라...
-
sjnam
2018.11.02 09:21
루아텍버전
% binom.tex % 실행: luatex binom.tex \def\binom#1#2{ {#1\choose #2}= \directlua{ local res, n, k = 1, #1, #2 for j=1,k do res = res * (n-k+j)/j end tex.print(res) }} $$\binom{12}{4}$$ \bye
-
작나
2018.11.02 10:08
위 코드는 이항계수의 아름다운 $${n\choose k}={n\over k}{n-1\choose k-1}$$를 이용한 것입니다.
-
noname
2018.11.06 15:16
큰 정수 계산을 위한 패키지로 bnumexpr와 xint가 있습니다. 둘 다 xint-core라는 큰 수 계산 엔진을 사용합니다. 저는 bnumexpr를 선호하는 편입니다.
위의 작나께서 가르쳐주신 조합 계산식
\[
\binom{n}{k} = \frac{n-k+1}{1}\times \frac{n-k+2}{2}\times \cdots \times \frac{n-1}{k-1}\times \frac{n}{k}
\]와 bnumexpr 패키지를 이용하여 큰 수의 조합( \({}_{100}\mathrm{C}_{25} \) 를 구해보았습니다.
expl3의 부동소숫점 실수 fp는 유효숫자가 16자리 정도 되는 걸로 보입니다. 큰 수에 대해서는 근삿값의 결과가 나오네요.
source: summary.tex
comment 1) bnumexpr에는 factorial 연산자가 제공됩니다. 그러므로
\thebnumexpr 100! /25! /75! \relax
로 해도 같은 결과를 얻을 수 있습니다.
comment 2) bnumexpr로 큰 수를 계산할 때에 token list로 처리하였습니다. \l_tmpa_bnum은 tl입니다.
-
yihoze
2018.11.06 16:58
좀 이해되지 않습니다. 외부 처리기를 사용하지 않는 한 모두 텍이 계산하는 건데 어떻게 값이 다를 수 있죠?
-
noname
2018.11.06 20:24
interfaces, pp. 189--190.
\NchooseR 명령은 기호에 맞게 고쳐 쓰시길.