我第一次使用Base.Cartesian并发现它非常强大。但是,它似乎生成了使用所有可用indeces的代码,而我有一个案例,我只想使用一些。
简而言之
如果我在@nloops
内,但我只想使用索引变量的子集,是否可以使用与其下标indeces对应的标量为这些索引变量生成表达式?
a,b -> i_{a}, i_{b} where we have i_{1:N}
长篇
具体来说,我有N个对象,每个对象可以采用一些值:
Obj1: m11, m12, m13
Obj2: m21, m22, m23, m24
Obj3: m31, m32
对应于:
i_1 = 1 : 3
i_2 = 1 : 4
i_3 = 1 : 2
我使用@nloops生成每个组合:
{m11,m21,m31}{m12,m21,m31}{m13,m21,m31}{m11,m22,m31}{m12,m22,m31}...
然后我为每个组合运行成对枚举:
comb = {m11,m21,m31} -> pairs = {m11,m21}{m11,m31}{m21,m31}
我想使用这些对来索引矩阵。这是我被绊倒的地方,因为我需要仅使用索引变量的子集生成变化的表达式。
a,b = pair[1],pair[2]
foo = max(foo, mat[i_{a}, i_{b}]) # need to figure out appropriate syntax here
以下是一个清理过的示范示例:(3用作N,我以后再用@ngenerate
)
@nloops 3 i d->1:lens[d] begin
foo = 0
for pair in combinations([1:3],2)
a, b = pair[1], pair[2]
M_ind = pair2ind(ia,ib)
mat = M[M_ind]
foo = max(foo, mat[i_{a}, i_{b}]) # need to figure this out
if foo==1 # early exit
break
end
end
# do something with foo...
end
有可能做我想做的事吗?
我尝试使用@eval
,但我无法编译:
@eval(parse(@sprintf("foo = max(foo, mat[i_%d, i_%d])", a, b)))
Error: a not defined
谢谢。
答案 0 :(得分:0)
通过完全避免问题解决了这个问题。使用了使用递归的单独版本。
N = number of objects
M = array containing number of states
function next_combination!( comb )
i = findfirst(i->comb[i] < M[i], 1:N)
@assert(i != 0)
comb[i] += 1
comb[1:i-1] = 1
return comb
end
ncombs = prod(M)
comb = int([0, ones(N-1)])
for ci = 1 : ncombs
next_combination!(comb)
foo = 0
for pair in combinations([1:N],2)
a, b = pair[1], pair[2]
col_ind = pair2ind(a,b)
foo = max(foo, mymat[col_ind][comb[a], comb[b]])
if foo == 1 # early out
break
end
end
# do something with foo...
end
修改现有方法
正如帝斯曼指出的那样,以下工作:
inds = @tuple 3 i
foo = max(foo, mymat[col_ind][inds[a], inds[b]])