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

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

Create a matrix where values are 1 one the outer most rows/cols and increase towards the center

问题

以下是您要翻译的内容:

  1. 正如标题所说,我想创建一个矩阵,其中值为1,位于最外面的行/列,并朝中心递增。
  2. 到目前为止,我的代码如下:
  3. dims = (5,5)
  4. m1 = zeros(Int, dims)
  5. for i in 1:dims[1], j in 1:dims[2]
  6. m1[i,j] = (min(i,j))
  7. end
  8. 5×5 Int64矩阵:
  9. 1 1 1 1 1
  10. 1 2 2 2 2
  11. 1 2 3 3 3
  12. 1 2 3 4 4
  13. 1 2 3 4 5
  14. 然后我尝试使用各种上三角和下三角函数来复制/粘贴三角形的部分,但没有成功。我想要的是:
  15. 5×5 Int64矩阵:
  16. 1 1 1 1 1
  17. 1 2 2 2 1
  18. 1 2 3 2 1
  19. 1 2 2 2 1
  20. 1 2 1 1 1
  21. 任何建议将不胜感激。
英文:

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:

  1. dims = (5,5)
  2. m1 = zeros(Int, dims)
  3. for i in 1:dims[1], j in 1:dims[2]
  4. m1[i,j] = (min(i,j))
  5. end
  6. 5×5 Matrix{Int64}:
  7. 1 1 1 1 1
  8. 1 2 2 2 2
  9. 1 2 3 3 3
  10. 1 2 3 4 4
  11. 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:

  1. 5×5 Matrix{Int64}:
  2. 1 1 1 1 1
  3. 1 2 2 2 1
  4. 1 2 3 2 1
  5. 1 2 2 2 1
  6. 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

  1. julia> indices(A) = Iterators.map(Tuple, CartesianIndices(A))
  2. julia> dims = (5,5)
  3. julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
  4. 5×5 Int64 Matrix:
  5. 1 1 1 1 1
  6. 1 2 2 2 1
  7. 1 2 3 2 1
  8. 1 2 2 2 1
  9. 1 1 1 1 1
  10. julia> dims = (4,4,3)
  11. (4, 4, 3)
  12. julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
  13. 4×4×3 3 Int64 数组:
  14. [:, :, 1] =
  15. 1 1 1 1
  16. 1 1 1 1
  17. 1 1 1 1
  18. 1 1 1 1
  19. [:, :, 2] =
  20. 1 1 1 1
  21. 1 2 2 1
  22. 1 2 2 1
  23. 1 1 1 1
  24. [:, :, 3] =
  25. 1 1 1 1
  26. 1 1 1 1
  27. 1 1 1 1
  28. 1 1 1 1

如图所示,这种方法可以自然地推广到更高维度的数组,并且也适用于非方形数组。

DNF成功摆脱了一些减速分配(请参阅他的答案),因此:

  1. [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

  1. julia> indices(A) = Iterators.map(Tuple, CartesianIndices(A))
  2. julia> dims = (5,5)
  3. julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
  4. 5×5 Matrix{Int64}:
  5. 1 1 1 1 1
  6. 1 2 2 2 1
  7. 1 2 3 2 1
  8. 1 2 2 2 1
  9. 1 1 1 1 1
  10. julia> dims = (4,4,3)
  11. (4, 4, 3)
  12. julia> [min(minimum.(zip(I,dims.-I.+1))...) for I in indices(dims)]
  13. 4×4×3 Array{Int64, 3}:
  14. [:, :, 1] =
  15. 1 1 1 1
  16. 1 1 1 1
  17. 1 1 1 1
  18. 1 1 1 1
  19. [:, :, 2] =
  20. 1 1 1 1
  21. 1 2 2 1
  22. 1 2 2 1
  23. 1 1 1 1
  24. [:, :, 3] =
  25. 1 1 1 1
  26. 1 1 1 1
  27. 1 1 1 1
  28. 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:

  1. [min(t..., (dims .+ 1 .- t)...) for t in indices(dims)]

is a simple rewrite of his code using the indices shortcut.

答案2

得分: 2

这里有一个简单的解决方案,使用条件语句来判断是否已经过了对角线,并相应地行为:

  1. for i in 1:dims[1], j in 1:dims[2]
  2. if (i + j) < dims[1] + 1
  3. m1[i,j] = (min(i,j))
  4. else
  5. m1[i,j] = min(dims[1] - i + 1, dims[2] - j + 1)
  6. end
  7. end
英文:

Here's a simple solution using a conditional to tell if you're past the diagonal and behave accordingly:

  1. for i in 1:dims[1], j in 1:dims[2]
  2. if (i + j) &lt; dims[1] + 1
  3. m1[i,j] = (min(i,j))
  4. else
  5. m1[i,j] = min(dims[1] - i + 1, dims[2] - j + 1)
  6. end
  7. end

答案3

得分: 2

这是一个简单的一行代码,而且速度也很快:

  1. foo(N) = [min(i, j, N+1-i, N+1-j) for i in 1:N, j in 1:N]

为了更通用,性能几乎一样好,可以尝试:

  1. 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:

  1. 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

  1. 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:

确定