【发布时间】:2016-05-17 12:58:07
【问题描述】:
我正在研究一个静态多维数组收缩框架,我遇到了一个有点难以解释的问题,但我会尽力而为。假设我们有一个N 维数组类
template<typename T, int ... dims>
class Array {}
可以实例化为
Array<double> scalar;
Array<double,4> vector_of_4s;
Array<float,2,3> matrix_of_2_by_3;
// and so on
现在我们有了另一个名为Indices的类
template<int ... Idx>
struct Indices {}
我现在有一个函数contraction,它的签名应该如下所示
template<T, int ... Dims, int ... Idx,
typename std::enable_if<sizeof...(Dims)==sizeof...(Idx),bool>::type=0>
Array<T,apply_to_dims<Dims...,do_contract<Idx...>>>
contraction(const Indices<Idx...> &idx, const Array<T,Dims...> &a)
我可能没有在这里得到语法,但我基本上希望返回的Array 具有基于Indices 条目的维度。让我提供contraction 可以执行的示例。请注意,在这种情况下,收缩意味着删除索引列表中参数相等的维度。
auto arr = contraction(Indices<0,0>, Array<double,3,3>)
// arr is Array<double> as both indices contract 0==0
auto arr = contraction(Indices<0,1>, Array<double,3,3>)
// arr is Array<double,3,3> as no contraction happens here, 0!=1
auto arr = contraction(Indices<0,1,0>, Array<double,3,4,3>)
// arr is Array<double,4> as 1st and 3rd indices contract 0==0
auto arr = contraction(Indices<0,1,0,7,7,2>, Array<double,3,4,3,5,5,6>)
// arr is Array<double,4,6> as (1st and 3rd, 0==0) and (4th and 5th, 7==7) indices contract
auto arr = contraction(Indices<10,10,2,3>, Array<double,5,6,4,4>
// should not compile as contraction between 1st and 2nd arguments
// requested but dimensions don't match 5!=6
// The parameters of Indices really do not matter as long as
// we can identify contractions. They are typically expressed as enums, I,J,K...
所以本质上,鉴于Idx... 和Dims... 的大小应该相等,检查Idx... 中的哪些值相等,获取它们出现的位置并删除@987654336 中的相应条目(位置) @。这本质上是一个tensor contraction rule。
数组收缩规则:
- 索引的参数个数和数组的维度/等级应该相同,即
sizeof...(Idx)==sizeof...(Dims) - 在
Idx和Dims之间存在一对一对应关系,即如果我们有Indices<0,1,2>和Array<double,4,5,6>,0映射到4,1映射到5和2映射到6。 - 如果
Idx中有相同/相等的值,则意味着收缩,这意味着Dims中的相应维度应该消失,例如,如果我们有Indices<0,0,3>和Array<double,4,4,6>,那么0==0和这些值映射到的对应维度是4和4都需要消失,结果数组应该是Array<double,6> - 如果
Idx具有相同的值,但对应的Dims不匹配,则应触发编译时错误,例如Indices<0,0,3>和Array<double,4,5,6>不可能为4!=5,类似Indices<0,1,0>不可能像4!=6,这会导致 - 不同维度的数组不能收缩,例如
Array<double,4,5,6>不能以任何方式收缩。 - 只要对应的
Dims也匹配,Idx允许多个对、三胞胎、四胞胎等,例如,Indices<0,0,0,0,1,1,4,3,3,7,7,7>将收缩为Array<double,6>,假设输入数组为@987654368 @。
我对元编程的了解并没有达到这个功能,但我希望我已经明确了意图,以便有人指导我朝着正确的方向前进。
【问题讨论】:
-
我无法弄清楚你的收缩规则是什么。给定
Idx...和Dims...,输出尺寸应该是多少?你能提供一套规则,而不是一套例子吗? -
本质上,给定
Idx...和Dims...的大小应该相等,检查Idx...中的哪些值相等,获取它们出现的位置并删除@ 中的相应条目987654374@. -
@romeric - 你在
Idx中只能有几个相等的值,甚至是三胞胎等?如果是三胞胎,规则是什么? -
潜在地,你可以有尽可能多的相等值,例如对于三元组
contraction(Indices<0,0,1,1,2,2,3>, Array<double,3,3,4,4,5,5,6>)将给出Array<double,6>为 (1st and 2nd, 0==0), (3rd and 4th, 1== 1), (5th and 6th, 2==2) 将全部收缩并消失。 -
我可以有索引 吗?
标签: c++ c++11 multidimensional-array template-meta-programming