В наблюдателе ODEINT + THRUST, получая ошибку, выражение должно быть изменяемым lvalue

0

Я работал над расширением/модификацией примера тяги + odeint [ код, документация ], который систематически меняет параметр и наблюдает за эффектами.

У меня странная ошибка, когда я пытаюсь изменить некоторые переменные, которые должны быть модифицируемы (и изменены в примере), я получаю следующую ошибку.

main.cu: error: expression must be a modifiable lvalue

Ниже приведен исходный код для структуры наблюдателя, которую я пытаюсь запустить, с комментарием, показывающим строку, которая вызывает ошибку.

Я понимаю, что эта ошибка означает, что выражение слева от оператора присваивания, =, не является изменяемым значением. Но для меня это выглядит точно так же, как переменная с тем же именем в приведенном выше примере источника (который отлично работает).

//// Observes the system to detect if it ever dies during the trial
struct death_observer {

  // CONSTRUCTOR
  death_observer( size_t N, size_t historyBufferLen = 1) 
    : m_N( N ), m_count( 0 ) { }

  template< class State , class Deriv >
  void operator()(State &x , Deriv &dxdt , value_type t ) const
  {
    ++m_count;                                 // <-- This line causes the error.
  }

  // variables
  size_t m_N;   
  size_t m_count;
};

... и вот код из main(), который запускает интегратор и этот наблюдатель, в случае, если это полезно.

  parallel_initial_condition_problem init_con_solver( N_ICS );
  death_observer obs( N_ICS );

  //////////////////////////////// // // integrate   
  typedef runge_kutta_dopri5< state_type , value_type , state_type , value_type, thrust_algebra, thrust_operations > stepper_type;
  const value_type abs_err = 1.0e-6;
  const value_type rel_err = 1.0e-6;

  double t = t_0;
  while( t < t_final ) {
    integrate_adaptive( make_controlled( abs_err, rel_err, stepper_type() ) ,
            init_con_solver ,
            std::make_pair( x.begin() , x.begin() + N_VARS*N_ICS  ),
            t , t + 1.0 , init_dt );
    t += 1.0;
    obs( x, *(&x+N_VARS*N_ICS), t); // not sure about middle arg here, but I don't think it is the cause of the error.
  }

Я попытался скрыть свой код до самого простого случая. Комментируя вышеприведенную строку от 3-й до последней, программа работает нормально.

Что я делаю неправильно? Чем отличается мой m_count и m_count в приведенном выше примере кода? Большое спасибо!

  • 2
    Вы объявили свой operator () const и все же пытаетесь изменить внутри него элемент данных класса. Кроме того, *(&x+N_VARS*N_ICS) почти наверняка не то, что вам нужно, поскольку x выглядит как контейнер из ваших .begin() .
  • 0
    Спасибо. Ключевое слово const действительно было причиной моей проблемы. Я сейчас пытаюсь выяснить, что я должен поставить вместо *(&x+N_VARS*N_ICS) . Если я выполняю x.begin () + N_VARS * N_ICS, я получаю сообщение об ошибке, что это неправильный тип, но я хочу, чтобы второй аргумент ссылался на более позднюю точку в x ... В любом случае, спасибо!
Показать ещё 1 комментарий
Теги:
odeint
thrust

1 ответ

3
Лучший ответ

Преобразование комментария в ответ:

template< class State , class Deriv >
void operator()(State &x , Deriv &dxdt , value_type t ) const
{
    ++m_count;                                 // <-- This line causes the error.
}

Вы объявили operator() как функцию-член const, и поэтому он не может изменять члены данных класса, если член не объявлен как mutable.

Замечание стороны: *(&x+N_VARS*N_ICS) почти наверняка неверно, так как x выглядит как контейнер из .begin().

Ещё вопросы

Сообщество Overcoder
Наверх
Меню