英文:
Create a matrix where values are 1 one the outer most rows/cols and increase towards the center
问题
以下是您要翻译的内容:
正如标题所说,我想创建一个矩阵,其中值为1,位于最外面的行/列,并朝中心递增。
到目前为止,我的代码如下:
dims = (5,5)
m1 = zeros(Int, dims)
for i in 1:dims[1], j in 1:dims[2]
m1[i,j] = (min(i,j))
end
5×5 Int64矩阵:
1 1 1 1 1
1 2 2 2 2
1 2 3 3 3
1 2 3 4 4
1 2 3 4 5
然后我尝试使用各种上三角和下三角函数来复制/粘贴三角形的部分,但没有成功。我想要的是:
5×5 Int64矩阵:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 2 1 1 1
任何建议将不胜感激。
英文:
As the title says, I want to create a matrix where values are 1 one the outer most rows/cols and increase towards the center.
Here is as far as I have gotten:
dims = (5,5)
m1 = zeros(Int, dims)
for i in 1:dims[1], j in 1:dims[2]
m1[i,j] = (min(i,j))
end
5×5 Matrix{Int64}:
1 1 1 1 1
1 2 2 2 2
1 2 3 3 3
1 2 3 4 4
1 2 3 4 5
I then tried using various upper and lower triangle functions to copy/paste parts of the triangle but no joy. What I want:
5×5 Matrix{Int64}:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 2 1 1 1
Any advice would be much appreciated.
答案1
得分: 3
以下是要翻译的内容:
这是另一个答案,还提供了一个使用我建议的函数的示例https://stackoverflow.com/questions/76191746/is-there-a-simple-way-to-enumerate-indices-of-an-array-in-base
julia> indices(A) = Iterators.map(Tuple, CartesianIndices(A))
julia> dims = (5,5)
julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
5×5 Int64 Matrix:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
julia> dims = (4,4,3)
(4, 4, 3)
julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
4×4×3 3维 Int64 数组:
[:, :, 1] =
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
[:, :, 2] =
1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1
[:, :, 3] =
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
如图所示,这种方法可以自然地推广到更高维度的数组,并且也适用于非方形数组。
DNF成功摆脱了一些减速分配(请参阅他的答案),因此:
[min(t..., (dims .+ 1 .- t)...) for t in indices(dims)]
是使用indices
快捷方式对他的代码进行的简单重写。
英文:
Here is another answer:, which also provides an example for using a function I've suggested in https://stackoverflow.com/questions/76191746/is-there-a-simple-way-to-enumerate-indices-of-an-array-in-base
julia> indices(A) = Iterators.map(Tuple, CartesianIndices(A))
julia> dims = (5,5)
julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
5×5 Matrix{Int64}:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
julia> dims = (4,4,3)
(4, 4, 3)
julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
4×4×3 Array{Int64, 3}:
[:, :, 1] =
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
[:, :, 2] =
1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1
[:, :, 3] =
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
As shown, this method generalizes to higher dimensional arrays naturally, and it will work with non-square arrays too.
DNF managed to get rid of some slowing allocations (see his answer), and so:
[min(t..., (dims .+ 1 .- t)...) for t in indices(dims)]
is a simple rewrite of his code using the indices
shortcut.
答案2
得分: 2
这里有一个简单的解决方案,使用条件语句来判断是否已经过了对角线,并相应地行为:
for i in 1:dims[1], j in 1:dims[2]
if (i + j) < dims[1] + 1
m1[i,j] = (min(i,j))
else
m1[i,j] = min(dims[1] - i + 1, dims[2] - j + 1)
end
end
英文:
Here's a simple solution using a conditional to tell if you're past the diagonal and behave accordingly:
for i in 1:dims[1], j in 1:dims[2]
if (i + j) < dims[1] + 1
m1[i,j] = (min(i,j))
else
m1[i,j] = min(dims[1] - i + 1, dims[2] - j + 1)
end
end
答案3
得分: 2
这是一个简单的一行代码,而且速度也很快:
foo(N) = [min(i, j, N+1-i, N+1-j) for i in 1:N, j in 1:N]
为了更通用,性能几乎一样好,可以尝试:
bar(dims...) = [(t=Tuple(i); min(t..., (dims .+ 1 .- t)...)) for i in CartesianIndices(dims)]
这与@DanGetz的解决方案非常相似,但避免了zip
,而是使用了Tuple
,这对性能似乎更有优势。
英文:
Here's a simple one-liner, that is also very fast:
foo(N) = [min(i, j, N+1-i, N+1-j) for i in 1:N, j in 1:N]
For more generality, and almost as good performance, try
bar(dims...) = [(t=Tuple(i); min(t..., (dims .+ 1 .- t)...)) for i in CartesianIndices(dims)]
It is quite similar to @DanGetz's solution, but avoids zip
, and uses Tuple
instead, which seems advantageous for performance.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论