[英]Defining a piecewise function (e.g. polynomial)
What's the best way to define a piecewise function in C++, needed for example when working with splines? 在C ++中定义分段函数的最佳方法是什么,例如在使用样条函数时需要?
Example: 例:
f1(x) if x from [0, 5)
f(x) = f2(x) if x from [5, 10)
f3(x) if x from [10, 20)
My current approach looks like this: 我目前的方法如下:
class Function
{
virtual double operator()( double x ) = 0;
}
class SomeFun : public Function
{
// implements operator() in a meaningful way
}
class PiecewiseFunction : public Function
{
// holds functions along with the upper bound of the interval
// for which they are defined
// e.g. (5, f1), (10, f2), (20, f3)
std::map< double, Function* > fns;
virtual double operator()( double x )
{
// search for the first upper interval boundary which is greater than x
auto it = fns.lower_bound( x );
// ... and evaluate the underlying function.
return *(it->second)(x);
}
}
This approach lacks of checking if x
is in the overall bounds of the function, like [0, 20) in the example above, I know, and perhaps the naming is not the best ( Function
vs. std::function
and so on). 这种方法缺乏检查
x
是否在函数的整体范围内,如上例中的[0,20],我知道,也许命名不是最好的( Function
与std::function
等) 。
Any ideas how to do that in a smarter way? 任何想法如何以更智能的方式做到这一点? The approach uses the property of the keys to be sorted in a
std::map
. 该方法使用键的属性在
std::map
进行排序。 It's not about efficiency, it's more about a clean design. 这不是关于效率,而是关于清洁设计。
SLICING SLICING
Not exactly part of the question, but in one of the comments, slicing is mentioned, here you can read about it. 不完全是问题的一部分,但在其中一条评论中,提到了切片 ,在这里你可以阅读它。
std::map unable to handle polymorphism? std :: map无法处理多态?
I corrected this in my code above. 我在上面的代码中更正了这一点。
An issue with the current design it doesn't allow for functions that are most naturally thought of as being undefined over certain intervals or points (like 0), but there are plenty of these, so it's another motivation for range-checking. 当前设计的一个问题是它不允许在某些间隔或点(如0)上最自然地被认为是未定义的函数,但是有很多这些函数,因此它是范围检查的另一个动机。 Also
Function
needs to be replaced with Function*
which necessitates some other changes in syntax. 此外,
Function
需要替换为Function*
,这需要对语法进行一些其他更改。
class PiecewiseFunction : public Function
{
//Holds function and interval
std::map< std::pair<double,double>, Function* > fns;
double operator()( double x )
{
auto iter = std::find_if(fns.cbegin(), fns.cend(),
[=](const std::pair< std::pair<double,double>, Function*>& fn)
{
return x>=fn.first.first && x<fn.first.second;
});
if (iter == fns.end()) throw... //Or something
return (*iter->second)(x);
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.