У меня есть класс для определения правых частей дифференциального уравнения:
этот класс предоставляет метод для вычисления функции rhs и ее производного
функция хранится в векторном контейнере, таким образом, класс также подходит для системы дифференциальных уравнений.
здесь интерфейс, в котором определяется метод, который я хотел бы изменить
template <typename Type = double>
class rhsODEProblem {
using analysisFunction = std::function<const Type(const Type, const std::valarray<Type>)>;public:rhsODEProblem(const std::vector<std::function<const Type(const Type,const std::valarray<Type>)>> numfun ,
const std::vector<std::function<const Type(const Type,const Type)>> exactfun ,
const Type,const Type,const Type,const std::valarray<Type>,const std::string ) noexcept ;rhsODEProblem(const std::vector<std::function<const Type(const Type,const std::valarray<Type>)>> numfun,
const Type, const Type, const Type, const std::valarray<Type> ) noexcept ;virtual ~rhsODEProblem() = default ;
rhsODEProblem(const rhsODEProblem &) = default ;
rhsODEProblem(rhsODEProblem&& ) = default ;
rhsODEProblem& operator=(const rhsODEProblem&) = default ;
rhsODEProblem& operator=(rhsODEProblem&& ) = default ;const std::vector<std::function<const Type(const Type,const std::valarray<Type>)>> numericalFunction ;
const std::vector<std::function<const Type(const Type,const Type)>> analiticalFunction ;const std::vector<analysisFunction>& f = numericalFunction ;const auto dfdt(std::size_t indx , const Type t , const std::valarray<Type> u) {
return (f[indx](t, u+eps )-f[indx](t,u))/eps ;
}auto setRhs (const std::vector<
std::function<const Type(const Type,const std::valarray<Type>)>> numfun) noexcept
{
for(auto i=0 ; i < numfun.size() ; i++)
{
numericalFunction.push_back(numfun.at(i)) ;
}
}
auto setExact(const std::vector<std::function<const Type(const Type,const Type)>> exactfun) noexcept
{
for(auto i=0 ; i < exactfun.size(); i++)
{
analiticalFunction.push_back(exactfun.at(i));
}
}
auto solveExact() noexcept ;
const Type t0() const noexcept { return _t0 ;}
const Type tf() const noexcept { return _tf ;}
const Type dt() const noexcept { return _dt ;}
const std::valarray<Type> u0() const noexcept { return _u0 ;}
const std::string fname () const noexcept { return filename ;}//---
private:
Type _t0 ; // start time
Type _tf ; // final time
Type _dt ; // time-step
std::valarray<Type> _u0 ; // iv
std::string filename ;
Type eps = 1e-12 ;};
Я хотел бы изменить метод dfdt таким образом, чтобы я мог вызвать его, используя следующий синтаксис dfdt[index]( t , u_valarray )
вместо dfdt(index, t, u_valarray )
Каким образом я могу изменить этот метод?
РЕДАКТИРОВАТЬ спасибо за ваш ответ, так что в моем случае это будет:
foo_helper(foo &, int index);
operator()(int n, Type t, std::valarray<Type> u );
право ?
РЕДАКТИРОВАТЬ нет, я не понял суть. Я написал :
class dfdx {
public:
dfdx( rhsODEProblem<Type> &r , int index_ ) : index{index_ } {}
void operator()(Type t, std::valarray<Type> u){
return (f[index](t, u + eps )-f[index](t,u))/eps ;
}
int index ;
};
dfdx operator[](std::size_t index) {
return dfdx(*this, index);
}
тогда я называю это так:
rhs.dfdx[j](t , uOld) )
но я получил ошибку:
BackwardEulerSolver.H:114:50: error: invalid use of ‘class mg::numeric::odesystem::rhsODEProblem<double>::dfdx’
( 1- dt() * rhs.dfdx[j](t , uOld) ) ;
~~~~^~~~
Я хотел бы изменить метод dfdt таким образом, чтобы я мог вызвать его, используя следующий синтаксис
dfdt[index]( t , u_valarray )
вместоdfdt(index, t, u_valarray )
Каким образом я могу изменить этот метод?
Вы можете сделать это, перегружая оператор индекса ([]
) и возвращает внутренний вспомогательный тип, который перегружает оператор вызова (()
).
Вот эскиз:
class foo {
class foo_helper;
friend class foo_helper;
public:
class foo_helper {
public:
foo_helper(foo &, int index);
void operator()(int n, double y);
};
foo_helper operator[](int index) {
return foo_helper(*this, index);
}
};
Других решений пока нет …