2013-05-25 19 views
3

在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)在上面的例子,我知道,也許命名不是最好的(Functionstd::function等等)。

任何想法如何以更聰明的方式做到這一點?該方法使用鍵的屬性在std::map中排序。這不是關於效率,而是關於乾淨的設計。

切片

不是問題的確切一部分,但在一個評論,切片中提到,在這裏你可以讀到它。

std::map unable to handle polymorphism?

我糾正了這個在我上面的代碼。

+4

if/else語句有什麼問題? – perreal

+0

我不認爲這會看起來更漂亮,是嗎? –

+2

@perreal,如果他有一個分段功能與大量的部分,然後如果語句將比二進制搜索慢......和一團糟。這種方法使構建分段函數變得相對容易。我認爲沃爾瑪墊子應該基本上與所呈現的一致。 –

回答

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); 
    } 
}; 
+0

@leemes好的謝謝,編輯。 –

+0

@leemes再次感謝。 –

+0

爲什麼你在這裏選擇'std :: map'有什麼特別的理由嗎?我接受了這個答案,因爲這樣可能有一個功能,例如在[-5,0]和[2,5)中定義(而不是[0,2]),並且完整區間的規範更加明確(在我的設計中,它是隱式給出的,除了' PiecewiseFunction'這是丟失)。 –

相關問題