$search
00001 00008 /***************************************************************************** 00009 ** Ifdefs 00010 *****************************************************************************/ 00011 00012 #ifndef ECL_GEOMETRY_CUBIC_SPLINE_HPP_ 00013 #define ECL_GEOMETRY_CUBIC_SPLINE_HPP_ 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include "polynomial.hpp" 00020 #include <ecl/config/macros.hpp> 00021 #include <ecl/concepts/macros.hpp> 00022 #include <ecl/concepts/streams.hpp> 00023 #include <ecl/concepts/containers.hpp> 00024 #include <ecl/containers/array.hpp> 00025 #include <ecl/exceptions/standard_exception.hpp> 00026 #include <ecl/utilities/blueprints.hpp> 00027 00028 /***************************************************************************** 00029 ** Namespaces 00030 *****************************************************************************/ 00031 00032 namespace ecl { 00033 00034 /***************************************************************************** 00035 ** Forward Declarations 00036 *****************************************************************************/ 00037 00038 class CubicSpline; 00039 00040 namespace blueprints { 00041 00042 class C2CubicSpline; 00043 class DerivativeHeuristicCubicSpline; 00044 00045 } // namespace blueprints 00046 00047 /***************************************************************************** 00048 ** BluePrintFactory 00049 *****************************************************************************/ 00058 template<> 00059 class ECL_PUBLIC BluePrintFactory< CubicSpline > { 00060 public: 00072 static blueprints::C2CubicSpline Natural(const Array<double>& x_set, const Array<double>& y_set); 00085 static blueprints::C2CubicSpline ContinuousDerivatives( 00086 const Array<double>& x_set, const Array<double>& y_set, const double ydot_0, const double ydot_f); 00100 static blueprints::DerivativeHeuristicCubicSpline DerivativeHeuristic( 00101 const Array<double>& x_set, const Array<double>& y_set, const double ydot_0, const double ydot_f); 00102 00103 virtual ~BluePrintFactory() {} 00104 }; 00105 00106 /***************************************************************************** 00107 ** Interface [CubicSpline] 00108 *****************************************************************************/ 00123 class ECL_PUBLIC CubicSpline : public BluePrintFactory< CubicSpline > { 00124 public: 00125 /****************************************** 00126 ** Constructors 00127 *******************************************/ 00133 CubicSpline () {}; 00160 template<typename Derived> 00161 CubicSpline(const BluePrint< Derived > &blueprint) { 00162 blueprint.implementApply(*this); 00163 } 00164 virtual ~CubicSpline () {}; 00165 00166 /****************************************** 00167 ** Access 00168 *******************************************/ 00169 friend class blueprints::DerivativeHeuristicCubicSpline; 00170 friend class blueprints::C2CubicSpline; 00179 double operator()(const double &x) const ecl_assert_throw_decl(StandardException); 00188 double derivative(double x) const ecl_assert_throw_decl(StandardException); 00197 double dderivative(double x) const ecl_assert_throw_decl(StandardException); 00198 00206 const Array<double>& domain() { return discretised_domain; } 00215 const Array<CubicPolynomial>& polynomials() { return cubic_polynomials; } 00216 00217 /****************************************** 00218 ** Streaming 00219 *******************************************/ 00231 template <typename OutputStream> 00232 friend OutputStream& operator << (OutputStream &ostream, const CubicSpline &cubic_spline); 00233 00234 private: 00235 Array<double> discretised_domain; // N+1 x_i's 00236 // Would normally use pointers here, but the polynomials have fixed storage 00237 // size, the copy cost is small and the access times will be faster this way. 00238 Array<CubicPolynomial> cubic_polynomials; // N polynomials 00239 }; 00240 00241 /***************************************************************************** 00242 ** Implementation [CubicSpline][Streaming] 00243 *****************************************************************************/ 00244 00245 template <typename OutputStream> 00246 OutputStream& operator << (OutputStream &ostream, const CubicSpline &cubic_spline) { 00247 00248 ecl_compile_time_concept_check(StreamConcept<OutputStream>); 00249 00250 for ( unsigned int i = 0; i < cubic_spline.cubic_polynomials.size(); ++i ) { 00251 ostream << cubic_spline.cubic_polynomials[i] << "\n"; 00252 } 00253 ostream.flush(); 00254 return ostream; 00255 } 00256 00257 /***************************************************************************** 00258 ** BluePrints 00259 *****************************************************************************/ 00260 00261 namespace blueprints { 00262 00263 /***************************************************************************** 00264 ** Interface [C2CubicSpline] 00265 *****************************************************************************/ 00266 00276 class ECL_PUBLIC C2CubicSpline : public ecl::BluePrint<C2CubicSpline> { 00277 public: 00281 typedef ecl::CubicSpline base_type; 00287 C2CubicSpline() {}; 00288 00301 C2CubicSpline(const ecl::Array<double>& x_set, const ecl::Array<double>& y_set, 00302 const double ydot_0, const double ydot_f) ecl_assert_throw_decl(ecl::StandardException); 00303 00304 virtual ~C2CubicSpline() {}; 00318 C2CubicSpline(const ecl::Array<double>& x_set, const ecl::Array<double>& y_set) ecl_assert_throw_decl(ecl::StandardException); 00319 00327 ecl::CubicSpline instantiate(); 00328 00336 void apply(ecl::CubicSpline& spline) const; 00337 00338 private: 00339 ecl::Array<double> x_data; 00340 ecl::Array<double> y_data; 00341 ecl::Array<double> yddot_data; 00342 }; 00343 00344 /***************************************************************************** 00345 ** Interface [DerivativeHeuristicCubicSpline] 00346 *****************************************************************************/ 00347 00362 class ECL_PUBLIC DerivativeHeuristicCubicSpline : public ecl::BluePrint<DerivativeHeuristicCubicSpline> { 00363 public: 00367 typedef ecl::CubicSpline base_type; 00373 DerivativeHeuristicCubicSpline() {}; 00374 00388 DerivativeHeuristicCubicSpline(const ecl::Array<double>& x_set, const ecl::Array<double>& y_set, 00389 const double ydot_0, const double ydot_f) ecl_assert_throw_decl(ecl::StandardException); 00390 00391 virtual ~DerivativeHeuristicCubicSpline() {}; 00399 ecl::CubicSpline instantiate(); 00400 00408 void apply(ecl::CubicSpline& spline) const; 00409 00410 private: 00411 ecl::Array<double> x_data; 00412 ecl::Array<double> y_data; 00413 ecl::Array<double> ydot_data; 00414 }; 00415 00416 } // namespace blueprints 00417 } // namespace ecl 00418 00419 #endif /* ECL_GEOMETRY_CUBIC_SPLINE_HPP_ */