Не могли бы вы помочь мне с моей проблемой. Я пытаюсь написать программу, в которой взаимодействуют объекты из разных классов. Я основываю свою модель на библиотеке gsl для разрешения моих обыкновенных дифференциальных уравнений (ода).
Экземпляры разных классов потребляют друг друга, поэтому они получают или теряют массу, когда едят или едят.
Мои 2 оды похожи на b [i] = сумма потребления — сумма потребления. Я рассчитываю потребление следующим образом: 1 — потребитель, а 0 — добыча.
conso [1] = y [0] * x [1] * y [1]
Исходный код взят из «примера кода с использованием подпрограмм gsl», как следует с изменениями. Экземпляры классов A и B включены в карты класса C.
Я новичок в c ++ и не понимаю, как интегрировать цикл в оду, чтобы он вычислял, что было потреблено каждым экземпляром, и удалял его из других экземпляров, которые были съедены. Лучше всего было бы использовать функции и переменные, которые находятся в классе istances, но функция, в которой находится ода, должна быть статической. Я думал о массиве, но кажется, что массивы не могут быть параметрами од.
Другая проблема заключается в том, что для каждого экземпляра параметры должны меняться и приниматься в классе, но, как я сделал здесь, в цикле с итераторами, Ода будет работать для последнего экземпляра … Опять я бы хотел использовать массив класса C, который принимает параметр экземпляров в классах A и B, но поскольку функция является статической, я не могу использовать массив класса «C». Я в настоящей беде!
Есть ли у вас какие-либо идеи ? Спасибо !
// include files
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv.h>
// ************************* C.h ****************************
class C
{
public :
C(std::map(std::map<std::string,A> &A, std::map<std::string,B> &B);
~C();
int integ(void);
int static rhs (double t, const double y[], double f[], void *params_ptr);
private :
std::map<std::string,A> &A,
std::map<std::string,B> &B,
};
//*************************** C.cpp ****************************
int C::integ (void)
{
int dimension = 2; // number of differential equations
double eps_abs = 1.e-8; // absolute error requested
double eps_rel = 1.e-10; // relative error requested
// define the type of routine for making steps:
const gsl_odeiv_step_type *type_ptr = gsl_odeiv_step_rkf45;
// allocate/initialize the stepper, the control function, and the
// evolution function.
gsl_odeiv_step *step_ptr = gsl_odeiv_step_alloc (type_ptr, dimension);
gsl_odeiv_control *control_ptr = gsl_odeiv_control_y_new (eps_abs, eps_rel);
gsl_odeiv_evolve *evolve_ptr = gsl_odeiv_evolve_alloc (dimension);
gsl_odeiv_system my_system; // structure with the rhs function, etc.
// parameter for the diffeq
for(itA=A.begin(); itA!=A.end(); ++itA)
{
x = itA->second.getx();
my_system.params = &x; // parameters to pass to rhs
}
for(itB=B.begin(); itB!=B.end(); ++itB)
{
z = itB->second.getz();
my_system.params = &z; // parameters to pass to rhs
}double y[2]; // current solution vector
double t, t_next; // current and next independent variable
double tmin, tmax, delta_t; // range of t and step size for output
double h = 1e-6; // starting step size for ode solver
// load values into the my_system structure
my_system.function = rhs; // the right-hand-side functions dy[i]/dt
my_system.dimension = dimension; // number of diffeq'stmin = 0.; // starting t value
tmax = 100.; // final t value
delta_t = 1.;
for(itA=A.begin(); itA!=A.end(); ++itA)
{
y[0] = itA->second.getY(); // initial y value
}
for(itB=B.begin(); itB!=B.end(); ++itB)
{
y[1] = itB->second.getY(); // initial y value
}t = tmin; // initialize t
// print initial values
cout << scientific << setprecision (5) << setw (12) << t << " "<< setw (12) << y[0] << " " << setw (12) << y[1] << endl;
// step to tmax from tmin
for (t_next = tmin + delta_t; t_next <= tmax; t_next += delta_t)
{
while (t < t_next) // evolve from t to t_next
{
gsl_odeiv_evolve_apply (evolve_ptr, control_ptr, step_ptr,
&my_system, &t, t_next, &h, y);
}
// print at t = t_next
cout << scientific << setprecision (5) << setw (12) << t << " "<< setw (12) << y[0] << " " << setw (12) << y[1] << endl;
}
// all done; free up the gsl_odeiv stuff
gsl_odeiv_evolve_free (evolve_ptr);
gsl_odeiv_control_free (control_ptr);
gsl_odeiv_step_free (step_ptr);
return 0;
}
//*************************** rhs ****************************
int C :: rhs (double , const double y[], double f[], void *params_ptr)
{
// get parameter(s) from params_ptr; here, just a double
double x = *(double *) params_ptr;
double z = *(double *) params_ptr;
// evaluate the right-hand-side functions at t
f[1] = x * y[1] + sum consumption - sum consumed; //objects of class A
f[0] = - z * y[0] - sum consumed; //objects of class B
return GSL_SUCCESS; // GSL_SUCCESS defined in gsl/errno.h as 0
}
Я пытался добавить потребление, но он говорит: «ошибка:« void »должен быть первым и единственным параметром, если
указано «:
int C :: rhs (double , const double y[], double f[], void *params_ptr, void conso)
{
// get parameter(s) from params_ptr; here, just a double
double x = *(double *) params_ptr;
double z = *(double *) params_ptr;
// evaluate the right-hand-side functions at t
f[0] = z * y[0]; //objects of class A
f[1] = - x * y[1] + conso; //objects of class B
return GSL_SUCCESS; // GSL_SUCCESS defined in gsl/errno.h as 0
}
//***And in int C :: integ :
for(itA=A.begin(); itA!=A.end(); ++itA)
{
for(itB=B.begin(); itB!=B.end(); ++itB)
{
void conso = itA->second.conso(itB->second, x);
}
}
//***With in class A :
void A :: conso(Group &prey, double x)
{
double conso=0;
conso = x * y * prey.gety();
}
Задача ещё не решена.