00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_SFUNCTOR_INCLUDE
00013 #define MTL_SFUNCTOR_INCLUDE
00014
00015 #include <cmath>
00016 #include <boost/numeric/mtl/concept/std_concept.hpp>
00017 #include <boost/numeric/mtl/concept/magnitude.hpp>
00018 #include <boost/numeric/mtl/concept/static_functor.hpp>
00019
00020 namespace mtl { namespace sfunctor {
00021
00022 template <typename Value1, typename Value2>
00023 struct plus
00024 {
00025 typedef const Value1& first_argument_type;
00026 typedef const Value2& second_argument_type;
00027 typedef typename Addable<Value1, Value2>::result_type result_type;
00028
00029 static inline result_type apply(const Value1& v1, const Value2& v2)
00030 {
00031 return v1 + v2;
00032 }
00033
00034 result_type operator() (const Value1& v1, const Value2& v2) const
00035 {
00036 return v1 + v2;
00037 }
00038 };
00039
00040 template <typename Value1, typename Value2>
00041 struct minus
00042 {
00043 typedef const Value1& first_argument_type;
00044 typedef const Value2& second_argument_type;
00045 typedef typename Subtractable<Value1, Value2>::result_type result_type;
00046
00047 static inline result_type apply(const Value1& v1, const Value2& v2)
00048 {
00049 return v1 - v2;
00050 }
00051
00052 result_type operator() (const Value1& v1, const Value2& v2) const
00053 {
00054 return v1 - v2;
00055 }
00056 };
00057
00058 template <typename Value1, typename Value2>
00059 struct times
00060 {
00061 typedef const Value1& first_argument_type;
00062 typedef const Value2& second_argument_type;
00063 typedef typename Multiplicable<Value1, Value2>::result_type result_type;
00064
00065 static inline result_type apply(const Value1& v1, const Value2& v2)
00066 {
00067 return v1 * v2;
00068 }
00069
00070 result_type operator() (const Value1& v1, const Value2& v2) const
00071 {
00072 return v1 * v2;
00073 }
00074 };
00075
00076 template <typename Value1, typename Value2>
00077 struct divide
00078 {
00079 typedef const Value1& first_argument_type;
00080 typedef const Value2& second_argument_type;
00081 typedef typename Divisible<Value1, Value2>::result_type result_type;
00082
00083 static inline result_type apply(const Value1& v1, const Value2& v2)
00084 {
00085 return v1 / v2;
00086 }
00087
00088 result_type operator() (const Value1& v1, const Value2& v2) const
00089 {
00090 return v1 / v2;
00091 }
00092 };
00093
00094 template <typename Value1, typename Value2>
00095 struct assign
00096 {
00097 typedef Value1& first_argument_type;
00098 typedef const Value2& second_argument_type;
00099 typedef Value1& result_type;
00100
00101 static inline result_type apply(Value1& v1, const Value2& v2)
00102 {
00103 return v1= v2;
00104 }
00105
00106 result_type operator() (Value1& v1, const Value2& v2) const
00107 {
00108 return v1= v2;
00109 }
00110 };
00111
00112 template <typename Value1, typename Value2>
00113 struct plus_assign
00114 {
00115 typedef Value1& first_argument_type;
00116 typedef const Value2& second_argument_type;
00117 typedef Value1& result_type;
00118
00119 static inline result_type apply(Value1& v1, const Value2& v2)
00120 {
00121 return v1+= v2;
00122 }
00123
00124 result_type operator() (Value1& v1, const Value2& v2) const
00125 {
00126 return v1+= v2;
00127 }
00128 };
00129
00130 template <typename Value1, typename Value2>
00131 struct minus_assign
00132 {
00133 typedef Value1& first_argument_type;
00134 typedef const Value2& second_argument_type;
00135 typedef Value1& result_type;
00136
00137 static inline result_type apply(Value1& v1, const Value2& v2)
00138 {
00139 return v1-= v2;
00140 }
00141
00142 result_type operator() (Value1& v1, const Value2& v2) const
00143 {
00144 return v1-= v2;
00145 }
00146 };
00147
00148 template <typename Value1, typename Value2>
00149 struct times_assign
00150 {
00151 typedef Value1& first_argument_type;
00152 typedef const Value2& second_argument_type;
00153 typedef Value1& result_type;
00154
00155 static inline result_type apply(Value1& v1, const Value2& v2)
00156 {
00157 return v1*= v2;
00158 }
00159
00160 result_type operator() (Value1& v1, const Value2& v2) const
00161 {
00162 return v1*= v2;
00163 }
00164 };
00165
00166 template <typename Value1, typename Value2>
00167 struct divide_assign
00168 {
00169 typedef Value1& first_argument_type;
00170 typedef const Value2& second_argument_type;
00171 typedef Value1& result_type;
00172
00173 static inline result_type apply(Value1& v1, const Value2& v2)
00174 {
00175 return v1/= v2;
00176 }
00177
00178 result_type operator() (Value1& v1, const Value2& v2) const
00179 {
00180 return v1/= v2;
00181 }
00182 };
00183
00184
00185
00186 template <typename Value>
00187 struct identity
00188 {
00189 typedef const Value& argument_type;
00190 typedef Value result_type;
00191
00192 static inline result_type apply(const Value& v)
00193 {
00194 return v;
00195 }
00196
00197 result_type operator() (const Value& v) const
00198 {
00199 return v;
00200 }
00201 };
00202
00203
00204 template <typename Value>
00205 struct negate
00206 {
00207 typedef const Value& argument_type;
00208 typedef Value result_type;
00209
00210 static inline result_type apply(const Value& v) { return -v; }
00211 result_type operator() (const Value& v) const { return -v; }
00212 };
00213
00214
00215 template <typename Value>
00216 struct abs
00217 {
00218 typedef const Value& argument_type;
00219 typedef typename Magnitude<Value>::type result_type;
00220
00221 static inline result_type apply(const Value& v)
00222 {
00223 using std::abs;
00224 return abs(v);
00225 }
00226
00227 result_type operator() (const Value& v) { return apply(v); }
00228 };
00229
00230 template <typename Value>
00231 struct sqrt
00232 {
00233 typedef const Value& argument_type;
00234 typedef Value result_type;
00235
00236 static inline result_type apply(const Value& v)
00237 {
00238 using std::sqrt;
00239 return sqrt(v);
00240 }
00241
00242 result_type operator() (const Value& v) { return apply(v); }
00243 };
00244
00245 template <typename Value>
00246 struct square
00247 {
00248 typedef const Value& argument_type;
00249 typedef Value result_type;
00250
00251 static inline result_type apply(const Value& v)
00252 {
00253 return v * v;
00254 }
00255
00256 result_type operator() (const Value& v) { return apply(v); }
00257 };
00258
00260
00265 template <typename F, typename G>
00266 struct compose
00267 {
00268 typedef typename StaticUnaryFunctor<G>::argument_type argument_type;
00269 typedef typename StaticUnaryFunctor<F>::result_type result_type;
00270
00271 static inline result_type apply(argument_type x)
00272 {
00273 return F::apply(G::apply(x));
00274 }
00275
00276 result_type operator()(argument_type x) { return apply(x); }
00277 };
00278
00279
00281
00286 template <typename F, typename G>
00287 struct compose_first
00288 {
00289 typedef typename StaticUnaryFunctor<G>::argument_type first_argument_type;
00290 typedef typename StaticBinaryFunctor<F>::second_argument_type second_argument_type;
00291 typedef typename StaticBinaryFunctor<F>::result_type result_type;
00292
00293 static inline result_type apply(first_argument_type x, second_argument_type y)
00294 {
00295 return F::apply(G::apply(x), y);
00296 }
00297
00298 result_type operator()(first_argument_type x, second_argument_type y) { return apply(x, y); }
00299 };
00300
00301
00303
00308 template <typename F, typename G>
00309 struct compose_second
00310 {
00311 typedef typename StaticBinaryFunctor<F>::first_argument_type first_argument_type;
00312 typedef typename StaticUnaryFunctor<G>::argument_type second_argument_type;
00313 typedef typename StaticBinaryFunctor<F>::result_type result_type;
00314
00315 static inline result_type apply(first_argument_type x, second_argument_type y)
00316 {
00317 return F::apply(x, G::apply(y));
00318 }
00319
00320 result_type operator()(first_argument_type x, second_argument_type y) { return apply(x, y); }
00321 };
00322
00324
00331 template <typename F, typename G, typename H>
00332 struct compose_both
00333 {
00334 typedef typename StaticUnaryFunctor<G>::argument_type first_argument_type;
00335 typedef typename StaticUnaryFunctor<H>::argument_type second_argument_type;
00336 typedef typename StaticBinaryFunctor<F>::result_type result_type;
00337
00338 static inline result_type apply(first_argument_type x, second_argument_type y)
00339 {
00340 return F::apply(G::apply(x), H::apply(y));
00341 }
00342
00343 result_type operator()(first_argument_type x, second_argument_type y) { return apply(x, y); }
00344 };
00345
00347
00352 template <typename F, typename G>
00353 struct compose_binary
00354 {
00355 typedef typename StaticBinaryFunctor<G>::first_argument_type first_argument_type;
00356 typedef typename StaticBinaryFunctor<G>::second_argument_type second_argument_type;
00357 typedef typename StaticUnaryFunctor<F>::result_type result_type;
00358
00359 static inline result_type apply(first_argument_type x, second_argument_type y)
00360 {
00361 return F::apply(G::apply(x, y));
00362 }
00363
00364 result_type operator()(first_argument_type x, second_argument_type y) { return apply(x, y); }
00365 };
00366
00367
00369 template <typename T>
00370 struct l_2_2D
00371 : public compose_binary<sqrt<typename abs<T>::result_type>,
00372 compose_binary<abs<T>,
00373 compose_both<plus<T, T>,
00374 square<T>,
00375 square<T> >
00376 >
00377 >
00378 {};
00379
00380 }}
00381
00382 #endif // MTL_SFUNCTOR_INCLUDE