如何在C++中使用Thrust和odeint求解简单的常微分方程
How to Solve Simple ODEs Using Thrust and odeint in C++
我正在尝试创建一个简单的程序来熟悉Thrust的GPU计算能力和odeint的ODE求解能力。我希望能够在GPU上使用龙格-库塔方法解决简单的ODE(即dy/dx=3x^2y),希望以后能处理更复杂的问题
#include <boost/lambda/lambda.hpp>
#include <boost/numeric/odeint.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace boost::numeric::odeint;
using namespace std;
typedef std::vector<double> state_type;
void sys( state_type &y, state_type &dydx, double x){
dydx[0] = 3*x*x*y[0]; // dydx = 3*x^2*y
}
int main(){
state_type y(3);
runge_kutta4< state_type > rk4;
y[0] = 2; // y0 = 2
double x = 1; // x0 = 1
double h = 0.1; // h = 0.1
for (int i = 0; i < 100; i++,x+=h){
rk4.do_step(sys,y,x,h);
cout << "(";
cout << x+h;
cout << ",";
cout << y[0];
cout << ")";
cout << endl;
}
}
然而,我很难理解推力是如何发挥作用的。我遇到的大多数在线资源都以洛伦兹参数研究为例,但我觉得这对我目前的水平来说太先进了。
我理解设备和主机矢量的概念,但我不明白如何使用GPU来解决我的问题。根据我自己的研究,我已经能够使用CUDA(而不是推力)求解简单的代数(非微分)方程。然而,事实证明,将我对odeint和thrust的知识结合起来比我预期的要困难。
特别是,我对以下内容感到困惑:
1) 龙格-库塔步进的改造
2) 调整系统函数本身(本例中dydx=3*x*x*y[0])。
3) 将odeint和Thrust/boost目录都包含到程序中
如果这个问题太基本或要求太多,我深表歉意;我是StackOverflow的新手,还没有学会所有的"提问"协议,也没有学会我应该在多大程度上自己解决这个问题。
这个问题有点令人困惑。如果你想使用GPU,你通常有大型的微分方程系统。只有三个变量通常是不够的。GPU上的一条指令速度较慢,但它可以在一条指令中并行执行许多操作。Thrust设计用于处理大型数据结构,如GPU上有许多条目的矢量。
简而言之,要回答您的问题,您需要
- 将
thrust_algebra
和thrust_operations
添加到RK步进器的定义中 - 利用推力实现系统功能,这是最困难的步骤,以及
- 将
#include <boost/numeric/odeint.hpp>
和#include <boost/numeric/odeint/external/thrust.hpp>
添加到源文件中。当然,您还需要链接到CUDA库,并使用nvcc
编译所有内容。在odeint的examples目录中有一个makefile显示了它是如何工作的
相关文章:
- 在c++中用vector填充一个简单的动态数组
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 一种在C++中读取TXT配置文件的简单方法
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 显示错误输出的简单数组排序程序
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 退出简单while循环时出现问题
- 为什么简单的算术减法在"if"条件下不起作用?
- boost odeint什么时候真正调用观测者
- C++-字符串是否包含一个带有简单循环的单词
- 关于 c++ 函数中指针赋值的简单问题
- 从函数返回任意简单类型的数据
- 如何在没有函数的情况下编写此代码并使C++更简单?
- 如何在C++中使用Thrust和odeint求解简单的常微分方程
- Odeint隐式欧拉的简单例子
- 使用boost:odeint的简单c++程序中的断言错误
- 使用odeint的简单2d系统(使用数组)无法编译