I'm moving from a class hierarchy for solving ODE to a class to solve a system of ODEs.
In my implementation to work with a single function, I use the following to store my function:
std::function<const Type(const Type, const Type)> numericalFunction
I have a wrapper to evaluate the numerical function:
Type f (Type t, Type u) const noexcept { return numericalFunction(t,u); }
Now I'm moving to solving a system of equations, so I need to store multiple functions. I tried to store the set of functions using a std::vector
as given below:
std::vector<std::function<const Type(const Type,const Type)>> numericalFunction;
I want to be able to use the same syntax as used in the above question. That is,
f[0](12,32);
should execute numericalFunction.at(0)(12,32);
dfdt[0](t, u);
should execute (numericalFunction.at(0)(t, u+eps) - numericalFunction.at(0)(t, u))/eps;
How can I write the code to allow such a syntax?
EDIT I have a problem .. now I need to change the function
std::vector<std::function<const Type(const Type,const Type)>> numericalFunction;
becames :
std::vector<std::function<const Type(const Type,const std::vector<Type>)>> numericalFunction;
and the derivative class doesn't works
You can store a collection of functions as:
std::vector<std::function<const Type(const Type t, const Type u)>> numericalFunList;
Your equivalent function to obtain the correct function will be:
const Type f(size_t idx, const Type t, const Type u) { return numericalFunList.at(idx)(t,u); }
The std::vector
is internally a dynamic array. This gives each function an index starting from 0
till numericalFunList.size() - 1
. You can identify each function by its index in the vector.
EDIT1:
The OP prefers to use the following syntax: f[0](arg1, arg2);
The above can be easily achieved: numericalFunList[0](1.2, 5.9);
If f
is needed for clarity (for mathematicians; programmers would hate it),
auto& f = numericalFunList;
f[0](10.9, 2.4);
As a tip, consider not using f
as a variable name globally. If f
is the preferred, use auto& f = numericalFunList
to do it for you.
EDIT2:
For the new syntax requirements, you need to use two classes each with one operator overload: one to store the set of derivatives with []
operator overloaded and the other to compute the derivative with ()
operator overloaded.
typedef long double Type;
constexpr Type eps = 1E-12;
using analysisFunction = std::function<const Type(const Type, const Type)>;
class derivatives {
private:
class derivative;
public:
derivatives(std::vector<analysisFunction>& p_fList) { fList = &p_fList; };
derivative operator[](int index) {
return derivative((*fList).at(index));
}
private:
class derivative {
public:
derivative(analysisFunction& p_f) { f = &p_f; }
Type operator()(Type t, Type u) {
return (((*f)(t, u + eps)) - ((*f)(t,u)))/eps;
}
private:
analysisFunction *f;
};
std::vector<analysisFunction> *fList; //dangling pointer
};
Example usage
int main ()
{
std::vector <analysisFunction> numericalFunctions;
auto& f = numericalFunctions;
f.push_back([](Type t, Type u)->Type { return u*u; });
std::cout << std::setprecision(16);
std::cout << f[0](5.0, 10.0) << '\n';
derivatives dfdt(f);
std::cout << dfdt[0](5.0, 10.0);
return 0;
}
Testing code: GeeksForGeeks Online IDE
Note: fList
is a dangling pointer. There are several ways to deal with it. You can leave it as it is if you can guarantee that the referenced object wouldn't be deallocated or you can maintain a copy in the object (which would cost memory and CPU).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.