Spec-Zone.ru › Julia 0.7

Математические операции и элементарные функции

Julia предоставляет полный набор основных арифметических и побитовых операторов для всех числовых типов, а также эффективные реализации стандартных математических функций.

Арифметические операторы

Следующие арифметические операторы поддерживаются для всех числовых типов:

Выражение Имя Описание
+x унарный плюс идентичная операция
-x унарный минус отображает значения на их аддитивные обратные
x + y бинарный плюс выполняет сложение
x - y бинарный минус выполняет вычитание
x * y умножение выполняет умножение
x / y деление выполняет деление
x ÷ y целочисленное деление x / y, усеченное до целого числа
x \ y обратное деление эквивалентно y / x
x ^ y возведение в степень возводит x в y-ую степень
x % y остаток от деления эквивалентно rem(x,y)

а также отрицание для типов Bool:

Выражение Имя Описание
!x отрицание меняет true на false и наоборот

Система повышения типов Julia делает арифметические операции на смешанных типах аргументов естественными и автоматическими. Подробности о системе повышения типов см. в разделе Преобразование и повышение.

Вот несколько простых примеров использования арифметических операторов:

julia> 1 + 2 + 3
6

julia> 1 - 2
-1

julia> 3*2/12
0.5

(По соглашению, мы стараемся располагать операторы более плотно, если они применяются до других операторов. Например, мы, как правило, пишем -x + 2 чтобы отразить, что сначала x отрицается, а затем 2 добавляется к результату.)

Побитовые операторы

Следующие побитовые операторы поддерживаются для всех целых типов:

Выражение Имя
~x побитовое отрицание
x & y побитовое И
x | y побитовое ИЛИ
x ⊻ y побитовое исключающее ИЛИ
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 += 3 эквивалентна записи x = 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

Векторизованные операторы "точка"

Для каждой бинарной операции, например, ^, существует соответствующая операция "точка" .^, которая автоматически определяется для выполнения ^ поэлементно над массивами. Например, [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

Более конкретно, a .^ b интерпретируется как "вызов точки" (^).(a,b), который выполняет операцию векторного расширения: он может объединять массивы и скаляры, массивы одинакового размера (выполняя операцию поэлементно), и даже массивы разных форм (например, объединяя строчные и столбцовые векторы для создания матрицы). Кроме того, как и все векторизованные "вызовы точки", эти "операторные точки" являются сливаемыми. Например, если вы вычисляете 2 .* A.^2 .+ sin.(A) (или эквивалентно @. 2A^2 + sin(A), используя макрос @.) для массива A, он выполняет один цикл по A, вычисляя 2a^2 + sin(a) для каждого элемента A. В частности, вложенные вызовы точки, такие как f.(g.(x)), сливаются, и "смежные" бинарные операторы, такие как x .+ 3 .* x.^2, эквивалентны вложенным вызовам точки (+).(x, (*).(3, (^).(x, 2))).

Кроме того, "точечные" операторы обновления, такие как a .+= b (или @. a += b ), интерпретируются как a .= a .+ b, где .= - это слитая ин-плос операция присваивания (см. документацию по синтаксису точки).

Обратите внимание, что синтаксис точки также применим к пользовательским операторам. Например, если вы определите ⊗(A,B) = kron(A,B) для получения удобного инфиксного синтаксиса A ⊗ B для произведений Кронекера (kron), то [A,B] .⊗ [C,D] вычислит [A⊗C, B⊗D] без дополнительного программирования.

Объединение операторов точки с числовыми литералами может быть неоднозначным. Например, неясно, означает ли 1.+x 1. + x или 1 .+ x. Поэтому такой синтаксис запрещен, и в таких случаях должны использоваться пробелы вокруг оператора.

Числовые сравнения

Стандартные операции сравнения определены для всех числовых типов:

Оператор Имя
== равенство
!=, ≠ неравенство
< меньше
<=, ≤ меньше или равно
> больше
>=, ≥ больше или равно

Вот несколько простых примеров:

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:

  • Конечные числа упорядочиваются обычным образом.
  • Положительный ноль равен, но не больше отрицательного нуля.
  • Inf равно самому себе и больше всего остального, кроме NaN.
  • -Inf равно самому себе и меньше всего остального, кроме NaN.
  • NaN не равно, не меньше и не больше ничего, включая себя.

Последний пункт потенциально неожиданный и заслуживает внимания:

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) x и y идентичны
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 также может использоваться для различения знаковых нулей:

julia> -0.0 == 0.0
true

julia> isequal(-0.0, 0.0)
false

Сравнения смешанных типов между знаковыми целыми числами, беззнаковыми целыми числами и числами с плавающей точкой могут быть сложными. Было приложено много усилий, чтобы обеспечить правильность их выполнения в Julia.

Для других типов isequal по умолчанию вызывает ==, поэтому если вы хотите определить равенство для собственных типов, вам нужно добавить метод ==. Если вы определите свою собственную функцию равенства, вам, вероятно, нужно определить соответствующий метод hash, чтобы убедиться, что isequal(x,y) подразумевает hash(x) == hash(y).

Цепочки сравнений

В отличие от большинства языков, за исключением Python, сравнения могут быть произвольно вложенными:

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

Цепочки сравнений часто бывают удобными в численном коде. Цепочки сравнений используют оператор && для скалярных сравнений и оператор & для поэлементных сравнений, что позволяет им работать с массивами. Например, 0 .< A .< 1 дает булевый массив, чьи элементы равны true, где соответствующие элементы A находятся между 0 и 1.

END_OF_DOCUMENT_MARKER

Обратите внимание на поведение цепочек сравнений:

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). Однако порядок вычислений в цепочке сравнений не определён. Сильно рекомендуется не использовать выражения с побочными эффектами (например, печать) в цепочках сравнений. Если побочные эффекты необходимы, следует явно использовать оператор короткого замыкания && (см. Вычисление с коротким замыканием).

Элементарные функции

Julia предоставляет обширную коллекцию математических функций и операторов. Эти математические операции определены для как можно более широкого класса числовых значений, включая целые числа, числа с плавающей точкой, рациональные и комплексные числа, где такие определения имеют смысл.

Кроме того, эти функции (как и любая функция Julia) могут применяться «векторизованным» способом к массивам и другим коллекциям с помощью синтаксиса точки f.(A), например, sin.(A) вычислит синус каждого элемента массива A.

Прецеденция и ассоциативность операторов

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 поддерживает три формы числовых преобразований, которые различаются по обработке неточных преобразований.

  • Запись T(x) или convert(T,x) преобразует x в значение типа T.

    • Если T — тип с плавающей точкой, результатом является ближайшее представимое значение, которое может быть положительной или отрицательной бесконечностью.
    • Если T — целочисленный тип, возникает InexactError , если x не представимо типом T.
  • x % T преобразует целое число x в значение целочисленного типа T , конгруэнтного x по модулю 2^n, где n — количество битов в T. Другими словами, двоичное представление усекается для соответствия.

  • Функции округления принимают тип T в качестве необязательного аргумента. Например, 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 к нулю typeof(x)
trunc(T, x) округление x к нулю T

Функции деления

Функция Описание
div(x,y), x÷y целочисленное деление; частное округляется к нулю
fld(x,y) деление с округлением вниз; частное округляется к нулю
cld(x,y) деление с округлением вверх; частное округляется к +Inf
rem(x,y) остаток; удовлетворяет x == div(x,y)*y + rem(x,y); знак совпадает со знаком x
mod(x,y) модуль; удовлетворяет x == fld(x,y)*y + mod(x,y); знак совпадает со знаком y
mod1(x,y) mod со смещением 1; возвращает r∈(0,y] для y>0 или r∈[y,0) для y<0, где mod(r, y) == mod(x, y)
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
sign(x) указывают знак x, возвращая -1, 0 или +1
signbit(x) указывает, установлен ли бит знака (истина) или сброшен (ложь)
copysign(x,y) значение с модулем x и знаком y
flipsign(x,y) значение с модулем x и знаком x*y

Степни, логарифмы и корни

Функция Описание
sqrt(x), √x квадратный корень из x
cbrt(x), ∛x кубический корень из x
hypot(x,y) гипотенуза прямоугольного треугольника с катетами длиной x и y
exp(x) экспонента от x
expm1(x) точное значение exp(x)-1 для x близких к нулю
ldexp(x,n) x*2^n эффективно вычисляется для целых значений n
log(x) натуральный логарифм от x
log(b,x) логарифм по основанию b от x
log2(x) логарифм по основанию 2 от x
log10(x) логарифм по основанию 10 от x
log1p(x) точное значение log(1+x) для x близких к нулю
exponent(x) бинарный порядок (экспонента) числа x
significand(x) бинарная мантисса (значащая часть) числа с плавающей точкой x

Для обзора причин, по которым функции, такие как hypot, expm1 и log1p необходимы и полезны, см. превосходную пару статей в блоге Джона Д. Кука по этой теме: 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 принимает два аргумента, соответствующие традиционной функции atan2.

Кроме того, sinpi(x) и cospi(x) предназначены для более точного вычисления sin(pi*x) и cos(pi*x) соответственно.

Для вычисления тригонометрических функций в градусах вместо радиан, добавьте суффикс d. Например, sind(x) вычисляет синус x, где x задано в градусах. Полный список тригонометрических функций с вариантами для градусов:

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

Специальные функции

Многие другие специальные математические функции предоставляются пакетом SpecialFunctions.jl.

© 2009–2019 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v0.7.0/manual/mathematical-operations/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API