表达式模板和求和符号

Posted

技术标签:

【中文标题】表达式模板和求和符号【英文标题】:Expression template and summation symbol 【发布时间】:2015-10-17 12:18:17 【问题描述】:

我正在为量子力学编写一个小型库,我想使用表达式模板来形成运算符表达式。特别是用表达式模板形成哈密顿量。

我基本上是按照这个源码来构造代码并重载对应的操作符+*-:https://en.wikipedia.org/wiki/Expression_templates

形成哈密顿量的表达式需要求和

Vec x = u_1 + u_2 + ... + u_N

其中 N 是一个 (const) 整数,u_i 也是 Vec 类型。在代码中编写此表达式有效,但我希望能够编写

Vec x = Sum_i=0^N u_i

如何做到这一点?

------------ 编辑 ------------

经过一些研究并在 cmets 的帮助下,我想出了一个静态 for 循环的想法……在谷歌搜索后,我在 http://www.drdobbs.com/loops-metaloops-c/184401835?pgno=8 找到了一篇文章,这正是我所需要的。

【问题讨论】:

您是否在问如何编写一个函数来使用您的表达式执行求和? 是的,这正是我的问题。 所以,问这个问题。这是一个问答网站。 根据 Mattia 的建议进行了编辑,并明确提出了问题。 u_i 是如何给出的?它们在数组中吗?它们是任意变量吗?这还是太模糊了。但是你可能想要一个 VecBigSum 类型,它存储一个数组的引用。 【参考方案1】:

没有办法编写一个模板或函数来神奇地匹配周围范围的变量,所以你的u_i 语法不能工作。你可以用宏做类似的事情,例如:

#define SUM_4(x) x ## 1 + x ## 2 + x ## 3 + x ## 4

用法:

Vec u_1, u_2, u_3, u_4;
...
Vec x = SUM_4(u_);

您需要为其他数量的源向量定义额外的宏。

C++ 中的下标运算符是通过数组访问来建模的,例如u[1], u[2], ...。如果您愿意维护一个Vec 数组,您可以编写一个遍历该数组的通用函数。在这种情况下,参数将是数组。比如:

template<typename T, int N>
T sum(T (&u)[N])

    // (or your preferred summation procedure)
    T x = u[0];
    for (int i=1; i < N; ++i)
        x += u[i];
    return x;

用法:

Vec u[4];
...
Vec x = sum(u);

最好使用std::vector 或固定大小的数组模板。

附:考虑使用Eigen。

编辑:更新 sum() 模板,从 http://www.cplusplus.com/articles/D4SGz8AR/ 中扣除数组大小

【讨论】:

为什么不让编译器推导出N? @MarkGlisse,因为我不知道该怎么做。但现在我愿意。固定。 非常感谢您的回答。不过,我不确定是否完全理解。在您提出的求和方式中,由于类型 T 是 Vec,那么运算符 += 应该返回类似 VecAdd 的东西,不是吗? (见en.wikipedia.org/wiki/Expression_templates)。因此,我的理解是 x += u[i]; 等操作。不可能吗? @user2460530 我想你是对的,如果你想让 sum() 返回一个表达式模板,那么你可以考虑递归定义 sum()。 @user2460530 如果您只期望一定数量的数组维度,那么您还可以使用特化来定义多个版本的 sum。

以上是关于表达式模板和求和符号的主要内容,如果未能解决你的问题,请参考以下文章

一个横着的M 数学符号 啥意思 急急

∑这个符号在数学,特别是高等数学和高中数学代表啥意思

angr 文档翻译(3):解析器引擎——符号表达式和约束求解

C++ template —— 表达式模板

在 BIRT 中对值进行单列求和

运算表达式求值模板