- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我打算求解几个矩阵微分方程,形式为 d/dt (X) = F(X)
, 其中X
是一个大的复杂矩阵,F
表示它的一些功能。我尝试将 Boost 的 odeint 与 state_type
一起使用作为 Armadillo 的 cx_mat
.但它会为受控步进器类型产生编译错误。我的示例代码如下
#include <armadillo>
#include <iostream>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace arma;
using namespace boost::numeric::odeint;
using state_type = arma::cx_mat;
void ode(const state_type& X, state_type& derr, double) {
derr = X; // sample derivative, can be anything else
}
// define resizable and norm_inf
namespace boost { namespace numeric { namespace odeint {
template <>
struct is_resizeable<arma::cx_mat> {
typedef boost::true_type type;
const static bool value = type::value;
};
template <>
struct same_size_impl<arma::cx_mat, arma::cx_mat> {
static bool same_size(const arma::cx_mat& x, const arma::cx_mat& y)
{
return arma::size(x) == arma::size(y);
}
};
template<>
struct resize_impl<arma::cx_mat, arma::cx_mat> {
static void resize(arma::cx_mat& v1, const arma::cx_mat& v2) {
v1.resize(arma::size(v2));
}
};
template<>
struct vector_space_norm_inf<state_type> {
typedef double result_type;
result_type operator()(const state_type& p) const
{
return arma::norm(p, "inf");
}
};
} } } // namespace boost::numeric::odeint
using stepper = runge_kutta_dopri5<state_type, double, state_type, double, vector_space_algebra>;
int main () {
cx_mat A = randu<cx_mat>(4, 4);
integrate_adaptive( make_controlled<stepper>(1E-10, 1E-10), ode, A, 0.0 , 10.0, 0.1);
}
此代码给出以下编译错误:
/usr/include/armadillo_bits/Mat_meat.hpp:5153:3: error: static assertion failed: error: incorrect or unsupported type
arma_type_check(( is_same_type< eT, typename T1::elem_type >::no ));
据我所知, Armadillo 不支持将真实矩阵(mat
)复制到复杂矩阵(cx_mat
)中,例如
mat Z = something;
cx_mat Y = Z; // ERROR
这发生在 odeint 的某处。现在我通过将整个矩阵复制到 std::vector<std::complex<double> >
来克服这个问题将其放入函数ode
, 然后在函数内部再次复制整个 std::vector<std::complex<double> >
进入cx_mat
, 计算 F(X)
, 然后复制到 std::vector<std::complex<double> >
并返回。显然,这是非常缓慢和低效的。
有什么简单的解决方法吗??如果可能的话,如果有帮助的话,我可能想转向 Eigen。
最佳答案
您好,我知道这已经很老了,但是当我遇到同样的问题时偶然发现它,我想分享我的解决方案。我使用了 Eigen,并添加了一些类似于 Armadillo 中的小部件,它对我有用(使用 icpc 和 g++ 测试编译)。这里有一个最小的代码片段:
#include<Eigen/Eigen>
#include<boost/numeric/odeint.hpp>
#include<iostream>
#include<complex>
#include<boost/numeric/odeint/external/eigen/eigen_algebra.hpp>
typedef std::complex<double> cdoub;
typedef Eigen::MatrixXcd state_type;
namespace boost {
namespace numeric {
namespace odeint {
template<typename B,int S1,int S2,int O, int M1, int M2>
struct algebra_dispatcher< Eigen::Matrix<B,S1,S2,O,M1,M2> >
{
typedef vector_space_algebra algebra_type;
};
template<>
struct vector_space_norm_inf<state_type> {
typedef double result_type;
result_type operator()(const state_type& p) const
{
return p.lpNorm<Eigen::Infinity>();
}
};
}}}
namespace Eigen {
template<typename D, int Rows, int Cols>
Matrix<D, Rows, Cols> operator/(const Matrix<D, Rows, Cols>& v1, const Matrix<D, Rows, Cols>& v2)
{
return v1.array()/v2.array();
}
template<typename D, int Rows, int Cols>
Matrix<D, Rows, Cols>
abs(Matrix<D, Rows, Cols> const& m) {
return m.cwiseAbs();
}
}
/* The rhs of x' = f(x) */
void harmonic_oscillator( const state_type &x , state_type &dxdt , const double /* t */ )
{
dxdt = x;
}
//]
int main() {
using namespace boost::numeric::odeint;
state_type X0(3,3);
X0 = state_type::Random(3,3);
state_type xout = X0;
typedef runge_kutta_dopri5<state_type,double,state_type,double,vector_space_algebra> error_stepper_type;
typedef controlled_runge_kutta< error_stepper_type > controlled_stepper_type;
controlled_stepper_type controlled_stepper;
double t =0.0;
double dt = 0.1;
controlled_stepper.try_step(harmonic_oscillator, X0, t, dt);
std::cout << X0 << std::endl;
}
也许问题已经解决了,但是这里又出现了问题https://gist.github.com/jefftrull/5625b77c0f86c439f29f五天前我想分享它,希望它能有所帮助:)
关于c++ - Armadillo的cx_mat和Boost的odeint编译报错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44987226/
我正在通过 odeint 集成生化常微分方程(见下图),但是主输入函数似乎在调用时用奇怪的数字重新设置(或替换)输入参数。尽管参数“iu”(v 的感应率,应在整个过程中保持恒定)和“v”(结果之一,应
我一直在努力使用新版本的 boost。我正在使用多精度的 odeint。下面这段代码可以用boost version 1.67.0编译成功。但是,自 1.68.0 及更新版本以来,我无法再编译。在版本
我最近偶然发现了 boost.odeint 库,我对可能性和可配置性的数量感到惊讶。但是,在广泛使用 scipy.integrate.odeint(它本质上是 Fortran 中 ODEPACK 的包
我刚开始使用 Boost Odeint 来集成一个 ODE 系统。为方便起见,我想将它与 Armadillo 一起使用,因为两者都是具有方便 API 的现代 C++ 库。但是,如果我指定 arma::
我想使用 scipy 的 odeint 函数求解具有 15 个时间相关系数的 7 个常微分方程 (ODE) 系统。 我将系数存储在字典中,以便可以通过我定义为与 odeint() 一起使用的函数 (f
我尝试在 Mac OS X 10.9.2 g++ 5.1 上的 boost_1_55_0 中运行 [odeint 复杂状态类型示例代码。 下面的代码是网站上解决 Stuart-Landau 振荡器的拷
所以我试图求解一个包含三个 ODE 的系统,并开发了以下代码来使用 ODEint 求解它们。但是当我运行时,ODEint 在调用我的方程组函数时出现问题。 from scipy.integrate i
我有以下 odeint 程序: #include #include using namespace std; typedef boost::array state_type; void eqsys
我有一个使用“odeint”模拟种群动态的程序。我想设置一个 if 条件来禁止我的颂歌的结果为负。这是我的代码摘要: class Communities { public : type
我正在尝试求解一个简单的方程:dM/dr = r*p(r) 在 python 中。 我在 r 的某些值处有 p 的值: p(0)=1, p(1)=3, p(2)=5, p( 3)=7, p(4)=9,
我正在尝试使用 scipy 的 odeint 来求解一些常微分方程。唯一的问题是我只想定义一个参数,看来要组成一个元组,你至少需要两个值。 我的代码是这样的: def system(state, t,
我正在尝试用 odeint 求解微分方程。这里一些常量参数是固定的,一些在列表中。 from scipy.integrate import odeint import matplotl
使用Python 2.7.8。 我正在使用的微分方程是 x'=2-3*x。没那么难。正确的解是 y 截距为 2/3 的衰减指数。运动有三个初始条件。还必须在同一地 block 上有一个带有解决方案的斜
我想将 scipy 的 odeint 与一个函数一起使用 def func(y,t,a=123,b=456) 然后将其用作 odeint(func,y0,t) 如果我想使用 args 改变值 a 和
我对使用隐式方案使用 odeint 库求解 ODE 系统很感兴趣,但我很难实现一个简单的 implicit_euler 示例。 查看文档,我设法使工作显式步进器、自适应步进器以及 rosenbrock
我刚刚实现了一组耦合 ODE 的数值积分来自使用 odeint C++ 库的离散 PDE。它很好用并且快如闪电,但有一个问题: 我的 ODE 系统具有所谓的吸收边界条件:时间我的状态变量 n 的导数,
运行以下代码: #include #include using namespace std; using namespace boost::numeric::odeint; class CSyst
显然,getting a non-negative solution from an ODE solver is non-trivial .在 Matlab 中,有 NonNegative optio
我在使用受控错误步进器和复杂状态类型的 odeint 库时遇到了问题。我对具有复杂斯图尔特朗道方程的示例中的代码进行了修改,使其包含自适应积分器。代码现在看起来像这样: #include #incl
有一些使用 arbitrary precision 的例子和 matrices在 boost.odeint( boost 常微分方程求解器)中。 我想在不同类型的坐标(笛卡尔、极坐标或作用角)中使用
我是一名优秀的程序员,十分优秀!