2013-05-25 3 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) 

:

x 같이, 함수의 전체 범위에있는 경우이 방법은 검사 부족
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); 
    } 
} 

[0, 20)에서 위의 예제에서 알 수 있습니다. 이름 지정이 가장 좋지 않습니다 (Functionstd::function 등등).

아이디어를 더 똑똑하게 만드는 방법은 무엇입니까? 이 접근법은 std::map에서 정렬 할 키의 속성을 사용합니다. 효율성에 관한 것이 아니라 깨끗한 디자인에 관한 것입니다. 슬라이스

질문

정확하지 않게 일부를 얇게 하지만 의견 중 하나는, 여기 당신이 그것에 대해 읽을 수있는 언급된다.

std::map unable to handle polymorphism?

나는 위의 내 코드에서이 문제를 수정했습니다.

+4

if/else 문에 무엇이 잘못 되었습니까? – perreal

+0

나는 이것이 더 예쁘게 보이지 않을 것이라고 생각합니까? –

+2

@perreal, 만약 그가 많은 부분을 가진 조각 별 함수를 가지고 있다면 if 문은 2 진 검색보다 느릴 것이다. 이 접근법은 조각 별 기능을 비교적 쉽게 구성 할 수있게합니다. 나는 월 - 오 - 매트는 기본적으로 제시된 것과 함께해야한다고 생각합니다. –

답변

1

현재 디자인의 문제는 특정 간격이나 점 (예 : 0)에 대해 정의되지 않은 것으로 간주되는 기능을 허용하지 않지만 이러한 기능이 많기 때문에 범위 지정 기능의 또 다른 동기가됩니다. 확인. 또한 FunctionFunction*으로 바꿔야하는데이 경우 구문에 몇 가지 다른 변경이 필요합니다.

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'을 선택하신 특별한 이유가 있습니까? 나는이 대답을 받아 들였다. 왜냐하면이 방법은 예를 들어 다음과 같은 기능을 가질 수 있기 때문이다.([0, 2]에 정의되어 있지 않다.) 완전한 인터벌의 지정은 더 명백하다. (나의 디자인에서 그것은 암묵적으로 주어진다. PiecewiseFunction'이 손실됩니다). –