首页 > 解决方案 > 在 C++ 中实现一个数学向量,重用标准库的容器

问题描述

这个问题是由以下实现一阶常微分方程 (ODE)积分的龙格库塔公式引起的。

template <typename Field, typename Vector>
auto
runge_kutta(const Vector& y,
           std::function<Vector(Field, const Vector&)> rhs,
           Field t, Field delta_t)
{
  Vector k1 = rhs(t, y);
  Vector k2 = rhs(t + delta_t/2, y + delta_t/2*k1);
  Vector k3 = rhs(t + delta_t/2, y + delta_t/2*k2);
  Vector k4 = rhs(t + delta_t,   y + delta_t * k3);
  return y + delta_t/6*(k1 + 2*k2 + 2*k3 + k4);
}

这可用于集成如下功能

double f(double t, double y) { return y; }

但是上面的 Runge Kutta 代码也可用于求解具有多个因变量的高阶 ODE 或 ODE。为此,模板参数 Vector 必须是具有适当定义的算术运算符的数字(或不同类型的向量)的容器。

因此,我正在寻找Vector具有以下属性的类型的实现:

  1. 类型是数字或不同类型向量的容器。
  2. 适当地重载运算符operator+,operator-和.operator*operator/
  3. 在调用代码中不需要使用这些运算符的 using 声明。
  4. 标准库被重用。

我想出的最好的方法是std::array在新的命名空间中创建运算符

namespace StackOverflow {

  template<typename Field, typename Element, std::size_t Dim>
  auto
  operator*(Field lhs, const std::array<Element, Dim>& rhs);

  // etc., etc.
}

并在调用代码中有合适的 using 声明(违反上述第 2 点)

using StackOverflow::operator+; ...

另一种可能性是公开地std::array. 这是可行的,但据我所知,这是 C++ 语言标准明确禁止的。

是否可以重用std::array- 保留上面的前四个属性 - 而无需std::array完全重写?

标签: c++odevector-space

解决方案


推荐阅读