算術演算と初等関数

算術演算と初等関数

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

算術演算子

次の 算術演算子は、すべてのプリミティブ数値型でサポートされています:

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

Boolタイプの否定も同様です:

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

A numeric literal placed directly before an identifier or parentheses, e.g. 2x or 2(x+y), is treated as a multiplication, except with higher precedence than other binary operations. See Numeric Literal Coefficients for details.

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

すべての二項算術演算子とビット演算子の代入バージョンは以下のとおりです:

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

代入演算子は、左辺側変数に再バインドを行います。結果、変数の方が変わることもあります。

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

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

julia> typeof(x)
Int64

ベクトル化した"ドット"演算子

全ての ^ のような二項演算子には、配列の各要素に対して ^を実行するドット演算子 .^が自動的に定義されます。たとえば、[1,2,3] ^ 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

具体的には、a.^ b"ドット"呼び出し(^).(a,b)として解析されます。これは、ブロードキャスト 操作を実行します: 配列とスカラー、同一サイズの配列2つ(要素ごとの演算子適用)そして、異なるサイズの配列(例えば、行ベクトルと列ベクトルの積)でさえも組み合わせ利用できます。さらに、すべてのベクトル化された"ドットコール"と同様に、これらの「ドット演算子」は融合的です。たとえば、配列Aに対して 2 .* A.^2 .+ sin(A) (もしくは、@ マクロを使用して@. 2A^2 + sin(A)とも書けますが)を計算する時、Aの要素に関するループを1回実行し2a^2 + sin(a) を各要素に対して計算します。特に、f.(g.(x)) のような入れ子になったドットコールは融合され、x.+ 3 .* x.^2 のような "隣接する" 二項演算子は入れ子になったドットコール (+) .(x, (*).(3,(^).(x, 2)))と等価になります。

さらに、a.+= b (または @. a += b) のような "ドットのついた" 代入演算子は a= a .+ b として解析され、.= は融合された インプレース 代入となります (ドット構文ドキュメントを参照してください)。

ドット構文は、ユーザーが定義した演算子にも適用できます。 たとえば、クローネッカー積(kron)に便利なイン二項演算構文 A ⊗ Bを使うために⊗(A,B) = kron(A,B) を定義した場合 、[A,B] .⊗[C,D] は追加のコーディングなしで [A⊗B, B⊗D] を計算します。

ドット演算子と数値リテラルの組み合わせがあいまいになる場合があります。 たとえば、1.+x1. +x1 .+ xのどちらを意味するかは自明ではありません。したがって、この構文は許可されず、このような場合は演算子の周囲にスペースを使用する必要があります。

数値比較

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

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

簡単な例を次に示します:

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 is NaNであるか

isequalNaN を互いに等しいと見なします:

julia> isequal(NaN, NaN)
true

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

julia> isequal(NaN, NaN32)
true

isequal は、符号付きゼロを区別するためにも使用できます:

julia> -0.0 == 0.0
true

julia> isequal(-0.0, 0.0)
false

符号付き整数、符号なし整数、および浮動小数点数が混在する比較は、難しい場合があります。Julia が正しい比較を行うために、多くの注意が払われてきました。

他の型については、isequal はデフォルトで == を呼び出すので、独自の型の等価性を定義する場合は、== メソッドを追加するだけで済みます。 さらに、isequal(x,y)Trueとなる時に hash(x) == hash(y)でもあることを保証したいのであれば、対応する hash メソッドも定義しなければいけないでしょう。

比較の連鎖

ほとんどの言語とは異なり、Julia は比較を任意に連鎖させることができます。(ほとんどの言語と言いましたが、なんとPythonは比較の連鎖ができます。)

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

真ん中の式は、v(1) < v(2) && v(2) <= v(3) と書かれてた場合のように2回評価されるのではなく、1回だけ評価されています。ただし、比較連鎖の中での評価の順序は未定義です。(printなどの)副作用のある表現を使用しないことを強くお勧めします。もし副作用が必要な場合は、短絡演算子 && を明示的に使用する必要があります(参照: 短絡評価)。

初等関数

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

Numeric literal coefficients, e.g. 2x, are treated as multiplications with higher precedence than any other binary operation, and also have higher precedence than ^.

また、組み込み関数 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_associaivity を呼び出すことによっても見つけることができます:

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 つの形式の数値変換をサポートしていますが、これらはそれぞれ厳密な変換ができないときの扱いが異なります。

以下にそれぞれの例を示します。

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(3.14)
Stacktrace:
[...]

julia> Int8(128.0)
ERROR: InexactError: 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 を ゼロの方向に丸めるtypeof(x)
trunc(T, x)x をゼロの方向に丸めるT

除算関数

関数説明
div(x,y), x÷y切り落とし除算; ゼロ方向に丸めた商
fld(x,y)floor除算; -Inf方向に丸めた商
cld(x,y)ceil除算; +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) を満たし y>0の場合 r∈(0,y]y<0 の場合 r∈[y,0) となるような rを返す
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,... の正の最大公約数 (greatest positive common divisor)
lcm(x,y...)x, y,... の正の最小公倍数 (least positive common multiple)

符号関数と絶対値関数

関数説明
abs(x)x の絶対値
abs2(x)x の絶対値の二乗
sign(x)x の符号。 returning -1, 0, +1 のいずれかを返す
signbit(x)サインビットが立っているかどうか true/false を返す
copysign(x,y)sign(y) * abs(x) を返す
flipsign(x,y)sign(x*y) * abs(x) を返す

累乗・対数・平方根

関数説明
sqrt(x), √xx の平方根
cbrt(x), ∛xx の三乗根
hypot(x,y)直角を挟む2辺の長さがx, y である直角三角形の斜辺の長さ
exp(x)自然指数関数 の x での値
expm1(x)ゼロ近傍の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)ゼロ近傍のx に対する log(1+x)の正確な値
exponent(x)浮動小数点x の 2を基数とする指数部分
significand(x)浮動小数点 x の 2を基数とする仮数部分

hypotexpm1、およびlog1pのような関数が必要かつ有用である理由概説については、John D. Cook の優れたブログ投稿を参照してください: 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

これらはすべて単一引数関数ですが、atanは2つの引数をとることもでき、そのときは 従来のatan2 関数の振る舞いになります。

また、sinpi(x)cospi(x)は、それぞれsin(pi*x)cos(pi*x)のより正確な計算のために提供されます。

ラジアンの代わりに"度"を使用して三角関数を計算するには、関数の接尾辞を d で囲みます。たとえば、sind(x)xが"度"で指定されるxのsinを計算します。 "度"を入力に使用した三角関数の完全なリストは次のとおりです:

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

特殊関数

他の多くの特殊関数は、パッケージSpecialFunctions.jlで提供されています。