![]() |
Blender V2.61 - r43446
|
00001 00002 /***************************************************************************** 00003 * \file 00004 * class for automatic differentiation on scalar values and 1st 00005 * derivatives . 00006 * 00007 * \author 00008 * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven 00009 * 00010 * \version 00011 * ORO_Geometry V0.2 00012 * 00013 * \par Note 00014 * VC6++ contains a bug, concerning the use of inlined friend functions 00015 * in combination with namespaces. So, try to avoid inlined friend 00016 * functions ! 00017 * 00018 * \par History 00019 * - $log$ 00020 * 00021 * \par Release 00022 * $Name: $ 00023 ****************************************************************************/ 00024 00025 #ifndef Rall1D_H 00026 #define Rall1D_H 00027 #include <assert.h> 00028 #include "utility.h" 00029 00030 namespace KDL { 00047 template <typename T,typename V=T,typename S=T> 00048 class Rall1d 00049 { 00050 public: 00051 typedef T valuetype; 00052 typedef V gradienttype; 00053 typedef S scalartype; 00054 public : 00055 T t; 00056 V grad; 00057 public : 00058 INLINE Rall1d() {} 00059 00060 T value() const { 00061 return t; 00062 } 00063 V deriv() const { 00064 return grad; 00065 } 00066 00067 explicit INLINE Rall1d(typename TI<T>::Arg c) 00068 {t=T(c);SetToZero(grad);} 00069 00070 INLINE Rall1d(typename TI<T>::Arg tn, typename TI<V>::Arg afg):t(tn),grad(afg) {} 00071 00072 INLINE Rall1d(const Rall1d<T,V,S>& r):t(r.t),grad(r.grad) {} 00073 //if one defines this constructor, it's better optimized then the 00074 //automatically generated one ( this one set's up a loop to copy 00075 // word by word. 00076 00077 INLINE T& Value() { 00078 return t; 00079 } 00080 00081 INLINE V& Gradient() { 00082 return grad; 00083 } 00084 00085 INLINE static Rall1d<T,V,S> Zero() { 00086 Rall1d<T,V,S> tmp; 00087 SetToZero(tmp); 00088 return tmp; 00089 } 00090 INLINE static Rall1d<T,V,S> Identity() { 00091 Rall1d<T,V,S> tmp; 00092 SetToIdentity(tmp); 00093 return tmp; 00094 } 00095 00096 INLINE Rall1d<T,V,S>& operator =(S c) 00097 {t=c;SetToZero(grad);return *this;} 00098 00099 INLINE Rall1d<T,V,S>& operator =(const Rall1d<T,V,S>& r) 00100 {t=r.t;grad=r.grad;return *this;} 00101 00102 INLINE Rall1d<T,V,S>& operator /=(const Rall1d<T,V,S>& rhs) 00103 { 00104 grad = LinComb(rhs.t,grad,-t,rhs.grad) / (rhs.t*rhs.t); 00105 t /= rhs.t; 00106 return *this; 00107 } 00108 00109 INLINE Rall1d<T,V,S>& operator *=(const Rall1d<T,V,S>& rhs) 00110 { 00111 LinCombR(rhs.t,grad,t,rhs.grad,grad); 00112 t *= rhs.t; 00113 return *this; 00114 } 00115 00116 INLINE Rall1d<T,V,S>& operator +=(const Rall1d<T,V,S>& rhs) 00117 { 00118 grad +=rhs.grad; 00119 t +=rhs.t; 00120 return *this; 00121 } 00122 00123 INLINE Rall1d<T,V,S>& operator -=(const Rall1d<T,V,S>& rhs) 00124 { 00125 grad -= rhs.grad; 00126 t -= rhs.t; 00127 return *this; 00128 } 00129 00130 INLINE Rall1d<T,V,S>& operator /=(S rhs) 00131 { 00132 grad /= rhs; 00133 t /= rhs; 00134 return *this; 00135 } 00136 00137 INLINE Rall1d<T,V,S>& operator *=(S rhs) 00138 { 00139 grad *= rhs; 00140 t *= rhs; 00141 return *this; 00142 } 00143 00144 INLINE Rall1d<T,V,S>& operator +=(S rhs) 00145 { 00146 t += rhs; 00147 return *this; 00148 } 00149 00150 INLINE Rall1d<T,V,S>& operator -=(S rhs) 00151 { 00152 t -= rhs; 00153 return *this; 00154 } 00155 00156 00157 00158 // = operators 00159 /* gives warnings on cygwin 00160 00161 template <class T2,class V2,class S2> 00162 friend INLINE Rall1d<T2,V2,S2> operator /(const Rall1d<T2,V2,S2>& lhs,const Rall1d<T2,V2,S2>& rhs); 00163 00164 friend INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs); 00165 friend INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs); 00166 friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs); 00167 friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& arg); 00168 friend INLINE Rall1d<T,V,S> operator *(S s,const Rall1d<T,V,S>& v); 00169 friend INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& v,S s); 00170 friend INLINE Rall1d<T,V,S> operator +(S s,const Rall1d<T,V,S>& v); 00171 friend INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& v,S s); 00172 friend INLINE Rall1d<T,V,S> operator -(S s,const Rall1d<T,V,S>& v); 00173 friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& v,S s); 00174 friend INLINE Rall1d<T,V,S> operator /(S s,const Rall1d<T,V,S>& v); 00175 friend INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& v,S s); 00176 00177 // = Mathematical functions that operate on Rall1d objects 00178 friend INLINE Rall1d<T,V,S> exp(const Rall1d<T,V,S>& arg); 00179 friend INLINE Rall1d<T,V,S> log(const Rall1d<T,V,S>& arg); 00180 friend INLINE Rall1d<T,V,S> sin(const Rall1d<T,V,S>& arg); 00181 friend INLINE Rall1d<T,V,S> cos(const Rall1d<T,V,S>& arg); 00182 friend INLINE Rall1d<T,V,S> tan(const Rall1d<T,V,S>& arg); 00183 friend INLINE Rall1d<T,V,S> sinh(const Rall1d<T,V,S>& arg); 00184 friend INLINE Rall1d<T,V,S> cosh(const Rall1d<T,V,S>& arg); 00185 friend INLINE Rall1d<T,V,S> sqr(const Rall1d<T,V,S>& arg); 00186 friend INLINE Rall1d<T,V,S> pow(const Rall1d<T,V,S>& arg,double m) ; 00187 friend INLINE Rall1d<T,V,S> sqrt(const Rall1d<T,V,S>& arg); 00188 friend INLINE Rall1d<T,V,S> atan(const Rall1d<T,V,S>& x); 00189 friend INLINE Rall1d<T,V,S> hypot(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x); 00190 friend INLINE Rall1d<T,V,S> asin(const Rall1d<T,V,S>& x); 00191 friend INLINE Rall1d<T,V,S> acos(const Rall1d<T,V,S>& x); 00192 friend INLINE Rall1d<T,V,S> abs(const Rall1d<T,V,S>& x); 00193 friend INLINE S Norm(const Rall1d<T,V,S>& value) ; 00194 friend INLINE Rall1d<T,V,S> tanh(const Rall1d<T,V,S>& arg); 00195 friend INLINE Rall1d<T,V,S> atan2(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x); 00196 00197 // = Utility functions to improve performance 00198 00199 friend INLINE Rall1d<T,V,S> LinComb(S alfa,const Rall1d<T,V,S>& a, 00200 const T& beta,const Rall1d<T,V,S>& b ); 00201 00202 friend INLINE void LinCombR(S alfa,const Rall1d<T,V,S>& a, 00203 const T& beta,const Rall1d<T,V,S>& b,Rall1d<T,V,S>& result ); 00204 00205 // = Setting value of a Rall1d object to 0 or 1 00206 00207 friend INLINE void SetToZero(Rall1d<T,V,S>& value); 00208 friend INLINE void SetToOne(Rall1d<T,V,S>& value); 00209 // = Equality in an eps-interval 00210 friend INLINE bool Equal(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x,double eps); 00211 */ 00212 }; 00213 00214 00215 template <class T,class V,class S> 00216 INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs) 00217 { 00218 return Rall1d<T,V,S>(lhs.t/rhs.t,(lhs.grad*rhs.t-lhs.t*rhs.grad)/(rhs.t*rhs.t)); 00219 } 00220 00221 template <class T,class V,class S> 00222 INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs) 00223 { 00224 return Rall1d<T,V,S>(lhs.t*rhs.t,rhs.t*lhs.grad+lhs.t*rhs.grad); 00225 } 00226 00227 template <class T,class V,class S> 00228 INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs) 00229 { 00230 return Rall1d<T,V,S>(lhs.t+rhs.t,lhs.grad+rhs.grad); 00231 } 00232 00233 00234 template <class T,class V,class S> 00235 INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs) 00236 { 00237 return Rall1d<T,V,S>(lhs.t-rhs.t,lhs.grad-rhs.grad); 00238 } 00239 00240 template <class T,class V,class S> 00241 INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& arg) 00242 { 00243 return Rall1d<T,V,S>(-arg.t,-arg.grad); 00244 } 00245 00246 template <class T,class V,class S> 00247 INLINE Rall1d<T,V,S> operator *(S s,const Rall1d<T,V,S>& v) 00248 { 00249 return Rall1d<T,V,S>(s*v.t,s*v.grad); 00250 } 00251 00252 template <class T,class V,class S> 00253 INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& v,S s) 00254 { 00255 return Rall1d<T,V,S>(v.t*s,v.grad*s); 00256 } 00257 00258 template <class T,class V,class S> 00259 INLINE Rall1d<T,V,S> operator +(S s,const Rall1d<T,V,S>& v) 00260 { 00261 return Rall1d<T,V,S>(s+v.t,v.grad); 00262 } 00263 00264 template <class T,class V,class S> 00265 INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& v,S s) 00266 { 00267 return Rall1d<T,V,S>(v.t+s,v.grad); 00268 } 00269 00270 template <class T,class V,class S> 00271 INLINE Rall1d<T,V,S> operator -(S s,const Rall1d<T,V,S>& v) 00272 { 00273 return Rall1d<T,V,S>(s-v.t,-v.grad); 00274 } 00275 00276 template <class T,class V,class S> 00277 INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& v,S s) 00278 { 00279 return Rall1d<T,V,S>(v.t-s,v.grad); 00280 } 00281 00282 template <class T,class V,class S> 00283 INLINE Rall1d<T,V,S> operator /(S s,const Rall1d<T,V,S>& v) 00284 { 00285 return Rall1d<T,V,S>(s/v.t,(-s*v.grad)/(v.t*v.t)); 00286 } 00287 00288 template <class T,class V,class S> 00289 INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& v,S s) 00290 { 00291 return Rall1d<T,V,S>(v.t/s,v.grad/s); 00292 } 00293 00294 00295 template <class T,class V,class S> 00296 INLINE Rall1d<T,V,S> exp(const Rall1d<T,V,S>& arg) 00297 { 00298 T v; 00299 v= (exp(arg.t)); 00300 return Rall1d<T,V,S>(v,v*arg.grad); 00301 } 00302 00303 template <class T,class V,class S> 00304 INLINE Rall1d<T,V,S> log(const Rall1d<T,V,S>& arg) 00305 { 00306 T v; 00307 v=(log(arg.t)); 00308 return Rall1d<T,V,S>(v,arg.grad/arg.t); 00309 } 00310 00311 template <class T,class V,class S> 00312 INLINE Rall1d<T,V,S> sin(const Rall1d<T,V,S>& arg) 00313 { 00314 T v; 00315 v=(sin(arg.t)); 00316 return Rall1d<T,V,S>(v,cos(arg.t)*arg.grad); 00317 } 00318 00319 template <class T,class V,class S> 00320 INLINE Rall1d<T,V,S> cos(const Rall1d<T,V,S>& arg) 00321 { 00322 T v; 00323 v=(cos(arg.t)); 00324 return Rall1d<T,V,S>(v,-sin(arg.t)*arg.grad); 00325 } 00326 00327 template <class T,class V,class S> 00328 INLINE Rall1d<T,V,S> tan(const Rall1d<T,V,S>& arg) 00329 { 00330 T v; 00331 v=(tan(arg.t)); 00332 return Rall1d<T,V,S>(v,arg.grad/sqr(cos(arg.t))); 00333 } 00334 00335 template <class T,class V,class S> 00336 INLINE Rall1d<T,V,S> sinh(const Rall1d<T,V,S>& arg) 00337 { 00338 T v; 00339 v=(sinh(arg.t)); 00340 return Rall1d<T,V,S>(v,cosh(arg.t)*arg.grad); 00341 } 00342 00343 template <class T,class V,class S> 00344 INLINE Rall1d<T,V,S> cosh(const Rall1d<T,V,S>& arg) 00345 { 00346 T v; 00347 v=(cosh(arg.t)); 00348 return Rall1d<T,V,S>(v,sinh(arg.t)*arg.grad); 00349 } 00350 00351 template <class T,class V,class S> 00352 INLINE Rall1d<T,V,S> sqr(const Rall1d<T,V,S>& arg) 00353 { 00354 T v; 00355 v=(arg.t*arg.t); 00356 return Rall1d<T,V,S>(v,(2.0*arg.t)*arg.grad); 00357 } 00358 00359 template <class T,class V,class S> 00360 INLINE Rall1d<T,V,S> pow(const Rall1d<T,V,S>& arg,double m) 00361 { 00362 T v; 00363 v=(pow(arg.t,m)); 00364 return Rall1d<T,V,S>(v,(m*v/arg.t)*arg.grad); 00365 } 00366 00367 template <class T,class V,class S> 00368 INLINE Rall1d<T,V,S> sqrt(const Rall1d<T,V,S>& arg) 00369 { 00370 T v; 00371 v=sqrt(arg.t); 00372 return Rall1d<T,V,S>(v, (0.5/v)*arg.grad); 00373 } 00374 00375 template <class T,class V,class S> 00376 INLINE Rall1d<T,V,S> atan(const Rall1d<T,V,S>& x) 00377 { 00378 T v; 00379 v=(atan(x.t)); 00380 return Rall1d<T,V,S>(v,x.grad/(1.0+sqr(x.t))); 00381 } 00382 00383 template <class T,class V,class S> 00384 INLINE Rall1d<T,V,S> hypot(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x) 00385 { 00386 T v; 00387 v=(hypot(y.t,x.t)); 00388 return Rall1d<T,V,S>(v,(x.t/v)*x.grad+(y.t/v)*y.grad); 00389 } 00390 00391 template <class T,class V,class S> 00392 INLINE Rall1d<T,V,S> asin(const Rall1d<T,V,S>& x) 00393 { 00394 T v; 00395 v=(asin(x.t)); 00396 return Rall1d<T,V,S>(v,x.grad/sqrt(1.0-sqr(x.t))); 00397 } 00398 00399 template <class T,class V,class S> 00400 INLINE Rall1d<T,V,S> acos(const Rall1d<T,V,S>& x) 00401 { 00402 T v; 00403 v=(acos(x.t)); 00404 return Rall1d<T,V,S>(v,-x.grad/sqrt(1.0-sqr(x.t))); 00405 } 00406 00407 template <class T,class V,class S> 00408 INLINE Rall1d<T,V,S> abs(const Rall1d<T,V,S>& x) 00409 { 00410 T v; 00411 v=(Sign(x)); 00412 return Rall1d<T,V,S>(v*x,v*x.grad); 00413 } 00414 00415 00416 template <class T,class V,class S> 00417 INLINE S Norm(const Rall1d<T,V,S>& value) 00418 { 00419 return Norm(value.t); 00420 } 00421 00422 template <class T,class V,class S> 00423 INLINE Rall1d<T,V,S> tanh(const Rall1d<T,V,S>& arg) 00424 { 00425 T v(tanh(arg.t)); 00426 return Rall1d<T,V,S>(v,arg.grad/sqr(cosh(arg.t))); 00427 } 00428 00429 template <class T,class V,class S> 00430 INLINE Rall1d<T,V,S> atan2(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x) 00431 { 00432 T v(x.t*x.t+y.t*y.t); 00433 return Rall1d<T,V,S>(atan2(y.t,x.t),(x.t*y.grad-y.t*x.grad)/v); 00434 } 00435 00436 00437 template <class T,class V,class S> 00438 INLINE Rall1d<T,V,S> LinComb(S alfa,const Rall1d<T,V,S>& a, 00439 const T& beta,const Rall1d<T,V,S>& b ) { 00440 return Rall1d<T,V,S>( 00441 LinComb(alfa,a.t,beta,b.t), 00442 LinComb(alfa,a.grad,beta,b.grad) 00443 ); 00444 } 00445 00446 template <class T,class V,class S> 00447 INLINE void LinCombR(S alfa,const Rall1d<T,V,S>& a, 00448 const T& beta,const Rall1d<T,V,S>& b,Rall1d<T,V,S>& result ) { 00449 LinCombR(alfa, a.t, beta, b.t, result.t); 00450 LinCombR(alfa, a.grad, beta, b.grad, result.grad); 00451 } 00452 00453 00454 template <class T,class V,class S> 00455 INLINE void SetToZero(Rall1d<T,V,S>& value) 00456 { 00457 SetToZero(value.grad); 00458 SetToZero(value.t); 00459 } 00460 template <class T,class V,class S> 00461 INLINE void SetToIdentity(Rall1d<T,V,S>& value) 00462 { 00463 SetToIdentity(value.t); 00464 SetToZero(value.grad); 00465 } 00466 00467 template <class T,class V,class S> 00468 INLINE bool Equal(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x,double eps=epsilon) 00469 { 00470 return (Equal(x.t,y.t,eps)&&Equal(x.grad,y.grad,eps)); 00471 } 00472 00473 } 00474 00475 00476 00477 #endif