python - 简化使用 sympy codegen 生成的表达式

标签 python c sympy

我正在使用 sympy.utilities.codegen 生成一些用于数值计算的 C 代码。例如,生成的 C 函数看起来像这样:

double f(double x, double y, double z){
    return M_PI*sin(M_PI*x)*sin(M_PI*y) + sin(M_PI*y)*sin(M_PI*z);
}

所以一般来说我有更大的函数和更多的表达式,这对我的数值计算来说是有问题的。由于我使用 CUDA,因此用于计算的寄存器集有所减少。我想要做的是将一个表达式拆分为更小的表达式,并进行一些替换,以便只计算一次昂贵的计算。下面是上述代码的示例。

double f(double x, double y, double z){
    double sinx = sin(M_PI*x);
    double siny = sin(M_PI*y);
    double sinz = sin(M_PI*z);
    double result;

    result  = M_PI*sinx*siny;
    result += siny*sinz;
    return result;
}

很明显,对于这个小函数来说,这种替换并没有什么返回,但总的来说,这是让我为更大的函数工作的唯一方法。所以我的问题是,是否有任何简单的内置选项可以实现这种行为?对我来说最重要的部分是将计算分成小步骤。我想可以通过一些字符串替换例程来完成替换。

最佳答案

您很可能想要执行common subexpression elimination 。 在您的示例中 siny 是实际重用的唯一表达式:

>>> expr = pi*sin(pi*x)*sin(pi*y) + sin(pi*y)*sin(pi*z)
>>> print(cse(expr))
([(x0, sin(pi*y))], [pi*x0*sin(pi*x) + x0*sin(pi*z)])

通常编译器应该已经完成​​这些转换 - 至少如果你要求的话 忽略例如的非关联性浮点乘法(通过传递例如 -ffast-math)。不过,我对 nvcc 没有任何经验。

如果您在使用 codegen 生成 CUDA 代码时遇到限制 - 请随时对其进行改进并将 Pull 请求发送至 SymPy project 。请务必检查最新的主分支,因为 Jim Crist 目前正在重构代码打印机:https://github.com/sympy/sympy/pull/7823

关于python - 简化使用 sympy codegen 生成的表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25309580/

相关文章:

c - 使用 void 指针在 C 中实现通用堆栈

python - 使用 Ctypes 从 Python 传递 C 结构

javascript - 如何使用不变的 URL 抓取多个页面 - Python 3

python - 将列表的元素与其自身进行比较

c - Tizen nativ 可穿戴开发错误找不到二进制文件(/Users/yvonne/CeBIT/CeBIT/Debug/cebit)

python - 为什么 sympy.init_printing 会更改集合表示法?

python - 通过 PIL 将图像转换为动画 webp 文件时出错

c - 将定义传递给函数

python-3.x - for循环中的Sympy求解器错误?

python - python 中的泰勒级数问题 (sympy)