【问题标题】:Defining a multiple-dimensional array of arbitrary dimension in Julia在 Julia 中定义任意维度的多维数组
【发布时间】:2022-01-16 20:51:13
【问题描述】:

上下文

这个问题与this one有关。

在 Julia 中,我想创建一个 5 x 5 的二维数组,其中 (i, j) 元素具有 [i,j],如下所示:

5×5 Matrix{Vector{Int64}}:
 [1, 1]  [1, 2]  [1, 3]  [1, 4]  [1, 5]
 [2, 1]  [2, 2]  [2, 3]  [2, 4]  [2, 5]
 [3, 1]  [3, 2]  [3, 3]  [3, 4]  [3, 5]
 [4, 1]  [4, 2]  [4, 3]  [4, 4]  [4, 5]
 [5, 1]  [5, 2]  [5, 3]  [5, 4]  [5, 5]

我尝试使用array comprehension

N = 5
L_2 = [[x1,x2] for x1 = 1:N, x2 = 1:N]

我想做什么

我想将这个定义推广到任意维度D

L_1 = [[x1] for x1 = 1:N] # 1-dimensional
L_2 = [[x1,x2] for x1 = 1:N, x2 = 1:N] # 2-dimensional
L_3 = [[x1,x2,x3] for x1 = 1:N, x2 = 1:N,x3 = 1:N] # 3-dimensional
...

#L_D = ??? # D-dimensional

我该如何定义?

不使用数组解析也没关系。

任何信息将不胜感激。

【问题讨论】:

  • 那么你想用这个做什么?如果它是为了索引到以前存在的 N 维数组 X,那么你可以只做 CartesianIndices(X)。这适用于任何维度和大小。
  • @DNF 换句话说,CartesianIndices(X)CartesianIndices(size(X)) 做同样的事情。只有当X 不存在并且您需要一个 NxNxNx... 索引数组时,才需要所有这些数字运算。

标签: arrays matrix multidimensional-array vector julia


【解决方案1】:

您似乎不需要 CartesianIndices,但为了记录,CartesianIndices 可以采用任何 Int 元组(更准确地说是 Dims aka NTuple{N,Int} where N)来表示数组的大小。 CartesianIndices((5,5)) 用于 5x5,CartesianIndices((2,8,3)) 用于 2x8x3 等。您可以快速创建 NxNxNx... 表示具有 D 维度的大小的元组与 NtotheD(N,D) = ntuple(i -> N, D)

【讨论】:

  • 谢谢。我想在我的项目中使用这个 CartesianIndices。但是,我需要在我的项目中为每个格点使用 Float64 的索引。 Int64转Float64容易吗?
  • Int64转Float64是很容易的,但是你不是说反过来问吗?我必须提醒您 CartesianIndex{N} 是仅 NTuple{N,Int} 的包装器,因此 NTuple{N,Float64} 不起作用。如果您像A[3.0] 那样进行索引,那么您的getindex 方法需要将3.0 转换为3。将Float64 转换为Int64 有点困难,因为如果您使用A[3.1],您必须决定如何舍入到最接近的整数。
  • 我未来想要的是制作一个“单元”格子,它有 5 x 5 个点并按规则间隔划分。 → 单位格: 0.2, 0.4, 0.6, 0.8, 1.0 。这是 CartesianIndices 的工作吗?
  • 可能。 CartesianIndex{N} 必须只包含 Int,但您可以根据需要从 Int 计算 Float64。在我的脑海中,您可以创建一个子类型 AbstractArray 的结构(请参阅 Julia 文档的接口页面)并简单地包装 CartesianIndices。该结构的 getindex 将索引 CartesianIndices 以获取 CartesianIndex,将 Int 转换为 Float64 值,然后返回它们。就像 CartesianIndices 一样,lattice 值是按需生成的,不需要预先在堆上分配内存(尽管您可以collect 它一次性生成所有值)。
【解决方案2】:

您可以概括我在另一个答案中发布的vcat 方法,如下所示:

julia> lattice(N, D) = vcat.((reshape(1:N, ntuple(j -> j == i ? N : 1, D)) for i in 1:D)...)
lattice (generic function with 1 method)

julia> lattice(2, 1)
2-element Vector{Vector{Int64}}:
 [1]
 [2]

julia> lattice(2, 2)
2×2 Matrix{Vector{Int64}}:
 [1, 1]  [1, 2]
 [2, 1]  [2, 2]

julia> lattice(2, 3)
2×2×2 Array{Vector{Int64}, 3}:
[:, :, 1] =
 [1, 1, 1]  [1, 2, 1]
 [2, 1, 1]  [2, 2, 1]

[:, :, 2] =
 [1, 1, 2]  [1, 2, 2]
 [2, 1, 2]  [2, 2, 2]

julia> lattice(2, 4)
2×2×2×2 Array{Vector{Int64}, 4}:
[:, :, 1, 1] =
 [1, 1, 1, 1]  [1, 2, 1, 1]
 [2, 1, 1, 1]  [2, 2, 1, 1]

[:, :, 2, 1] =
 [1, 1, 2, 1]  [1, 2, 2, 1]
 [2, 1, 2, 1]  [2, 2, 2, 1]

[:, :, 1, 2] =
 [1, 1, 1, 2]  [1, 2, 1, 2]
 [2, 1, 1, 2]  [2, 2, 1, 2]

[:, :, 2, 2] =
 [1, 1, 2, 2]  [1, 2, 2, 2]
 [2, 1, 2, 2]  [2, 2, 2, 2]

julia> lattice(2, 5)
2×2×2×2×2 Array{Vector{Int64}, 5}:
[:, :, 1, 1, 1] =
 [1, 1, 1, 1, 1]  [1, 2, 1, 1, 1]
 [2, 1, 1, 1, 1]  [2, 2, 1, 1, 1]

[:, :, 2, 1, 1] =
 [1, 1, 2, 1, 1]  [1, 2, 2, 1, 1]
 [2, 1, 2, 1, 1]  [2, 2, 2, 1, 1]

[:, :, 1, 2, 1] =
 [1, 1, 1, 2, 1]  [1, 2, 1, 2, 1]
 [2, 1, 1, 2, 1]  [2, 2, 1, 2, 1]

[:, :, 2, 2, 1] =
 [1, 1, 2, 2, 1]  [1, 2, 2, 2, 1]
 [2, 1, 2, 2, 1]  [2, 2, 2, 2, 1]

[:, :, 1, 1, 2] =
 [1, 1, 1, 1, 2]  [1, 2, 1, 1, 2]
 [2, 1, 1, 1, 2]  [2, 2, 1, 1, 2]

[:, :, 2, 1, 2] =
 [1, 1, 2, 1, 2]  [1, 2, 2, 1, 2]
 [2, 1, 2, 1, 2]  [2, 2, 2, 1, 2]

[:, :, 1, 2, 2] =
 [1, 1, 1, 2, 2]  [1, 2, 1, 2, 2]
 [2, 1, 1, 2, 2]  [2, 2, 1, 2, 2]

[:, :, 2, 2, 2] =
 [1, 1, 2, 2, 2]  [1, 2, 2, 2, 2]
 [2, 1, 2, 2, 2]  [2, 2, 2, 2, 2]

【讨论】:

  • 感谢您向我展示了许多使我易于理解的示例。
猜你喜欢
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多