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 #include "macros.hpp" 00026 00027 /***************************************************************************** 00028 ** Namespaces 00029 *****************************************************************************/ 00030 00031 namespace ecl { 00032 00033 /***************************************************************************** 00034 ** Interface [SmoothLinearSpline] 00035 *****************************************************************************/ 00045 class ecl_geometry_PUBLIC SmoothLinearSpline { 00046 public: 00053 SmoothLinearSpline() {} 00077 SmoothLinearSpline(const Array<double>& x_data, const Array<double>& y_data, double a_max) throw (DataException<int>); 00078 00079 virtual ~SmoothLinearSpline() {} 00080 00090 double operator()(const double &x) const ecl_assert_throw_decl(StandardException); 00101 double derivative(const double &x) const ecl_assert_throw_decl(StandardException); 00110 double dderivative(const double &x) const ecl_assert_throw_decl(StandardException); 00111 00120 const Array<double>& domain() const { return discretised_domain; } 00121 00122 /********************* 00123 * Static Constructor 00124 **********************/ 00136 static SmoothLinearSpline Interpolation(const Array<double>& x_data, const Array<double>& y_data, double a_max) throw (DataException<int>) 00137 { 00138 try { 00139 return SmoothLinearSpline(x_data, y_data, a_max); 00140 } catch ( DataException<int> &e ) { 00141 throw DataException<int>(LOC,e); 00142 } 00143 return SmoothLinearSpline(); // avoid a warning because of the rethrown exception. 00144 } 00145 00146 /****************************************** 00147 * Streaming 00148 *******************************************/ 00162 template <typename OutputStream> 00163 friend OutputStream& operator << (OutputStream &ostream, const SmoothLinearSpline &smooth_linear_spline); 00164 00165 private: 00166 Array<double> discretised_domain; // 2*N points (2 end points + 2*(N-1) corner points) 00167 Array<LinearFunction> segments; // N linear segments 00168 Array<QuinticPolynomial> corners; // N-1 corners 00169 }; 00170 00171 /***************************************************************************** 00172 ** Implementation [SmoothLinearSpline][Streaming] 00173 *****************************************************************************/ 00174 00175 template <typename OutputStream> 00176 OutputStream& operator << (OutputStream &ostream, const SmoothLinearSpline &smooth_linear_spline) { 00177 00178 ecl_compile_time_concept_check(StreamConcept<OutputStream>); 00179 00180 ostream << smooth_linear_spline.segments[0] << "\n"; 00181 for ( unsigned int i = 1; i < smooth_linear_spline.segments.size(); ++i ) { 00182 ostream << smooth_linear_spline.corners[i-1] << "\n"; 00183 ostream << smooth_linear_spline.segments[i] << "\n"; 00184 } 00185 ostream.flush(); 00186 return ostream; 00187 } 00188 00189 } // namespace ecl 00190 00191 #endif /* ECL_SMOOTH_LINEAR_SPLINE_HPP_ */