如何用std::transform_reduce计算复杂复合表达式?
问题描述
现有以下变量:
std::vector<double> Coefficients; std::vector<std::function<double(double)>> Functions; std::vector<std::vector<double>> Polynomials;
给定输入std::vector<double> X,需要计算表达式:c1 * f1((x1^p1) * (x2^p2) * ...) + c2 * f2(...),其中:
c是Coefficients中的元素f是Functions中的函数(如sin、cos)p是Polynomials中的多项式系数
示例:
Coefficients = {2, -4}; Functions = {std::sin, std::cos}; Polynomials = {{4, 3}, {2, 5}};
需计算:
2 * sin(x1^4 * x2^3) - 4 * cos(x1^2 * x2^5)
已知std::transform_reduce可高效完成该计算,但嵌套操作的实现方式不明确,初步思路如下:
std::transform_reduce( std::execution::par, Coefficients.begin(), Coefficients.end(), Functions.begin(), 0.0, std::plus<>(), [&](double c, auto f) { return c * f(std::transform_reduce( // 此处需再次用transform_reduce处理函数内的多项式及x^p?
解决方案
可以通过**嵌套std::transform_reduce**实现需求,外层处理系数与函数的组合,内层计算每个多项式对应的x^p乘积。需确保Coefficients、Functions、Polynomials三个容器长度一致,否则会触发未定义行为。
完整实现代码如下:
#include <vector> #include <execution> #include <numeric> #include <cmath> #include <functional> double compute_expression(const std::vector<double>& Coefficients, const std::vector<std::function<double(double)>>& Functions, const std::vector<std::vector<double>>& Polynomials, const std::vector<double>& X) { // 外层transform_reduce:遍历三组序列,计算每一项并累加 return std::transform_reduce( std::execution::par, // 并行执行提升大数据量下的计算效率 Coefficients.begin(), Coefficients.end(), Functions.begin(), 0.0, // 累加初始值 std::plus<>(), // 项之间的累加操作 [&](double c, const auto& f, const auto& poly) { // 内层transform_reduce:计算x1^p1 * x2^p2 * ...的乘积 double product = std::transform_reduce( X.begin(), X.end(), poly.begin(), 1.0, // 乘积初始值 std::multiplies<>(), // 因子之间的乘法操作 [](double x, double p) { return std::pow(x, p); // 计算单个x^p项 } ); return c * f(product); // 生成当前项:系数 * 函数(乘积结果) }, Polynomials.begin() // 第三个并行遍历的序列起始迭代器 ); }
代码说明
外层
transform_reduce:- 同时遍历
Coefficients、Functions、Polynomials三个序列,通过第三个输入迭代器参数实现多序列并行遍历 - 用
std::plus<>()完成所有项的累加,初始值设为0.0 std::execution::par并行策略可利用多核资源,适合处理大规模计算场景
- 同时遍历
内层
transform_reduce:- 遍历
X与当前多项式poly,逐对计算x_i^p_i - 用
std::multiplies<>()将所有x_i^p_i相乘,初始值设为1.0 - 最终乘积传入函数
f,再乘以系数c得到当前项的值
- 遍历
使用示例
int main() { std::vector<double> Coefficients = {2, -4}; std::vector<std::function<double(double)>> Functions = {std::sin, std::cos}; std::vector<std::vector<double>> Polynomials = {{4, 3}, {2, 5}}; std::vector<double> X = {1.0, 2.0}; // x1=1, x2=2 double result = compute_expression(Coefficients, Functions, Polynomials, X); // 计算结果:2*sin(1^4*2^3) -4*cos(1^2*2^5) = 2*sin(8) -4*cos(32) return 0; }
内容的提问来源于stack exchange,提问作者dearn44
相关产品推荐
相关产品推荐

