提问人:Buzz 提问时间:11/4/2023 最后编辑:Buzz 更新时间:11/6/2023 访问量:34
Boost OdeInt 在进入集成例程时无法设置类属性
Boost OdeInt cannot set class property when entering integration routine
问:
我正在构建一个自定义集成器。
除了计算状态的离散导数外,我还在计算每个积分步骤进入时的输出方程。我知道它效率不高,但到目前为止,我需要它来了解库的工作方式。boost::numeric::odeint
operator ()
在调试时,在方法内部,变量和变量都计算得很好。但是,一旦程序返回主循环,对象和变量就会取消初始化。operator ()
y
test
sys
y
test
下面显示了代码和重现所讨论内容的结果。
TestSystem.h
#pragma once
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
const int n = 2; // State size
const int q = 1; // Output size
const int m = 1; // Input size
typedef Vector<double, n> state_type;
typedef Vector<double, m> input_type;
typedef Vector<double, q> output_type;
typedef Matrix<double, n, n> state_matrix_type;
typedef Matrix<double, n, m> input_matrix_type;
typedef Matrix<double, q, n> output_matrix_type;
typedef Matrix<double, q, m> feedthrough_matrix_type;
class TestSystem
{
public:
state_matrix_type A{
{ -4.0, -3.0},
{ 1.0, 0.0}
};
input_matrix_type B{ 1.0, 0.0 };
output_matrix_type C{ 1.0, 1.0 };
feedthrough_matrix_type D{ 0.0 };
double test;
input_type u;
output_type y;
void operator() (const state_type& x, state_type& x_dot, const double t);
};
测试系统.cpp
#include "TestSystem.h"
void TestSystem::operator()(const state_type& x, state_type& x_dot, const double t)
{
x_dot = A * x + B * u;
this->y = C * x + D * u;
this->test = (C * x + D * u)(0);
cout << "Output computed within integration step: " << endl;
}
main.cpp
#include <iostream>
#include <Eigen/Dense>
#include "TestSystem.h"
using namespace Eigen;
using namespace std;
using namespace cnpy;
const double PI = 3.14159265359;
const int N = 5000;
VectorXd u(N);
#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp>
using namespace boost::numeric::odeint;
int main()
{
VectorXd t(N);
t = VectorXd::LinSpaced(N, 0.0, 1.0);
TestSystem sys;
u = (2 * PI * 200 * t).array().cos() + (2 * PI * 20 * t).array().sin();
state_type x = state_type::Zero();
// Just one step for example sake
for (size_t i = 0; i < 1; i++) {
input_type _u{ u(i) };
// _u << u(i);
sys.u = _u;
runge_kutta4<state_type> rk;
rk.do_step(sys, x, t(i), t(1));
cout << "System object output variable: " << sys.test << endl;
}
}
结果
Output computed within integration step: 0
Output computed within integration step: 0.00010002
Output computed within integration step: 9.999e-05
Output computed within integration step: 0.00019998
System object output variable: -9.25596e+61
答:
1赞
sehe
11/6/2023
#1
系统是按值传递的。若要强制引用语义,请使用引用包装器:
#include <Eigen/Dense>
#include <iostream>
using Eigen::Matrix;
using Eigen::Vector;
using Eigen::VectorXd;
int constexpr n = 2; // State size
int constexpr q = 1; // Output size
int constexpr m = 1; // Input size
using state_type = Vector<double, n>;
using input_type = Vector<double, m>;
using output_type = Vector<double, q>;
using state_matrix_type = Matrix<double, n, n>;
using input_matrix_type = Matrix<double, n, m>;
using output_matrix_type = Matrix<double, q, n>;
using feedthrough_matrix_type = Matrix<double, q, m>;
struct TestSystem {
state_matrix_type A{{-4.0, -3.0}, {1.0, 0.0}};
input_matrix_type B{1.0, 0.0};
output_matrix_type C{1.0, 1.0};
feedthrough_matrix_type D{0.0};
double test;
input_type u;
output_type y;
void operator()(state_type const& x, state_type& x_dot, double t);
};
void TestSystem::operator()(state_type const& x, state_type& x_dot, double) {
x_dot = A * x + B * u;
this->y = C * x + D * u;
this->test = (C * x + D * u)(0);
std::cout << "Output computed within integration step: " << test << std::endl;
}
#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp>
namespace ode = boost::numeric::odeint;
int main() {
int constexpr N = 5000;
VectorXd t(N);
t = VectorXd::LinSpaced(N, 0.0, 1.0);
TestSystem sys;
VectorXd u(N);
u = (2 * M_PI * 200 * t).array().cos() + (2 * M_PI * 20 * t).array().sin();
state_type x = state_type::Zero();
// Just one step for example sake
for (size_t i = 0; i < 1; i++) {
input_type _u{ u(i) };
// _u << u(i);
sys.u = _u;
ode::runge_kutta4<state_type> rk;
rk.do_step(std::ref(sys), x, t(i), t(1));
std::cout << "System object output variable: " << sys.test << std::endl;
}
}
印刷
Output computed within integration step: 0
Output computed within integration step: 0.00010002
Output computed within integration step: 9.999e-05
Output computed within integration step: 0.00019998
System object output variable: 0.00019998
评论