00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_SPLINE_H
00051 #define LASS_GUARDIAN_OF_INCLUSION_NUM_SPLINE_H
00052
00053 #include "num_common.h"
00054 #include "../stde/extended_iterator.h"
00055
00056 namespace lass
00057 {
00058 namespace num
00059 {
00060
00061 template
00062 <
00063 typename ScalarType,
00064 typename DataType
00065 >
00066 class Spline
00067 {
00068 public:
00069
00070 typedef ScalarType TScalar;
00071 typedef DataType TData;
00072
00073 class ControlRange
00074 {
00075 public:
00076 ControlRange(TScalar begin, TScalar end): begin_(begin), end_(end) {}
00077 const TScalar begin() const { return begin_; }
00078 const TScalar end() const { return end_; }
00079 private:
00080 TScalar begin_;
00081 TScalar end_;
00082 };
00083
00084 virtual ~Spline() {}
00085
00086 virtual const TData operator()(TScalar iX) const = 0;
00087 virtual const TData derivative(TScalar iX) const = 0;
00088 virtual const TData derivative2(TScalar iX) const = 0;
00089 virtual const TData integral(TScalar iA, TScalar iB) const = 0;
00090
00091 virtual const bool isEmpty() const = 0;
00092 virtual const ControlRange controlRange() const = 0;
00093 };
00094
00095
00096
00097
00098
00099 #pragma LASS_TODO("below are data traits that should move to a seperate header when appropriate, [Bramz]")
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 template <typename SequenceType>
00130 struct DataTraitsSequence
00131 {
00132 typedef SequenceType TData;
00133 typedef typename SequenceType::value_type TScalar;
00134 static size_t dimension(const TData& iY) { return std::distance(iY.begin(), iY.end()); }
00135 static void zero(TData& ioY, size_t iDim) { ioY = TData(iDim); }
00136 static TScalar get(const TData& iY, size_t iIndex) { return *stde::next(iY.begin(), iIndex); }
00137 static void set(TData& ioY, size_t iIndex, TScalar iV) { *stde::next(ioY.begin(), iIndex) = iV; }
00138 static void scale(TData& ioAcc, TScalar iS)
00139 {
00140 std::transform(ioAcc.begin(), ioAcc.end(), ioAcc.begin(), std::bind2nd(std::multiplies<TScalar>(), iS));
00141 }
00142 static void multiplyAccumulate(TData& ioAcc, const TData& iY, TScalar iS)
00143 {
00144 std::transform(ioAcc.begin(), ioAcc.end(), iY.begin(), ioAcc.begin(), Mac(iS));
00145 }
00146 private:
00147 class Mac
00148 {
00149 TScalar s_;
00150 public:
00151 Mac(TScalar iS): s_(iS) {}
00152 TScalar operator()(TScalar iA, TScalar iB) const { return iA + s_ * iB; }
00153 };
00154 };
00155
00156
00157
00158 template <typename ScalarType>
00159 struct DataTraitsScalar
00160 {
00161 typedef ScalarType TData;
00162 typedef ScalarType TScalar;
00163 static size_t dimension(TScalar iY) { return 1; }
00164 static void zero(TScalar& ioY, size_t iDim) { ioY = TScalar(); }
00165 static TScalar get(TScalar iY, size_t iIndex) { return iY; }
00166 static void set(TScalar& ioY, size_t iIndex, TScalar iV) { ioY = iV; }
00167 static void scale(TScalar& ioAcc, TScalar iS) { ioAcc *= iS; }
00168 static void multiplyAccumulate(TScalar& ioAcc, TScalar iY, TScalar iS) { ioAcc += iY * iS; }
00169 };
00170
00171
00172
00173
00174 template <typename DataType>
00175 struct DataTraitsDynamicVector
00176 {
00177 typedef DataType TData;
00178 typedef typename DataType::TValue TScalar;
00179 static size_t dimension(const TData& iY) { return iY.size(); }
00180 static void zero(TData& ioY, size_t iDim) { ioY = TData(iDim); }
00181 static TScalar get(const TData& iY, size_t iIndex) { return iY[iIndex]; }
00182 static void set(TData& ioY, size_t iIndex, TScalar iV) { ioY[iIndex] = iV; }
00183 static void scale(TData& ioAcc, TScalar iS) { ioAcc *= iS; }
00184 static void multiplyAccumulate(TData& ioAcc, const TData& iY, TScalar iS) { ioAcc += iY * iS; }
00185 };
00186
00187
00188
00189 template <typename DataType>
00190 struct DataTraitsStaticVector
00191 {
00192 typedef DataType TData;
00193 typedef typename DataType::TValue TScalar;
00194 static size_t dimension(const TData& ) { return TData::dimension; }
00195 static void zero(TData& ioY, size_t ) { ioY = TData(); }
00196 static TScalar get(const TData& iY, size_t iIndex) { return iY[iIndex]; }
00197 static void set(TData& ioY, size_t iIndex, TScalar iV) { ioY[iIndex] = iV; }
00198 static void scale(TData& ioAcc, TScalar iS) { ioAcc *= iS; }
00199 static void multiplyAccumulate(TData& ioAcc, const TData& iY, TScalar iS) { ioAcc += iY * iS; }
00200 };
00201
00202
00203 }
00204
00205 }
00206
00207 #endif
00208
00209