Spec-Zone.ru › Julia 1.4

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

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 и наоборот

Числовая литерал, размещенная непосредственно перед идентификатором или скобками, например, 2x или 2(x+y), обрабатывается как умножение, за исключением более высокого приоритета, чем другие бинарные операции. Подробности см. в разделе Коэффициенты числовых литералов.

Система повышения типов 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. В частности, вложенные вызовы точка сливаются, а "смежные" бинарные операторы, такие как 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.

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

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]
Синтаксис : .. Слева
Синтаксис |> Слева
Синтаксис <| Справа
Сравнения > < >= <= == === != !== <: Неассоциативное
Управление потоком && и || и ? Справа
Пара => Справа
Присваивания = += -= *= /= //= \= ^= ÷= %= |= &= ⊻= <<= >>= >>>= Справа

Полный список всех операторов Julia с приоритетом см. в начале этого файла: src/julia-parser.scm

Коэффициенты числовых литералов, например, 2x, обрабатываются как умножения с более высоким приоритетом, чем любая другая бинарная операция, и также имеют более высокий приоритет, чем ^.

Вы также можете найти числовой приоритет любого заданного оператора с помощью встроенной функции Base.operator_precedence, где более высокие числа имеют более высокий приоритет:

julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.)
(11, 12, 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(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) деление с округлением вниз; частное округлено к нулю
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) указывает, включён ли бит знака (true) или выключен (false)
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.

  • 1Унарные операторы + и - требуют явных скобок вокруг своего аргумента, чтобы отличить их от оператора ++, и т. д. Другие композиции унарных операторов анализируются с правой ассоциативностью, например, √√-a как √(√(-a)).
  • 2Операторы +, ++ и * не ассоциативны. a + b + c анализируется как +(a, b, c), а не как +(+(a, b), c). Однако, методы по умолчанию для +(a, b, c, d...) и *(a, b, c, d...) оба по умолчанию используют левоассоциативное вычисление.

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

Spec-Zone.ru

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