在 Julia 中的矩阵中引用元素,同时在其他矩阵中赋值
Reference elements in matrices in Julia while assigning values in other matrices
我有一个向量 X,它的元素是 0 和 1。我想创建另一个与 X 大小相同的向量 Z,如果 X 中的相应元素为零,则 Z 的每个元素为 0,否则它是从 a 中随机抽取的。均匀分布。在 Matlab 中,我可以通过以下方式轻松做到这一点:
n = 1000;
X = randi([0, 1], [1, n]);
Z(X) = rand(); #Here wherever X takes a value of 1, the element of Z is a draw from a uniform distribution.
我想在 Julia 中实现它。有没有更简洁的方法来代替使用 if 条件语句。谢谢!!
这是一种方法:
julia> n = 1000;
julia> x = rand(Bool, n);
julia> z = zeros(n);
julia> using Distributions
julia> z[x] .= rand.(Uniform(-10, 10));
julia> z
100-element Vector{Float64}:
-2.6946644136672004
0.0
0.0
⋮
您可以根据需要调整 Uniform
分布的参数,或者如果默认 [0, 1)
范围是您需要的,则忽略该参数。
行 z[x] .= rand.(Uniform(-10, 10))
使用 Julia 的逻辑索引(与 MATLAB 相同)和广播功能 - 对于每个 x
值为 true
的值,都会进行 rand
调用并将结果分配给 z
.
的那个元素
使用广播的优势(与创建 rand(Uniform(-10, 10), count(x))
并将其分配给 z[x]
相比)是直接将值 in-place 分配给它们在 z
,所以没有分配额外的不必要的内存(正如@DNF在评论中提到的)。
首先,由于两个原因,您的 Matlab 代码在 Matlab 中不起作用:首先,因为逻辑索引必须是布尔值,它们不能是 0 和 1。其次, 因为 Z(X) = rand()
只会抽取一个随机数并将其分配给 Z
.
的所有对应元素
相反,您可能需要这样的 Matlab 代码:
X = rand(1, n) > 0.5
Z(X) = rand(sum(X), 1)
在 Julia 中你可以做到
X = rand(Bool, n)
Z = float.(X) # you have to initialize Z
Z[X] .= rand.()
编辑: 这是一个具有理解力的替代方案,您不需要初始化 Z
:
X = rand(Bool, n)
Z = [x ? float(x) : rand() for x in X]
从技术上讲,您从此处采样的是 left-censored 均匀分布——相当于 Dirac 分布在 0 和 Uniform(0, 1)
处的混合。 The next release of Distributions.jl 将有一个 censored
的实现,这将完全不需要做任何花哨的赋值:
Z = rand(censored(Uniform(-1.0, 1.0), lower=0.0), N)
选择左侧的范围以使混合成分具有相同的权重。
我有一个向量 X,它的元素是 0 和 1。我想创建另一个与 X 大小相同的向量 Z,如果 X 中的相应元素为零,则 Z 的每个元素为 0,否则它是从 a 中随机抽取的。均匀分布。在 Matlab 中,我可以通过以下方式轻松做到这一点:
n = 1000;
X = randi([0, 1], [1, n]);
Z(X) = rand(); #Here wherever X takes a value of 1, the element of Z is a draw from a uniform distribution.
我想在 Julia 中实现它。有没有更简洁的方法来代替使用 if 条件语句。谢谢!!
这是一种方法:
julia> n = 1000;
julia> x = rand(Bool, n);
julia> z = zeros(n);
julia> using Distributions
julia> z[x] .= rand.(Uniform(-10, 10));
julia> z
100-element Vector{Float64}:
-2.6946644136672004
0.0
0.0
⋮
您可以根据需要调整 Uniform
分布的参数,或者如果默认 [0, 1)
范围是您需要的,则忽略该参数。
行 z[x] .= rand.(Uniform(-10, 10))
使用 Julia 的逻辑索引(与 MATLAB 相同)和广播功能 - 对于每个 x
值为 true
的值,都会进行 rand
调用并将结果分配给 z
.
使用广播的优势(与创建 rand(Uniform(-10, 10), count(x))
并将其分配给 z[x]
相比)是直接将值 in-place 分配给它们在 z
,所以没有分配额外的不必要的内存(正如@DNF在评论中提到的)。
首先,由于两个原因,您的 Matlab 代码在 Matlab 中不起作用:首先,因为逻辑索引必须是布尔值,它们不能是 0 和 1。其次, 因为 Z(X) = rand()
只会抽取一个随机数并将其分配给 Z
.
相反,您可能需要这样的 Matlab 代码:
X = rand(1, n) > 0.5
Z(X) = rand(sum(X), 1)
在 Julia 中你可以做到
X = rand(Bool, n)
Z = float.(X) # you have to initialize Z
Z[X] .= rand.()
编辑: 这是一个具有理解力的替代方案,您不需要初始化 Z
:
X = rand(Bool, n)
Z = [x ? float(x) : rand() for x in X]
从技术上讲,您从此处采样的是 left-censored 均匀分布——相当于 Dirac 分布在 0 和 Uniform(0, 1)
处的混合。 The next release of Distributions.jl 将有一个 censored
的实现,这将完全不需要做任何花哨的赋值:
Z = rand(censored(Uniform(-1.0, 1.0), lower=0.0), N)
选择左侧的范围以使混合成分具有相同的权重。