c++ - Armadillo 与 Boost Odeint : Odeint resizes the state vector to zero during integration 冲突

标签 c++ c++11 boost armadillo

我刚开始使用 Boost Odeint 来集成一个 ODE 系统。为方便起见,我想将它与 Armadillo 一起使用,因为两者都是具有方便 API 的现代 C++ 库。但是,如果我指定 arma::vec作为状态类型,立即证明在集成的第一步中,integrate_adaptive()将状态 vector 调整为 0x1 .我在这里发布一个简单的例子:

#include <iostream>
#include <armadillo>

#include <boost/numeric/odeint.hpp>

using namespace std;
using namespace arma;
using namespace boost::numeric::odeint;

typedef vec state_type;

class harm_osc
{
    private:
    mat my_A;

    public:
        harm_osc(double gam)
        {
            my_A = { {0.0, 1.0}, {-gam*gam, 0.0} };
        }

        harm_osc()
        {
            my_A = { {0.0, 1.0}, {-1.0, 0.0} };
        }

        void operator() (const vec& x, vec& dxdt, const double t)
        {
            cout << "size of x: " << size(x) << endl;
            cout << "size of dxdt: " << size(dxdt) << endl;
            dxdt = my_A*x;
        }
};

class observer
{
    private:
        mat& my_states;
        vec& my_times;                        

    public:
        observer(mat& states, vec& times):
            my_states(states),
            my_times(times)
        {}    

        void operator() (const vec& x, double t)
        {
            my_states.insert_rows(my_states.n_rows, x);
            my_times.insert_rows(my_times.n_rows, t);
            cout << t << '\t';
            for(auto elem : x)
                cout << elem << '\t';
            cout << endl;
        }
};

typedef runge_kutta_cash_karp54<state_type> error_stepper_type;
typedef controlled_runge_kutta<error_stepper_type> controlled_stepper_type;

int main()
{
    state_type x = {0.0, 1.0};

    vec t;
    mat x_full;

    integrate_adaptive(make_controlled<error_stepper_type>(1e-5, 1e-5), harm_osc(1.0), x, 0.0, 200.0, 0.01, observer(x_full, t));
}

如果我指定 arma::vec::fixed<2>而不是 arma::vecstate_type ,这个简单的演示可以正确运行。我的问题是,在我正在处理的当前项目中,我不知道编译时状态 vector 的大小,因此我无法使用前面提到的模板参数来修复它。

是否有任何解决方案可以将 Armadillo 与 Boost Odeint 结合使用,而无需在编译时固定状态 vector 的大小?在我项目的其他部分,我可以正确使用 Armadillo 。我想在我的整个项目中使用它。现在,在集成 ODE 时,我使用 Boost Ublas 来定义 ODE 系统。

最佳答案

Odeint 在内部存储了几个中间状态。在您的情况下,我认为它不知道如何正确调整中间状态的大小。这可以通过引入正确的调整大小适配器轻松解决:

namespace boost { namespace numeric { namespace odeint {

template <>
struct is_resizeable<arma::vec>
{
    typedef boost::true_type type;
    const static bool value = type::value;
};

template <>
struct same_size_impl<arma::vec, arma::vec>
{
    static bool same_size(const arma::vec& x, const arma::vec& y)
    {
        return x.size() == y.size();   // or use .n_elem attributes
    }
};

template<>
struct resize_impl<arma::vec, arma::vec>
{
    static void resize(arma::vec &v1, const arma::vec& v2)
    {
        v1.resize(v2.size());     // not sure if this is correct for arma
    }
};

} } } // namespace boost::numeric::odeint

看看这里:http://www.boost.org/doc/libs/1_63_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/odeint_in_detail/state_types__algebras_and_operations.html

关于c++ - Armadillo 与 Boost Odeint : Odeint resizes the state vector to zero during integration 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41753823/

相关文章:

c++ - 如何调试LLVM3.2插件断言错误

c++ - 使用 cmake 将 LLVM 添加到项目

c++ - 用于 std::list 和 std::map 的 Visual C++11 堆栈分配器

c++ - 尝试将 boost::stacktrace 添加到 CMake 项目时生成错误

c++ - 有什么方法可以将 varargs 与 boost::format 一起使用吗?

c++ - 函数参数中的 const'ing 原始类型是否会显着提高性能?

c++ - 为什么调用不接受带参数的函数的函数在 C 中编译但在 C++ 中不编译

c++ - `std::packaged_task` 是否需要 CopyConstructible 构造函数参数?

c++ - 通过 constexpr union 进行类型双关

c++ - 使用 Boost Polygon 的减法结果不正确