在C ++中定义分段函数的最佳方法是什么,例如在使用样条函数时需要?
示例:
f1(x) if x from [0, 5)
f(x) = f2(x) if x from [5, 10)
f3(x) if x from [10, 20)
我目前的做法如下:
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);
}
}
这种方法缺乏检查x
是否在函数的整体范围内,如上例中的[0,20],我知道,也许命名不是最好的({{1} }与Function
等等。)
任何想法如何以更智能的方式做到这一点?该方法使用键的属性在std::function
中进行排序。这不是关于效率,而是关于清洁设计。
SLICING
不完全是问题的一部分,但在其中一条评论中,提到了切片,在这里你可以阅读它。
std::map unable to handle polymorphism?
我在上面的代码中对此进行了更正。
答案 0 :(得分:1)
当前设计的一个问题是它不允许在某些间隔或点(如0)中最自然地被认为是未定义的函数,但是有很多这些函数,所以它是范围检查的另一个动机。另外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);
}
};