嵌套n个for循环-(Julia)

时间:2020-07-15 16:42:26

标签: loops julia nested-loops

我目前正在尝试创建n个嵌套循环,以计算出相当复杂的总和。

总和中的每一项取决于最后一项,因此需要嵌套。这是一些朱莉娅(Julia)编写的伪代码,用于解释我要获取的内容:

# u,v are fixed integers

# m is a fixed, n-length array of integers

                                      _
for i_1 in 0:min(m[1], u)              |#Trio of Loops we want to repeat n times
    for j_1 in 0:min(m[1], v)          | 
        for t_1 in i_1:(i_1 + j_1)    _|#1
                                                  _
            for i_2 in 0:min(m[2], u - i_1)        |
                for j_2 in 0:min(m[2], v - j_1)    |
                    for t_2 in i_2:(i_2 + j_2)    _|#2

                      #... repeat until nth time...#
                                                                                 _
                        for i_n in 0:min(m[n],u - sum(#all i_'s up to n-1))       |
                            for j_n in 0:min(m[n],v - sum(#all j_'s up to n-1))   |
                                for t_n in i_n:(i_n + j_n)                       _|#n
                                    
                                    #Sum over sum function which depends on i_'s and j_'s and t_'s
                                    X += f(i_1,j_1,t_1)*f(i_2,j_2,t_2)*...*f(i_n,j_n,t_n)


我完全不确定如何为任意n个三重奏正确编码。如果数字n小,那么显然可以明确地写出来,但如果不是,那么我们就陷入困境。我假设有一种递归的方式来使用此代码,但是我不确定该如何进行。 任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

这里是您的问题的简化版本的快速尝试。

function inner(X, f, ms)
    is = [Symbol(:i_, n) for n in 1:length(ms)]
    js = [Symbol(:j_, n) for n in 1:length(ms)]
    fs = [:($f($i, $j)) for (i,j) in zip(is, js)]
    :($X += *($(fs...)))
end

inner(:X, :g, [3,4,5]) # :(X += g(i_1, j_1) * g(i_2, j_2) * g(i_3, j_3))

function looper(ex::Expr, ms, u)
    isempty(ms) && return ex
    n = length(ms)
    m_n = ms[n]
    i_n = Symbol(:i_,n)
    j_n = Symbol(:j_,n)
    out = :( for $i_n in 0:min($m_n, $u)
        for $j_n in 0:min($m_n, $u)
            $ex
        end
    end)
    looper(out, ms[1:end-1], u)
end

looper(inner(:g, [4,5]), [4,5], 3)
# :(for i_1 = 0:min(4, 3)
#       for j_1 = 0:min(4, 3)
#           for i_2 = 0:min(5, 3)
#               for j_2 = 0:min(5, 3)
#                   X += g(i_1, j_1) * g(i_2, j_2) ...

macro multi(X, f, ms, u)
    ms isa Expr && ms.head == :vect || error("expected a literal vector like [1,2,3]")
    looper(inner(esc(X), esc(f), ms.args), ms.args, esc(u))
end

@macroexpand @multi X f [4,5] u
# :(for var"#74#i_1" = 0:Main.min(4, u) ...

function multi(X, f, u)
    @multi X f [4,5] u
    X
end

multi(0.0, atan, 1)