inverse.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
00007 
00008  *-----------------------------------------------------------------------*/
00013 #ifndef quaternion_inverse_h
00014 #define quaternion_inverse_h
00015 
00016 #include <cml/quaternion/quaternion_expr.h>
00017 #include <cml/quaternion/quaternion_functions.h>
00018 
00019 namespace cml {
00020 namespace et {
00021 
00028 template<class ExprT>
00029 class QuaternionInverseOp
00030 {
00031   public:
00032 
00033     typedef QuaternionInverseOp<ExprT> expr_type;
00034 
00035     /* Record ary-ness of the expression: */
00036     typedef unary_expression expr_ary;
00037 
00038     /* Copy the expression by value into higher-up expressions: */
00039     typedef expr_type expr_const_reference;
00040 
00041     /* The subexpression is a ConjugateOp: */
00042     typedef et::ConjugateOp<ExprT> subexpression_type;
00043     typedef ExprTraits<subexpression_type> expr_traits;
00044 
00045     /* Get traits for the ExprT: */
00046     typedef ExprTraits<ExprT> arg_traits;
00047     typedef typename arg_traits::const_reference arg_reference;
00048 
00049     typedef typename subexpression_type::value_type value_type;
00050     typedef quaternion_result_tag result_tag;
00051     typedef typename subexpression_type::size_tag size_tag;
00052 
00053     /* Reference type for the subexpression: */
00054     typedef typename expr_traits::const_reference expr_reference;
00055 
00056     /* Get the result type (same as for subexpression): */
00057     typedef typename expr_traits::result_type result_type;
00058 
00059     /* For matching by assignability: */
00060     typedef cml::et::not_assignable_tag assignable_tag;
00061 
00062     /* Get the temporary type: */
00063     typedef typename result_type::temporary_type temporary_type;
00064 
00065     /* Get the vector type: */
00066     typedef typename result_type::vector_type vector_type;
00067 
00068     /* Get the imaginary part type: */
00069     typedef typename vector_type::subvector_type imaginary_type;
00070 
00071     /* Record the order type: */
00072     typedef typename result_type::order_type order_type;
00073 
00074 
00075   public:
00076 
00078     enum { array_size = ExprT::array_size };
00079 
00081     enum {
00082         W = order_type::W,
00083         X = order_type::X,
00084         Y = order_type::Y,
00085         Z = order_type::Z
00086     };
00087 
00088 
00089   public:
00090 
00092     value_type real() const {
00093         return m_expr.real()/m_norm;
00094     }
00095 
00100     imaginary_type imaginary() const {
00101         return m_expr.imaginary()/m_norm;
00102     }
00103 
00105     value_type norm() const {
00106         return length_squared();
00107     }
00108 
00110     value_type length_squared() const {
00111         return dot(
00112                 QuaternionXpr<expr_type>(*this),
00113                 QuaternionXpr<expr_type>(*this));
00114     }
00115 
00117     value_type length() const {
00118         return std::sqrt(length_squared());
00119     }
00120 
00122     temporary_type normalize() const {
00123         temporary_type q(QuaternionXpr<expr_type>(*this));
00124         return q.normalize();
00125     }
00126 
00131     value_type operator[](size_t i) const {
00132         return m_expr[i]/m_norm;
00133     }
00134 
00135 
00136   public:
00137 
00139     size_t size() const {
00140         return m_expr.size();
00141     }
00142 
00144     expr_reference expression() const { return m_expr; }
00145 
00146 
00147   public:
00148 
00150     explicit QuaternionInverseOp(arg_reference arg)
00151         //: m_expr(arg), m_norm(cml::norm(arg)) {}
00152         : m_expr(arg), m_norm(arg.norm()) {}
00153 
00155     QuaternionInverseOp(const expr_type& e)
00156         : m_expr(e.m_expr), m_norm(e.m_norm) {}
00157 
00158 
00159   protected:
00160 
00161     subexpression_type m_expr;
00162     value_type m_norm;
00163 
00164 
00165   private:
00166 
00167     /* Cannot be assigned to: */
00168     expr_type& operator=(const expr_type&);
00169 };
00170 
00172 template<class ExprT>
00173 struct ExprTraits< QuaternionInverseOp<ExprT> >
00174 {
00175     typedef QuaternionInverseOp<ExprT> expr_type;
00176     typedef ExprT arg_type;
00177 
00178     typedef typename expr_type::value_type value_type;
00179     typedef typename expr_type::expr_const_reference const_reference;
00180     typedef typename expr_type::result_tag result_tag;
00181     typedef typename expr_type::size_tag size_tag;
00182     typedef typename expr_type::result_type result_type;
00183     typedef typename expr_type::assignable_tag assignable_tag;
00184     typedef expr_node_tag node_tag;
00185 
00186     value_type get(const expr_type& v, size_t i) const { return v[i]; }
00187     size_t size(const expr_type& e) const { return e.size(); }
00188 };
00189 
00190 } // namespace et
00191 
00193 template<typename E, class AT, class OrderT, class CrossT> inline
00194 et::QuaternionXpr< et::QuaternionInverseOp< quaternion<E,AT,OrderT,CrossT> > >
00195 inverse(const quaternion<E,AT,OrderT,CrossT>& arg)
00196 {
00197     typedef et::QuaternionInverseOp< quaternion<E,AT,OrderT,CrossT> > ExprT;
00198     return et::QuaternionXpr<ExprT>(ExprT(arg));
00199 }
00200 
00202 template<class XprT> inline
00203 et::QuaternionXpr< et::QuaternionInverseOp<XprT> >
00204 inverse(QUATXPR_ARG_TYPE arg)
00205 {
00206     typedef et::QuaternionInverseOp<XprT> ExprT;
00207     return et::QuaternionXpr<ExprT>(ExprT(arg.expression()));
00208 }
00209 
00210 /* NOTE: Quaternion division no longer supported, but I'm leaving the
00211    code here for reference (Jesse) */
00212 
00213 #if 0
00214 
00215 template<typename E1, class AT1, typename E2, class AT2, class OT, class CT>
00216 inline typename et::QuaternionPromote<
00217     quaternion<E1,AT1,OT,CT>, quaternion<E2,AT2,OT,CT>
00218 >::temporary_type
00219 operator/(
00220         const quaternion<E1,AT1,OT,CT>& left,
00221         const quaternion<E2,AT2,OT,CT>& right)
00222 {
00223     return left*inverse(right);
00224 }
00225 
00227 template<typename E, class AT, class OT, class CT, class XprT>
00228 inline typename et::QuaternionPromote<
00229     quaternion<E,AT,OT,CT>, typename XprT::result_type
00230 >::temporary_type
00231 operator/(
00232         const quaternion<E,AT,OT,CT>& left,
00233         QUATXPR_ARG_TYPE right)
00234 {
00235     return left*inverse(right);
00236 }
00237 
00239 template<class XprT, typename E, class AT, class OT, class CT>
00240 inline typename et::QuaternionPromote<
00241     typename XprT::result_type, quaternion<E,AT,OT,CT>
00242 >::temporary_type
00243 operator/(
00244         QUATXPR_ARG_TYPE left,
00245         const quaternion<E,AT,OT,CT>& right)
00246 {
00247     return left*inverse(right);
00248 }
00249 
00251 template<class XprT1, class XprT2>
00252 inline typename et::QuaternionPromote<
00253     typename XprT1::result_type, typename XprT2::result_type
00254 >::temporary_type
00255 operator/(
00256         QUATXPR_ARG_TYPE_N(1) left,
00257         QUATXPR_ARG_TYPE_N(2) right)
00258 {
00259     return left*inverse(right);
00260 }
00261 #endif
00262 
00263 } // namespace cml
00264 
00265 #endif
00266 
00267 // -------------------------------------------------------------------------
00268 // vim:ft=cpp

Generated on Sat Jul 18 19:35:23 2009 for CML 1.0 by  doxygen 1.5.9