nce;

  /** \brief degree of freedom of group */
  static const int DoF = Base::DoF;
  /** \brief number of internal parameters used */
  static const int num_parameters = Base::num_parameters;
  /** \brief group transformations are NxN matrices */
  static const int N = Base::N;
  /** \brief group transfomation type */
  typedef typename Base::Transformation Transformation;
  /** \brief point type */
  typedef typename Base::Point Point;
  /** \brief tangent vector type */
  typedef typename Base::Tangent Tangent;
  /** \brief adjoint transformation type */
  typedef typename Base::Adjoint Adjoint;

  // base is friend so unit_complex_nonconst can be accessed from base
  friend class SO2GroupBase<SO2Group<_Scalar,_Options> >;

  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  /**
   * \brief Default constructor
   *
   * Initialize complex number to identity rotation.
   */
  inline SO2Group()
    : unit_complex_(static_cast<Scalar>(1), static_cast<Scalar>(0)) {
  }

  /**
   * \brief Copy constructor
   */
  template<typename OtherDerived> inline
  SO2Group(const SO2GroupBase<OtherDerived> & other)
    : unit_complex_(other.unit_complex()) {
  }

  /**
   * \brief Constructor from rotation matrix
   *
   * \pre rotation matrix need to be orthogonal with determinant of 1
   */
  inline explicit
  SO2Group(const Transformation & R)
    : unit_complex_(static_cast<Scalar>(0.5)*(R(0,0)+R(1,1)),
                    static_cast<Scalar>(0.5)*(R(1,0)-R(0,1))) {
    if (std::abs(R.determinant()-static_cast<Scalar>(1))
        > SophusConstants<Scalar>::epsilon()) {
      throw SophusException("det(R) is not near 1.");
    }
  }

  /**
   * \brief Constructor from pair of real and imaginary number
   *
   * \pre pair must not be zero
   */
  inline SO2Group(const Scalar & real, const Scalar & imag)
    : unit_complex_(real, imag) {
    Base::normalize();
  }

  /**
   * \brief Constructor from 2-vector
   *
   * \pre vector must not be zero
   */
  inline explicit
  SO2Group(const Matrix<Scalar,2,1> & complex)
    : unit_complex_(com