手动展开3个嵌套循环(Julia)



这是使用for循环将文字插入数组中每个表达式的后续问题在那个问题中,我想在循环中插入表达式的1D数组(向量(。使用已接受的答案:

julia> array_of_expr = Any[:(A * 5), :(B * 6 * T)]
julia> arglist = [:A; :B; :T]
julia> test_input = [1e5, 1e1, 100]
julia> @eval begin
function interpolate_1by1($(arglist...))
result_array = similar($array_of_expr)
$((quote
result_array[$i] = $(array_of_expr[i])
end for i in 1:length(array_of_expr))...)
return result_array
end
end
julia> interpolate_all(test_input...)
2-element Array{Float64,1}:
500000.0
6000.0

根据公认的答案,假设我现在有了一组表达式向量:

args = [:A, :B, :C]
args_typed = [:($s::Float64) for s in args]

big_expr_array = Array{Vector{Expr}}(undef, 3, 4)

big_expr_array[1, :] = [[:(A+B), :(C/A)], [:(B+1), :(A+C)], [:(B%5)], [:(C+7)]]
big_expr_array[2, :] = [[:(A*B+C), :(B*C+A)], [:(C/6), :(C+C)], [:(3*C)], [:(A%2)]]
big_expr_array[3, :] = [[:(A*C), :(A*B)], [:(A-6), :(B+C/A)], [:(B+2)], [:(C%3)]]

并且希望在给定一些参数的情况下评估所有表达式,而不会丢失数组的整体结构。在我看来,我必须在数组中的i行、j列和k元素(表达式向量(上循环。

我试图用两种方式修改上一个问题的公认答案,这两种方式都会产生错误:

@eval begin
function looped_eval1($(args_typed...))
result = similar($big_expr_array)
$( (quote 
$( (quote 
$( (quote
# i = row, j = vector, k = specific expression
result[$i, $j][$k] = $(big_expr_array[i, j][k])
end for k in 1:length(big_expr_array[i, j]))...
) 
end for j in 1:size(big_expr_array)[2])...
)
end for i in 1:size(big_expr_array)[1])...
)
end
end

则抛出CCD_ 4。

第二:

@eval begin
function looped_eval2($(args_typed...))

result = similar($big_expr_array)
$( (quote (quote (quote
# i = row, j = vector, k = specific expression
result[$i, $j][$k] = $(big_expr_array[i, j][k])
end for k in 1:length(big_expr_array[i, j]))... 
end for j in 1:size(big_expr_array)[2])...
end for i in 1:size(big_expr_array)[1])...
)

end
end

则抛出CCD_ 5。

自变量A=10,B=20,C=30的期望结果示例:

big_expr_array[1, :] = [[30, 3], [21, 40], [0], [37]]
big_expr_array[2, :] = [[230, 610], [5, 60], [90], [0]]
big_expr_array[3, :] = [[300, 200], [4, 23], [22], [0]]

我应该如何编写手动循环展开来容纳这些嵌套数组?或者,有没有一种更优雅的方法来实现对所有这些表达式的评估并保持相同的数组结构?

(代码也有可能正确地分配给result——因为我一直在循环展开,所以我不确定。(

这里有一些工作:

@eval begin                                                                                                                                                      
function looped_eval2($(args_typed...))                                                                                                                                                                                                                                                                                       
result = similar($big_expr_array, Vector{Float64})                                                                                                           
result .= [[]]                                                                                                                                               
$( (quote                                                                                                                                                                          
# i = row, j = vector, k = specific expression                                                                                                 
push!(result[$i, $j], $(expr))                                                                                                                           
end                                                                                                                                                                                                                                                                                                                       
for i in 1:size(big_expr_array, 1)                                                                                                                           
for j in 1:size(big_expr_array, 2)                                                                                                                           
for expr in big_expr_array[i, j]                                                                                                                                  
)...                                                                                                                                                                                    
)                                                                                                                                                           
result                                                                                                                                                   
end                                                                                                                                                      
end

在你之前的工作中需要进行一些修改:

  • 您必须键入annotate并初始化结果,否则当您尝试访问result的任何元素时,都会得到UndefRefError
  • 展开循环时,只需要一个引号,所有3个循环都在引号之外,然后计算生成的表达式的整个列表
  • 由于big_expr_array中的所有向量大小不相同,因此结果的类型有点复杂(矩阵{Vector{Float}}(,并且必须在引号中使用push!,而不是直接定义值

结果是您所期望的:

julia> looped_eval2(10., 20., 30.)                                                                                                                           
3×4 Matrix{Vector{Float64}}:                                                                                                                                  
[30.0, 3.0]     [21.0, 40.0]  [0.0]   [37.0]                                                                                                                 
[230.0, 610.0]  [5.0, 60.0]   [90.0]  [0.0]                                                                                                                  
[300.0, 200.0]  [4.0, 23.0]   [22.0]  [0.0]

相同代码的一个更好的Julia版本(根据BenchmarkTools稍微好一点(是:

@eval begin                                                                                                                                                      
function looped_eval3($(args_typed...))                                                                                                                                                                                                                                                                                       
result = map(_ -> Float64[], $big_expr_array)                                                                                                                
$( (quote                                                                                                                                                            
# i = row, j = vector, k = specific expression                                                                                                               
push!(result[$i], $(expr))                                                                                                                               
end                                                                                                                                                          
for (i, expr_l) in enumerate(big_expr_array)                                                                                                                 
for expr in expr_l                                                                                                                                           
)...                                                                                                                                                      
)                                                                                                                                                           
result                                                                                                                                                   
end                                                                                                                                                      
end

最新更新