// @(#)root/mathcore:$Name: $:$Id: LorentzRotation.h,v 1.3 2005/09/19 16:43:07 brun Exp $
// Authors: W. Brown, M. Fischler, L. Moneta 2005
/**********************************************************************
* *
* Copyright (c) 2005 ROOT MathLib Team *
* *
* *
**********************************************************************/
// Header file for LorentzRotation
//
// Created by: Mark Fischler Mon Aug 8 2005
//
// Last update: $Id: LorentzRotation.h,v 1.3 2005/09/19 16:43:07 brun Exp $
//
#ifndef ROOT_Math_GenVector_LorentzRotation
#define ROOT_Math_GenVector_LorentzRotation 1
#include "Math/GenVector/LorentzRotationfwd.h"
#include "Math/GenVector/LorentzVector.h"
#include "Math/GenVector/PxPyPzE4D.h"
#include "Math/GenVector/Rotation3Dfwd.h"
#include "Math/GenVector/AxisAnglefwd.h"
#include "Math/GenVector/EulerAnglesfwd.h"
#include "Math/GenVector/Quaternionfwd.h"
#include "Math/GenVector/RotationXfwd.h"
#include "Math/GenVector/RotationYfwd.h"
#include "Math/GenVector/RotationZfwd.h"
#include "Math/GenVector/Boostfwd.h"
#include "Math/GenVector/BoostXfwd.h"
#include "Math/GenVector/BoostYfwd.h"
#include "Math/GenVector/BoostZfwd.h"
namespace ROOT {
namespace Math {
/**
Lorentz transformation class with the (4D) transformation represented by
a 4x4 orthosymplectic matrix.
See also Boost, BoostX, BoostY and BoostZ for classes representing
specialized Lorentz transformations.
Also, the 3-D rotation classes can be considered to be special Lorentz
transformations which do not mix space and time components.
@ingroup GenVector
*/
class LorentzRotation {
public:
typedef double Scalar;
enum LorentzRotationMatrixIndex {
XX = 0, XY = 1, XZ = 2, XT = 3
, YX = 4, YY = 4, YZ = 6, YT = 7
, ZX = 8, ZY = 9, ZZ = 10, ZT = 11
, TX = 12, TY = 13, TZ = 14, TT = 15
};
// ========== Constructors and Assignment =====================
/**
Default constructor (identity transformation)
*/
LorentzRotation();
/**
Construct given a pair of pointers or iterators defining the
beginning and end of an array of sixteen Scalars
*/
template<class IT>
LorentzRotation(IT begin, IT end) { SetComponents(begin,end); }
/**
Construct from a pure boost
*/
explicit LorentzRotation( Boost const & ) {} // TODO
explicit LorentzRotation( BoostX const & ) {} // TODO
explicit LorentzRotation( BoostY const & ) {} // TODO
explicit LorentzRotation( BoostZ const & ) {} // TODO
/**
Construct from a 3-D rotation (no space-time mixing)
*/
explicit LorentzRotation( Rotation3D const & r );
explicit LorentzRotation( AxisAngle const & a );
explicit LorentzRotation( EulerAngles const & e );
explicit LorentzRotation( Quaternion const & q );
explicit LorentzRotation( RotationX const & r );
explicit LorentzRotation( RotationY const & r );
explicit LorentzRotation( RotationZ const & r );
/**
Construct from a linear algebra matrix of size at least 4x4,
which must support operator()(i,j) to obtain elements (0,3) thru (3,3).
Precondition: The matrix is assumed to be orthosymplectic. NO checking
or re-adjusting is performed.
Note: (0,0) refers to the XX component; (3,3) refers to the TT component.
*/
template<class ForeignMatrix>
explicit LorentzRotation(const ForeignMatrix & m) { SetComponents(m); }
/**
Construct from three orthosymplectic vectors (which must have methods
x(), y(), z() and t()) which will be used as the columns of the Lorentz
rotation matrix. The orthosymplectic conditions will be checked, and
values adjusted so that the result will always be a good Lorentz rotation
matrix.
*/
template<class Foreign4Vector>
LorentzRotation(const Foreign4Vector& v1,
const Foreign4Vector& v2,
const Foreign4Vector& v3,
const Foreign4Vector& v4 ) { SetComponents(v1, v2, v3, v4); }
// The compiler-generated copy ctor, copy assignment, and dtor are OK.
/**
Raw constructor from sixteen Scalar components (without any checking)
*/
LorentzRotation(Scalar xx, Scalar xy, Scalar xz, Scalar xt,
Scalar yx, Scalar yy, Scalar yz, Scalar yt,
Scalar zx, Scalar zy, Scalar zz, Scalar zt,
Scalar tx, Scalar ty, Scalar tz, Scalar tt)
{
SetComponents (xx, xy, xz, xt,
yx, yy, yz, yt,
zx, zy, zz, zt,
tx, ty, tz, tt);
}
/**
Assign from a pure boost
*/
LorentzRotation &
operator=( Boost const & b ) { return operator=(LorentzRotation(b)); }
LorentzRotation &
operator=( BoostX const & b ) { return operator=(LorentzRotation(b)); }
LorentzRotation &
operator=( BoostY const & b ) { return operator=(LorentzRotation(b)); }
LorentzRotation &
operator=( BoostZ const & b ) { return operator=(LorentzRotation(b)); }
/**
Assign from a 3-D rotation
*/
LorentzRotation &
operator=( Rotation3D const & r ) { return operator=(LorentzRotation(r)); }
LorentzRotation &
operator=( AxisAngle const & a ) { return operator=(LorentzRotation(a)); }
LorentzRotation &
operator=( EulerAngles const & e ) { return operator=(LorentzRotation(e)); }
LorentzRotation &
operator=( Quaternion const & q ) { return operator=(LorentzRotation(q)); }
LorentzRotation &
operator=( RotationZ const & r ) { return operator=(LorentzRotation(r)); }
LorentzRotation &
operator=( RotationY const & r ) { return operator=(LorentzRotation(r)); }
LorentzRotation &
operator=( RotationX const & r ) { return operator=(LorentzRotation(r)); }
/**
Assign from a linear algebra matrix of size at least 4x4,
which must support operator()(i,j) to obtain elements (0,3) thru (3,3).
Precondition: The matrix is assumed to be orthosymplectic. NO checking
or re-adjusting is performed.
*/
template<class ForeignMatrix>
LorentzRotation &
operator=(const ForeignMatrix & m) { SetComponents(m); return *this; }
/**
Re-adjust components to eliminate small deviations from a perfect
orthosyplectic matrix.
*/
void Rectify();
// ======== Components ==============
/**
Set components from four orthosymplectic vectors (which must have methods
x(), y(), z(), and t()) which will be used as the columns of the
Lorentz rotation matrix. The values will be adjusted
so that the result will always be a good Lorentz rotation matrix.
*/
template<class Foreign4Vector>
void
SetComponents (const Foreign4Vector& v1,
const Foreign4Vector& v2,
const Foreign4Vector& v3,
const Foreign4Vector& v4 ) {
fM[XX]=v1.x(); fM[XY]=v2.x(); fM[XZ]=v3.x(); fM[XT]=v4.x();
fM[YX]=v1.y(); fM[YY]=v2.y(); fM[YZ]=v3.y(); fM[YT]=v4.Y();
fM[ZX]=v1.z(); fM[ZY]=v2.z(); fM[ZZ]=v3.z(); fM[ZT]=v4.z();
fM[TX]=v1.t(); fM[TY]=v2.t(); fM[TZ]=v3.t(); fM[TT]=v4.t();
Rectify();
}
/**
Get components into four 4-vectors which will be the (orthosymplectic)
columns of the rotation matrix. (The 4-vector class must have a
constructor from 4 Scalars used as x, y, z, t)
*/
template<class Foreign4Vector>
void
GetComponents ( Foreign4Vector& v1,
Foreign4Vector& v2,
Foreign4Vector& v3,
Foreign4Vector& v4 ) {
v1 = Foreign4Vector ( fM[XX], fM[YX], fM[ZX], fM[TX] );
v2 = Foreign4Vector ( fM[XY], fM[YY], fM[ZY], fM[TY] );
v3 = Foreign4Vector ( fM[XZ], fM[YZ], fM[ZZ], fM[TZ] );
v4 = Foreign4Vector ( fM[XT], fM[YT], fM[ZT], fM[TT] );
}
/**
Set the 16 matrix components given an iterator to the start of
the desired data, and another to the end (16 past start).
*/
template<class IT>
void SetComponents(IT begin, IT end) {
assert (end==begin+16);
std::copy ( begin, end, fM );
}
/**
Get the 16 matrix components into data specified by an iterator begin
and another to the end of the desired data (16 past start).
*/
template<class IT>
void GetComponents(IT begin, IT end) const {
assert (end==begin+16);
std::copy ( fM, fM+16, begin );
}
/**
Set components from a linear algebra matrix of size at least 4x4,
which must support operator()(i,j) to obtain elements (0,0) thru (3,3).
Precondition: The matrix is assumed to be orthosymplectic. NO checking
or re-adjusting is performed.
*/
template<class ForeignMatrix>
void
SetComponents (const ForeignMatrix & m) {
fM[XX]=m(0,0); fM[XY]=m(0,1); fM[XZ]=m(0,2); fM[XT]=m(0,3);
fM[YX]=m(1,0); fM[YY]=m(1,1); fM[YZ]=m(1,2); fM[YT]=m(1,3);
fM[ZX]=m(2,0); fM[ZY]=m(2,1); fM[ZZ]=m(2,2); fM[ZT]=m(2,3);
fM[TX]=m(3,0); fM[TY]=m(3,1); fM[TZ]=m(3,2); fM[TT]=m(3,3);
}
/**
Get components into a linear algebra matrix of size at least 4x4,
which must support operator()(i,j) for write access to elements
(0,0) thru (3,3).
*/
template<class ForeignMatrix>
void
GetComponents (ForeignMatrix & m) const {
m(0,0)=fM[XX]; m(0,1)=fM[XY]; m(0,2)=fM[XZ]; m(0,3)=fM[XT];
m(1,0)=fM[YX]; m(1,1)=fM[YY]; m(1,2)=fM[YZ]; m(1,3)=fM[YT];
m(2,0)=fM[ZX]; m(2,1)=fM[ZY]; m(2,2)=fM[ZZ]; m(2,3)=fM[ZT];
m(3,0)=fM[TX]; m(3,1)=fM[TY]; m(3,2)=fM[TZ]; m(3,3)=fM[TT];
}
/**
Set the components from sixteen scalars -- UNCHECKED for orthosymplectic
*/
void
SetComponents (Scalar xx, Scalar xy, Scalar xz, Scalar xt,
Scalar yx, Scalar yy, Scalar yz, Scalar yt,
Scalar zx, Scalar zy, Scalar zz, Scalar zt,
Scalar tx, Scalar ty, Scalar tz, Scalar tt) {
fM[XX]=xx; fM[XY]=xy; fM[XZ]=xz; fM[XT]=xt;
fM[YX]=yx; fM[YY]=yy; fM[YZ]=yz; fM[YT]=yt;
fM[ZX]=zx; fM[ZY]=zy; fM[ZZ]=zz; fM[ZT]=zt;
fM[TX]=tx; fM[TY]=ty; fM[TZ]=tz; fM[TT]=tt;
}
/**
Get the sixteen components into sixteen scalars
*/
void
GetComponents (Scalar &xx, Scalar &xy, Scalar &xz, Scalar &xt,
Scalar &yx, Scalar &yy, Scalar &yz, Scalar &yt,
Scalar &zx, Scalar &zy, Scalar &zz, Scalar &zt,
Scalar &tx, Scalar &ty, Scalar &tz, Scalar &tt) const {
xx=fM[XX]; xy=fM[XY]; xz=fM[XZ]; xt=fM[XT];
yx=fM[YX]; yy=fM[YY]; yz=fM[YZ]; yt=fM[YT];
zx=fM[ZX]; zy=fM[ZY]; zz=fM[ZZ]; zt=fM[ZT];
tx=fM[TX]; ty=fM[TY]; tz=fM[TZ]; tt=fM[TT];
}
// =========== operations ==============
/**
Lorentz transformation operation on a Minkowski ('Cartesian')
LorentzVector
*/
LorentzVector< ROOT::Math::PxPyPzE4D<double> >
operator() (const LorentzVector< ROOT::Math::PxPyPzE4D<double> > & v) const;
/**
Lorentz transformation operation on a LorentzVector in any
coordinate system
*/
template <class CoordSystem>
LorentzVector<CoordSystem>
operator() (const LorentzVector<CoordSystem> & v) const {
LorentzVector< PxPyPzE4D<double> > xyzt(v);
LorentzVector< PxPyPzE4D<double> > Rxyzt = operator()(xyzt);
return LorentzVector<CoordSystem> ( Rxyzt );
}
/**
Lorentz transformation operation on an arbitrary 4-vector v.
Preconditions: v must implement methods x(), y(), z(), and t()
and the arbitrary vector type must have a constructor taking (x,y,z,t)
*/
template <class Foreign4Vector>
Foreign4Vector
operator() (const Foreign4Vector & v) const {
LorentzVector< PxPyPzE4D<double> > xyzt(v);
LorentzVector< PxPyPzE4D<double> > Rxyzt = operator()(xyzt);
return ForeignVector ( Rxyzt.X(), Rxyzt.Y(), Rxyzt.Z(), Rxyzt.T() );
}
/**
Overload operator * for rotation on a vector
*/
template <class A4Vector>
inline
A4Vector operator* (const A4Vector & v) const
{
return operator()(v);
}
/**
Invert a Lorentz rotation in place
*/
void Invert();
/**
Return inverse of a rotation
*/
LorentzRotation Inverse() const;
// ========= Multi-Rotation Operations ===============
/**
Multiply (combine) this Lorentz rotation by another LorentzRotation
*/
LorentzRotation operator * (const LorentzRotation & r) const;
#ifdef TODO_LATER
/**
Multiply (combine) this Lorentz rotation by a pure Lorentz boost
*/
LorentzRotation operator * (const Boost & b) const; // TODO
LorentzRotation operator * (const BoostX & b) const; // TODO
LorentzRotation operator * (const BoostY & b) const; // TODO
LorentzRotation operator * (const BoostZ & b) const; // TODO
/**
Multiply (combine) this Lorentz rotation by a 3-D Rotation
*/
LorentzRotation operator * (const Rotation3D & r) const; // TODO
LorentzRotation operator * (const AxisAngle & a) const; // TODO
LorentzRotation operator * (const EulerAngles & e) const; // TODO
LorentzRotation operator * (const Quaternion & q) const; // TODO
LorentzRotation operator * (const RotationX & rx) const; // TODO
LorentzRotation operator * (const RotationY & ry) const; // TODO
LorentzRotation operator * (const RotationZ & rz) const; // TODO
#endif
/**
Post-Multiply (on right) by another LorentzRotation, Boost, or
rotation : T = T*R
*/
template <class R>
LorentzRotation & operator *= (const R & r) { return *this = (*this)*r; }
/**
Equality/inequality operators
*/
bool operator == (const LorentzRotation & rhs) {
for (unsigned int i=0; i < 16; ++i) {
if( fM[i] != rhs.fM[i] ) return false;
}
return true;
}
bool operator != (const LorentzRotation & rhs) {
return ! operator==(rhs);
}
private:
Scalar fM[16];
}; // LorentzRotation
// ============ Class LorentzRotation ends here ============
// ============================================ vetted to here ============
#ifdef NOTYET
/**
Distance between two Lorentz rotations
*/
template <class R>
inline
typename Rotation3D::Scalar
Distance ( const Rotation3D& r1, const R & r2) {return gv_detail::dist(r1,r2);}
#endif
} //namespace Math
} //namespace ROOT
#endif /* ROOT_Math_GenVector_LorentzRotation */
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.