n. It is up to the user to call normalize() once in a while.
   *
   * \see operator*=()
   */
  inline
  void fastMultiply(const SO2Group<Scalar>& other) {
    Scalar lhs_real = unit_complex().x();
    Scalar lhs_imag = unit_complex().y();
    const Scalar & rhs_real = other.unit_complex().x();
    const Scalar & rhs_imag = other.unit_complex().y();
    // complex multiplication
    unit_complex_nonconst().x() = lhs_real*rhs_real - lhs_imag*rhs_imag;
    unit_complex_nonconst().y() = lhs_real*rhs_imag + lhs_imag*rhs_real;
  }

  /**
   * \returns group inverse of instance
   */
  inline
  const SO2Group<Scalar> inverse() const {
    return SO2Group<Scalar>(unit_complex().x(), -unit_complex().y());
  }

  /**
   * \brief Logarithmic map
   *
   * \returns tangent space representation (=rotation angle) of instance
   *
   * \see  log().
   */
  inline
  const Scalar log() const {
    return SO2Group<Scalar>::log(*this);
  }

  /**
   * \brief Normalize complex number
   *
   * It re-normalizes complex number to unit length. This method only needs to
   * be called in conjunction with fastMultiply() or data() write access.
   */
  inline
  void normalize() {
    Scalar length =
        std::sqrt(unit_complex().x()*unit_complex().x()
             + unit_complex().y()*unit_complex().y());
    if(length < SophusConstants<Scalar>::epsilon()) {
      throw SophusException("Complex number is (near) zero!");
    }
    unit_complex_nonconst().x() /= length;
    unit_complex_nonconst().y() /= length;
  }

  /**
   * \returns 2x2 matrix representation of instance
   *
   * For SO2, the matrix representation is an orthogonal matrix R with det(R)=1,
   * thus the so-called rotation matrix.
   */
  inline
  const Transformation matrix() const {
    const Scalar & real = unit_complex().x();
    const Scalar & imag = unit_complex().y();
    Transformation R;
    R << real, -imag
        ,imag,  real;
    return R;
  }

  /**
   * \brief Assignment operator
   */
  template<typename OtherDerived> inline
  SO2GroupBase<Derived>& op