Spec-Zone.ru › Julia 1.3

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

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 побитовое 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 += 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 возвращает булевый массив, элементы которого истинны, если соответствующие элементы 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]
Синтаксис : .. Слева
Синтаксис |> Слева
Синтаксис <| Справа
Сравнения > < >= <= == === != !== <: Неассоциативные
Управление потоком && и || и ? Справа
Пара => Справа
Присваивания = += -= *= /= //= \= ^= ÷= %= |= &= ⊻= <<= >>= >>>= Справа
[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

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

Вы также можете найти числовую прецедентность любого заданного оператора с помощью встроенной функции 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 — тип целого числа, генерируется исключение, если 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) деление с округлением вниз; частное округляется в сторону -Inf
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) модуль относительно 2π; 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) точная экспоненциальная функция для 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) точная функция натурального логарифма для 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–2020 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.3.1/manual/mathematical-operations/

Spec-Zone.ru

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