Eigen::JacobiRotation< Scalar > Class Template Reference

Rotation given by a cosine-sine pair. More...

#include <Jacobi.h>

Public Types

typedef NumTraits< Scalar >::Real RealScalar
 

Public Member Functions

EIGEN_DEVICE_FUNC JacobiRotation ()
 
EIGEN_DEVICE_FUNC JacobiRotation (const Scalar &c, const Scalar &s)
 
EIGEN_DEVICE_FUNC Scalarc ()
 
EIGEN_DEVICE_FUNC Scalar c () const
 
EIGEN_DEVICE_FUNC Scalars ()
 
EIGEN_DEVICE_FUNC Scalar s () const
 
EIGEN_DEVICE_FUNC JacobiRotation operator* (const JacobiRotation &other)
 
EIGEN_DEVICE_FUNC JacobiRotation transpose () const
 
EIGEN_DEVICE_FUNC JacobiRotation adjoint () const
 
template<typename Derived >
EIGEN_DEVICE_FUNC bool makeJacobi (const MatrixBase< Derived > &, Index p, Index q)
 
EIGEN_DEVICE_FUNC bool makeJacobi (const RealScalar &x, const Scalar &y, const RealScalar &z)
 
EIGEN_DEVICE_FUNC void makeGivens (const Scalar &p, const Scalar &q, Scalar *r=0)
 

Protected Member Functions

EIGEN_DEVICE_FUNC void makeGivens (const Scalar &p, const Scalar &q, Scalar *r, internal::true_type)
 
EIGEN_DEVICE_FUNC void makeGivens (const Scalar &p, const Scalar &q, Scalar *r, internal::false_type)
 

Protected Attributes

Scalar m_c
 
Scalar m_s
 

Detailed Description

template<typename Scalar>
class Eigen::JacobiRotation< Scalar >

Rotation given by a cosine-sine pair.

\jacobi_module

This class represents a Jacobi or Givens rotation. This is a 2D rotation in the plane J of angle \( \theta \) defined by its cosine c and sine s as follow: \( J = \left ( \begin{array}{cc} c & \overline s \\ -s & \overline c \end{array} \right ) \)

You can apply the respective counter-clockwise rotation to a column vector v by applying its adjoint on the left: \( v = J^* v \) that translates to the following Eigen code:

v.applyOnTheLeft(J.adjoint());
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
See also
MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()

Member Typedef Documentation

◆ RealScalar

template<typename Scalar >
typedef NumTraits<Scalar>::Real Eigen::JacobiRotation< Scalar >::RealScalar

Constructor & Destructor Documentation

◆ JacobiRotation() [1/2]

template<typename Scalar >
EIGEN_DEVICE_FUNC Eigen::JacobiRotation< Scalar >::JacobiRotation ( )
inline

◆ JacobiRotation() [2/2]

template<typename Scalar >
EIGEN_DEVICE_FUNC Eigen::JacobiRotation< Scalar >::JacobiRotation ( const Scalar c,
const Scalar s 
)
inline

Construct a planar rotation from a cosine-sine pair (c, s).

46 : m_c(c), m_s(s) {}
EIGEN_DEVICE_FUNC Scalar & s()
Definition: Jacobi.h:50
Scalar m_c
Definition: Jacobi.h:82
EIGEN_DEVICE_FUNC Scalar & c()
Definition: Jacobi.h:48
Scalar m_s
Definition: Jacobi.h:82

Member Function Documentation

◆ adjoint()

template<typename Scalar >
EIGEN_DEVICE_FUNC JacobiRotation Eigen::JacobiRotation< Scalar >::adjoint ( ) const
inline

Returns the adjoint transformation

67  {
68  using numext::conj;
69  return JacobiRotation(conj(m_c), -m_s);
70  }
AnnoyingScalar conj(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:133
EIGEN_DEVICE_FUNC JacobiRotation()
Definition: Jacobi.h:43
const AutoDiffScalar< DerType > & conj(const AutoDiffScalar< DerType > &x)
Definition: AutoDiffScalar.h:482

References conj(), Eigen::conj(), Eigen::JacobiRotation< Scalar >::JacobiRotation(), Eigen::JacobiRotation< Scalar >::m_c, and Eigen::JacobiRotation< Scalar >::m_s.

Referenced by Eigen::internal::matrix_function_permute_schur().

◆ c() [1/2]

◆ c() [2/2]

template<typename Scalar >
EIGEN_DEVICE_FUNC Scalar Eigen::JacobiRotation< Scalar >::c ( ) const
inline
49 { return m_c; }

References Eigen::JacobiRotation< Scalar >::m_c.

◆ makeGivens() [1/3]

template<typename Scalar >
EIGEN_DEVICE_FUNC void Eigen::JacobiRotation< Scalar >::makeGivens ( const Scalar p,
const Scalar q,
Scalar r,
internal::false_type   
)
protected
208  {
209  using std::abs;
210  using std::sqrt;
211  if (numext::is_exactly_zero(q)) {
212  m_c = p < Scalar(0) ? Scalar(-1) : Scalar(1);
213  m_s = Scalar(0);
214  if (r) *r = abs(p);
215  } else if (numext::is_exactly_zero(p)) {
216  m_c = Scalar(0);
217  m_s = q < Scalar(0) ? Scalar(1) : Scalar(-1);
218  if (r) *r = abs(q);
219  } else if (abs(p) > abs(q)) {
220  Scalar t = q / p;
221  Scalar u = sqrt(Scalar(1) + numext::abs2(t));
222  if (p < Scalar(0)) u = -u;
223  m_c = Scalar(1) / u;
224  m_s = -t * m_c;
225  if (r) *r = p * u;
226  } else {
227  Scalar t = p / q;
228  Scalar u = sqrt(Scalar(1) + numext::abs2(t));
229  if (q < Scalar(0)) u = -u;
230  m_s = -Scalar(1) / u;
231  m_c = -t * m_s;
232  if (r) *r = q * u;
233  }
234 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
float * p
Definition: Tutorial_Map_using.cpp:9
SCALAR Scalar
Definition: bench_gemm.cpp:45
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X &x)
Definition: Meta.h:592
EIGEN_DEVICE_FUNC const Scalar & q
Definition: SpecialFunctionsImpl.h:2019
EIGEN_DEVICE_FUNC bool abs2(bool x)
Definition: MathFunctions.h:1102
r
Definition: UniformPSDSelfTest.py:20
t
Definition: plotPSD.py:36

References abs(), Eigen::numext::abs2(), Eigen::numext::is_exactly_zero(), p, Eigen::numext::q, UniformPSDSelfTest::r, sqrt(), and plotPSD::t.

◆ makeGivens() [2/3]

template<typename Scalar >
EIGEN_DEVICE_FUNC void Eigen::JacobiRotation< Scalar >::makeGivens ( const Scalar p,
const Scalar q,
Scalar r,
internal::true_type   
)
protected
159  {
160  using numext::conj;
161  using std::abs;
162  using std::sqrt;
163 
164  if (q == Scalar(0)) {
165  m_c = numext::real(p) < 0 ? Scalar(-1) : Scalar(1);
166  m_s = 0;
167  if (r) *r = m_c * p;
168  } else if (p == Scalar(0)) {
169  m_c = 0;
170  m_s = -q / abs(q);
171  if (r) *r = abs(q);
172  } else {
173  RealScalar p1 = numext::norm1(p);
174  RealScalar q1 = numext::norm1(q);
175  if (p1 >= q1) {
176  Scalar ps = p / p1;
177  RealScalar p2 = numext::abs2(ps);
178  Scalar qs = q / p1;
179  RealScalar q2 = numext::abs2(qs);
180 
181  RealScalar u = sqrt(RealScalar(1) + q2 / p2);
182  if (numext::real(p) < RealScalar(0)) u = -u;
183 
184  m_c = Scalar(1) / u;
185  m_s = -qs * conj(ps) * (m_c / p2);
186  if (r) *r = p * u;
187  } else {
188  Scalar ps = p / q1;
189  RealScalar p2 = numext::abs2(ps);
190  Scalar qs = q / q1;
191  RealScalar q2 = numext::abs2(qs);
192 
193  RealScalar u = q1 * sqrt(p2 + q2);
194  if (numext::real(p) < RealScalar(0)) u = -u;
195 
196  p1 = abs(p);
197  ps = p / p1;
198  m_c = p1 / u;
199  m_s = -conj(ps) * (q / u);
200  if (r) *r = ps * u;
201  }
202  }
203 }
Vector3f p1
Definition: MatrixBase_all.cpp:2
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
NumTraits< Scalar >::Real RealScalar
Definition: Jacobi.h:40
float real
Definition: datatypes.h:10
int RealScalar int RealScalar int RealScalar RealScalar * ps
Definition: level1_cplx_impl.h:124

References abs(), Eigen::numext::abs2(), conj(), Eigen::conj(), p, p1, ps, Eigen::numext::q, UniformPSDSelfTest::r, and sqrt().

◆ makeGivens() [3/3]

template<typename Scalar >
EIGEN_DEVICE_FUNC void Eigen::JacobiRotation< Scalar >::makeGivens ( const Scalar p,
const Scalar q,
Scalar r = 0 
)

Makes *this as a Givens rotation G such that applying \( G^* \) to the left of the vector \( V = \left ( \begin{array}{c} p \\ q \end{array} \right )\) yields: \( G^* V = \left ( \begin{array}{c} r \\ 0 \end{array} \right )\).

The value of r is returned if r is not null (the default is null). Also note that G is built such that the cosine is always real.

Example:

Vector2f v = Vector2f::Random();
JacobiRotation<float> G;
G.makeGivens(v.x(), v.y());
cout << "Here is the vector v:" << endl << v << endl;
v.applyOnTheLeft(0, 1, G.adjoint());
cout << "Here is the vector J' * v:" << endl << v << endl;
JacobiRotation< float > G
Definition: Jacobi_makeGivens.cpp:2

Output:

This function implements the continuous Givens rotation generation algorithm found in Anderson (2000), Discontinuous Plane Rotations and the Symmetric Eigenvalue Problem. LAPACK Working Note 150, University of Tennessee, UT-CS-00-454, December 4, 2000.

See also
MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
152  {
153  makeGivens(p, q, r, std::conditional_t<NumTraits<Scalar>::IsComplex, internal::true_type, internal::false_type>());
154 }
EIGEN_DEVICE_FUNC void makeGivens(const Scalar &p, const Scalar &q, Scalar *r=0)
Definition: Jacobi.h:152
@ IsComplex
Definition: NumTraits.h:176

References makeGivens(), p, Eigen::numext::q, and UniformPSDSelfTest::r.

Referenced by Eigen::internal::llt_rank_update_lower(), Eigen::internal::lmqrsolv(), Eigen::internal::matrix_function_permute_schur(), Eigen::internal::qrsolv(), and Eigen::internal::r1updt().

◆ makeJacobi() [1/2]

template<typename Scalar >
template<typename Derived >
EIGEN_DEVICE_FUNC bool Eigen::JacobiRotation< Scalar >::makeJacobi ( const MatrixBase< Derived > &  m,
Index  p,
Index  q 
)
inline

Makes *this as a Jacobi rotation J such that applying J on both the right and left sides of the 2x2 selfadjoint matrix \( B = \left ( \begin{array}{cc} \text{this}_{pp} & \text{this}_{pq} \\ (\text{this}_{pq})^* & \text{this}_{qq} \end{array} \right )\) yields a diagonal matrix \( A = J^* B J \)

Example:

Matrix2f m = Matrix2f::Random();
m = (m + m.adjoint()).eval();
JacobiRotation<float> J;
J.makeJacobi(m, 0, 1);
cout << "Here is the matrix m:" << endl << m << endl;
m.applyOnTheLeft(0, 1, J.adjoint());
m.applyOnTheRight(0, 1, J);
cout << "Here is the matrix J' * m * J:" << endl << m << endl;
int * m
Definition: level2_cplx_impl.h:294
internal::nested_eval< T, 1 >::type eval(const T &xpr)
Definition: sparse_permutations.cpp:47

Output:

See also
JacobiRotation::makeJacobi(RealScalar, Scalar, RealScalar), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
131  {
132  return makeJacobi(numext::real(m.coeff(p, p)), m.coeff(p, q), numext::real(m.coeff(q, q)));
133 }
EIGEN_DEVICE_FUNC bool makeJacobi(const MatrixBase< Derived > &, Index p, Index q)
Definition: Jacobi.h:131

References m, makeJacobi(), p, and Eigen::numext::q.

Referenced by Eigen::internal::real_2x2_jacobi_svd().

◆ makeJacobi() [2/2]

template<typename Scalar >
EIGEN_DEVICE_FUNC bool Eigen::JacobiRotation< Scalar >::makeJacobi ( const RealScalar x,
const Scalar y,
const RealScalar z 
)

Makes *this as a Jacobi rotation J such that applying J on both the right and left sides of the selfadjoint 2x2 matrix \( B = \left ( \begin{array}{cc} x & y \\ \overline y & z \end{array} \right )\) yields a diagonal matrix \( A = J^* B J \)

See also
MatrixBase::makeJacobi(const MatrixBase<Derived>&, Index, Index), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
93  {
94  using std::abs;
95  using std::sqrt;
96 
97  RealScalar deno = RealScalar(2) * abs(y);
98  if (deno < (std::numeric_limits<RealScalar>::min)()) {
99  m_c = Scalar(1);
100  m_s = Scalar(0);
101  return false;
102  } else {
103  RealScalar tau = (x - z) / deno;
104  RealScalar w = sqrt(numext::abs2(tau) + RealScalar(1));
105  RealScalar t;
106  if (tau > RealScalar(0)) {
107  t = RealScalar(1) / (tau + w);
108  } else {
109  t = RealScalar(1) / (tau - w);
110  }
111  RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
113  m_s = -sign_t * (numext::conj(y) / abs(y)) * abs(t) * n;
114  m_c = n;
115  return true;
116  }
117 }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
RowVector3d w
Definition: Matrix_resize_int.cpp:3
#define min(a, b)
Definition: datatypes.h:22
Scalar * y
Definition: level1_cplx_impl.h:128
list x
Definition: plotDoE.py:28

References abs(), Eigen::numext::abs2(), conj(), min, n, sqrt(), plotPSD::t, w, plotDoE::x, and y.

◆ operator*()

template<typename Scalar >
EIGEN_DEVICE_FUNC JacobiRotation Eigen::JacobiRotation< Scalar >::operator* ( const JacobiRotation< Scalar > &  other)
inline

Concatenates two planar rotation

54  {
55  using numext::conj;
56  return JacobiRotation(m_c * other.m_c - conj(m_s) * other.m_s,
57  conj(m_c * conj(other.m_s) + conj(m_s) * conj(other.m_c)));
58  }

References conj(), Eigen::conj(), Eigen::JacobiRotation< Scalar >::JacobiRotation(), Eigen::JacobiRotation< Scalar >::m_c, and Eigen::JacobiRotation< Scalar >::m_s.

◆ s() [1/2]

◆ s() [2/2]

template<typename Scalar >
EIGEN_DEVICE_FUNC Scalar Eigen::JacobiRotation< Scalar >::s ( ) const
inline
51 { return m_s; }

References Eigen::JacobiRotation< Scalar >::m_s.

◆ transpose()

Member Data Documentation

◆ m_c

◆ m_s


The documentation for this class was generated from the following files: