我正在DSEL上工作,并希望有以下内容:
Bra ij;
Ket kl, cd;
(ij||kl); // initialize some array
(ij||cd); // ditto
....
T(i,j,k,l)*(ij||kl); // do some math without recomputing (ij||kl)所以从本质上讲,我想让表达式充当变量。有可能吗?
到目前为止,我的想法是有一个“单例”工厂,它使用expression (ij|kl)生成/查找数组。还要别的吗?
发布于 2011-02-27 12:20:37
如果您不想重新计算ij||kl,那么只需将它们存储到该表达式返回的任何类型的变量中。这正是变量存在的原因之一。
好吧,这是我唯一能想到的方法,尽管听起来不是很好。您可以做的是,当操作符||函数被调用时,将操作数以及结果存储到实例变量中(如果操作符||是某个类的成员函数),或者存储到一个静态分配的变量中(如果操作符||在其上声明为lonesome)。
下次调用运算符||时,请检查操作数是否与上次调用时相同。如果是,只需返回您存储的最后一个结果。否则,计算新的结果。
这应该能起到作用。令人讨厌的是,它需要将操作数复制到其他变量中,根据环境的不同,这可能会耗费大量资源。然而,如果变量是不可变的,你可以只保留指向操作数的指针,这会更便宜一些。
如果您想更进一步,可以使用map或其他东西来存储多个先前调用的操作数和结果。这样,如果您需要对多个不同的计算执行此操作,则此方法将起作用。
发布于 2011-02-27 13:12:06
要做这类事情,很明显你需要一些全局的知识。换句话说,您必须构建某种全局或半全局结构,以保持操作/表达式的记录。
我建议您构建一个图(可能使用BGL),其中节点是表达式(变量是零度运算符的特例)。如果将每个操作数作为关联顶点连接到操作符的顶点,则可以构造一个图。稍后,当需要实际计算表达式时,您可以首先使用一些修剪规则遍历图,从而消除冗余操作。如果你确保图中没有任何顶点被复制,那么修剪是隐式的,我猜。
如果您希望避免使用全局数据,我建议您使用某种类型的表达式管理器类,并将所有操作注册到它。例如,如下所示:
int main() {
expression_handler expression; //have some class to handle a sequence of operations.
expression
<< (ij||kl)
<< (ij||cd)
<< ....
<< T(i,j,k,l)*(ij||kl); //register all the expressions, in order.
expression.evaluate(); //evaluate the expression (possibly optimizing the graph before)
return 0;
};发布于 2011-02-27 13:48:45
我会把Ken和Mikael的建议结合起来做。这类事情在操作符重载时非常容易,特别是当你在每一端都有自定义类型的时候。
上面的T(i,j,k,l)*(ij||kl);
https://stackoverflow.com/questions/5131412
复制相似问题