算術演算と初等関数

`

算術演算と初等関数

Juliaには、すべての数値プリミティブ型に対して、基本的な算術演算子とビット演算子が一通りそろっています。 また、移植性が高く効率的な実装の、標準的な数学関数も一通りそろっています。

`

算術演算子

下記の算術演算子 はすべてのプリミティブ数値型で利用可能です。

名前説明
+x単項加算恒等演算
-x単項減算加算の逆元への関数
x + y二項加算加算を実行
x - y二項減算減算を実行
x * y乗算乗算を実行
x / y除算除算を実行
x ÷ y整数除算x / y, 整数に切り捨て
x \ y逆除算y / xと同等
x ^ yxy
x % y剰余算rem(x,y)と同等

Bool 型の否定も同様です

名前説明
!x否定truefalseを逆にする

Juliaは昇格の仕組みのおかげで、引数に型の混合した算術演算をおこなっても、自然かつ自動的に"うまく動作"します。 昇格の仕組みの詳細は変換と昇格を参照してください。

julia> 1 + 2 + 3
6

julia> 1 - 2
-1

julia> 3*2/12
0.5

(慣習的に、周りの演算子より先に演算を行うときは、空白を詰めがちです。 例えば、よく-x + 2と書きますが、これは先にXに-1を掛けてから2を足すことを反映しています。)

`

ビット演算子

下記のビット演算子 はすべてのプリミティブ整数型で利用可能です。

名前
~x否定(not)
x & y論理積(and)
x | y論理和(or)
x ⊻ y排他的論理和(xor)
x >>> y論理シフト
x >> y算術シフト
x << y論理/算術 シフト 左

ビット演算の例をいくつかあげます。

julia> ~123
-124

julia> 123 & 234
106

julia> 123 | 234
251

julia> 123 ⊻ 234
145

julia> xor(123, 234)
145

julia> ~UInt32(123)
0xffffff84

julia> ~UInt8(123)
0x84

`

代入演算子

算術・ビット演算子で二項演算子のものはすべて演算結果を左の演算子に代入するバージョンの演算子が存在します。 代入バージョンの演算子は元の演算子のすぐ後ろに=をつけます。 例えば、x += 3x = x + 3と同等です。

julia> x = 1
1

julia> x += 3
4

julia> x
4

代入バージョンの二項演算子である算術・ビット演算子をすべて挙げると

+=  -=  *=  /=  \=  ÷=  %=  ^=  &=  |=  ⊻=  >>>=  >>=  <<=

!!! 注意 代入演算子は左辺の変数に対して再束縛を行います。この結果、変数の型が変わることも起こりえます。

julia> x = 0x01; typeof(x)
UInt8

julia> x *= 2 # Same as x = x * 2
2

julia> typeof(x)
Int64

`

ベクトル化した "dot" 演算子

すべての ^のような二項演算子に対して 、.^のように対応する"dot"演算子が存在します。 これは 自動的に 定義されて、配列の要素ごとに演算を行います。 例えば、[1,2,3] ^ 3は定義されていません。というのも、(二次元ではない)配列に数学的に標準的な"三乗"の 意味がないからです。 しかし、[1,2,3] .^ 3は要素ごとの(またはベクトル化した)計算結果[1^3, 2^3, 3^3]が定義できます。 同様に!などの単項演算子にも、.√のような、要素ごとに演算するものが存在します。

julia> [1,2,3] .^ 3
3-element Array{Int64,1}:
  1
  8
 27

More specifically, a .^ b is parsed as the "dot" call (^).(a,b), which performs a broadcast operation: it can combine arrays and scalars, arrays of the same size (performing the operation elementwise), and even arrays of different shapes (e.g. combining row and column vectors to produce a matrix). Moreover, like all vectorized "dot calls," these "dot operators" are fusing. For example, if you compute 2 .* A.^2 .+ sin.(A) (or equivalently @. 2A^2 + sin(A), using the @. macro) for an array A, it performs a single loop over A, computing 2a^2 + sin(a) for each element of A. In particular, nested dot calls like f.(g.(x)) are fused, and "adjacent" binary operators like x .+ 3 .* x.^2 are equivalent to nested dot calls (+).(x, (*).(3, (^).(x, 2))).

Furthermore, "dotted" updating operators like a .+= b (or @. a += b) are parsed as a .= a .+ b, where .= is a fused in-place assignment operation (see the dot syntax documentation).

Note the dot syntax is also applicable to user-defined operators. For example, if you define ⊗(A,B) = kron(A,B) to give a convenient infix syntax A ⊗ B for Kronecker products (kron), then [A,B] .⊗ [C,D] will compute [A⊗C, B⊗D] with no additional coding.

Combining dot operators with numeric literals can be ambiguous. For example, it is not clear whether 1.+x means 1. + x or 1 .+ x. Therefore this syntax is disallowed, and spaces must be used around the operator in such cases.

`

数値の比較

すべてのプリミティブ数値型に対して標準的な比較演算が定義されています。

演算名前
==等号
!=, 不等号
<未満
<=, 以下
>より大きい
>=, 以上

簡単な例を挙げます。

julia> 1 == 1
true

julia> 1 == 2
false

julia> 1 != 2
true

julia> 1 == 1.0
true

julia> 1 < 2
true

julia> 1.0 > 3
false

julia> 1 >= 1.0
true

julia> -1 <= 1
true

julia> -1 <= -1
true

julia> -1 <= -2
false

julia> 3 < -0.5
false

整数の比較は標準的にビットの比較によって行います。 浮動小数点の比較はIEEE 754 規格によって行います。

julia> NaN == NaN
false

julia> NaN != NaN
true

julia> NaN < NaN
false

julia> NaN > NaN
false

配列を扱いは、頭痛の種になりえます。

julia> [1 NaN] == [1 NaN]
false

Juliaには特殊な値の数を検査する補助的な関数があって、ハッシュキーの比較などには役立ちます。

関数検査内容
isequal(x, y)xyが等しいかどうか
isfinite(x)x が有限の数かどうか
isinf(x)x が無限かどうか
isnan(x)x が非数かどうか

isequalではNaNは互いに等しいとみなします。

julia> isequal(NaN, NaN)
true

julia> isequal([1 NaN], [1 NaN])
true

julia> isequal(NaN, NaN32)
true

isequalは符号つきの0を見分ける用途にも利用できます。

julia> -0.0 == 0.0
true

julia> isequal(-0.0, 0.0)
false

符号付整数、符号なし整数、浮動小数点数と型の混ざった比較には技巧が必要です。 Juliaでは比較が正しくできることを保証するために、多大な注意を払ってきました。 他の型に対しては、isequalはデフォルトで ==を呼び出します。 なので、自分の作った型に対して等号を定義するには、 ==メソッドを加えるだけいいです。 自分で等号を定義する場合には、isequal(x,y) が成り立つときはhash(x) == hash(y)が成り立つのを保証するために 対応するhashメソッドも定義すべきでしょう。

`

比較の連鎖

有名な例外であるPython は別にして、ほとんどの言語とは異なり、Juliaでは比較を好きなだけつなぐことができます。

julia> 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
true

比較の連鎖は数値を使うコードでは大変便利です。 比較の連鎖では、&&演算子をスカラ値の比較に使い、&演算子を要素ごとの比較に使って配列での比較を可能にします。 例えば、0 .< A .< 1は 、Aの対応する要素が0と1の間にある場合にtrueをとなるブール値の配列を返します。

julia> v(x) = (println(x); x)
v (generic function with 1 method)

julia> v(1) < v(2) <= v(3)
2
1
3
true

julia> v(1) > v(2) <= v(3)
2
1
false

真ん中の式は1度しか評価されませんが、v(1) < v(2) && v(2) <= v(3)と書いたなら評価は2度行われます。 しかし、連鎖した比較の評価の順番は決まっていません。 比較の連鎖では、(表示などの)副作用を伴う式は使わないように強くお勧めします。 副作用が必要な場合は短絡評価の&&演算子を明示的に使うべきでしょう。 (短絡評価を参照のこと。)

`

初等関数

Juliaには、数学的な関数や演算子が一通りそろっています。 この数学的な演算子は、広範な種類の数値に対して、意味をなす限り定義され、 対象は整数、浮動小数点数、有理数、複素数に及びます。

さらに、これらの関数は(Juliaの他の関数と同じように)、"ベクトル化"した形で、配列やその他のコレクションに対して 適用できます。 その時には、dot 構文 f.(A)を使い、 例えば、sin.(A)だと配列Aの各要素に対するsinの値を計算します。

`

演算子の優先順位と結合則

Juliaでは、下記の優先順位と結合則で、高いほうから低いほうへと、演算子が適用されます。

種別演算子結合則
構文. 次に ::
^
単項+ - √[1]
シフト<< >> >>>
分数//
乗算* / % & \ ÷[2]
加算+ - | ⊻[2]
構文: ..
構文|>
構文<|
比較> < >= <= == === != !== <:非結合
制御&& 次に || 次に ?
=>
代入= += -= *= /= //= \= ^= ÷= %= |= &= ⊻= <<= >>= >>>=
[1]

単項演算子の +-には、++などの演算子との曖昧さをなくすために、明示的な括弧が必要です。 他の単項演算子の結合は右結合として解析されます。例えば、 √√-a√(√(-a))です。

[2]

演算子の +, ++,* は非結合的です。 a + b + c+(a, b, c) として解析され +(+(a, b),c)ではありません。 しかし、フォールバックメソッドの +(a, b, c, d...)*(a, b, c, d...) は両方ともデフォルトでは左結合で評価されます。

すべての Juliaの演算子の優先順位の完全なリストはこのファイルの最初をみてください。 src/julia-parser.scm

また演算子の優先順位を表す数値は、組み込み関数のBase.operator_precedenceを使ってみることができます。 大きい数字のほうが優先順位が高くなります。

julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.)
(11, 13, 17)

julia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=))  # (Note the necessary parens on `:(=)`)
(0, 1, 1)

演算子を表すシンボルの結合則も、組み込み関数のBase.operator_associativityを使ってみることができます。

julia> Base.operator_associativity(:-), Base.operator_associativity(:+), Base.operator_associativity(:^)
(:left, :none, :right)

julia> Base.operator_associativity(:⊗), Base.operator_associativity(:sin), Base.operator_associativity(:→)
(:left, :none, :right)

:sinのようなシンボルには優先順位が 0として返される点に注意してください。 この値は演算子として無効であることを表し、優先順位が最も低いわけではありません。 同様にこういった演算子には結合性は:noneが割り当てられています。

`

数値変換

Juliaでは3種の数値変換が利用できますが、それぞれ厳密な変換ができないときの扱いが異なります。

  * `T`が浮動小数点数型の場合、最近接の表現可能な値を返し、正負の無限大になることもありえます。
  * `T`が整数型の場合、`x`が型`T`で表現不可能な場合、`InexactError`が生じる。

例えば、round(Int,x)Int(round(x))を手短にしたものです。

それぞれの例を下記に挙げます。

julia> Int8(127)
127

julia> Int8(128)
ERROR: InexactError: trunc(Int8, 128)
Stacktrace:
[...]

julia> Int8(127.0)
127

julia> Int8(3.14)
ERROR: InexactError: Int8(Int8, 3.14)
Stacktrace:
[...]

julia> Int8(128.0)
ERROR: InexactError: Int8(Int8, 128.0)
Stacktrace:
[...]

julia> 127 % Int8
127

julia> 128 % Int8
-128

julia> round(Int8,127.4)
127

julia> round(Int8,127.6)
ERROR: InexactError: trunc(Int8, 128.0)
Stacktrace:
[...]

自分で変換や昇格を定義するには、変換と昇格を参照してください。

`

端数処理関数

関数説明戻り値の型
round(x)xを最近接の整数に丸めるtypeof(x)
round(T, x)xを最近接の整数に丸めるT
floor(x)x-Inf方向に丸めるtypeof(x)
floor(T, x)x-Inf方向に丸めるT
ceil(x)x+Inf方向に丸めるtypeof(x)
ceil(T, x)x+Inf方向に丸めるT
trunc(x)xを0方向に丸めるtypeof(x)
trunc(T, x)xを0方向に丸めるT

`

除算関数

関数説明
div(x,y), x÷y切り落とし除算 0方向に丸めた商
fld(x,y)床除算   -Inf方向に丸めた商
cld(x,y)天井除算  +Inf方向に丸めた商
rem(x,y)剰余(remainder)  x == div(x,y)*y + rem(x,y)  符号は x と一致
mod(x,y)剰余(modulus)   x == fld(x,y)*y + mod(x,y)  符号は y と一致
mod1(x,y)1 オフセットしたmod mod(r, y) == mod(x, y)を満たすrの中でy>0の時r∈(0,y]`y<0の時 r∈[y,0)のものを返す
mod2pi(x)2piを法とする剰余 0 <= mod2pi(x)   < 2pi
divrem(x,y)(div(x,y),rem(x,y))を返す
fldmod(x,y)(fld(x,y),mod(x,y))を返す
gcd(x,y...)x, y,... の正の最大公約数
lcm(x,y...)x, y,... の正の最小公倍数

`

符号・絶対値関数

関数説明
abs(x)xの絶対値である正の値
abs2(x)xの絶対値の2乗
sign(x)xの符号。 -1, 0, +1 のいずれかを返す
signbit(x)符号ビットが オン (真) か オフ (偽)かを示す
copysign(x,y)絶対値がxで符号がyの値
flipsign(x,y)絶対値がxで符号がx*yの値

`

巾、対数、平方根

関数説明
sqrt(x), √xxの平方根
cbrt(x), ∛xxの三乗根
hypot(x,y)直角をはさむ2辺が x,yである三角形の斜辺
exp(x)自然指数関数の xでの値
expm1(x)0付近のxに対する exp(x)-1の正確な値
ldexp(x,n)整数nにたいして効率的に計算できるx*2^nの値
log(x)自然対数のxでの値
log(b,x)bを底とする対数のxでの値
log2(x)2を底とする対数のxでの値
log10(x)10を底とする対数のxでの値
log1p(x)0付近のxに対する log(1+x)の正確な値
exponent(x)浮動小数点数のxの2を基数とする指数部分
significand(x)浮動小数点数のxの2を基数とする仮数部分

hypot, expm1, log1pといった関数がなぜ必要で役に立つのを概観するには John D. Cook の 優れた2編のブログ投稿を参照のこと。 expm1, log1p, erfc, hypot.

`

三角関数と双曲線関数

標準的な三角関数と双曲線関数はすべて定義されています。

sin    cos    tan    cot    sec    csc
sinh   cosh   tanh   coth   sech   csch
asin   acos   atan   acot   asec   acsc
asinh  acosh  atanh  acoth  asech  acsch
sinc   cosc

これらの関数の引数はすべて1つですが、atanの場合は、引数を2つとると昔からあるatan2 として使うことができます。

さらに、 sinpi(x)cospi(x) を、それぞれsin(pi*x)cos(pi*x)よりも 正確な計算をする関数として使うことができます。

ラジアンのかわりに度を使うには、三角関数の後ろにdをつけます。 例えば、sind(x)xに度が指定されたものとして、計算します。 変数を度として扱う三角関数の完全なリストは、

sind   cosd   tand   cotd   secd   cscd
asind  acosd  atand  acotd  asecd  acscd

`

特殊関数

その他多くの数学の特殊関数がパッケージ SpecialFunctions.jl. によって利用可能です。