我正在odeint和推力之上构建一个分析工具。该工具解决了大量初始条件问题。我在odeint和推力教程/演示之后取得了成功。到目前为止,我一直在使用的系统有少于5个状态变量,但现在我需要扩展系统以便能够处理更多。
正如教程中所提到的,推文的元组最多只能包含10个项目。使用嵌套的zip_iterators可以解决此问题。
从one of the tutorials底部附近引用:
“Thrust的元组最小为10的小难度。但这只是一个小问题,因为我们可以创建一个包含zip迭代器的zip迭代器。所以顶级zip迭代器包含一个用于状态的zip迭代器,参数的一个普通迭代器,以及派生的一个zip迭代器。“
我已经实施了这个解决方案,但它很有效,但遗憾的是速度大幅下降。对于同一系统(双变量系统,同时求解8192初始条件),原始的,简单但不可扩展的超过5个变量解决方案在一秒钟内运行:
real 0m1.244s
user 0m0.798s
sys 0m0.356s
而更复杂但可扩展的嵌套解决方案需要大约2000倍的时间!
real 4m3.613s
user 2m15.124s
sys 1m47.363s
两个程序之间的唯一区别是
在仿函数operator()
中,我指的是状态变量和派生词,
在仿函数的构造函数中,特别是for_each
命令,我在其中创建了zip_iterators和元组。
下面我列出了每个节目的摘录。我希望我在这里做错了,因为这种速度损失是毁灭性的!任何帮助将不胜感激。
//////////////////////////////////////////////////////////
//// Inside ICFunctor's operator()
// getting the state variable
value_type X = thrust::get< 0 >( t );
// setting the derivative
thrust::get< 2 >( t ) = 0.5*A - 1.5*X;
//////////////////////////////////////////////////////////
//// the for_each statement that creates the zip_iterator
thrust::for_each(
//// START INDICES
thrust::make_zip_iterator( thrust::make_tuple(
// State-variables
boost::begin( x ) + 0*m_N,
boost::begin( x ) + 1*m_N,
// Derivatives
boost::begin( dxdt ) + 0*m_N,
boost::begin( dxdt ) + 1*m_N)) ,
//// END INDICES
thrust::make_zip_iterator( thrust::make_tuple(
// State-variables
boost::begin( x ) + 1*m_N,
boost::begin( x ) + 2*m_N,
// Derivatives
boost::begin( dxdt ) + 1*m_N,
boost::begin( dxdt ) + 2*m_N)) ,
ICFunctor() );
//////////////////////////////////////////////////////////
//// Inside ICFunctor's operator()
// getting the state variable
const int STATE_VARIABLES = 0; // defined as a global constant
value_type X = thrust::get<0>(thrust::get<STATE_VARIABLES>( t ));
// setting the derivative
const int DERIVATIVES = 1; // defined as a global constant
thrust::get<0>(thrust::get<DERIVATIVES>( t )) = 0.5*A - 1.5*X;
//////////////////////////////////////////////////////////
//// the for_each statement that creates the zip_iterator
thrust::for_each(
//// START INDICES
thrust::make_zip_iterator( thrust::make_tuple(
// State variables
thrust::make_zip_iterator( thrust::make_tuple(
boost::begin( x ) + 0*m_N,
boost::begin( x ) + 1*m_N)),
// Derivatives
thrust::make_zip_iterator( thrust::make_tuple(
boost::begin( dxdt ) + 0*m_N,
boost::begin( dxdt ) + 1*m_N))
)),
//// END INDICES
thrust::make_zip_iterator( thrust::make_tuple(
// State variables
thrust::make_zip_iterator( thrust::make_tuple(
boost::begin( x ) + 1*m_N,
boost::begin( x ) + 2*m_N)),
// Derivatives
thrust::make_zip_iterator( thrust::make_tuple(
boost::begin( dxdt ) + 1*m_N,
boost::begin( dxdt ) + 2*m_N))
)),
ICFunctor() );