创建一个矩阵,其中数值在最外部的行/列上为1,向中心逐渐增加。

huangapple go评论57阅读模式
英文:

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 3Int64 数组:
[:, :, 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) &lt; 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.

huangapple
  • 本文由 发表于 2023年5月22日 06:56:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76302256.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定