裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

Julia の小ネタ--027 素数に関連する関数たち

2021年06月04日 | ブログラミング

Julia の Primes モジュールは,R や Python で gmp パッケージでサポートされているものと同じだ。

using Primes

素因数分解 factor(n::Integer), factor(ContainerType, n::Integer)

結果の表示法

特に指定しない場合は,数式として見やすい結果が得られる。
540 = 2^2 * 3^3 * 5

factor(540)
# 2^2 * 3^3 * 5

ベクトルとして結果を得るためには ContainerType を Vector とする。同じ素因数が複数個ある場合は,複数個数分の要素として含まれる。

factor(Vector, 540)
#=
6-element Vector{Int64}:
 2
 2
 3
 3
 3
 5
=#

集合として結果を得る場合は,ContainerType を Set とする。この場合は,ユニークな素因数が列挙されるだけであり,それぞれの素因数が何個あったかの情報は失われる。

factor(Set, 540)
#=
Set{Int64} with 3 elements:
  5
  2
  3
=#

キーをソートした辞書型として結果を得るる場合は,ContainerType を DataStructures.SortedDict とする。

factor(DataStructures.SortedDict, 540)
#=
SortedDict{Int64, Int64, Base.Order.ForwardOrdering} with 3 entries:
  2 => 2
  3 => 3
  5 => 1
=#

大きな数の素因数分解

n = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 29 * 31 * 37 # 7420738134810
factor(n) # 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 29 * 31 * 37

factor(100000000000000000000000000007) # 53 * 827 * 2281490269444000821336497

factor(2281490269444000821336497) # 2281490269444000821336497
factor(big"2281490269444000821336497") # 2281490269444000821336497

factor() の逆関数 prodfactors()

factor() の結果を全部掛け合わすと,元の数になる。

n = 540
prod(factor(n)) # 540
prodfactors(factor(Vector, n)) # 540
prodfactors(factor(DataStructures.SortedDict, n)) # 540
prodfactors(factor(Set, n)) # 30 これは,正しい答えではない

範囲内の素数生成 primes([lo,] hi)

primes(20, 50)
#=
7-element Vector{Int64}:
 23
 29
 31
 37
 41
 43
 47
=#

次の素数 nextprime(n::Integer, i::Integer=1; interval::Integer=1)

n より小さくない i 番目に小さい素数を返す。言い回しがまだるっこしいが,指定された数が素数だった場合,次の(1番目に小さい)素数はその数自体であるということ。

nextprime(100000000000000000000000000000) # 100000000000000000000000000319
factor(100000000000000000000000000319)    # 100000000000000000000000000319

nextprime(100000000000000000000000000319) # 100000000000000000000000000319

前の素数 prevprime(n::Integer, i::Integer=1; interval::Integer=1)

n より大きくない i 番目に大きい素数

2 つ先の素数

nextprime(100000000000000000000000000000, 2) # 100000000000000000000000000379

1 つ前の素数

prevprime(100000000000000000000000000378)    # 100000000000000000000000000319

i 番目の素数 prime(::Type{<:Integer}=Int, i::Integer)

100000 番目の素数は 1299709

prime(100000) # 1299709

primes() で生成される 1299709 までの素数の個数を数えれば,100000 になっていることが確認できる。

length(primes(1299709))
# 100000

素数判定 isprime(n::Integer) -> Bool

isprime(100000000000000000000000000319) # true

BigInt の場合は,確率的素数判定を行う。偽陽性率(素数ではないのに素数であると判定する率)は 0.25^reps。デフォルトでは reps = 25 なので,0.25^25 = 8.881784197001252e-16 に設定される。
isprime(x::BigInt, [reps = 25]) -> Bool


isprime(big(100000000000000000000000000319)) # true
isprime(big"100000000000000000000000000319") # true

isprime(big(100000000000000000000000000318)) # false

メルセンヌ素数判定 ismersenneprime(M::Integer; [check::Bool = true]) -> Bool

メルセンヌ数とは、2の冪よりも 1 小さい自然数、すなわち 2^n − 1(n は自然数)の形の自然数のことである。
これが素数の場合はメルセンヌ素数と呼ばれる。

ismersenneprime(2^11 - 1) # false
ismersenneprime(2^13 - 1) # true

素数の篩 primesmask([lo,], hi)

lo から hi までの数に対して,素数なら 1,合成数なら 0 の BitVector を返す。

mask = primesmask(10)
#=
10-element BitVector:
 0
 1
 1
 0
 1
 0
 1
 0
 0
 0
=#

mask が 1 である数を取り出す。

(1:10)[mask]
#=
4-element Vector{Int64}:
 2
 3
 5
 7
=#

ラディカル radical(n::Integer)

偶数個の素因数を持たないように選択した素因数の累積。

n = 2*2*3*7*7*7 # 4116
radical(n) # 42 = 2 * 3 * 7
factor(radical(n)) # 2 * 3 * 7

トーシエント数 totient(f::Factorization{T}) -> T
                   totient(n::Integer) -> Integer

オイラーのトーシエント関数( ϕ(n); totient function) の値
m ≦ n で,gcd(m, n) == 1 つまり,m, n が互いに素であるものの数

n が 素数の場合は 1 〜 n-1 と n は互いに素であるので,ϕ(11) は 10

sum(gcd(m, 11) == 1 for m = 1:11)
totient(11) # 10

n が合成数の場合は,n - 1 より小さな値になる

sum(gcd(m, 100) == 1 for m = 1:100) # 40
totient(100) # 40

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村