我正在编写代码来执行与点的高斯积分n
,其中n
是编译时间常数。
对于给定的n
,我知道如何计算横坐标和权重。对于每个不同的 . 计算必须从头开始n
。
现在,我按照以下方式做一些事情:
// Several structs like this one (laguerre, chebyshev, etc).
template <size_t n>
struct legendre
{
static const size_t size = n;
static const double x[n];
static const double w[n];
};
template <typename Rule, typename F>
double gauss_quadrature (F&& f)
{
double acc = 0;
for (size_t j = 0; j < Rule::size; j++)
acc += Rule::w[j] * f (Rule::x[j]);
return acc;
}
像这样使用:
double i = gauss_quadrature<legendre<12>> (f);
legendre<12>
现在,我可以通过做专门研究系数的翻译单元
template <>
const legendre<12>::x[12] = { ... };
template <>
const legendre<12>::w[12] = { ... };
一切都很好,只要我只使用 12 点 Gauss-Legendre。
现在,我正在尝试不同数量的点,并且我知道如何生成权重和节点。例如,我可以提供一个例程
void compute_legendre_coeffs (size_t n, double* w, double* x);
和 :
- 当我调用
gauss_quadrature<legendre<n>>
时,模板legendre<n>
会自动实例化(就是这种情况)。 - 当
legendre<n>
为某些 compile-time 实例化时n
,我希望compute_legendre_coeffs
在 main 之前的某个时间点调用上面的内容,以便它填充x
和w
成员数组。我该如何做到这一点?
我知道必须先定义数组:
template <size_t n>
const double legendre<n>::x[n] = {};
template <size_t n>
const double legendre<n>::w[n] = {};
但我想不出一种方法来初始化它们。任何人都有这样做的诀窍吗?