Как правильно совместить map () и rand () в Julia? - PullRequest
1 голос
/ 01 февраля 2020

Я использую Zygote в Julia, и у меня есть некоторый код, который должен l oop через два объекта одинакового размера и, для каждого элемента длиной менее <= 1, случайным образом выбирать между этой частью / для первого или второго объекта. Код может лучше объяснить, что я пытаюсь сделать:

function rangeThrough(parent1, parent2)
    child = map(x -> if length(x[1]) > 1 rangeThrough(x[1], x[2]) else rand([x[1] x[2]]) end, zip(parent1, parent2))
    return child
end

aa = [Float32[0. 0. 0. 0.], Float32[0. 0. 0.], Float32[0.]]

bb = [Float32[1. 1. 1. 1.], Float32[1. 1. 1.], Float32[1.]]

Zygote.Params(rangeThrough(aa, bb))

Вывод, который я получаю для последней строки кода, выглядит примерно так:

Params([Float32[1.0 1.0 1.0 0.0], Float32[0.0 0.0 1.0], 0.0])

Однако что Я пытаюсь достичь:

Params([Float32[1.0 1.0 1.0 0.0], Float32[0.0 0.0 1.0], Float32[0.0]])

Я пробовал несколько вещей, но пока не смог заставить его работать. Я не уверен, почему последнее число не содержится в массиве Float32[]. Что я мог бы сделать по-другому, чтобы исправить это?

Редактировать: Упрощая код, чтобы принимать только один список в качестве ввода, например так:

function tempRangeThrough(parent1)
    child = map(x -> if length(x) > 1 tempRangeThrough(x) else rand([x]) end, parent1)
    return child
end
Zygote.Params(tempRangeThrough(aa))

Я получаю предполагаемый вывод:

Params([Float32[0.0 0.0 0.0 0.0], Float32[0.0 0.0 0.0], Float32[0.0]])

Итак, я считаю, что это связано со свойствами zip(), но я не уверен, как это исправить.

Ответы [ 2 ]

1 голос
/ 02 февраля 2020

Я не совсем понял, какое именно поведение вы ищете, но хотел упомянуть, что map может принимать и n-арные функции - поэтому вам не нужно zip здесь. И в сочетании с do -блоком функция может выглядеть следующим образом:

julia> range_through(parent1, parent2) = map(parent1, parent2) do x, y
           if length(x) > 1
               return x
           else
               return rand((x, y))
           end
       end
range_through (generic function with 1 method)

julia> range_through(aa, bb)
3-element Array{Array{Float32,N} where N,1}:
 [0.0 0.0 0.0 0.0]
 [0.0 0.0 0.0]    
 [1.0]  
1 голос
/ 01 февраля 2020

Возможно, вы захотите что-то вроде этого:

julia> rangeThrough(p1, p2) = [length(a) > 1 ? a : rand((a,b)) for (a, b) in zip(p1, p2)]
rangeThrough (generic function with 1 method)

julia> rangeThrough(aa, bb)
3-element Array{Array{Float32,N} where N,1}:
 [0.0 0.0 0.0 0.0]
 [0.0 0.0 0.0]
 [1.0]
...