You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用标量/整数对Eigen张量做除法?FFT归一化遇零值问题

问题根源与解决方案

为什么会得到全零结果?

  • 整数除法陷阱:1/(nx*ny*nz)中,nx/ny/nz都是整数,C++里整数间除法会执行整数除法,结果直接取整截断。当nx*ny*nz > 1时,这个表达式的结果就是0,后续和张量相乘自然得到全零。
  • 错误调用data():rArr.data()返回的是张量底层数据的指针,不是张量对象,直接和数值相乘是完全错误的操作(本质是把指针地址和数值做乘法,和张量元素毫无关系)。

高效的归一化实现方式

不需要额外创建dummy张量,直接在rArr上执行原地运算即可,既节省内存开销又提升执行效率:

// 用1.0触发浮点数除法,规避整数除法问题
rArr *= 1.0 / (nx*ny*nz);

如果担心nx*ny*nz整数溢出(比如三个维度数值都很大),可以拆分转换为浮点数再计算,更安全:

const double scale = 1.0 / static_cast<double>(nx) / ny / nz;
rArr *= scale;

修正后的完整代码片段

void c2rfft3d(Eigen::Tensor<std::complex<double>, 3>& cArr, Eigen::Tensor<double, 3>& rArr){    
    fftw_complex *input_array = (fftw_complex*) fftw_malloc(nx*ny*nz * sizeof(fftw_complex));
    memcpy(input_array, cArr.data(), nx*ny*nz * sizeof(fftw_complex));
    
    fftw_complex *output_array = (fftw_complex*) fftw_malloc(nx*ny*nz * sizeof(fftw_complex));
    
    fftw_plan backward = fftw_plan_dft_3d(nx, ny, nz, input_array, output_array, FFTW_BACKWARD, FFTW_ESTIMATE);
    
    fftw_execute(backward);
    fftw_destroy_plan(backward);
    fftw_cleanup();

    memcpy(rArr.data(), output_array, nx*ny*nz * sizeof(double));
    
    // 原地归一化,高效且避免错误
    const double scale = 1.0 / static_cast<double>(nx*ny*nz);
    rArr *= scale;

    // 释放fftw分配的内存,避免泄漏
    fftw_free(input_array);
    fftw_free(output_array);
}

内容的提问来源于stack exchange,提问作者Jamie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:02:22