В следующей функции
function foo(g)
a = [g * sqrt(i) for i in 1:4]
b = [g * i ^ 2 for i in 1:4]
for j in [a, b]
j /= sum(j)
println(j)
end
return a, b
end
foo(2)
Я ожидаю, что напечатанные значения согласуются с возвращенными значениями. Вместо этого возвращаемые значения не отражают деление, выполненное в строке 5. Результат
[0.16270045344786252, 0.2300931878702196, 0.2818054517861928, 0.32540090689572504]
[0.03333333333333333, 0.13333333333333333, 0.3, 0.5333333333333333]
([2.0, 2.8284271247461903, 3.4641016151377544, 4.0], [2, 8, 18, 32])
Я видел обсуждение на форуме Julia, где у пользователя были похожие проблемы в сеансе REPL. Но предложенное решение состояло в том, чтобы либо обернуть цикл for функцией, что я уже сделал, либо написать эквивалент global j \= sum(j)
вместо строки 5, что не меняет результат.
Подобные предложения появляются в этом вопросе SE: Изменение переменной в цикле [Юлия]
Как я могу пакетно изменить a
и b
перед их возвратом?
Вам нужно векторизовать деление и использовать Float64
аргумент:
function foo(g)
a = [g * sqrt(i) for i in 1:4]
b = [g * i ^ 2 for i in 1:4]
for j in [a, b]
j ./= sum(j)
println(j)
end
return a, b
end
И сейчас:
julia> foo(2.0)
[0.16270045344786252, 0.2300931878702196, 0.2818054517861928, 0.32540090689572504]
[0.03333333333333333, 0.13333333333333333, 0.3, 0.5333333333333333]
([0.16270045344786252, 0.2300931878702196, 0.2818054517861928, 0.32540090689572504], [0.03333333333333333, 0.13333333333333333, 0.3, 0.5333333333333333])
Теперь сложное объяснение
Int
, чем в вашем коде a
является Vector
из Float64
s, а b
является Vector
из Int
s. Посмотрите, что получится, если их объединить:
julia> [[1.0,2.0],[1,2]]
2-element Array{Array{Float64,1},1}:
[1.0, 2.0]
[1.0, 2.0]
Юля выводит все данные в общий Float64 и в вашем случае вы теряете справочную информацию!j =/ sum(j)
— это подразделение линейной алгебры, которое выделяет новый объект. Вы хотите иметь поэлементную операцию, поэтому вам нужно векторизовать.