00001 00008 /***************************************************************************** 00009 ** Ifdefs 00010 *****************************************************************************/ 00011 00012 #ifndef ECL_SMOOTH_LINEAR_SPLINE_HPP_ 00013 #define ECL_SMOOTH_LINEAR_SPLINE_HPP_ 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include <ecl/config/macros.hpp> 00020 #include <ecl/concepts/streams.hpp> 00021 #include <ecl/containers/array.hpp> 00022 #include <ecl/exceptions/data_exception.hpp> 00023 #include <ecl/exceptions/standard_exception.hpp> 00024 #include "polynomial.hpp" 00025 00026 /***************************************************************************** 00027 ** Namespaces 00028 *****************************************************************************/ 00029 00030 namespace ecl { 00031 00032 /***************************************************************************** 00033 ** Interface [SmoothLinearSpline] 00034 *****************************************************************************/ 00044 class ECL_PUBLIC SmoothLinearSpline { 00045 public: 00052 SmoothLinearSpline() {} 00076 SmoothLinearSpline(const Array<double>& x_data, const Array<double>& y_data, double a_max) throw (DataException<int>); 00077 00078 virtual ~SmoothLinearSpline() {} 00079 00089 double operator()(const double &x) const ecl_assert_throw_decl(StandardException); 00100 double derivative(const double &x) const ecl_assert_throw_decl(StandardException); 00109 double dderivative(const double &x) const ecl_assert_throw_decl(StandardException); 00110 00119 const Array<double>& domain() const { return discretised_domain; } 00120 00121 /********************* 00122 * Static Constructor 00123 **********************/ 00135 static SmoothLinearSpline Interpolation(const Array<double>& x_data, const Array<double>& y_data, double a_max) throw (DataException<int>) 00136 { 00137 try { 00138 return SmoothLinearSpline(x_data, y_data, a_max); 00139 } catch ( DataException<int> &e ) { 00140 throw DataException<int>(LOC,e); 00141 } 00142 return SmoothLinearSpline(); // avoid a warning because of the rethrown exception. 00143 } 00144 00145 /****************************************** 00146 * Streaming 00147 *******************************************/ 00161 template <typename OutputStream> 00162 friend OutputStream& operator << (OutputStream &ostream, const SmoothLinearSpline &smooth_linear_spline); 00163 00164 private: 00165 Array<double> discretised_domain; // 2*N points (2 end points + 2*(N-1) corner points) 00166 Array<LinearFunction> segments; // N linear segments 00167 Array<QuinticPolynomial> corners; // N-1 corners 00168 }; 00169 00170 /***************************************************************************** 00171 ** Implementation [SmoothLinearSpline][Streaming] 00172 *****************************************************************************/ 00173 00174 template <typename OutputStream> 00175 OutputStream& operator << (OutputStream &ostream, const SmoothLinearSpline &smooth_linear_spline) { 00176 00177 ecl_compile_time_concept_check(StreamConcept<OutputStream>); 00178 00179 ostream << smooth_linear_spline.segments[0] << "\n"; 00180 for ( unsigned int i = 1; i < smooth_linear_spline.segments.size(); ++i ) { 00181 ostream << smooth_linear_spline.corners[i] << "\n"; 00182 ostream << smooth_linear_spline.segments[i] << "\n"; 00183 } 00184 ostream.flush(); 00185 return ostream; 00186 } 00187 00188 } // namespace ecl 00189 00190 #endif /* ECL_SMOOTH_LINEAR_SPLINE_HPP_ */