Чтобы построить набор векторов, мне нужно взять декартово произведение множеств С [1] .. C [D],декартово произведение в Mata
D: = {х: х [г] ε С [I], I = 1..d}
Пример: Если *C[1]=(5,6,7)';*C[2]=(3,5,6)';*C[3]=(1,3,5)'
, то некоторые элементы D
являются (5,3,1), (5,3,3) ...
Я хотел бы знать: Каков наилучший способ взять декартово произведение в Мата, в общем? Я нашел неуклюжий подход для d = 3, как показано ниже.
Подробный пример. Этот код должен иллюстрировать то, что я пробовал, и желаемый результат. Функция mm_expand
поступает от ssc install moremata
.
mata
// prep
lo = (5,3,1)'
hi = (7,6,5)'
all = uniqrows((lo\hi))
n_cols = length(lo)
n_vals = length(all)
c_list = J(1,n_cols,NULL)
c_lens = J(1,n_cols,0)
for (i=1;i<=n_cols;i++){
c_list[i] = &(select(all,all :>= lo[i] :& all :<= hi[i]))
c_lens[i] = length(*c_list[i])
}
// question: How should I take this Cartesian product?
grid_box =
mm_expand(*c_list[1],c_lens[2]*c_lens[3],0,1),
mm_expand(mm_expand(*c_list[2],c_lens[1],0,1),c_lens[3],0,0),
mm_expand(*c_list[3],c_lens[1]*c_lens[2],0,0)
// (just fyi) my next step
is_decr = ! rowsum(grid_box[,1..(n_cols-1)]-grid_box[,2..n_cols] :< 0)
select(grid_box,is_decr)
end
нотация и «подготовительную» часть кода связаны с my application.
Спасибо! Я принимаю ваше элегантное решение, но также публикую свои собственные, так как я подозреваю, что это немного быстрее. – Frank