Как применить не оператор ко всем элементам матрицы в Юлии? - PullRequest
3 голосов
/ 28 октября 2019

Мне нужно применить оператор «не» к матрице нулей и единиц в Юлии. В Matlab я бы сделал это:

A=not(B);

В Джулии я попытался сделать это:

A = .~ B;

и

A = .! B;

Это должно превратить нули в единицы и единицы. нулями, но в результате я получаю ошибку, или все элементы матрицы являются отрицательными числами, которые я не ввел. Заранее спасибо!

Ответы [ 4 ]

6 голосов
/ 28 октября 2019

Проблема с A = .!B заключается в том, что логическое отрицание !(::Int64) не определено для целых чисел. Это имеет смысл: что, скажем, !3 разумно дать?

Поскольку вы хотите выполнить логическую операцию, есть ли более глубокая причина, по которой вы начинаете работать с целыми числами?

Возможно, вы могли бы работать с BitArray, который гораздо более эффективен и должен вести себя как обычный Array в большинстве операций.

Вы можете легко преобразовать вашу целочисленную матрицу в BitArray. После этого применение логического не работает, как ожидалось.

julia> A = rand(0:1, 5,5)
5×5 Array{Int64,2}:
 0  0  0  1  1
 0  1  0  0  1
 0  1  1  1  0
 1  1  0  0  0
 1  1  1  0  0

julia> B = BitArray(A)
5×5 BitArray{2}:
 0  0  0  1  1
 0  1  0  0  1
 0  1  1  1  0
 1  1  0  0  0
 1  1  1  0  0

julia> .!B
5×5 BitArray{2}:
 1  1  1  0  0
 1  0  1  1  0
 1  0  0  0  1
 0  0  1  1  1
 0  0  0  1  1

Важнейшей частью здесь является то, что тип элемента (eltype) для BitArray равен Bool, для которого отрицание явно хорошо определено,В этом смысле вы также можете использовать B = Bool.(A) для преобразования всех элементов в логические значения.

4 голосов
/ 28 октября 2019

Для общего решения перехода от A, где A - это матрица чисел к логической матрице с истинными значениями, где в других местах были нули и ложные значения, вы можете сделать это:

julia> A = rand(0:3, 5, 5)
5×5 Array{Int64,2}:
 1  0  1  0  3
 2  0  1  1  0
 2  1  1  3  1
 1  0  3  0  3
 1  3  3  1  2

julia> (!iszero).(A)
5×5 BitArray{2}:
 1  0  1  0  1
 1  0  1  1  0
 1  1  1  1  1
 1  0  1  0  1
 1  1  1  1  1

Чтобы разобрать, что здесь происходит:

  • iszero - это предикат, который проверяет, является ли скалярное значение нулевым
  • !iszero - это предикат, который возвращается, если скалярзначение не ноль
  • (!iszero).(A) передает !iszero функцию по матрице A

Возвращает BitArray с желаемым шаблоном нулей (ложных значений) иодни (правда). Обратите внимание, что в контексте массива false печатает как 0, а true печатает как 1 (они численно равны). Вы также можете сравнить с номером 0, например:

julia> A .!= 0
5×5 BitArray{2}:
 1  0  1  0  1
 1  0  1  1  0
 1  1  1  1  1
 1  0  1  0  1
 1  1  1  1  1
2 голосов
/ 29 октября 2019

Вы также можете свернуть свои собственные:

not(x) = (x |> Bool |> !) |> Float64

определяет метод, который преобразует x в boolean, не применяется, а затем преобразует результат обратно в числа. not.(A) будет действовать поэлементно для массива A. Здесь |> перенаправляет вывод на следующий метод и работает с вещанием.

2 голосов
/ 28 октября 2019

Хотя концептуально не самый чистый, A=1.-B будет делать то, что вы хотите. Проблема с ~ заключается в том, что он выполняет побитовое, а не целое число, которое выдает отрицательные числа. Не уверен, что не так с !, за исключением, может быть, !.B

...