diff --git a/.github/workflows/root-ci-config/buildconfig/fedora41.txt b/.github/workflows/root-ci-config/buildconfig/fedora41.txt
index 41df17ddea7cf..ec779824cbe52 100644
--- a/.github/workflows/root-ci-config/buildconfig/fedora41.txt
+++ b/.github/workflows/root-ci-config/buildconfig/fedora41.txt
@@ -2,5 +2,7 @@ builtin_zstd=ON
builtin_zlib=ON
builtin_nlohmannjson=On
builtin_vdt=On
+experimental_adaptivecpp=ON
+experimental_genvectorx=ON
pythia8=Off
ccache=On
diff --git a/.github/workflows/root-ci-config/buildconfig/fedora42.txt b/.github/workflows/root-ci-config/buildconfig/fedora42.txt
index b9c895b0a227e..0013f42882ca6 100644
--- a/.github/workflows/root-ci-config/buildconfig/fedora42.txt
+++ b/.github/workflows/root-ci-config/buildconfig/fedora42.txt
@@ -3,6 +3,8 @@ builtin_unuran=OFF
builtin_zlib=ON
builtin_zstd=ON
ccache=ON
+experimental_adaptivecpp=ON
+experimental_genvectorx=ON
pythia8=OFF
unuran=OFF
-vdt=OFF
+vdt=OFF
\ No newline at end of file
diff --git a/.github/workflows/root-ci-config/buildconfig/global.txt b/.github/workflows/root-ci-config/buildconfig/global.txt
index e40f12788fb65..c1206cfa342b3 100644
--- a/.github/workflows/root-ci-config/buildconfig/global.txt
+++ b/.github/workflows/root-ci-config/buildconfig/global.txt
@@ -45,6 +45,8 @@ davix=ON
dcache=OFF
dev=OFF
distcc=OFF
+experimental_adaptivecpp=OFF
+experimental_genvectorx=OFF
fail-on-missing=On
fcgi=OFF
fftw3=ON
diff --git a/.github/workflows/root-ci-config/buildconfig/ubuntu2404-cuda.txt b/.github/workflows/root-ci-config/buildconfig/ubuntu2404-cuda.txt
index b7b693c1dbcfd..d36538b8c8a5a 100644
--- a/.github/workflows/root-ci-config/buildconfig/ubuntu2404-cuda.txt
+++ b/.github/workflows/root-ci-config/buildconfig/ubuntu2404-cuda.txt
@@ -2,6 +2,8 @@ CMAKE_BUILD_TYPE=RelWithDebInfo
pythia8=OFF
cuda=ON
ccache=ON
+experimental_adaptivecpp=ON
+experimental_genvectorx=ON
tmva=ON
tmva-cpu=ON
tmva-gpu=ON
@@ -14,4 +16,4 @@ sqlite=OFF
test_distrdf_dask=OFF
test_distrdf_pyspark=OFF
unfold=OFF
-webgui=ON
+webgui=ON
\ No newline at end of file
diff --git a/.github/workflows/root-ci-config/buildconfig/ubuntu2404.txt b/.github/workflows/root-ci-config/buildconfig/ubuntu2404.txt
index 287ce0f69d122..355a32db539c3 100644
--- a/.github/workflows/root-ci-config/buildconfig/ubuntu2404.txt
+++ b/.github/workflows/root-ci-config/buildconfig/ubuntu2404.txt
@@ -1,3 +1,5 @@
+experimental_adaptivecpp=ON
+experimental_genvectorx=ON
pythia8=OFF
tmva-sofie=ON
-ccache=On
+ccache=On
\ No newline at end of file
diff --git a/.github/workflows/root-ci-config/buildconfig/ubuntu2504.txt b/.github/workflows/root-ci-config/buildconfig/ubuntu2504.txt
index 9439d1f4057e1..7f54d7491a6ae 100644
--- a/.github/workflows/root-ci-config/buildconfig/ubuntu2504.txt
+++ b/.github/workflows/root-ci-config/buildconfig/ubuntu2504.txt
@@ -1,2 +1,4 @@
+experimental_adaptivecpp=ON
+experimental_genvectorx=ON
ccache=ON
-pythia8=OFF
+pythia8=OFF
\ No newline at end of file
diff --git a/cmake/modules/SearchInstalledSoftware.cmake b/cmake/modules/SearchInstalledSoftware.cmake
index 3fa55ef5a0e3e..b1d6b88b40e63 100644
--- a/cmake/modules/SearchInstalledSoftware.cmake
+++ b/cmake/modules/SearchInstalledSoftware.cmake
@@ -1643,6 +1643,126 @@ if (vecgeom)
endif()
endif()
+if(experimental_builtin_adaptivecpp)
+ ROOT_CHECK_CONNECTION_AND_DISABLE_OPTION("experimental_builtin_adaptivecpp")
+endif()
+
+#---Check for AdaptiveCpp-------------------------------------------------------------------
+if (experimental_adaptivecpp OR experimental_builtin_adaptivecpp)
+ if (experimental_oneapi)
+ message(WARNING "Disable OneAPI to load AdaptiveCpp")
+ set(sycl OFF CACHE BOOL "Disabled because AdaptiveCpp is enabled" FORCE)
+ else()
+
+ if(NOT experimental_builtin_adaptivecpp)
+ message(STATUS "Looking for AdaptiveCpp")
+ find_package(AdaptiveCpp)
+
+ if(NOT AdaptiveCpp_FOUND)
+ message(STATUS "AdaptiveCpp not found. Ensure that the installation of AdaptiveCpp is in the CMAKE_PREFIX_PATH")
+ if(NO_CONNECTION)
+ set(experimental_builtin_adaptivecpp OFF CACHE BOOL "Disabled because not found and no internet connection" FORCE)
+ set(sycl OFF CACHE BOOL FORCE)
+ if(fail-on-missing)
+ message(FATAL_ERROR "AdaptiveCpp cannot be built.")
+ endif()
+ else()
+ message(STATUS " Switching ON 'experimental_builtin_adaptivecpp' option")
+ set(experimental_builtin_adaptivecpp ON CACHE BOOL "Enabled because external AdaptiveCpp not found" FORCE)
+ endif()
+ endif()
+ endif()
+
+ if(experimental_builtin_adaptivecpp)
+ # Use ADAPTIVE_CPP_SOURCE_DIR variable if it is defined in the CMake
+ # configuration
+ if(NOT DEFINED ADAPTIVE_CPP_SOURCE_DIR)
+ include(FetchContent)
+ set(ADAPTIVE_CPP_SOURCE_DIR "${CMAKE_BINARY_DIR}/AdaptiveCpp")
+ FetchContent_Declare(
+ AdaptiveCpp
+ GIT_REPOSITORY https://github.com/devajithvs/AdaptiveCpp.git
+ GIT_TAG 3fb375fdc84ad0423139e05167739e9e906ca183
+ )
+ FetchContent_GetProperties(AdaptiveCpp)
+ if(NOT AdaptiveCpp_POPULATED)
+ FetchContent_Populate(AdaptiveCpp)
+ endif()
+
+ set(ADAPTIVE_CPP_SOURCE_DIR "${adaptivecpp_SOURCE_DIR}")
+ endif()
+
+ set(AdaptiveCpp_FOUND True)
+
+ list(INSERT CMAKE_MODULE_PATH 0 "${ADAPTIVE_CPP_SOURCE_DIR}/cmake/")
+
+ set(ADAPTIVE_CPP_HEADER_BUILD_PATH
+ "${CMAKE_CURRENT_BINARY_DIR}/include/AdaptiveCpp")
+ set(ADAPTIVE_CPP_HEADER_INSTALL_PATH
+ "${CMAKE_INSTALL_PREFIX}/include/AdaptiveCpp")
+
+ add_subdirectory(
+ ${ADAPTIVE_CPP_SOURCE_DIR}
+ ${adaptivecpp_BINARY_DIR}
+ )
+
+ set(ACPP_EXPORTS
+ acpp-common
+ acpp-rt
+ acpp-clang-cbs
+ acpp-clang
+ llvm-to-backend
+ llvm-to-host
+ rt-backend-omp)
+
+ if(WITH_CUDA_BACKEND)
+ list(APPEND ACPP_EXPORTS llvm-to-ptx rt-backend-cuda)
+ endif()
+
+ if(WITH_OPENCL_BACKEND)
+ list(APPEND ACPP_EXPORTS llvm-to-spirv rt-backend-ocl ocl-cxx-headers ocl-headers)
+ endif()
+
+ if(WITH_ROCM_BACKEND)
+ list(APPEND ACPP_EXPORTS llvm-to-amdgpu rt-backend-hip)
+ endif()
+ endif()
+
+ if (AdaptiveCpp_FOUND)
+ set(sycl ON)
+ set(SYCL_COMPILER_FLAGS "-ffast-math ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_BUILD_TYPE_UPPER}}")
+ message(STATUS "SYCL compiler flags: ${SYCL_COMPILER_FLAGS}")
+ separate_arguments(SYCL_COMPILER_FLAGS NATIVE_COMMAND ${SYCL_COMPILER_FLAGS})
+ function(add_sycl_library_to_root_target)
+ CMAKE_PARSE_ARGUMENTS(ARG "" "TARGET" "SOURCES" ${ARGN})
+ add_sycl_to_target(TARGET ${ARG_TARGET} SOURCES ${ARG_SOURCES})
+ target_link_libraries(${ARG_TARGET} INTERFACE AdaptiveCpp::acpp-rt)
+ target_compile_options(${ARG_TARGET} PUBLIC ${SYCL_COMPILER_FLAGS})
+ endfunction()
+ function(add_sycl_library_to_main_root_target)
+ CMAKE_PARSE_ARGUMENTS(ARG "" "TARGET" "SOURCES" ${ARGN})
+ add_sycl_to_target(TARGET ${ARG_TARGET} SOURCES ${ARG_SOURCES})
+ target_link_libraries(${ARG_TARGET} INTERFACE AdaptiveCpp::acpp-rt)
+ target_compile_options(${ARG_TARGET} PUBLIC ${SYCL_COMPILER_FLAGS})
+ endfunction()
+ function(add_sycl_to_root_target)
+ CMAKE_PARSE_ARGUMENTS(ARG "" "TARGET" "SOURCES" ${ARGN})
+ add_sycl_to_target(TARGET ${ARG_TARGET} SOURCES ${ARG_SOURCES})
+ target_link_libraries(${ARG_TARGET} INTERFACE AdaptiveCpp::acpp-rt)
+ target_compile_options(${ARG_TARGET} PUBLIC ${SYCL_COMPILER_FLAGS})
+ endfunction()
+ message(STATUS "AdaptiveCpp sycl enabled")
+ else()
+ if(fail-on-missing)
+ message(FATAL_ERROR "AdaptiveCpp library not found")
+ else()
+ message(STATUS "AdaptiveCpp library not found")
+ set(sycl OFF CACHE BOOL "Disabled because no SYCL implementation is not found" FORCE)
+ endif()
+ endif()
+ endif()
+endif()
+
#---Check for protobuf-------------------------------------------------------------------
if(tmva-sofie)
diff --git a/math/CMakeLists.txt b/math/CMakeLists.txt
index 543adbf6b1e8d..fddecb1db1a1e 100644
--- a/math/CMakeLists.txt
+++ b/math/CMakeLists.txt
@@ -20,6 +20,9 @@ add_subdirectory(smatrix)
add_subdirectory(splot)
#add_subdirectory(mathcore/test EXCLUDE_FROM_ALL)
add_subdirectory(genvector)
+if(sycl AND experimental_genvectorx)
+ add_subdirectory(experimental/genvectorx)
+endif()
if(tmva)
add_subdirectory(genetic)
endif()
diff --git a/math/experimental/genvectorx/CMakeLists.txt b/math/experimental/genvectorx/CMakeLists.txt
new file mode 100644
index 0000000000000..e0aff45a3b552
--- /dev/null
+++ b/math/experimental/genvectorx/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.
+# All rights reserved.
+#
+# For the licensing terms see $ROOTSYS/LICENSE.
+# For the list of contributors see $ROOTSYS/README/CREDITS.
+
+############################################################################
+# CMakeLists.txt file for building ROOT math/genvector package
+############################################################################
+
+message(STATUS "Experimental GenVectorX")
+
+ ROOT_LINKER_LIBRARY(GenVectorSYCL
+ src/3DConversions.cxx
+ src/3DDistances.cxx
+ src/AxisAngle.cxx
+ src/AxisAngleXother.cxx
+ src/BitReproducible.cxx
+ src/Boost.cxx
+ src/BoostX.cxx
+ src/BoostY.cxx
+ src/BoostZ.cxx
+ src/EulerAngles.cxx
+ src/LorentzRotation.cxx
+ src/Quaternion.cxx
+ src/QuaternionXaxial.cxx
+ src/Rotation3D.cxx
+ src/Rotation3DxAxial.cxx
+ src/RotationZYX.cxx
+ src/VectorUtil.cxx
+ DEPENDENCIES
+ Core
+ MathCore
+ )
+
+ add_sycl_library_to_root_target(
+ TARGET
+ GenVectorSYCL
+ SOURCES
+ src/3DConversions.cxx
+ src/3DDistances.cxx
+ src/AxisAngle.cxx
+ src/AxisAngleXother.cxx
+ src/BitReproducible.cxx
+ src/Boost.cxx
+ src/BoostX.cxx
+ src/BoostY.cxx
+ src/BoostZ.cxx
+ src/EulerAngles.cxx
+ src/LorentzRotation.cxx
+ src/Quaternion.cxx
+ src/QuaternionXaxial.cxx
+ src/Rotation3D.cxx
+ src/Rotation3DxAxial.cxx
+ src/RotationZYX.cxx
+ src/VectorUtil.cxx
+ COMPILE_DEFINITIONS
+ ROOT_MATH_SYCL
+ )
+
+target_compile_definitions(GenVectorSYCL PUBLIC ROOT_MATH_SYCL)
+
+ROOT_ADD_TEST_SUBDIRECTORY(test)
+
+ROOT_INSTALL_HEADERS()
\ No newline at end of file
diff --git a/math/experimental/genvectorx/doc/index.md b/math/experimental/genvectorx/doc/index.md
new file mode 100644
index 0000000000000..00379def5d4ec
--- /dev/null
+++ b/math/experimental/genvectorx/doc/index.md
@@ -0,0 +1,220 @@
+\defgroup GenVector Physics Vectors
+\ingroup Math
+\brief Vector classes (2D, 3D and 4D / Lorentz vector) and their transformations.
+
+These classes represent vectors and their operations and transformations, such as rotations and Lorentz transformations, in two, three and four dimensions.
+The 4D space-time is used for physics vectors representing relativistic particles in [Minkowski-space](https://en.wikipedia.org/wiki/Minkowski_space).
+These vectors are different from Linear Algebra vectors or `std::vector` which describe generic N-dimensional vectors.
+
+Hint: the most commonly used Lorentz vector class is ROOT::Math::PtEtaPhiMVector, a typedef to ROOT::Math::LorentzVector < ROOT::Math::PtEtaPhiM4D < double > >.
+
+## Points and Vector concept
+
+Mathematically, vectors and points are two distinct concepts. They have different
+transformations: vectors can only be rotated, while points can be rotated or translated.
+You can add two vectors but not two points, and the difference between two points is a vector.
+We then distinguish for the 2 and 3 dimensional case, between points and vectors,
+modeling them with different classes:
+* ROOT::Math::DisplacementVector2D and ROOT::Math::DisplacementVector3D describe
+ 2- and 3-component direction and magnitude vectors, not rooted at any particular point;
+* ROOT::Math::PositionVector2D and ROOT::Math::PositionVector3D model points in
+ 2 and 3 dimensions.
+
+ROOT::Math::LorentzVector models 4D space-time vectors. There is no class for a 4D point.
+
+
+\anchor GenVectorCoordinateSystems
+## Coordinate Systems
+
+### Generic Coordinate System
+
+The vector classes are based on a generic type of coordinate system, expressed as a
+template parameter of the class. Various classes exist to describe the various
+coordinates systems:
+* **2D coordinate system** classes:
+ * ROOT::Math::Cartesian2D, based on (x,y) ;
+ * ROOT::Math::Polar2D, based on (r, phi) ;
+* **3D coordinate system** classes:
+ * ROOT::Math::Cartesian3D, based on (x,y,z);
+ * ROOT::Math::Polar3D, based on (r, theta, phi);
+ * ROOT::Math::Cylindrical3D, based on (rho, z, phi)
+ * ROOT::Math::CylindricalEta3D, based on (rho, eta, phi);
+* **4D coordinate system** classes:
+ * ROOT::Math::PxPyPzE4D, based on based on (px,py,pz,E);
+ * ROOT::Math::PxPyPzM4D, based on based on (px,py,pz,M);
+ * ROOT::Math::PtEtaPhiE4D, based on based on (pt,eta,phi,E);
+ * ROOT::Math::PtEtaPhiM4D, based on based on (pt,eta,phi,M);
+
+The angle _theta_ is defined between [0,\f$\pi\f$] and _phi_ between [-\f$\pi\f$,\f$\pi\f$].
+The angles are expressed in radians.
+The _eta_ component is known as [pseudo-rapidity](https://en.wikipedia.org/wiki/Pseudorapidity).
+
+Users can define the Vectors according to the coordinate type which
+is most efficient for their use. Transformations between the various coordinate
+systems are available through copy constructors or the assignment `operator =`.
+The coordinate system classes are templated on the scalar type for maximum flexibility,
+and to minimize memory usage for some use cases.
+
+### Coordinate System Tag
+
+The 2D and 3D point and vector classes can be associated to a tag defining the
+coordinate system. This can be used to distinguish between vectors of different
+coordinate systems like global or local vectors. The coordinate system tag is a
+template parameter of the ROOT::Math::DisplacementVector3D
+(and ROOT::Math::DisplacementVector2D) and ROOT::Math::PositionVector3D
+(and ROOT::Math::PositionVector2D) classes. A default tag,
+ROOT::Math::DefaultCoordinateSystemTag, exists for users who don't need this
+functionality.
+
+
+\anchor GenVectorTypedefs
+## Concrete Vector typedefs
+
+To avoid exposing templated parameters to the users, typedefs are defined for all types of vectors based an `double`s and `float`s.
+The table below lists the `double` versions; the `float` counterpart ends on an extra `F`, such as ROOT::Math::XYPointF instead of ROOT::Math::XYPoint.
+
+### Point2D
+
+Type definitions for points in two dimensions, based on ROOT::Math::PositionVector2D, are defined by `MathX/Point2D.h`:
+
+* ROOT::Math::XYPoint vector based on x,y coordinates (cartesian)
+* ROOT::Math::Polar2DPoint vector based on r,phi coordinates (polar)
+
+### Vector2D
+
+Type definitions for vectors in two dimensions, based on ROOT::Math::DisplacementVector2D, are defined by `MathX/Vector2D.h`:
+
+* ROOT::Math::XYVector vector based on x,y coordinates (cartesian)
+* ROOT::Math::Polar2DVector vector based on r,phi coordinates (polar)
+
+### Point3D
+
+Type definitions for points in three dimensions, based on ROOT::Math::PositionVector3D, are defined by `MathX/Point3D.h`:
+
+* ROOT::Math::XYZPoint point based on x,y,z coordinates (cartesian)
+* ROOT::Math::Polar3DPoint point based on r,theta,phi coordinates (polar)
+* ROOT::Math::RhoZPhiPoint point based on rho,z,phi coordinates (cylindrical using z)
+* ROOT::Math::RhoEtaPhiPoint point based on rho,eta,phi coordinates (cylindrical using eta instead of z)
+
+### Vector3D
+
+Type definitions for vectors in three dimensions, based on ROOT::Math::DisplacementVector3D, are defined by `MathX/Vector3D.h`:
+
+* ROOT::Math::XYZVector vector based on x,y,z coordinates (cartesian)
+* ROOT::Math::Polar3DVector vector based on r,theta,phi coordinates (polar)
+* ROOT::Math::RhoZPhiVector vector based on rho, z,phi coordinates (cylindrical)
+* ROOT::Math::RhoEtaPhiVector vector based on rho,eta,phi coordinates (cylindrical using eta instead of z)
+
+### LorentzVector
+
+Type definitions for Lorentz vectors in four dimensions, based on ROOT::Math::LorentzVector, are defined by `MathX/Vector4D.h`:
+
+* ROOT::Math::XYZTVector vector based on x,y,z,t coordinates (cartesian)
+* ROOT::Math::PtEtaPhiEVector vector based on pt (rho),eta,phi and E (t) coordinates
+* ROOT::Math::PtEtaPhiMVector vector based on pt (rho),eta,phi and M (t) coordinates
+* ROOT::Math::PxPyPzMVector vector based on px,py,pz and M (mass) coordinates
+* ROOT::Math::PxPyPzEVector vector based on px,py,pz and E (energy) coordinates
+
+The metric used for any such LorentzVector is (-,-,-,+).
+
+
+\anchor GenVectorOperations
+## Operations
+
+### Constructors and Assignment
+
+A vector can be constructed from its coordinate representation:
+
+~~~{.cpp}
+ROOT::Math::PtEtaPhiMVector v1(10. /*pt*/, 0.1 /*eta*/, 0.24 /*phi*/, 5 /*M*/);
+~~~
+
+In addition, the vector classes can be constructed from any object that implements the
+accessors x(), y() and z(). This can be a vector using a different coordinate
+system, or even an object from a different package as long as it implements the required signatures.
+One such vector type is CLHEP's `Hep3Vector`:
+
+~~~{.cpp}
+XYZVector v1(1,2,3);
+RhoEtaPhiVector r2(v1);
+CLHEP::Hep3Vector q(1,2,3);
+XYZVector v3(q)
+~~~
+
+### Arithmetic Operations
+
+The following operations are possible between vector classes, even of different
+coordinate system types:
+
+~~~{.cpp}
+v1 += v2;
+v1 -= v2;
+v1 = - v2;
+v1 *= a;
+v1 /= a;
+v2 = a * v1;
+v2 = v1 / a;
+v2 = v1 * a;
+v3 = v1 + v2;
+v3 = v1 - v2;
+~~~
+
+Note that the multiplication between two vectors using the `operator *` is not supported
+because it is ambiguous.
+
+### Other Methods
+
+The vector classes support methods for:
+
+- computation of the dot product via Dot(),
+- computation of the cross product via Cross(),
+- construction of a unit vector via Unit().
+
+
+\anchor GenVectorTransformations
+## Transformations
+
+The transformations are modeled using simple (non-template) classes, using `double` as
+the scalar type to avoid too large numerical errors. The transformations are grouped
+in Rotations (in 3 dimensions), Lorentz transformations. Each group has several members which may
+model physically equivalent transformations but with different internal representations.
+Transformation classes can operate on all type of vectors using the `operator()`
+or the `operator *` and the transformations can also be combined via the `operator *`.
+In more detail the transformations available are:
+
+### 3D Rotations
+
+* ROOT::Math::Rotation3D, rotation described by a 3x3 matrix of doubles
+* ROOT::Math::EulerAngles rotation described by the three Euler angles (phi, theta and psi) following the GoldStein [definition](http://mathworld.wolfram.com/EulerAngles.html).
+* ROOT::Math::RotationZYX rotation described by three angles defining a rotation first along the Z axis, then along the rotated Y' axis and then along the rotated X'' axis.
+* ROOT::Math::AxisAngle, rotation described by a vector (axis) and an angle
+* ROOT::Math::Quaternion, rotation described by a quaternion (4 numbers)
+* ROOT::Math::RotationX, specialized rotation along the X axis
+* ROOT::Math::RotationY, specialized rotation along the Y axis
+* ROOT::Math::RotationZ, specialized rotation along the Z axis
+
+### 3D Transformation
+
+* ROOT::Math::Translation3D, (only translation) described by a 3D vector
+* ROOT::Math::Transform3D, (rotations and then translation) described by a 3x4 matrix (12 numbers)
+
+### Lorentz Rotation
+
+* ROOT::Math::LorentzRotation , 4D rotation (3D rotation plus a boost) described by a 4x4 matrix
+* ROOT::Math::Boost, a Lorentz boost in an arbitrary direction and described by a 4x4 symmetric matrix (10 numbers)
+* ROOT::Math::BoostX, a boost in the X axis direction
+* ROOT::Math::BoostY, a boost in the Y axis direction
+* ROOT::Math::BoostZ, a boost in the Z axis direction
+
+## Compatibility with CLHEP Vector classes
+
+For compatibility with CLHEP, the vector classes can be constructed easily
+from a CLHEP `Hep3Vector` or `HepLorentzVector`, by using a template constructor, which
+requires only that the classes implement the accessors `x()`, `y()` and `z()` (and `t()`
+for `HepLorentzVector`).
+The vector classes also provide member function with the same naming convention
+as CLHEP for the most used functions like `x()`, `y()` and `z()`.
+
+## Additional Documentation
+
+A more detailed description of all the GenVector classes is available in this [document](https://root.cern/topical/GenVector.pdf).
diff --git a/math/experimental/genvectorx/inc/MathX/AxisAngle.h b/math/experimental/genvectorx/inc/MathX/AxisAngle.h
new file mode 100644
index 0000000000000..c392b495d1285
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/AxisAngle.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_AxisAngle
+#define ROOT_MathX_AxisAngle
+
+
+#include "MathX/GenVectorX/AxisAngle.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/Boost.h b/math/experimental/genvectorx/inc/MathX/Boost.h
new file mode 100644
index 0000000000000..1214f34bc12b0
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/Boost.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_Boost
+#define ROOT_MathX_Boost
+
+
+#include "MathX/GenVectorX/Boost.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/BoostX.h b/math/experimental/genvectorx/inc/MathX/BoostX.h
new file mode 100644
index 0000000000000..a37e6085416f2
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/BoostX.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_BoostX
+#define ROOT_MathX_BoostX
+
+
+#include "MathX/GenVectorX/BoostX.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/BoostY.h b/math/experimental/genvectorx/inc/MathX/BoostY.h
new file mode 100644
index 0000000000000..b6b66c9a32927
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/BoostY.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_BoostY
+#define ROOT_MathX_BoostY
+
+
+#include "MathX/GenVectorX/BoostY.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/BoostZ.h b/math/experimental/genvectorx/inc/MathX/BoostZ.h
new file mode 100644
index 0000000000000..dde11746bb429
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/BoostZ.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_BoostZ
+#define ROOT_MathX_BoostZ
+
+
+#include "MathX/GenVectorX/BoostZ.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/Cartesian2D.h b/math/experimental/genvectorx/inc/MathX/Cartesian2D.h
new file mode 100644
index 0000000000000..1c16820ebd474
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/Cartesian2D.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_Cartesian2D
+#define ROOT_MathX_Cartesian2D
+
+
+#include "MathX/GenVectorX/Cartesian2D.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/Cartesian3D.h b/math/experimental/genvectorx/inc/MathX/Cartesian3D.h
new file mode 100644
index 0000000000000..f9bd13558d66d
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/Cartesian3D.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_Cartesian3D
+#define ROOT_MathX_Cartesian3D
+
+
+#include "MathX/GenVectorX/Cartesian3D.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/Cylindrical3D.h b/math/experimental/genvectorx/inc/MathX/Cylindrical3D.h
new file mode 100644
index 0000000000000..ab2701a71f25b
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/Cylindrical3D.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_Cylindrical3D
+#define ROOT_MathX_Cylindrical3D
+
+
+#include "MathX/GenVectorX/Cylindrical3D.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/CylindricalEta3D.h b/math/experimental/genvectorx/inc/MathX/CylindricalEta3D.h
new file mode 100644
index 0000000000000..0bac60e00d9f8
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/CylindricalEta3D.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_CylindricalEta3D
+#define ROOT_MathX_CylindricalEta3D
+
+
+#include "MathX/GenVectorX/CylindricalEta3D.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/DisplacementVector2D.h b/math/experimental/genvectorx/inc/MathX/DisplacementVector2D.h
new file mode 100644
index 0000000000000..4e626b6d04ef4
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/DisplacementVector2D.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_DisplacementVector2D
+#define ROOT_MathX_DisplacementVector2D
+
+
+#include "MathX/GenVectorX/DisplacementVector2D.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/DisplacementVector3D.h b/math/experimental/genvectorx/inc/MathX/DisplacementVector3D.h
new file mode 100644
index 0000000000000..3da419ca28ebb
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/DisplacementVector3D.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_DisplacementVector3D
+#define ROOT_MathX_DisplacementVector3D
+
+
+#include "MathX/GenVectorX/DisplacementVector3D.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/EulerAngles.h b/math/experimental/genvectorx/inc/MathX/EulerAngles.h
new file mode 100644
index 0000000000000..d84337aa93468
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/EulerAngles.h
@@ -0,0 +1,11 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_EulerAngles
+#define ROOT_MathX_EulerAngles
+
+
+#include "MathX/GenVectorX/EulerAngles.h"
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/3DConversions.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/3DConversions.h
new file mode 100644
index 0000000000000..ba2a5b047096f
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/3DConversions.h
@@ -0,0 +1,132 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005, LCG ROOT FNAL MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class Rotation in 3 dimensions, represented by 3x3 matrix
+//
+// Created by: Mark Fischler and Walter Brown Thurs July 7, 2005
+//
+// Last update: Wed Thurs July 7, 2005
+//
+#ifndef ROOT_MathX_GenVectorX_3DConversions
+#define ROOT_MathX_GenVectorX_3DConversions 1
+
+#include "MathX/GenVectorX/Rotation3Dfwd.h"
+#include "MathX/GenVectorX/AxisAnglefwd.h"
+#include "MathX/GenVectorX/EulerAnglesfwd.h"
+#include "MathX/GenVectorX/Quaternionfwd.h"
+#include "MathX/GenVectorX/RotationXfwd.h"
+#include "MathX/GenVectorX/RotationYfwd.h"
+#include "MathX/GenVectorX/RotationZfwd.h"
+#include "MathX/GenVectorX/RotationZYXfwd.h"
+
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+namespace ROOT {
+namespace ROOT_MATH_ARCH {
+
+
+namespace gv_detail {
+
+// flag a link time error when a wrong conversion is instantiated
+ struct ERROR_This_Rotation_Conversion_is_NOT_Supported {
+ ERROR_This_Rotation_Conversion_is_NOT_Supported();
+ };
+template
+void convert( R1 const &, R2 const) {
+ ERROR_This_Rotation_Conversion_is_NOT_Supported();
+}
+
+// ----------------------------------------------------------------------
+// conversions from Rotation3D
+/**
+ conversion functions from 3D rotation.
+ For converting to Euler Angles see
+ here
+ */
+
+void convert( Rotation3D const & from, AxisAngle & to);
+void convert( Rotation3D const & from, EulerAngles & to);
+void convert( Rotation3D const & from, Quaternion & to);
+void convert( Rotation3D const & from, RotationZYX & to);
+
+
+// ----------------------------------------------------------------------
+// conversions from AxisAngle
+
+void convert( AxisAngle const & from, Rotation3D & to);
+void convert( AxisAngle const & from, EulerAngles & to);
+void convert( AxisAngle const & from, Quaternion & to);
+void convert( AxisAngle const & from, RotationZYX & to);
+
+
+// ----------------------------------------------------------------------
+// conversions from EulerAngles
+
+void convert( EulerAngles const & from, Rotation3D & to);
+void convert( EulerAngles const & from, AxisAngle & to);
+void convert( EulerAngles const & from, Quaternion & to);
+void convert( EulerAngles const & from, RotationZYX & to);
+
+
+// ----------------------------------------------------------------------
+// conversions from Quaternion
+
+void convert( Quaternion const & from, Rotation3D & to);
+void convert( Quaternion const & from, AxisAngle & to);
+void convert( Quaternion const & from, EulerAngles & to);
+void convert( Quaternion const & from, RotationZYX & to);
+
+// ----------------------------------------------------------------------
+// conversions from RotationZYX
+
+void convert( RotationZYX const & from, Rotation3D & to);
+void convert( RotationZYX const & from, AxisAngle & to);
+void convert( RotationZYX const & from, EulerAngles & to);
+void convert( RotationZYX const & from, Quaternion & to);
+
+
+// ----------------------------------------------------------------------
+// conversions from RotationX
+
+void convert( RotationX const & from, Rotation3D & to);
+void convert( RotationX const & from, RotationZYX & to);
+void convert( RotationX const & from, AxisAngle & to);
+void convert( RotationX const & from, EulerAngles & to);
+void convert( RotationX const & from, Quaternion & to);
+
+
+// ----------------------------------------------------------------------
+// conversions from RotationY
+
+void convert( RotationY const & from, Rotation3D & to);
+void convert( RotationY const & from, RotationZYX & to);
+void convert( RotationY const & from, AxisAngle & to);
+void convert( RotationY const & from, EulerAngles & to);
+void convert( RotationY const & from, Quaternion & to);
+
+
+// ----------------------------------------------------------------------
+// conversions from RotationZ
+
+void convert( RotationZ const & from, Rotation3D & to);
+void convert( RotationZ const & from, RotationZYX & to);
+void convert( RotationZ const & from, AxisAngle & to);
+void convert( RotationZ const & from, EulerAngles & to);
+void convert( RotationZ const & from, Quaternion & to);
+
+
+} //namespace gv_detail
+} //namespace Math
+} //namespace ROOT
+
+#endif // ROOT_MathX_GenVectorX_3DConversions
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/3DDistances.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/3DDistances.h
new file mode 100644
index 0000000000000..b44860b55fe60
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/3DDistances.h
@@ -0,0 +1,155 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005, LCG ROOT FNAL MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class implementations of Distance() functions among
+// Rotations in 3 dimensions
+//
+// Created by: Mark Fischler and Walter Brown Thurs July 7, 2005
+//
+// Last update: $Id$
+//
+#ifndef ROOT_MathX_GenVectorX_3DDistances
+#define ROOT_MathX_GenVectorX_3DDistances 1
+
+#include "MathX/GenVectorX/Rotation3Dfwd.h"
+#include "MathX/GenVectorX/AxisAnglefwd.h"
+#include "MathX/GenVectorX/EulerAnglesfwd.h"
+#include "MathX/GenVectorX/Quaternionfwd.h"
+#include "MathX/GenVectorX/RotationZYXfwd.h"
+#include "MathX/GenVectorX/RotationXfwd.h"
+#include "MathX/GenVectorX/RotationYfwd.h"
+#include "MathX/GenVectorX/RotationZfwd.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+namespace ROOT {
+namespace ROOT_MATH_ARCH {
+namespace gv_detail {
+
+// Technical note:
+//
+// Most of these functions are identical, converting to Quaternions
+// and then taking the simple distance between two Quaternions. This
+// makes it tempting to use a template function (which could appear in
+// each individual rotation header).
+//
+// However, then we would have to include Quaternion.h in this header,
+// and by induction, each rotation class would depend on Quaternion, which
+// would be undesirable.
+
+
+// ----------------------------------------------------------------------
+// Distance from Rotation3D
+
+double dist( Rotation3D const & r1, Rotation3D const & r2);
+double dist( Rotation3D const & r1, AxisAngle const & r2);
+double dist( Rotation3D const & r1, EulerAngles const & r2);
+double dist( Rotation3D const & r1, Quaternion const & r2);
+double dist( Rotation3D const & r1, RotationZYX const & r2);
+double dist( Rotation3D const & r1, RotationX const & r2);
+double dist( Rotation3D const & r1, RotationY const & r2);
+double dist( Rotation3D const & r1, RotationZ const & r2);
+
+
+// ----------------------------------------------------------------------
+// Distance from AxisAngle
+
+double dist( AxisAngle const & r1, Rotation3D const & r2);
+double dist( AxisAngle const & r1, AxisAngle const & r2);
+double dist( AxisAngle const & r1, EulerAngles const & r2);
+double dist( AxisAngle const & r1, Quaternion const & r2);
+double dist( AxisAngle const & r1, RotationZYX const & r2);
+double dist( AxisAngle const & r1, RotationX const & r2);
+double dist( AxisAngle const & r1, RotationY const & r2);
+double dist( AxisAngle const & r1, RotationZ const & r2);
+
+
+// ----------------------------------------------------------------------
+// Distance from EulerAngles
+
+double dist( EulerAngles const & r1, Rotation3D const & r2);
+double dist( EulerAngles const & r1, AxisAngle const & r2);
+double dist( EulerAngles const & r1, EulerAngles const & r2);
+double dist( EulerAngles const & r1, Quaternion const & r2);
+double dist( EulerAngles const & r1, RotationZYX const & r2);
+double dist( EulerAngles const & r1, RotationX const & r2);
+double dist( EulerAngles const & r1, RotationY const & r2);
+double dist( EulerAngles const & r1, RotationZ const & r2);
+
+
+// ----------------------------------------------------------------------
+// Distance from Quaternion
+
+double dist( Quaternion const & r1, Rotation3D const & r2);
+double dist( Quaternion const & r1, AxisAngle const & r2);
+double dist( Quaternion const & r1, EulerAngles const & r2);
+double dist( Quaternion const & r1, Quaternion const & r2);
+double dist( Quaternion const & r1, RotationZYX const & r2);
+double dist( Quaternion const & r1, RotationX const & r2);
+double dist( Quaternion const & r1, RotationY const & r2);
+double dist( Quaternion const & r1, RotationZ const & r2);
+
+// ----------------------------------------------------------------------
+// Distance from RotationZYX
+
+double dist( RotationZYX const & r1, Rotation3D const & r2);
+double dist( RotationZYX const & r1, AxisAngle const & r2);
+double dist( RotationZYX const & r1, EulerAngles const & r2);
+double dist( RotationZYX const & r1, Quaternion const & r2);
+double dist( RotationZYX const & r1, RotationZYX const & r2);
+double dist( RotationZYX const & r1, RotationX const & r2);
+double dist( RotationZYX const & r1, RotationY const & r2);
+double dist( RotationZYX const & r1, RotationZ const & r2);
+
+
+
+// ----------------------------------------------------------------------
+// Distance from RotationX
+
+double dist( RotationX const & r1, Rotation3D const & r2);
+double dist( RotationX const & r1, AxisAngle const & r2);
+double dist( RotationX const & r1, EulerAngles const & r2);
+double dist( RotationX const & r1, Quaternion const & r2);
+double dist( RotationX const & r1, RotationX const & r2);
+double dist( RotationX const & r1, RotationY const & r2);
+double dist( RotationX const & r1, RotationZ const & r2);
+
+
+// ----------------------------------------------------------------------
+// Distance from RotationY
+
+double dist( RotationY const & r1, Rotation3D const & r2);
+double dist( RotationY const & r1, AxisAngle const & r2);
+double dist( RotationY const & r1, EulerAngles const & r2);
+double dist( RotationY const & r1, Quaternion const & r2);
+double dist( RotationY const & r1, RotationX const & r2);
+double dist( RotationY const & r1, RotationY const & r2);
+double dist( RotationY const & r1, RotationZ const & r2);
+
+
+// ----------------------------------------------------------------------
+// Distance from RotationZ
+
+double dist( RotationZ const & r1, Rotation3D const & r2);
+double dist( RotationZ const & r1, AxisAngle const & r2);
+double dist( RotationZ const & r1, EulerAngles const & r2);
+double dist( RotationZ const & r1, Quaternion const & r2);
+double dist( RotationZ const & r1, RotationX const & r2);
+double dist( RotationZ const & r1, RotationY const & r2);
+double dist( RotationZ const & r1, RotationZ const & r2);
+
+
+} //namespace gv_detail
+} //namespace Math
+} //namespace ROOT
+
+#endif // ROOT_MathX_GenVectorX_3DDistances
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/AccHeaders.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/AccHeaders.h
new file mode 100644
index 0000000000000..c05375a33aa3d
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/AccHeaders.h
@@ -0,0 +1,42 @@
+#ifndef ROOT_AccHeaders_H
+#define ROOT_AccHeaders_H
+
+#if defined(ROOT_MATH_SYCL)
+
+#include
+#ifndef ROOT_MATH_ARCH
+#define ROOT_MATH_ARCH MathSYCL
+#endif // ROOT_MATH_ARCH
+
+#elif defined(ROOT_MATH_CUDA)
+
+#include
+#ifndef ROOT_MATH_ARCH
+#define ROOT_MATH_ARCH MathCUDA
+#endif // ROOT_MATH_ARCH
+
+#else
+
+#include
+#ifndef ROOT_MATH_ARCH
+#define ROOT_MATH_ARCH Math
+#endif // ROOT_MATH_ARCH
+
+#endif
+
+#if defined(ROOT_MATH_CUDA) && defined(__CUDACC__)
+
+#define __roodevice__ __device__
+#define __roohost__ __host__
+#define __rooglobal__ __global__
+
+#else
+
+#define __roodevice__
+#define __roohost__
+#define __rooglobal__
+
+#endif
+
+
+#endif // ROOT_AccHeaders_H
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/AxisAngle.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/AxisAngle.h
new file mode 100644
index 0000000000000..003a89765614b
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/AxisAngle.h
@@ -0,0 +1,349 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+/**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG ROOT MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class AxisAngle
+//
+// Created by: Lorenzo Moneta at Wed May 11 10:37:10 2005
+//
+// Last update: Wed May 11 10:37:10 2005
+//
+#ifndef ROOT_MathX_GenVectorX_AxisAngle
+#define ROOT_MathX_GenVectorX_AxisAngle 1
+
+#include "MathX/GenVectorX/Rotation3D.h"
+#include "MathX/GenVectorX/DisplacementVector3D.h"
+#include "MathX/GenVectorX/PositionVector3D.h"
+#include "MathX/GenVectorX/LorentzVector.h"
+#include "MathX/GenVectorX/3DConversions.h"
+#include
+#include
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+namespace ROOT {
+namespace ROOT_MATH_ARCH {
+
+
+//__________________________________________________________________________________________
+ /**
+ AxisAngle class describing rotation represented with direction axis (3D Vector) and an
+ angle of rotation around that axis.
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+class AxisAngle {
+
+public:
+
+ typedef double Scalar;
+
+ /**
+ definition of vector axis
+ */
+ typedef DisplacementVector3D > AxisVector;
+
+
+ /**
+ Default constructor (axis is z and angle is zero)
+ */
+ AxisAngle() : fAxis(0,0,1), fAngle(0) { }
+
+ /**
+ Construct from a non-zero vector (x,y,z) and an angle.
+ Precondition: the Vector needs to implement x(), y(), z(), and unit()
+ */
+ template
+ AxisAngle(const AnyVector & v, Scalar angle) :
+ fAxis(v.unit()), fAngle(angle) { }
+
+ /**
+ Construct given a pair of pointers or iterators defining the
+ beginning and end of an array of four Scalars, to be treated as
+ the x, y, and z components of a unit axis vector, and the angle
+ of rotation.
+ Precondition: The first three components are assumed to represent
+ the rotation axis vector and the 4-th the rotation angle.
+ The angle is assumed to be in the range (-pi,pi].
+ The axis vector is automatically normalized to be a unit vector
+ */
+ template
+ AxisAngle(IT begin, IT end) { SetComponents(begin,end); }
+
+ // The compiler-generated copy ctor, copy assignment, and dtor are OK.
+
+ /**
+ Re-adjust components to eliminate small deviations from the axis
+ being a unit vector and angles out of the canonical range (-pi,pi]
+ */
+ void Rectify();
+
+ // ======== Construction From other Rotation Forms ==================
+
+ /**
+ Construct from another supported rotation type (see gv_detail::convert )
+ */
+ template
+ explicit AxisAngle(const OtherRotation & r) {gv_detail::convert(r,*this);}
+
+
+ /**
+ Assign from another supported rotation type (see gv_detail::convert )
+ */
+ template
+ AxisAngle & operator=( OtherRotation const & r ) {
+ gv_detail::convert(r,*this);
+ return *this;
+ }
+
+ // ======== Components ==============
+
+ /**
+ Set the axis and then the angle given a pair of pointers or iterators
+ defining the beginning and end of an array of four Scalars.
+ Precondition: The first three components are assumed to represent
+ the rotation axis vector and the 4-th the rotation angle.
+ The angle is assumed to be in the range (-pi,pi].
+ The axis vector is automatically normalized to be a unit vector
+ */
+ template
+ void SetComponents(IT begin, IT end) {
+ IT a = begin; IT b = ++begin; IT c = ++begin;
+ fAxis.SetCoordinates(*a,*b,*c);
+ fAngle = *(++begin);
+ (void)end;
+ assert (++begin==end);
+ // re-normalize the vector
+ double tot = fAxis.R();
+ if (tot > 0) fAxis /= tot;
+ }
+
+ /**
+ Get the axis and then the angle into data specified by an iterator begin
+ and another to the end of the desired data (4 past start).
+ */
+ template
+ void GetComponents(IT begin, IT end) const {
+ IT a = begin; IT b = ++begin; IT c = ++begin;
+ fAxis.GetCoordinates(*a,*b,*c);
+ *(++begin) = fAngle;
+ (void)end;
+ assert (++begin==end);
+ }
+
+ /**
+ Get the axis and then the angle into data specified by an iterator begin
+ */
+ template
+ void GetComponents(IT begin) const {
+ double ax,ay,az = 0;
+ fAxis.GetCoordinates(ax,ay,az);
+ *begin++ = ax;
+ *begin++ = ay;
+ *begin++ = az;
+ *begin = fAngle;
+ }
+
+ /**
+ Set components from a non-zero vector (x,y,z) and an angle.
+ Precondition: the Vector needs to implement x(), y(), z(), and unit()
+ */
+ template
+ void SetComponents(const AnyVector & v, Scalar angle) {
+ fAxis=v.unit();
+ fAngle=angle;
+ }
+
+ /**
+ Set components into a non-zero vector (x,y,z) and an angle.
+ The vector is intended to be a cartesian displacement vector
+ but any vector class assignable from one will work.
+ */
+ template
+ void GetComponents(AnyVector & axis, Scalar & angle) const {
+ axis = fAxis;
+ angle = fAngle;
+ }
+
+ /**
+ access to rotation axis
+ */
+ AxisVector Axis() const { return fAxis; }
+
+ /**
+ access to rotation angle
+ */
+ Scalar Angle() const { return fAngle; }
+
+ // =========== operations ==============
+
+ /**
+ Rotation operation on a cartesian vector
+ */
+ typedef DisplacementVector3D, DefaultCoordinateSystemTag > XYZVector;
+ XYZVector operator() (const XYZVector & v) const;
+
+ /**
+ Rotation operation on a displacement vector in any coordinate system
+ */
+ template
+ DisplacementVector3D
+ operator() (const DisplacementVector3D & v) const {
+ DisplacementVector3D< Cartesian3D > xyz(v.X(), v.Y(), v.Z());
+ DisplacementVector3D< Cartesian3D > rxyz = operator()(xyz);
+ DisplacementVector3D< CoordSystem, Tag > vNew;
+ vNew.SetXYZ( rxyz.X(), rxyz.Y(), rxyz.Z() );
+ return vNew;
+ }
+
+ /**
+ Rotation operation on a position vector in any coordinate system
+ */
+ template
+ PositionVector3D
+ operator() (const PositionVector3D & p) const {
+ DisplacementVector3D< Cartesian3D,Tag > xyz(p);
+ DisplacementVector3D< Cartesian3D,Tag > rxyz = operator()(xyz);
+ return PositionVector3D ( rxyz );
+ }
+
+ /**
+ Rotation operation on a Lorentz vector in any 4D coordinate system
+ */
+ template
+ LorentzVector
+ operator() (const LorentzVector & v) const {
+ DisplacementVector3D< Cartesian3D > xyz(v.Vect());
+ xyz = operator()(xyz);
+ LorentzVector< PxPyPzE4D > xyzt (xyz.X(), xyz.Y(), xyz.Z(), v.E());
+ return LorentzVector ( xyzt );
+ }
+
+
+ /**
+ Rotation operation on an arbitrary vector v.
+ Preconditions: v must implement methods x(), y(), and z()
+ and the arbitrary vector type must have a constructor taking (x,y,z)
+ */
+ template
+ ForeignVector
+ operator() (const ForeignVector & v) const {
+ DisplacementVector3D< Cartesian3D > xyz(v);
+ DisplacementVector3D< Cartesian3D > rxyz = operator()(xyz);
+ return ForeignVector ( rxyz.X(), rxyz.Y(), rxyz.Z() );
+ }
+
+ /**
+ Overload operator * for rotation on a vector
+ */
+ template
+ inline
+ AVector operator* (const AVector & v) const
+ {
+ return operator()(v);
+ }
+
+ /**
+ Invert an AxisAngle rotation in place
+ */
+ void Invert() { fAngle = -fAngle; }
+
+ /**
+ Return inverse of an AxisAngle rotation
+ */
+ AxisAngle Inverse() const { AxisAngle result(*this); result.Invert(); return result; }
+
+ // ========= Multi-Rotation Operations ===============
+
+ /**
+ Multiply (combine) two rotations
+ */
+ AxisAngle operator * (const Rotation3D & r) const;
+ AxisAngle operator * (const AxisAngle & a) const;
+ AxisAngle operator * (const EulerAngles & e) const;
+ AxisAngle operator * (const Quaternion & q) const;
+ AxisAngle operator * (const RotationZYX & r) const;
+ AxisAngle operator * (const RotationX & rx) const;
+ AxisAngle operator * (const RotationY & ry) const;
+ AxisAngle operator * (const RotationZ & rz) const;
+
+ /**
+ Post-Multiply (on right) by another rotation : T = T*R
+ */
+ template
+ AxisAngle & operator *= (const R & r) { return *this = (*this)*r; }
+
+
+ /**
+ Distance between two rotations
+ */
+ template
+ Scalar Distance ( const R & r ) const {return gv_detail::dist(*this,r);}
+
+ /**
+ Equality/inequality operators
+ */
+ bool operator == (const AxisAngle & rhs) const {
+ if( fAxis != rhs.fAxis ) return false;
+ if( fAngle != rhs.fAngle ) return false;
+ return true;
+ }
+ bool operator != (const AxisAngle & rhs) const {
+ return ! operator==(rhs);
+ }
+
+private:
+
+ AxisVector fAxis; // rotation axis (3D vector)
+ Scalar fAngle; // rotation angle
+
+ void RectifyAngle();
+
+ static double Pi() { return 3.14159265358979323; }
+
+}; // AxisAngle
+
+// ============ Class AxisAngle ends here ============
+
+/**
+ Distance between two rotations
+ */
+template
+inline
+typename AxisAngle::Scalar
+Distance ( const AxisAngle& r1, const R & r2) {return gv_detail::dist(r1,r2);}
+
+/**
+ Multiplication of an axial rotation by an AxisAngle
+ */
+AxisAngle operator* (RotationX const & r1, AxisAngle const & r2);
+AxisAngle operator* (RotationY const & r1, AxisAngle const & r2);
+AxisAngle operator* (RotationZ const & r1, AxisAngle const & r2);
+
+/**
+ Stream Output and Input
+ */
+ // TODO - I/O should be put in the manipulator form
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+
+std::ostream & operator<< (std::ostream & os, const AxisAngle & a);
+
+#endif
+
+} // namespace Math
+} // namespace ROOT
+
+
+#endif /* ROOT_MathX_GenVectorX_AxisAngle */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/AxisAnglefwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/AxisAnglefwd.h
new file mode 100644
index 0000000000000..636bc679963ab
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/AxisAnglefwd.h
@@ -0,0 +1,23 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_AxisAnglefwd
+#define ROOT_MathX_GenVectorX_AxisAnglefwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ /**
+ Class describing a rotation represented
+ by an axis and an angle of rotation
+ */
+
+class AxisAngle;
+
+} // namespace Math
+} // namespace ROOT
+
+#endif // ROOT_MathX_GenVectorX_AxisAnglefwd
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/BitReproducible.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/BitReproducible.h
new file mode 100644
index 0000000000000..c7edf0f43079c
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/BitReproducible.h
@@ -0,0 +1,133 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+/**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG / FNAL ROOT MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class LorentzVector
+//
+// Created by: fischler at Mon Jun 25 2005
+//
+// Last update: $Id$
+//
+#ifndef ROOT_MathX_GenVectorX_BitReproducible
+#define ROOT_MathX_GenVectorX_BitReproducible 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+#include
+#include
+#include
+
+#include
+
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+
+namespace ROOT {
+ namespace ROOT_MATH_ARCH {
+ namespace GenVector_detail {
+
+class BitReproducibleException : public std::exception
+{
+public:
+ BitReproducibleException(const std::string & w) noexcept : fMsg(w) {}
+ ~BitReproducibleException() noexcept override {}
+ const char *what() const noexcept override { return fMsg.c_str(); }
+ private:
+ std::string fMsg;
+};
+
+class BitReproducible {
+public:
+
+ // dto2longs(d, i1, i2) returns (in i1 and i2) two unsigned ints
+ // representation of its double input. This is byte-ordering
+ // independent, and depends for complete portability ONLY on adherence
+ // to the IEEE 754 standard for 64-bit floating point representation.
+ // The first unsigned int contains the high-order bits in IEEE; thus
+ // 1.0 will always be 0x3FF00000, 00000000
+ static void Dto2longs(double d, unsigned int & i1, unsigned int & i2);
+
+ // longs2double (i1,i2) returns a double containing the value represented by
+ // its input, which must be a 2 unsigned ints.
+ // The input is taken to be the representation according to
+ // the IEEE 754 standard for a 64-bit floating point number, whose value
+ // is returned as a double. The byte-ordering of the double result is,
+ // of course, tailored to the proper byte-ordering for the system.
+ static double Longs2double (unsigned int i1, unsigned int i2);
+
+ // dtox(d) returns a 16-character string containing the (zero-filled) hex
+ // representation of its double input. This is byte-ordering
+ // independent, and depends for complete portability ONLY on adherence
+ // to the IEEE 754 standard for 64-bit floating point representation.
+ static std::string D2x(double d);
+
+ static void Output ( std::ostream & os, double d ) {
+ unsigned int i1, i2;
+ Dto2longs(d, i1, i2);
+ os << " " << i1 << " " << i2;
+ }
+
+ static void Input ( std::istream & is, double & d ) {
+ unsigned int i1, i2;
+ is >> i1 >> i2;
+ d = Longs2double(i1, i2);
+ }
+
+ static void Output ( std::ostream & os, float f ) {
+ unsigned int i1, i2;
+ Dto2longs( double(f), i1, i2 );
+ os << " " << i1 << " " << i2;
+ }
+
+ static void Input ( std::istream & is, float & f ) {
+ unsigned int i1, i2;
+ is >> i1 >> i2;
+ f = float( Longs2double(i1, i2) );
+ }
+
+
+private:
+ union DB8 {
+ unsigned char fB[8];
+ double fD;
+ };
+ static void Fill_byte_order ();
+ static bool fgByte_order_known;
+ static int fgByte_order[8];
+ // Meaning of byte_order: The first (high-order in IEEE 754) byte to
+ // output (or the high-order byte of the first unsigned int)
+ // is of db.b[byte_order[0]]. Thus the index INTO byte_order
+ // is a position in the IEEE representation of the double, and the value
+ // of byte_order[k] is an offset in the memory representation of the
+ // double.
+
+}; // BitReproducible
+
+} // namespace _GenVector_detail
+} // namespace Math
+} // namespace ROOT
+
+// A note about floats and long doubles:
+//
+// BitReproducible can be used with floats by doing the equivalent of
+// float x = x0; BitReproducible::dto2longs (x, i, j);
+// float y = BitReproducible::longs2double (i, j);
+// The results are correct.
+// The only inefficiency is that two integers are used where one would suffice.
+//
+// The same artifice will compile for long double. However, any value of the
+// long double which is not precisely representable as a double will not
+// give exact results for the read-back.
+//
+// We intend in the near future to create a templated version of this class
+// which cures both the above flaws. (In the case of long double, this is
+// contingent upon finding some IEEE standard for the bits in a 128-bit double.)
+
+#endif
+
+#endif // DOUBCONV_HH
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Boost.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Boost.h
new file mode 100644
index 0000000000000..1710af71c2058
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Boost.h
@@ -0,0 +1,313 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 ROOT FNAL MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for Boost
+//
+// Created by: Mark Fischler Mon Nov 1 2005
+//
+// Last update: $Id$
+//
+#ifndef ROOT_MathX_GenVectorX_Boost
+#define ROOT_MathX_GenVectorX_Boost 1
+
+#include "MathX/GenVectorX/LorentzVector.h"
+#include "MathX/GenVectorX/PxPyPzE4D.h"
+#include "MathX/GenVectorX/DisplacementVector3D.h"
+#include "MathX/GenVectorX/Cartesian3D.h"
+
+#include "MathX/GenVectorX/BoostX.h"
+#include "MathX/GenVectorX/BoostY.h"
+#include "MathX/GenVectorX/BoostZ.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Lorentz boost class with the (4D) transformation represented internally
+ by a 4x4 orthosymplectic matrix.
+ See also BoostX, BoostY and BoostZ for classes representing
+ specialized Lorentz boosts.
+ Also, the 3-D rotation classes can be considered to be special Lorentz
+ transformations which do not mix space and time components.
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+class Boost {
+
+public:
+
+ typedef double Scalar;
+
+ enum ELorentzRotationMatrixIndex {
+ kLXX = 0, kLXY = 1, kLXZ = 2, kLXT = 3
+ , kLYX = 4, kLYY = 5, kLYZ = 6, kLYT = 7
+ , kLZX = 8, kLZY = 9, kLZZ = 10, kLZT = 11
+ , kLTX = 12, kLTY = 13, kLTZ = 14, kLTT = 15
+ };
+
+ enum EBoostMatrixIndex {
+ kXX = 0, kXY = 1, kXZ = 2, kXT = 3
+ , kYY = 4, kYZ = 5, kYT = 6
+ , kZZ = 7, kZT = 8
+ , kTT = 9
+ };
+
+ // ========== Constructors and Assignment =====================
+
+ /**
+ Default constructor (identity transformation)
+ */
+ Boost() { SetIdentity(); }
+
+ /**
+ Construct given a three Scalars beta_x, beta_y, and beta_z
+ */
+ Boost(Scalar beta_x, Scalar beta_y, Scalar beta_z)
+ { SetComponents(beta_x, beta_y, beta_z); }
+
+ /**
+ Construct given a beta vector (which must have methods x(), y(), z())
+ */
+ template
+ explicit
+ Boost(const Avector & beta) { SetComponents(beta); }
+
+ /**
+ Construct given a pair of pointers or iterators defining the
+ beginning and end of an array of three Scalars to use as beta_x, _y, and _z
+ */
+ template
+ Boost(IT begin, IT end) { SetComponents(begin,end); }
+
+ /**
+ copy constructor
+ */
+ Boost(Boost const & b) {
+ *this = b;
+ }
+
+ /**
+ Construct from an axial boost
+ */
+
+ explicit Boost( BoostX const & bx ) {SetComponents(bx.BetaVector());}
+ explicit Boost( BoostY const & by ) {SetComponents(by.BetaVector());}
+ explicit Boost( BoostZ const & bz ) {SetComponents(bz.BetaVector());}
+
+ // The compiler-generated copy ctor, copy assignment, and dtor are OK.
+
+ /**
+ Assignment operator
+ */
+ Boost &
+ operator=(Boost const & rhs ) {
+ for (unsigned int i=0; i < 10; ++i) {
+ fM[i] = rhs.fM[i];
+ }
+ return *this;
+ }
+
+ /**
+ Assign from an axial pure boost
+ */
+ Boost &
+ operator=( BoostX const & bx ) { return operator=(Boost(bx)); }
+ Boost &
+ operator=( BoostY const & by ) { return operator=(Boost(by)); }
+ Boost &
+ operator=( BoostZ const & bz ) { return operator=(Boost(bz)); }
+
+ /**
+ Re-adjust components to eliminate small deviations from a perfect
+ orthosyplectic matrix.
+ */
+ void Rectify();
+
+ // ======== Components ==============
+
+ /**
+ Set components from beta_x, beta_y, and beta_z
+ */
+ void
+ SetComponents (Scalar beta_x, Scalar beta_y, Scalar beta_z);
+
+ /**
+ Get components into beta_x, beta_y, and beta_z
+ */
+ void
+ GetComponents (Scalar& beta_x, Scalar& beta_y, Scalar& beta_z) const;
+
+ /**
+ Set components from a beta vector
+ */
+ template
+ void
+ SetComponents (const Avector & beta)
+ { SetComponents(beta.x(), beta.y(), beta.z()); }
+
+ /**
+ Set given a pair of pointers or iterators defining the beginning and end of
+ an array of three Scalars to use as beta_x,beta _y, and beta_z
+ */
+ template
+ void SetComponents(IT begin, IT end) {
+ IT a = begin; IT b = ++begin; IT c = ++begin;
+ (void)end;
+ assert (++begin==end);
+ SetComponents (*a, *b, *c);
+ }
+
+ /**
+ Get given a pair of pointers or iterators defining the beginning and end of
+ an array of three Scalars into which to place beta_x, beta_y, and beta_z
+ */
+ template
+ void GetComponents(IT begin, IT end) const {
+ IT a = begin; IT b = ++begin; IT c = ++begin;
+ (void)end;
+ assert (++begin==end);
+ GetComponents (*a, *b, *c);
+ }
+
+ /**
+ Get given a pointer or an iterator defining the beginning of
+ an array into which to place beta_x, beta_y, and beta_z
+ */
+ template
+ void GetComponents(IT begin ) const {
+ double bx,by,bz = 0;
+ GetComponents (bx,by,bz);
+ *begin++ = bx;
+ *begin++ = by;
+ *begin = bz;
+ }
+
+ /**
+ The beta vector for this boost
+ */
+ typedef DisplacementVector3D, DefaultCoordinateSystemTag > XYZVector;
+ XYZVector BetaVector() const;
+
+ /**
+ Get elements of internal 4x4 symmetric representation, into a data
+ array suitable for direct use as the components of a LorentzRotation
+ Note -- 16 Scalars will be written into the array; if the array is not
+ that large, then this will lead to undefined behavior.
+ */
+ void
+ GetLorentzRotation (Scalar r[]) const;
+
+ // =========== operations ==============
+
+ /**
+ Lorentz transformation operation on a Minkowski ('Cartesian')
+ LorentzVector
+ */
+ LorentzVector< PxPyPzE4D >
+ operator() (const LorentzVector< PxPyPzE4D > & v) const;
+
+ /**
+ Lorentz transformation operation on a LorentzVector in any
+ coordinate system
+ */
+ template
+ LorentzVector
+ operator() (const LorentzVector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return LorentzVector ( r_xyzt );
+ }
+
+ /**
+ 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
+ Foreign4Vector
+ operator() (const Foreign4Vector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return Foreign4Vector ( r_xyzt.X(), r_xyzt.Y(), r_xyzt.Z(), r_xyzt.T() );
+ }
+
+ /**
+ Overload operator * for boost on a vector
+ */
+ template
+ inline
+ A4Vector operator* (const A4Vector & v) const
+ {
+ return operator()(v);
+ }
+
+ /**
+ Invert a Boost in place
+ */
+ void Invert();
+
+ /**
+ Return inverse of a boost
+ */
+ Boost Inverse() const;
+
+ /**
+ Equality/inequality operators
+ */
+ bool operator == (const Boost & rhs) const {
+ for (unsigned int i=0; i < 10; ++i) {
+ if( fM[i] != rhs.fM[i] ) return false;
+ }
+ return true;
+ }
+ bool operator != (const Boost & rhs) const {
+ return ! operator==(rhs);
+ }
+
+protected:
+
+ void SetIdentity();
+
+private:
+
+ Scalar fM[10];
+
+}; // Boost
+
+// ============ Class Boost ends here ============
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+
+/**
+ Stream Output and Input
+ */
+ // TODO - I/O should be put in the manipulator form
+
+std::ostream & operator<< (std::ostream & os, const Boost & b);
+#endif
+
+} //namespace Math
+} //namespace ROOT
+
+
+
+
+
+
+
+#endif /* ROOT_MathX_GenVectorX_Boost */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostX.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostX.h
new file mode 100644
index 0000000000000..d14c20ca32017
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostX.h
@@ -0,0 +1,225 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 ROOT FNAL MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for BoostX
+//
+// Created by: Mark Fischler Mon Nov 1 2005
+//
+// Last update: $Id$
+//
+#ifndef ROOT_MathX_GenVectorX_BoostX
+#define ROOT_MathX_GenVectorX_BoostX 1
+
+#include "MathX/GenVectorX/LorentzVector.h"
+#include "MathX/GenVectorX/PxPyPzE4D.h"
+#include "MathX/GenVectorX/DisplacementVector3D.h"
+#include "MathX/GenVectorX/Cartesian3D.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+namespace ROOT {
+
+namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Class representing a Lorentz Boost along the X axis, by beta.
+ For efficiency, gamma is held as well.
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+class BoostX {
+
+public:
+
+ typedef double Scalar;
+
+ enum ELorentzRotationMatrixIndex {
+ kLXX = 0, kLXY = 1, kLXZ = 2, kLXT = 3
+ , kLYX = 4, kLYY = 5, kLYZ = 6, kLYT = 7
+ , kLZX = 8, kLZY = 9, kLZZ = 10, kLZT = 11
+ , kLTX = 12, kLTY = 13, kLTZ = 14, kLTT = 15
+ };
+
+ enum EBoostMatrixIndex {
+ kXX = 0, kXY = 1, kXZ = 2, kXT = 3
+ , kYY = 4, kYZ = 5, kYT = 6
+ , kZZ = 7, kZT = 8
+ , kTT = 9
+ };
+
+ // ========== Constructors and Assignment =====================
+
+ /**
+ Default constructor (identity transformation)
+ */
+ BoostX();
+
+ /**
+ Construct given a Scalar beta_x
+ */
+ explicit BoostX(Scalar beta_x) { SetComponents(beta_x); }
+
+
+ // The compiler-generated copy ctor, copy assignment, and dtor are OK.
+
+ /**
+ Re-adjust components to eliminate small deviations from a perfect
+ orthosyplectic matrix.
+ */
+ void Rectify();
+
+ // ======== Components ==============
+
+ /**
+ Set components from a Scalar beta_x
+ */
+ void
+ SetComponents (Scalar beta_x);
+
+ /**
+ Get components into a Scalar beta_x
+ */
+ void
+ GetComponents (Scalar& beta_x) const;
+
+
+ /**
+ Retrieve the beta of the Boost
+ */
+ Scalar Beta() const { return fBeta; }
+
+ /**
+ Retrieve the gamma of the Boost
+ */
+ Scalar Gamma() const { return fGamma; }
+
+ /**
+ Set the given beta of the Boost
+ */
+ void SetBeta(Scalar beta) { SetComponents(beta); }
+
+ /**
+ The beta vector for this boost
+ */
+ typedef DisplacementVector3D, DefaultCoordinateSystemTag > XYZVector;
+ XYZVector BetaVector() const;
+
+ /**
+ Get elements of internal 4x4 symmetric representation, into a data
+ array suitable for direct use as the components of a LorentzRotation
+ Note -- 16 Scalars will be written into the array; if the array is not
+ that large, then this will lead to undefined behavior.
+ */
+ void
+ GetLorentzRotation (Scalar r[]) const;
+
+ // =========== operations ==============
+
+ /**
+ Lorentz transformation operation on a Minkowski ('Cartesian')
+ LorentzVector
+ */
+ LorentzVector< PxPyPzE4D >
+ operator() (const LorentzVector< PxPyPzE4D > & v) const;
+
+ /**
+ Lorentz transformation operation on a LorentzVector in any
+ coordinate system
+ */
+ template
+ LorentzVector
+ operator() (const LorentzVector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return LorentzVector ( r_xyzt );
+ }
+
+ /**
+ 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
+ Foreign4Vector
+ operator() (const Foreign4Vector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return Foreign4Vector ( r_xyzt.X(), r_xyzt.Y(), r_xyzt.Z(), r_xyzt.T() );
+ }
+
+ /**
+ Overload operator * for operation on a vector
+ */
+ template
+ inline
+ A4Vector operator* (const A4Vector & v) const
+ {
+ return operator()(v);
+ }
+
+ /**
+ Invert a BoostX in place
+ */
+ void Invert();
+
+ /**
+ Return inverse of a boost
+ */
+ BoostX Inverse() const;
+
+ /**
+ Equality/inequality operators
+ */
+ bool operator == (const BoostX & rhs) const {
+ if( fBeta != rhs.fBeta ) return false;
+ if( fGamma != rhs.fGamma ) return false;
+ return true;
+ }
+
+ bool operator != (const BoostX & rhs) const {
+ return ! operator==(rhs);
+ }
+
+private:
+
+ Scalar fBeta; // boost beta X
+ Scalar fGamma; // boost gamma
+
+}; // BoostX
+
+// ============ Class BoostX ends here ============
+
+
+/**
+ Stream Output and Input
+*/
+// TODO - I/O should be put in the manipulator form
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+
+std::ostream & operator<< (std::ostream & os, const BoostX & b);
+
+#endif
+
+} //namespace Math
+} //namespace ROOT
+
+
+
+
+
+
+
+#endif /* ROOT_MathX_GenVectorX_BoostX */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostXfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostXfwd.h
new file mode 100644
index 0000000000000..1c0884b2bbb6f
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostXfwd.h
@@ -0,0 +1,23 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_BoostXfwd
+#define ROOT_MathX_GenVectorX_BoostXfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ /**
+ Class describing a pure Lorentz Boost along the X axis
+ */
+
+class BoostX;
+
+} // namespace Math
+} // namespace ROOT
+
+#endif // ROOT_MathX_GenVectorX_BoostXfwd
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostY.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostY.h
new file mode 100644
index 0000000000000..25b499a99a5f9
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostY.h
@@ -0,0 +1,221 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 ROOT FNAL MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for BoostY
+//
+// Created by: Mark Fischler Mon Nov 1 2005
+//
+// Last update: $Id$
+//
+#ifndef ROOT_MathX_GenVectorX_BoostY
+#define ROOT_MathX_GenVectorX_BoostY 1
+
+#include "MathX/GenVectorX/LorentzVector.h"
+#include "MathX/GenVectorX/PxPyPzE4D.h"
+#include "MathX/GenVectorX/DisplacementVector3D.h"
+#include "MathX/GenVectorX/Cartesian3D.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+namespace ROOT {
+
+namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Class representing a Lorentz Boost along the Y axis, by beta.
+ For efficiency, gamma is held as well.
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+class BoostY {
+
+public:
+
+ typedef double Scalar;
+
+ enum ELorentzRotationMatrixIndex {
+ kLXX = 0, kLXY = 1, kLXZ = 2, kLXT = 3
+ , kLYX = 4, kLYY = 5, kLYZ = 6, kLYT = 7
+ , kLZX = 8, kLZY = 9, kLZZ = 10, kLZT = 11
+ , kLTX = 12, kLTY = 13, kLTZ = 14, kLTT = 15
+ };
+
+ enum EBoostMatrixIndex {
+ kXX = 0, kXY = 1, kXZ = 2, kXT = 3
+ , kYY = 4, kYZ = 5, kYT = 6
+ , kZZ = 7, kZT = 8
+ , kTT = 9
+ };
+
+ // ========== Constructors and Assignment =====================
+
+ /**
+ Default constructor (identity transformation)
+ */
+ BoostY();
+
+ /**
+ Construct given a Scalar beta_y
+ */
+ explicit BoostY(Scalar beta_y) { SetComponents(beta_y); }
+
+
+ // The compiler-generated copy ctor, copy assignment, and dtor are OK.
+
+ /**
+ Re-adjust components to eliminate small deviations from a perfect
+ orthosyplectic matrix.
+ */
+ void Rectify();
+
+ // ======== Components ==============
+
+ /**
+ Set components from a Scalar beta_y
+ */
+ void
+ SetComponents (Scalar beta_y);
+
+ /**
+ Get components into a Scalar beta_y
+ */
+ void
+ GetComponents (Scalar& beta_y) const;
+
+
+ /**
+ Retrieve the beta of the Boost
+ */
+ Scalar Beta() const { return fBeta; }
+
+ /**
+ Retrieve the gamma of the Boost
+ */
+ Scalar Gamma() const { return fGamma; }
+
+ /**
+ Set the given beta of the Boost
+ */
+ void SetBeta(Scalar beta) { SetComponents(beta); }
+
+ /**
+ The beta vector for this boost
+ */
+ typedef DisplacementVector3D, DefaultCoordinateSystemTag > XYZVector;
+ XYZVector BetaVector() const;
+
+ /**
+ Get elements of internal 4x4 symmetric representation, into a data
+ array suitable for direct use as the components of a LorentzRotation
+ Note -- 16 Scalars will be written into the array; if the array is not
+ that large, then this will lead to undefined behavior.
+ */
+ void
+ GetLorentzRotation (Scalar r[]) const;
+
+ // =========== operations ==============
+
+ /**
+ Lorentz transformation operation on a Minkowski ('Cartesian')
+ LorentzVector
+ */
+ LorentzVector< PxPyPzE4D >
+ operator() (const LorentzVector< PxPyPzE4D > & v) const;
+
+ /**
+ Lorentz transformation operation on a LorentzVector in any
+ coordinate system
+ */
+ template
+ LorentzVector
+ operator() (const LorentzVector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return LorentzVector ( r_xyzt );
+ }
+
+ /**
+ 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
+ Foreign4Vector
+ operator() (const Foreign4Vector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return Foreign4Vector ( r_xyzt.X(), r_xyzt.Y(), r_xyzt.Z(), r_xyzt.T() );
+ }
+
+ /**
+ Overload operator * for rotation on a vector
+ */
+ template
+ inline
+ A4Vector operator* (const A4Vector & v) const
+ {
+ return operator()(v);
+ }
+
+ /**
+ Invert a BoostY in place
+ */
+ void Invert();
+
+ /**
+ Return inverse of a rotation
+ */
+ BoostY Inverse() const;
+
+ /**
+ Equality/inequality operators
+ */
+ bool operator == (const BoostY & rhs) const {
+ if( fBeta != rhs.fBeta ) return false;
+ if( fGamma != rhs.fGamma ) return false;
+ return true;
+ }
+ bool operator != (const BoostY & rhs) const {
+ return ! operator==(rhs);
+ }
+
+private:
+
+ Scalar fBeta; // beta Y of the Boost
+ Scalar fGamma; // gamma of the Boost
+
+}; // BoostY
+
+// ============ Class BoostY ends here ============
+
+/**
+ Stream Output and Input
+*/
+ // TODO - I/O should be put in the manipulator form
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+ std::ostream & operator<< (std::ostream & os, const BoostY & b);
+#endif
+
+} //namespace Math
+} //namespace ROOT
+
+
+
+
+
+
+
+#endif /* ROOT_MathX_GenVectorX_BoostY */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostYfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostYfwd.h
new file mode 100644
index 0000000000000..80a6600b379d9
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostYfwd.h
@@ -0,0 +1,22 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_BoostYfwd
+#define ROOT_MathX_GenVectorX_BoostYfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ /**
+ Class describing a pure Lorentz Boost along the Y axis
+ */
+
+class BoostY;
+
+} // namespace Math
+} // namespace ROOT
+
+#endif // ROOT_MathX_GenVectorX_BoostYfwd
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostZ.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostZ.h
new file mode 100644
index 0000000000000..ca8162aeea9ff
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostZ.h
@@ -0,0 +1,221 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 ROOT FNAL MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for BoostZ
+//
+// Created by: Mark Fischler Mon Nov 1 2005
+//
+// Last update: $Id$
+//
+#ifndef ROOT_MathX_GenVectorX_BoostZ
+#define ROOT_MathX_GenVectorX_BoostZ 1
+
+#include "MathX/GenVectorX/LorentzVector.h"
+#include "MathX/GenVectorX/PxPyPzE4D.h"
+#include "MathX/GenVectorX/DisplacementVector3D.h"
+#include "MathX/GenVectorX/Cartesian3D.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Class representing a Lorentz Boost along the Z axis, by beta.
+ For efficiency, gamma is held as well.
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+class BoostZ {
+
+public:
+
+ typedef double Scalar;
+
+ enum ELorentzRotationMatrixIndex {
+ kLXX = 0, kLXY = 1, kLXZ = 2, kLXT = 3
+ , kLYX = 4, kLYY = 5, kLYZ = 6, kLYT = 7
+ , kLZX = 8, kLZY = 9, kLZZ = 10, kLZT = 11
+ , kLTX = 12, kLTY = 13, kLTZ = 14, kLTT = 15
+ };
+
+ enum EBoostMatrixIndex {
+ kXX = 0, kXY = 1, kXZ = 2, kXT = 3
+ , kYY = 4, kYZ = 5, kYT = 6
+ , kZZ = 7, kZT = 8
+ , kTT = 9
+ };
+
+ // ========== Constructors and Assignment =====================
+
+ /**
+ Default constructor (identity transformation)
+ */
+ BoostZ();
+
+ /**
+ Construct given a Scalar beta_z
+ */
+ explicit BoostZ(Scalar beta_z) { SetComponents(beta_z); }
+
+
+ // The compiler-generated copy ctor, copy assignment, and dtor are OK.
+
+ /**
+ Re-adjust components to eliminate small deviations from a perfect
+ orthosyplectic matrix.
+ */
+ void Rectify();
+
+ // ======== Components ==============
+
+ /**
+ Set components from a Scalar beta_z
+ */
+ void
+ SetComponents (Scalar beta_z);
+
+ /**
+ Get components into a Scalar beta_z
+ */
+ void
+ GetComponents (Scalar& beta_z) const;
+
+
+ /**
+ Retrieve the beta of the Boost
+ */
+ Scalar Beta() const { return fBeta; }
+
+ /**
+ Retrieve the gamma of the Boost
+ */
+ Scalar Gamma() const { return fGamma; }
+
+ /**
+ Set the given beta of the Boost
+ */
+ void SetBeta(Scalar beta) { SetComponents(beta); }
+
+ /**
+ The beta vector for this boost
+ */
+ typedef DisplacementVector3D, DefaultCoordinateSystemTag > XYZVector;
+ XYZVector BetaVector() const;
+
+ /**
+ Get elements of internal 4x4 symmetric representation, into a data
+ array suitable for direct use as the components of a LorentzRotation
+ Note -- 16 Scalars will be written into the array; if the array is not
+ that large, then this will lead to undefined behavior.
+ */
+ void
+ GetLorentzRotation (Scalar r[]) const;
+
+ // =========== operations ==============
+
+ /**
+ Lorentz transformation operation on a Minkowski ('Cartesian')
+ LorentzVector
+ */
+ LorentzVector< PxPyPzE4D >
+ operator() (const LorentzVector< PxPyPzE4D > & v) const;
+
+ /**
+ Lorentz transformation operation on a LorentzVector in any
+ coordinate system
+ */
+ template
+ LorentzVector
+ operator() (const LorentzVector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return LorentzVector ( r_xyzt );
+ }
+
+ /**
+ 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
+ Foreign4Vector
+ operator() (const Foreign4Vector & v) const {
+ LorentzVector< PxPyPzE4D > xyzt(v);
+ LorentzVector< PxPyPzE4D > r_xyzt = operator()(xyzt);
+ return Foreign4Vector ( r_xyzt.X(), r_xyzt.Y(), r_xyzt.Z(), r_xyzt.T() );
+ }
+
+ /**
+ Overload operator * for boost on a vector
+ */
+ template
+ inline
+ A4Vector operator* (const A4Vector & v) const
+ {
+ return operator()(v);
+ }
+
+ /**
+ Invert a BoostZ in place
+ */
+ void Invert();
+
+ /**
+ Return inverse of a BoostZ
+ */
+ BoostZ Inverse() const;
+
+ /**
+ Equality/inequality operators
+ */
+ bool operator == (const BoostZ & rhs) const {
+ if( fBeta != rhs.fBeta ) return false;
+ if( fGamma != rhs.fGamma ) return false;
+ return true;
+ }
+ bool operator != (const BoostZ & rhs) const {
+ return ! operator==(rhs);
+ }
+
+private:
+
+ Scalar fBeta; // boost beta z
+ Scalar fGamma; // boost gamma
+
+}; // BoostZ
+
+// ============ Class BoostZ ends here ============
+
+/**
+ Stream Output and Input
+ */
+ // TODO - I/O should be put in the manipulator form
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+std::ostream & operator<< (std::ostream & os, const BoostZ & b);
+#endif
+
+} //namespace Math
+} //namespace ROOT
+
+
+
+
+
+
+
+#endif /* ROOT_MathX_GenVectorX_BoostZ */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostZfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostZfwd.h
new file mode 100644
index 0000000000000..332ee46a63d75
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/BoostZfwd.h
@@ -0,0 +1,22 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_BoostZfwd
+#define ROOT_MathX_GenVectorX_BoostZfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ /**
+ Class describing a pure Lorentz Boost along the Z axis
+ */
+
+class BoostZ;
+
+} // namespace Math
+} // namespace ROOT
+
+#endif // ROOT_MathX_GenVectorX_BoostZfwd
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Boostfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Boostfwd.h
new file mode 100644
index 0000000000000..ee7caa860b187
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Boostfwd.h
@@ -0,0 +1,22 @@
+// @(#)root/mathcore:$Id$
+// Authors: M. Fischler 2005
+
+#ifndef ROOT_MathX_GenVectorX_Boostfwd
+#define ROOT_MathX_GenVectorX_Boostfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ /**
+ Class describing a pure boost in some direction
+ */
+
+class Boost;
+
+} // namespace Math
+} // namespace ROOT
+
+#endif // ROOT_MathX_GenVectorX_Boostfwd
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian2D.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian2D.h
new file mode 100644
index 0000000000000..c9160e6c09fa2
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian2D.h
@@ -0,0 +1,260 @@
+// @(#)root/mathcore:$Id: b12794c790afad19142e34a401af6c233aba446b $
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG ROOT MathLib Team *
+ * & FNAL LCG ROOT Mathlib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class Cartesian2D
+//
+// Created by: Lorenzo Moneta at Mon 16 Apr 2007
+//
+#ifndef ROOT_MathX_GenVectorX_Cartesian2D
+#define ROOT_MathX_GenVectorX_Cartesian2D 1
+
+#include "MathX/GenVectorX/Polar2Dfwd.h"
+
+#include "Math/Math.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+namespace ROOT {
+
+namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Class describing a 2D cartesian coordinate system
+ (x, y coordinates)
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+template
+class Cartesian2D {
+
+public :
+
+ typedef T Scalar;
+
+ /**
+ Default constructor with x=y=0
+ */
+ Cartesian2D() : fX(0.0), fY(0.0) { }
+
+ /**
+ Constructor from x,y coordinates
+ */
+ Cartesian2D(Scalar xx, Scalar yy) : fX(xx), fY(yy) { }
+
+ /**
+ Construct from any Vector or coordinate system implementing
+ X() and Y()
+ */
+ template
+ explicit Cartesian2D(const CoordSystem & v)
+ : fX(v.X()), fY(v.Y()) { }
+
+
+ // for g++ 3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
+ // re-implement them ( there is no no need to have them with g++4)
+ /**
+ copy constructor
+ */
+ Cartesian2D(const Cartesian2D & v) :
+ fX(v.X()), fY(v.Y()) { }
+
+ /**
+ assignment operator
+ */
+ Cartesian2D & operator= (const Cartesian2D & v) {
+ fX = v.X();
+ fY = v.Y();
+ return *this;
+ }
+
+ /**
+ Set internal data based on 2 Scalar numbers
+ */
+ void SetCoordinates(Scalar xx, Scalar yy) { fX=xx; fY=yy; }
+
+ /**
+ get internal data into 2 Scalar numbers
+ */
+ void GetCoordinates(Scalar& xx, Scalar& yy ) const {xx=fX; yy=fY; }
+
+ Scalar X() const { return fX;}
+ Scalar Y() const { return fY;}
+ Scalar Mag2() const { return fX*fX + fY*fY; }
+ Scalar R() const { return math_sqrt(Mag2()); }
+ Scalar Phi() const { return (fX == Scalar(0) && fY == Scalar(0)) ? Scalar(0) : math_atan2(fY, fX); }
+
+ /**
+ set the x coordinate value keeping y constant
+ */
+ void SetX(Scalar a) { fX = a; }
+
+ /**
+ set the y coordinate value keeping x constant
+ */
+ void SetY(Scalar a) { fY = a; }
+
+ /**
+ set all values using cartesian coordinates
+ */
+ void SetXY(Scalar xx, Scalar yy ) {
+ fX=xx;
+ fY=yy;
+ }
+
+ /**
+ scale the vector by a scalar quantity a
+ */
+ void Scale(Scalar a) { fX *= a; fY *= a; }
+
+ /**
+ negate the vector
+ */
+ void Negate() { fX = -fX; fY = -fY; }
+
+ /**
+ rotate by an angle
+ */
+ void Rotate(Scalar angle) {
+ const Scalar s = math_sin(angle);
+ const Scalar c = math_cos(angle);
+ SetCoordinates(c * fX - s * fY, s * fX + c * fY);
+ }
+
+ /**
+ Assignment from any class implementing x(),y()
+ (can assign from any coordinate system)
+ */
+ template
+ Cartesian2D & operator = (const CoordSystem & v) {
+ fX = v.x();
+ fY = v.y();
+ return *this;
+ }
+
+ /**
+ Exact equality
+ */
+ bool operator == (const Cartesian2D & rhs) const {
+ return fX == rhs.fX && fY == rhs.fY;
+ }
+ bool operator != (const Cartesian2D & rhs) const {return !(operator==(rhs));}
+
+
+ // ============= Compatibility section ==================
+
+ // The following make this coordinate system look enough like a CLHEP
+ // vector that an assignment member template can work with either
+ Scalar x() const { return X();}
+ Scalar y() const { return Y();}
+
+ // ============= Overloads for improved speed ==================
+
+ template
+ explicit Cartesian2D( const Polar2D & v )
+ {
+ const Scalar r = v.R(); // re-using this instead of calling v.X() and v.Y()
+ // is the speed improvement
+ fX = r * math_cos(v.Phi());
+ fY = r * math_sin(v.Phi());
+ }
+ // Technical note: This works even though only Polar2Dfwd.h is
+ // included (and in fact, including Polar2D.h would cause circularity
+ // problems). It works because any program **using** this ctor must itself
+ // be including Polar2D.h.
+
+ template
+ Cartesian2D & operator = (const Polar2D & v)
+ {
+ const Scalar r = v.R();
+ fX = r * math_cos(v.Phi());
+ fY = r * math_sin(v.Phi());
+ return *this;
+ }
+
+
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+
+ // ====== Set member functions for coordinates in other systems =======
+
+ void SetR(Scalar r);
+
+ void SetPhi(Scalar phi);
+
+#endif
+
+
+private:
+
+ /**
+ (Contiguous) data containing the coordinates values x and y
+ */
+ T fX;
+ T fY;
+
+};
+
+
+ } // end namespace ROOT_MATH_ARCH
+
+} // end namespace ROOT
+
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+// need to put here setter methods to resolve nasty cyclical dependencies
+// I need to include other coordinate systems only when Cartesian is already defined
+// since they depend on it
+
+#include "MathX/GenVectorX/GenVector_exception.h"
+#include "MathX/GenVectorX/Polar2D.h"
+
+// ====== Set member functions for coordinates in other systems =======
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ template
+ void Cartesian2D::SetR(Scalar r) {
+ GenVector_exception e("Cartesian2D::SetR() is not supposed to be called");
+ throw e;
+ Polar2D v(*this); v.SetR(r); *this = Cartesian2D(v);
+ }
+
+
+ template
+ void Cartesian2D::SetPhi(Scalar phi) {
+ GenVector_exception e("Cartesian2D::SetPhi() is not supposed to be called");
+ throw e;
+ Polar2D v(*this); v.SetPhi(phi); *this = Cartesian2D(v);
+ }
+
+
+
+ } // end namespace Math
+
+} // end namespace ROOT
+
+#endif
+#endif
+
+
+
+#endif /* ROOT_MathX_GenVectorX_Cartesian2D */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian2Dfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian2Dfwd.h
new file mode 100644
index 0000000000000..406b76a806567
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian2Dfwd.h
@@ -0,0 +1,21 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_Cartesian2Dfwd
+#define ROOT_MathX_GenVectorX_Cartesian2Dfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ template
+ class Cartesian2D;
+
+ } // end namespace Math
+
+} // end namespace ROOT
+
+
+#endif /* ROOT_MathX_GenVectorX_Cartesian2Dfwd */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian3D.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian3D.h
new file mode 100644
index 0000000000000..d8dcdb72bdcb1
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian3D.h
@@ -0,0 +1,320 @@
+// @(#)root/mathcore:$Id: 2fd203872f434b1e4e74933903abb3429494ea6f $
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG ROOT MathLib Team *
+ * & FNAL LCG ROOT Mathlib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class Cartesian3D
+//
+// Created by: Lorenzo Moneta at Mon May 30 11:16:56 2005
+// Major revamp: M. FIschler at Wed Jun 8 2005
+//
+// Last update: $ID: $
+//
+#ifndef ROOT_MathX_GenVectorX_Cartesian3D
+#define ROOT_MathX_GenVectorX_Cartesian3D 1
+
+#include "MathX/GenVectorX/Polar3Dfwd.h"
+
+#include "Math/Math.h"
+
+#include "MathX/GenVectorX/eta.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+#include
+#include
+
+
+namespace ROOT {
+
+namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Class describing a 3D cartesian coordinate system
+ (x, y, z coordinates)
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+template
+class Cartesian3D {
+
+public :
+
+ typedef T Scalar;
+
+ /**
+ Default constructor with x=y=z=0
+ */
+ Cartesian3D() : fX(0.0), fY(0.0), fZ(0.0) { }
+
+ /**
+ Constructor from x,y,z coordinates
+ */
+ Cartesian3D(Scalar xx, Scalar yy, Scalar zz) : fX(xx), fY(yy), fZ(zz) { }
+
+ /**
+ Construct from any Vector or coordinate system implementing
+ X(), Y() and Z()
+ */
+ template
+ explicit Cartesian3D(const CoordSystem & v)
+ : fX(v.X()), fY(v.Y()), fZ(v.Z()) { }
+
+ // for g++ 3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
+ // re-implement them ( there is no no need to have them with g++4)
+ /**
+ copy constructor
+ */
+ Cartesian3D(const Cartesian3D & v) :
+ fX(v.X()), fY(v.Y()), fZ(v.Z()) { }
+
+ /**
+ assignment operator
+ */
+ Cartesian3D & operator= (const Cartesian3D & v) {
+ fX = v.x();
+ fY = v.y();
+ fZ = v.z();
+ return *this;
+ }
+
+ /**
+ Set internal data based on an array of 3 Scalar numbers
+ */
+ void SetCoordinates( const Scalar src[] ) { fX=src[0]; fY=src[1]; fZ=src[2]; }
+
+ /**
+ get internal data into an array of 3 Scalar numbers
+ */
+ void GetCoordinates( Scalar dest[] ) const
+ { dest[0] = fX; dest[1] = fY; dest[2] = fZ; }
+
+ /**
+ Set internal data based on 3 Scalar numbers
+ */
+ void SetCoordinates(Scalar xx, Scalar yy, Scalar zz) { fX=xx; fY=yy; fZ=zz; }
+
+ /**
+ get internal data into 3 Scalar numbers
+ */
+ void GetCoordinates(Scalar& xx, Scalar& yy, Scalar& zz) const {xx=fX; yy=fY; zz=fZ;}
+
+ Scalar X() const { return fX;}
+ Scalar Y() const { return fY;}
+ Scalar Z() const { return fZ;}
+ Scalar Mag2() const { return fX*fX + fY*fY + fZ*fZ;}
+ Scalar Perp2() const { return fX*fX + fY*fY ;}
+ Scalar Rho() const { return math_sqrt(Perp2()); }
+ Scalar R() const { return math_sqrt(Mag2()); }
+ Scalar Theta() const { return math_atan2(Rho(), Z()); }
+ Scalar Phi() const { return math_atan2(fY, fX); }
+
+ // pseudorapidity
+ Scalar Eta() const {
+ return Impl::Eta_FromRhoZ( Rho(), fZ );
+ }
+
+ /**
+ set the x coordinate value keeping y and z constant
+ */
+ void SetX(Scalar xx) { fX = xx; }
+
+ /**
+ set the y coordinate value keeping x and z constant
+ */
+ void SetY(Scalar yy) { fY = yy; }
+
+ /**
+ set the z coordinate value keeping x and y constant
+ */
+ void SetZ(Scalar zz) { fZ = zz; }
+
+ /**
+ set all values using cartesian coordinates
+ */
+ void SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
+ fX=xx;
+ fY=yy;
+ fZ=zz;
+ }
+
+ /**
+ scale the vector by a scalar quantity a
+ */
+ void Scale(Scalar a)
+ {
+ fX *= a;
+ fY *= a;
+ fZ *= a;
+ }
+
+ /**
+ negate the vector
+ */
+ void Negate() { fX = -fX; fY = -fY; fZ = -fZ; }
+
+ /**
+ Assignment from any class implementing x(),y() and z()
+ (can assign from any coordinate system)
+ */
+ template
+ Cartesian3D & operator = (const CoordSystem & v) {
+ fX = v.x();
+ fY = v.y();
+ fZ = v.z();
+ return *this;
+ }
+
+ /**
+ Exact equality
+ */
+ bool operator == (const Cartesian3D & rhs) const {
+ return fX == rhs.fX && fY == rhs.fY && fZ == rhs.fZ;
+ }
+ bool operator != (const Cartesian3D & rhs) const {return !(operator==(rhs));}
+
+
+ // ============= Compatibility section ==================
+
+ // The following make this coordinate system look enough like a CLHEP
+ // vector that an assignment member template can work with either
+ T x() const { return X();}
+ T y() const { return Y();}
+ T z() const { return Z(); }
+
+ // ============= Overloads for improved speed ==================
+
+ template
+ explicit Cartesian3D( const Polar3D & v ) : fZ (v.Z())
+ {
+ const T rho = v.Rho();
+ // re-using this instead of calling v.X() and v.Y()
+ // is the speed improvement
+ fX = rho * math_cos(v.Phi());
+ fY = rho * math_sin(v.Phi());
+ }
+ // Technical note: This works even though only Polar3Dfwd.h is
+ // included (and in fact, including Polar3D.h would cause circularity
+ // problems). It works because any program **using** this ctor must itself
+ // be including Polar3D.h.
+
+ template
+ Cartesian3D & operator = (const Polar3D & v)
+ {
+ const T rho = v.Rho();
+ fX = rho * math_cos(v.Phi());
+ fY = rho * math_sin(v.Phi());
+ fZ = v.Z();
+ return *this;
+ }
+
+
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+
+ // ====== Set member functions for coordinates in other systems =======
+
+ void SetR(Scalar r);
+
+ void SetTheta(Scalar theta);
+
+ void SetPhi(Scalar phi);
+
+ void SetRho(Scalar rho);
+
+ void SetEta(Scalar eta);
+
+#endif
+
+
+private:
+
+ T fX; // x coordinate
+ T fY; // y coordinate
+ T fZ; // z coordinate
+};
+
+
+ } // end namespace ROOT_MATH_ARCH
+
+} // end namespace ROOT
+
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+// need to put here setter methods to resolve nasty cyclical dependencies
+// I need to include other coordinate systems only when Cartesian is already defined
+// since they depend on it
+#include "MathX/GenVectorX/GenVector_exception.h"
+#include "MathX/GenVectorX/CylindricalEta3D.h"
+#include "MathX/GenVectorX/Polar3D.h"
+
+ // ====== Set member functions for coordinates in other systems =======
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+template
+void Cartesian3D::SetR(Scalar r) {
+ GenVector_exception e("Cartesian3D::SetR() is not supposed to be called");
+ throw e;
+ Polar3D v(*this); v.SetR(r); *this = Cartesian3D(v);
+}
+
+template
+void Cartesian3D::SetTheta(Scalar theta) {
+ GenVector_exception e("Cartesian3D::SetTheta() is not supposed to be called");
+ throw e;
+ Polar3D v(*this); v.SetTheta(theta); *this = Cartesian3D(v);
+}
+
+template
+void Cartesian3D::SetPhi(Scalar phi) {
+ GenVector_exception e("Cartesian3D::SetPhi() is not supposed to be called");
+ throw e;
+ Polar3D v(*this); v.SetPhi(phi); *this = Cartesian3D(v);
+}
+
+template
+void Cartesian3D::SetRho(Scalar rho) {
+ GenVector_exception e("Cartesian3D::SetRho() is not supposed to be called");
+ throw e;
+ CylindricalEta3D v(*this); v.SetRho(rho);
+ *this = Cartesian3D(v);
+}
+
+template
+void Cartesian3D::SetEta(Scalar eta) {
+ GenVector_exception e("Cartesian3D::SetEta() is not supposed to be called");
+ throw e;
+ CylindricalEta3D v(*this); v.SetEta(eta);
+ *this = Cartesian3D(v);
+}
+
+
+
+ } // end namespace ROOT_MATH_ARCH
+
+} // end namespace ROOT
+
+#endif
+#endif
+
+
+
+#endif /* ROOT_MathX_GenVectorX_Cartesian3D */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian3Dfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian3Dfwd.h
new file mode 100644
index 0000000000000..a1022ce9fc6ed
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cartesian3Dfwd.h
@@ -0,0 +1,21 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_Cartesian3Dfwd
+#define ROOT_MathX_GenVectorX_Cartesian3Dfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT_MATH_ARCH {
+
+ namespace Math {
+
+template
+class Cartesian3D;
+
+ } // end namespace Math
+
+} // end namespace ROOT
+
+
+#endif /* ROOT_MathX_GenVectorX_Cartesian3Dfwd */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/CoordinateSystemTags.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/CoordinateSystemTags.h
new file mode 100644
index 0000000000000..05c6d0914a391
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/CoordinateSystemTags.h
@@ -0,0 +1,69 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG ROOT MathLib Team and *
+ * FNAL LCG ROOT MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header source file for CoordinateSystemTag's classes
+//
+// Created by: Lorenzo Moneta at Wed Apr 05 2006
+//
+//
+
+#ifndef ROOT_MathX_GenVectorX_CoordinateSystemTags
+#define ROOT_MathX_GenVectorX_CoordinateSystemTags 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+
+namespace ROOT {
+
+namespace ROOT_MATH_ARCH {
+
+
+//__________________________________________________________________________________________
+ /**
+ DefaultCoordinateSystemTag
+ Default tag for identifying any coordinate system
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+ class DefaultCoordinateSystemTag {};
+
+
+//__________________________________________________________________________________________
+ /**
+ Tag for identifying vectors based on a global coordinate system
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+ class GlobalCoordinateSystemTag {};
+
+//__________________________________________________________________________________________
+ /**
+ Tag for identifying vectors based on a local coordinate system
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+ class LocalCoordinateSystemTag {};
+
+
+} // namespace Math
+
+} // namespace ROOT
+
+
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Cylindrical3D.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cylindrical3D.h
new file mode 100644
index 0000000000000..c724731f3f958
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cylindrical3D.h
@@ -0,0 +1,325 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG ROOT MathLib Team and *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class Cylindrica3D
+//
+// Created by: Lorenzo Moneta at Tue Dec 06 2005
+//
+//
+#ifndef ROOT_MathX_GenVectorX_Cylindrical3D
+#define ROOT_MathX_GenVectorX_Cylindrical3D 1
+
+#include "Math/Math.h"
+
+#include "MathX/GenVectorX/eta.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+#include
+#include
+
+namespace ROOT {
+
+namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Class describing a cylindrical coordinate system based on rho, z and phi.
+ The base coordinates are rho (transverse component) , z and phi
+ Phi is restricted to be in the range [-PI,PI)
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+template
+class Cylindrical3D {
+
+public :
+
+ typedef T Scalar;
+
+ /**
+ Default constructor with rho=z=phi=0
+ */
+ Cylindrical3D() : fRho(0), fZ(0), fPhi(0) { }
+
+ /**
+ Construct from rho eta and phi values
+ */
+ Cylindrical3D(Scalar rho, Scalar zz, Scalar phi) :
+ fRho(rho), fZ(zz), fPhi(phi) { Restrict(); }
+
+ /**
+ Construct from any Vector or coordinate system implementing
+ Rho(), Z() and Phi()
+ */
+ template
+ explicit Cylindrical3D( const CoordSystem & v ) :
+ fRho( v.Rho() ), fZ( v.Z() ), fPhi( v.Phi() ) { Restrict(); }
+
+ // for g++ 3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
+ // re-implement them ( there is no no need to have them with g++4)
+
+ /**
+ copy constructor
+ */
+ Cylindrical3D(const Cylindrical3D & v) :
+ fRho(v.Rho() ), fZ(v.Z() ), fPhi(v.Phi() ) { }
+
+ /**
+ assignment operator
+ */
+ Cylindrical3D & operator= (const Cylindrical3D & v) {
+ fRho = v.Rho();
+ fZ = v.Z();
+ fPhi = v.Phi();
+ return *this;
+ }
+
+ /**
+ Set internal data based on an array of 3 Scalar numbers ( rho, z , phi)
+ */
+ void SetCoordinates( const Scalar src[] )
+ { fRho=src[0]; fZ=src[1]; fPhi=src[2]; Restrict(); }
+
+ /**
+ get internal data into an array of 3 Scalar numbers ( rho, z , phi)
+ */
+ void GetCoordinates( Scalar dest[] ) const
+ { dest[0] = fRho; dest[1] = fZ; dest[2] = fPhi; }
+
+ /**
+ Set internal data based on 3 Scalar numbers ( rho, z , phi)
+ */
+ void SetCoordinates(Scalar rho, Scalar zz, Scalar phi)
+ { fRho=rho; fZ=zz; fPhi=phi; Restrict(); }
+
+ /**
+ get internal data into 3 Scalar numbers ( rho, z , phi)
+ */
+ void GetCoordinates(Scalar& rho, Scalar& zz, Scalar& phi) const
+ {rho=fRho; zz=fZ; phi=fPhi;}
+
+private:
+ inline static Scalar pi() { return Scalar(M_PI); }
+ inline void Restrict()
+ {
+ if (fPhi <= -pi() || fPhi > pi()) fPhi = fPhi - math_floor(fPhi / (2 * pi()) + .5) * 2 * pi();
+ }
+public:
+
+ // accessors
+
+ Scalar Rho() const { return fRho; }
+ Scalar Z() const { return fZ; }
+ Scalar Phi() const { return fPhi; }
+ Scalar X() const { return fRho * math_cos(fPhi); }
+ Scalar Y() const { return fRho * math_sin(fPhi); }
+
+ Scalar Mag2() const { return fRho*fRho + fZ*fZ; }
+ Scalar R() const { return math_sqrt(Mag2()); }
+ Scalar Perp2() const { return fRho*fRho; }
+ Scalar Theta() const { return (fRho == Scalar(0) && fZ == Scalar(0)) ? Scalar(0) : math_atan2(fRho, fZ); }
+
+ // pseudorapidity - use same implementation as in Cartesian3D
+ Scalar Eta() const {
+ return Impl::Eta_FromRhoZ( fRho, fZ);
+ }
+
+ // setters (only for data members)
+
+
+ /**
+ set the rho coordinate value keeping z and phi constant
+ */
+ void SetRho(T rho) {
+ fRho = rho;
+ }
+
+ /**
+ set the z coordinate value keeping rho and phi constant
+ */
+ void SetZ(T zz) {
+ fZ = zz;
+ }
+
+ /**
+ set the phi coordinate value keeping rho and z constant
+ */
+ void SetPhi(T phi) {
+ fPhi = phi;
+ Restrict();
+ }
+
+ /**
+ set all values using cartesian coordinates
+ */
+ void SetXYZ(Scalar x, Scalar y, Scalar z);
+
+ /**
+ scale by a scalar quantity a --
+ for cylindrical coords only rho and z change
+ */
+ void Scale (T a) {
+ if (a < 0) {
+ Negate();
+ a = -a;
+ }
+ fRho *= a;
+ fZ *= a;
+ }
+
+ /**
+ negate the vector
+ */
+ void Negate ( ) {
+ fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi() );
+ fZ = -fZ;
+ }
+
+ // assignment operators
+ /**
+ generic assignment operator from any coordinate system implementing Rho(), Z() and Phi()
+ */
+ template
+ Cylindrical3D & operator= ( const CoordSystem & c ) {
+ fRho = c.Rho();
+ fZ = c.Z();
+ fPhi = c.Phi();
+ return *this;
+ }
+
+ /**
+ Exact component-by-component equality
+ */
+ bool operator==(const Cylindrical3D & rhs) const {
+ return fRho == rhs.fRho && fZ == rhs.fZ && fPhi == rhs.fPhi;
+ }
+ bool operator!= (const Cylindrical3D & rhs) const
+ {return !(operator==(rhs));}
+
+
+ // ============= Compatibility section ==================
+
+ // The following make this coordinate system look enough like a CLHEP
+ // vector that an assignment member template can work with either
+ T x() const { return X();}
+ T y() const { return Y();}
+ T z() const { return Z(); }
+
+ // ============= Specializations for improved speed ==================
+
+ // (none)
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+
+ // ====== Set member functions for coordinates in other systems =======
+
+ void SetX(Scalar x);
+
+ void SetY(Scalar y);
+
+ void SetEta(Scalar eta);
+
+ void SetR(Scalar r);
+
+ void SetTheta(Scalar theta);
+
+#endif
+
+
+private:
+
+ T fRho;
+ T fZ;
+ T fPhi;
+
+};
+
+ } // end namespace ROOT_MATH_ARCH
+
+} // end namespace ROOT
+
+// move implementations here to avoid circle dependencies
+
+#include "MathX/GenVectorX/Cartesian3D.h"
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+#include "MathX/GenVectorX/GenVector_exception.h"
+#include "MathX/GenVectorX/CylindricalEta3D.h"
+#include "MathX/GenVectorX/Polar3D.h"
+#endif
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+template
+void Cylindrical3D::SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
+ *this = Cartesian3D(xx, yy, zz);
+}
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+
+
+ // ====== Set member functions for coordinates in other systems =======
+
+
+
+template
+void Cylindrical3D::SetX(Scalar xx) {
+ GenVector_exception e("Cylindrical3D::SetX() is not supposed to be called");
+ throw e;
+ Cartesian3D v(*this); v.SetX(xx); *this = Cylindrical3D(v);
+}
+template
+void Cylindrical3D::SetY(Scalar yy) {
+ GenVector_exception e("Cylindrical3D::SetY() is not supposed to be called");
+ throw e;
+ Cartesian3D v(*this); v.SetY(yy); *this = Cylindrical3D(v);
+}
+template
+void Cylindrical3D::SetR(Scalar r) {
+ GenVector_exception e("Cylindrical3D::SetR() is not supposed to be called");
+ throw e;
+ Polar3D v(*this); v.SetR(r);
+ *this = Cylindrical3D(v);
+}
+template
+void Cylindrical3D::SetTheta(Scalar theta) {
+ GenVector_exception e("Cylindrical3D::SetTheta() is not supposed to be called");
+ throw e;
+ Polar3D v(*this); v.SetTheta(theta);
+ *this = Cylindrical3D(v);
+}
+template
+void Cylindrical3D::SetEta(Scalar eta) {
+ GenVector_exception e("Cylindrical3D::SetEta() is not supposed to be called");
+ throw e;
+ CylindricalEta3D v(*this); v.SetEta(eta);
+ *this = Cylindrical3D(v);
+}
+
+#endif
+#endif
+
+ } // end namespace ROOT_MATH_ARCH
+
+} // end namespace ROOT
+
+
+#endif /* ROOT_MathX_GenVectorX_Cylindrical3D */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/Cylindrical3Dfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cylindrical3Dfwd.h
new file mode 100644
index 0000000000000..343f21b7fe105
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/Cylindrical3Dfwd.h
@@ -0,0 +1,24 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_Cylindrical3Dfwd
+#define ROOT_MathX_GenVectorX_Cylindrical3Dfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ /**
+ Class describing a 3D Cylindrical Eta coordinate system
+ (rho, z, phi coordinates)
+ */
+
+template
+class Cylindrical3D;
+
+}
+}
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/CylindricalEta3D.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/CylindricalEta3D.h
new file mode 100644
index 0000000000000..38174e4988efd
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/CylindricalEta3D.h
@@ -0,0 +1,357 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG ROOT MathLib Team and *
+ * FNAL LCG ROOT MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header file for class CylindricalEta3D
+//
+// Created by: Lorenzo Moneta at Mon May 30 11:58:46 2005
+// Major revamp: M. Fischler at Fri Jun 10 2005
+//
+// Last update: $Id$
+
+//
+#ifndef ROOT_MathX_GenVectorX_CylindricalEta3D
+#define ROOT_MathX_GenVectorX_CylindricalEta3D 1
+
+#include "Math/Math.h"
+
+#include "MathX/GenVectorX/etaMax.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+#include
+#include
+
+
+namespace ROOT {
+
+namespace ROOT_MATH_ARCH {
+
+//__________________________________________________________________________________________
+ /**
+ Class describing a cylindrical coordinate system based on eta (pseudorapidity) instead of z.
+ The base coordinates are rho (transverse component) , eta and phi
+ Phi is restricted to be in the range [-PI,PI)
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+template
+class CylindricalEta3D {
+
+public :
+
+ typedef T Scalar;
+
+ /**
+ Default constructor with rho=eta=phi=0
+ */
+ CylindricalEta3D() : fRho(0), fEta(0), fPhi(0) { }
+
+ /**
+ Construct from rho eta and phi values
+ */
+ CylindricalEta3D(Scalar rho, Scalar eta, Scalar phi) :
+ fRho(rho), fEta(eta), fPhi(phi) { Restrict(); }
+
+ /**
+ Construct from any Vector or coordinate system implementing
+ Rho(), Eta() and Phi()
+ */
+ template
+ explicit CylindricalEta3D( const CoordSystem & v ) :
+ fRho(v.Rho() ), fEta(v.Eta() ), fPhi(v.Phi() )
+ {
+ static Scalar bigEta = Scalar(-0.3) * math_log(std::numeric_limits::epsilon());
+ if (math_fabs(fEta) > bigEta) {
+ // This gives a small absolute adjustment in rho,
+ // which, for large eta, results in a significant
+ // improvement in the faithfullness of reproducing z.
+ fRho *= v.Z() / Z();
+ }
+ }
+
+ // for g++ 3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
+ // re-implement them ( there is no no need to have them with g++4)
+
+ /**
+ copy constructor
+ */
+ CylindricalEta3D(const CylindricalEta3D & v) :
+ fRho(v.Rho() ), fEta(v.Eta() ), fPhi(v.Phi() ) { }
+
+ /**
+ assignment operator
+ */
+ CylindricalEta3D & operator= (const CylindricalEta3D & v) {
+ fRho = v.Rho();
+ fEta = v.Eta();
+ fPhi = v.Phi();
+ return *this;
+ }
+
+ /**
+ Set internal data based on an array of 3 Scalar numbers
+ */
+ void SetCoordinates( const Scalar src[] )
+ { fRho=src[0]; fEta=src[1]; fPhi=src[2]; Restrict(); }
+
+ /**
+ get internal data into an array of 3 Scalar numbers
+ */
+ void GetCoordinates( Scalar dest[] ) const
+ { dest[0] = fRho; dest[1] = fEta; dest[2] = fPhi; }
+
+ /**
+ Set internal data based on 3 Scalar numbers
+ */
+ void SetCoordinates(Scalar rho, Scalar eta, Scalar phi)
+ { fRho=rho; fEta=eta; fPhi=phi; Restrict(); }
+
+ /**
+ get internal data into 3 Scalar numbers
+ */
+ void GetCoordinates(Scalar& rho, Scalar& eta, Scalar& phi) const
+ {rho=fRho; eta=fEta; phi=fPhi;}
+
+private:
+ inline static Scalar pi() { return M_PI; }
+ inline void Restrict() {
+ if (fPhi <= -pi() || fPhi > pi()) fPhi = fPhi - math_floor(fPhi / (2 * pi()) + .5) * 2 * pi();
+ return;
+ }
+public:
+
+ // accessors
+
+ T Rho() const { return fRho; }
+ T Eta() const { return fEta; }
+ T Phi() const { return fPhi; }
+ T X() const { return fRho * math_cos(fPhi); }
+ T Y() const { return fRho * math_sin(fPhi); }
+ T Z() const
+ {
+ return fRho > 0 ? fRho * math_sinh(fEta) : fEta == 0 ? 0 : fEta > 0 ? fEta - etaMax() : fEta + etaMax();
+ }
+ T R() const
+ {
+ return fRho > 0 ? fRho * math_cosh(fEta)
+ : fEta > etaMax() ? fEta - etaMax() : fEta < -etaMax() ? -fEta - etaMax() : 0;
+ }
+ T Mag2() const
+ {
+ const Scalar r = R();
+ return r * r;
+ }
+ T Perp2() const { return fRho*fRho; }
+ T Theta() const { return fRho > 0 ? 2 * math_atan(exp(-fEta)) : (fEta >= 0 ? 0 : pi()); }
+
+ // setters (only for data members)
+
+
+ /**
+ set the rho coordinate value keeping eta and phi constant
+ */
+ void SetRho(T rho) {
+ fRho = rho;
+ }
+
+ /**
+ set the eta coordinate value keeping rho and phi constant
+ */
+ void SetEta(T eta) {
+ fEta = eta;
+ }
+
+ /**
+ set the phi coordinate value keeping rho and eta constant
+ */
+ void SetPhi(T phi) {
+ fPhi = phi;
+ Restrict();
+ }
+
+ /**
+ set all values using cartesian coordinates
+ */
+ void SetXYZ(Scalar x, Scalar y, Scalar z);
+
+
+ /**
+ scale by a scalar quantity a --
+ for cylindrical eta coords, as long as a >= 0, only rho changes!
+ */
+ void Scale (T a) {
+ if (a < 0) {
+ Negate();
+ a = -a;
+ }
+ // angles do not change when scaling by a positive quantity
+ if (fRho > 0) {
+ fRho *= a;
+ } else if ( fEta > etaMax() ) {
+ fEta = ( fEta-etaMax())*a + etaMax();
+ } else if ( fEta < -etaMax() ) {
+ fEta = ( fEta+etaMax())*a - etaMax();
+ } // when rho==0 and eta is not above etaMax, vector represents 0
+ // and remains unchanged
+ }
+
+ /**
+ negate the vector
+ */
+ void Negate ( ) {
+ fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi() );
+ fEta = -fEta;
+ }
+
+ // assignment operators
+ /**
+ generic assignment operator from any coordinate system
+ */
+ template
+ CylindricalEta3D & operator= ( const CoordSystem & c ) {
+ fRho = c.Rho();
+ fEta = c.Eta();
+ fPhi = c.Phi();
+ return *this;
+ }
+
+ /**
+ Exact component-by-component equality
+ Note: Peculiar representations of the zero vector such as (0,1,0) will
+ not test as equal to one another.
+ */
+ bool operator==(const CylindricalEta3D & rhs) const {
+ return fRho == rhs.fRho && fEta == rhs.fEta && fPhi == rhs.fPhi;
+ }
+ bool operator!= (const CylindricalEta3D & rhs) const
+ {return !(operator==(rhs));}
+
+
+ // ============= Compatibility section ==================
+
+ // The following make this coordinate system look enough like a CLHEP
+ // vector that an assignment member template can work with either
+ T x() const { return X();}
+ T y() const { return Y();}
+ T z() const { return Z(); }
+
+ // ============= Specializations for improved speed ==================
+
+ // (none)
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+
+ // ====== Set member functions for coordinates in other systems =======
+
+ void SetX(Scalar x);
+
+ void SetY(Scalar y);
+
+ void SetZ(Scalar z);
+
+ void SetR(Scalar r);
+
+ void SetTheta(Scalar theta);
+
+
+#endif
+
+
+private:
+ T fRho;
+ T fEta;
+ T fPhi;
+
+};
+
+ } // end namespace ROOT_MATH_ARCH
+
+} // end namespace ROOT
+
+
+// move implementations here to avoid circle dependencies
+
+#include "MathX/GenVectorX/Cartesian3D.h"
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+#include "MathX/GenVectorX/GenVector_exception.h"
+#include "MathX/GenVectorX/Polar3D.h"
+#endif
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+template
+void CylindricalEta3D::SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
+ *this = Cartesian3D(xx, yy, zz);
+}
+
+#if defined(__MAKECINT__) || defined(G__DICTIONARY)
+#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
+
+ // ====== Set member functions for coordinates in other systems =======
+
+
+template
+void CylindricalEta3D::SetX(Scalar xx) {
+ GenVector_exception e("CylindricalEta3D::SetX() is not supposed to be called");
+ throw e;
+ Cartesian3D v(*this); v.SetX(xx);
+ *this = CylindricalEta3D(v);
+}
+template
+void CylindricalEta3D::SetY(Scalar yy) {
+ GenVector_exception e("CylindricalEta3D::SetY() is not supposed to be called");
+ throw e;
+ Cartesian3D v(*this); v.SetY(yy);
+ *this = CylindricalEta3D(v);
+}
+template
+void CylindricalEta3D::SetZ(Scalar zz) {
+ GenVector_exception e("CylindricalEta3D::SetZ() is not supposed to be called");
+ throw e;
+ Cartesian3D v(*this); v.SetZ(zz);
+ *this = CylindricalEta3D(v);
+}
+template
+void CylindricalEta3D::SetR(Scalar r) {
+ GenVector_exception e("CylindricalEta3D::SetR() is not supposed to be called");
+ throw e;
+ Polar3D v(*this); v.SetR(r);
+ *this = CylindricalEta3D(v);
+}
+template
+void CylindricalEta3D::SetTheta(Scalar theta) {
+ GenVector_exception e("CylindricalEta3D::SetTheta() is not supposed to be called");
+ throw e;
+ Polar3D v(*this); v.SetTheta(theta);
+ *this = CylindricalEta3D(v);
+}
+
+#endif
+#endif
+
+
+ } // end namespace ROOT_MATH_ARCH
+
+} // end namespace ROOT
+
+
+
+#endif /* ROOT_MathX_GenVectorX_CylindricalEta3D */
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/CylindricalEta3Dfwd.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/CylindricalEta3Dfwd.h
new file mode 100644
index 0000000000000..4132d04afb226
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/CylindricalEta3Dfwd.h
@@ -0,0 +1,24 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+#ifndef ROOT_MathX_GenVectorX_CylindricalEta3Dfwd
+#define ROOT_MathX_GenVectorX_CylindricalEta3Dfwd 1
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+ /**
+ Class describing a 3D Cylindrical Eta coordinate system
+ (rho, eta, phi coordinates)
+ */
+
+template
+class CylindricalEta3D;
+
+}
+}
+
+#endif
diff --git a/math/experimental/genvectorx/inc/MathX/GenVectorX/DisplacementVector2D.h b/math/experimental/genvectorx/inc/MathX/GenVectorX/DisplacementVector2D.h
new file mode 100644
index 0000000000000..11edcc8fef8d0
--- /dev/null
+++ b/math/experimental/genvectorx/inc/MathX/GenVectorX/DisplacementVector2D.h
@@ -0,0 +1,549 @@
+// @(#)root/mathcore:$Id$
+// Authors: W. Brown, M. Fischler, L. Moneta 2005
+
+ /**********************************************************************
+ * *
+ * Copyright (c) 2005 , LCG ROOT MathLib Team and *
+ * FNAL LCG ROOT MathLib Team *
+ * *
+ * *
+ **********************************************************************/
+
+// Header source file for class DisplacementVector2D
+//
+// Created by: Lorenzo Moneta at Mon Apr 16 2007
+//
+
+#ifndef ROOT_MathX_GenVectorX_DisplacementVector2D
+#define ROOT_MathX_GenVectorX_DisplacementVector2D 1
+
+#include "MathX/GenVectorX/Cartesian2D.h"
+
+#include "MathX/GenVectorX/PositionVector2Dfwd.h"
+
+#include "MathX/GenVectorX/GenVectorIO.h"
+
+#include "MathX/GenVectorX/BitReproducible.h"
+
+#include "MathX/GenVectorX/CoordinateSystemTags.h"
+
+//#include "MathX/GenVectorX/Expression2D.h"
+
+#include "MathX/GenVectorX/MathHeaders.h"
+
+#include "MathX/GenVectorX/AccHeaders.h"
+
+using namespace ROOT::ROOT_MATH_ARCH;
+
+
+namespace ROOT {
+
+ namespace ROOT_MATH_ARCH {
+
+
+
+//__________________________________________________________________________________________
+ /**
+ Class describing a generic displacement vector in 2 dimensions.
+ This class is templated on the type of Coordinate system.
+ One example is the XYVector which is a vector based on
+ double precision x,y data members by using the
+ ROOT::Math::Cartesian2D Coordinate system.
+ The class is having also an extra template parameter, the coordinate system tag,
+ to be able to identify (tag) vector described in different reference coordinate system,
+ like global or local coordinate systems.
+
+ @ingroup GenVector
+
+ @sa Overview of the @ref GenVector "physics vector library"
+ */
+
+ template
+ class DisplacementVector2D {
+
+ public:
+
+ typedef typename CoordSystem::Scalar Scalar;
+ typedef CoordSystem CoordinateType;
+ typedef Tag CoordinateSystemTag;
+
+ // ------ ctors ------
+
+ /**
+ Default constructor. Construct an empty object with zero values
+ */
+ DisplacementVector2D ( ) : fCoordinates() { }
+
+
+ /**
+ Construct from three values of type Scalar.
+ In the case of a XYVector the values are x,y
+ In the case of a polar vector they are r, phi
+ */
+ DisplacementVector2D(Scalar a, Scalar b) :
+ fCoordinates ( a , b ) { }
+
+ /**
+ Construct from a displacement vector expressed in different
+ coordinates, or using a different Scalar type, but with same coordinate system tag
+ */
+ template
+ explicit DisplacementVector2D( const DisplacementVector2D & v) :
+ fCoordinates ( v.Coordinates() ) { }
+
+
+ /**
+ Construct from a position vector expressed in different coordinates
+ but with the same coordinate system tag
+ */
+ template
+ explicit DisplacementVector2D( const PositionVector2D & p) :
+ fCoordinates ( p.Coordinates() ) { }
+
+
+ /**
+ Construct from a foreign 2D vector type, for example, Hep2Vector
+ Precondition: v must implement methods x() and y()
+ */
+ template
+ explicit DisplacementVector2D( const ForeignVector & v) :
+ fCoordinates ( Cartesian2D( v.x(), v.y() ) ) { }
+
+
+
+ // compiler-generated copy ctor and dtor are fine.
+
+ // ------ assignment ------
+
+ /**
+ Assignment operator from a displacement vector of arbitrary type
+ */
+ template
+ DisplacementVector2D & operator=
+ ( const DisplacementVector2D & v) {
+ fCoordinates = v.Coordinates();
+ return *this;
+ }
+
+ /**
+ Assignment operator from a position vector
+ (not necessarily efficient unless one or the other is Cartesian)
+ */
+ template
+ DisplacementVector2D & operator=
+ ( const PositionVector2D & rhs) {
+ SetXY(rhs.x(), rhs.y() );
+ return *this;
+ }
+
+
+ /**
+ Assignment from a foreign 2D vector type, for example, Hep2Vector
+ Precondition: v must implement methods x() and y()
+ */
+ template
+ DisplacementVector2D & operator= ( const ForeignVector & v) {
+ SetXY( v.x(), v.y() );
+ return *this;
+ }
+
+
+ // ------ Set, Get, and access coordinate data ------
+
+ /**
+ Retrieve a copy of the coordinates object
+ */
+ CoordSystem Coordinates() const {
+ return fCoordinates;
+ }
+
+ /**
+ Set internal data based on 2 Scalar numbers.
+ These are for example (x,y) for a cartesian vector or (r,phi) for a polar vector
+ */
+ DisplacementVector2D& SetCoordinates( Scalar a, Scalar b) {
+ fCoordinates.SetCoordinates(a, b);
+ return *this;
+ }
+
+
+ /**
+ get internal data into 2 Scalar numbers.
+ These are for example (x,y) for a cartesian vector or (r,phi) for a polar vector
+ */
+ void GetCoordinates( Scalar& a, Scalar& b) const
+ { fCoordinates.GetCoordinates(a, b); }
+
+
+ /**
+ set the values of the vector from the cartesian components (x,y)
+ (if the vector is held in polar coordinates,
+ then (x, y) are converted to that form)
+ */
+ DisplacementVector2D& SetXY (Scalar a, Scalar b) {
+ fCoordinates.SetXY(a,b);
+ return *this;
+ }
+
+ // ------------------- Equality -----------------
+
+ /**
+ Exact equality
+ */
+ bool operator==(const DisplacementVector2D & rhs) const {
+ return fCoordinates==rhs.fCoordinates;
+ }
+ bool operator!= (const DisplacementVector2D & rhs) const {
+ return !(operator==(rhs));
+ }
+
+ // ------ Individual element access, in various coordinate systems ------
+
+ /**
+ Cartesian X, converting if necessary from internal coordinate system.
+ */
+ Scalar X() const { return fCoordinates.X(); }
+
+ /**
+ Cartesian Y, converting if necessary from internal coordinate system.
+ */
+ Scalar Y() const { return fCoordinates.Y(); }
+
+
+ /**
+ Polar R, converting if necessary from internal coordinate system.
+ */
+ Scalar R() const { return fCoordinates.R(); }
+
+
+ /**
+ Polar phi, converting if necessary from internal coordinate system.
+ */
+ Scalar Phi() const { return fCoordinates.Phi(); }
+
+
+ // ----- Other fundamental properties -----
+
+ /**
+ Magnitute squared ( r^2 in spherical coordinate)
+ */
+ Scalar Mag2() const { return fCoordinates.Mag2();}
+
+
+ /**
+ return unit vector parallel to this
+ */
+ DisplacementVector2D Unit() const {
+ Scalar tot = R();
+ return tot == 0 ? *this : DisplacementVector2D(*this) / tot;
+ }
+
+ // ------ Setting individual elements present in coordinate system ------
+
+ /**
+ Change X - Cartesian2D coordinates only
+ */
+ DisplacementVector2D& SetX (Scalar a) {
+ fCoordinates.SetX(a);
+ return *this;
+ }
+
+ /**
+ Change Y - Cartesian2D coordinates only
+ */
+ DisplacementVector2D& SetY (Scalar a) {
+ fCoordinates.SetY(a);
+ return *this;
+ }
+
+
+ /**
+ Change R - Polar2D coordinates only
+ */
+ DisplacementVector2D& SetR (Scalar a) {
+ fCoordinates.SetR(a);
+ return *this;
+ }
+
+
+ /**
+ Change Phi - Polar2D coordinates
+ */
+ DisplacementVector2D& SetPhi (Scalar ang) {
+ fCoordinates.SetPhi(ang);
+ return *this;
+ }
+
+
+
+ // ------ Operations combining two vectors ------
+ // -- need to have the specialized version in order to avoid
+
+ /**
+ Return the scalar (dot) product of two displacement vectors.
+ It is possible to perform the product for any type of vector coordinates,
+ but they must have the same coordinate system tag
+ */
+ template< class OtherCoords >
+ Scalar Dot( const DisplacementVector2D & v) const {
+ return X()*v.X() + Y()*v.Y();
+ }
+ /**
+ Return the scalar (dot) product of two vectors.
+ It is possible to perform the product for any classes
+ implementing x() and y() member functions
+ */
+ template< class OtherVector >
+ Scalar Dot( const OtherVector & v) const {
+ return X()*v.x() + Y()*v.y();
+ }
+
+
+
+ /**
+ Self Addition with a displacement vector.
+ */
+ template
+ DisplacementVector2D & operator+=
+ (const DisplacementVector2D & v) {
+ SetXY( X() + v.X(), Y() + v.Y() );
+ return *this;
+ }
+
+ /**
+ Self Difference with a displacement vector.
+ */
+ template
+ DisplacementVector2D & operator-=
+ (const DisplacementVector2D & v) {
+ SetXY( x() - v.x(), y() - v.y() );
+ return *this;
+ }
+
+
+ /**
+ multiply this vector by a scalar quantity
+ */
+ DisplacementVector2D & operator*= (Scalar a) {
+ fCoordinates.Scale(a);
+ return *this;
+ }
+
+ /**
+ divide this vector by a scalar quantity
+ */
+ DisplacementVector2D & operator/= (Scalar a) {
+ fCoordinates.Scale(1/a);
+ return *this;
+ }
+
+ // -- The following methods (v*a and v/a) could instead be free functions.
+ // -- They were moved into the class to solve a problem on AIX.
+
+ /**
+ Multiply a vector by a real number
+ */
+ DisplacementVector2D operator * ( Scalar a ) const {
+ DisplacementVector2D tmp(*this);
+ tmp *= a;
+ return tmp;
+ }
+
+ /**
+ Negative of the vector
+ */
+ DisplacementVector2D operator - ( ) const {
+ return operator*( Scalar(-1) );
+ }
+
+ /**
+ Positive of the vector, return itself
+ */
+ DisplacementVector2D operator + ( ) const {return *this;}
+
+ /**
+ Division of a vector with a real number
+ */
+ DisplacementVector2D operator/ (Scalar a) const {
+ DisplacementVector2D tmp(*this);
+ tmp /= a;
+ return tmp;
+ }
+
+ /**
+ Rotate by an angle
+ */
+ void Rotate( Scalar angle) {
+ return fCoordinates.Rotate(angle);
+ }
+
+
+ // Methods providing Limited backward name compatibility with CLHEP
+
+ Scalar x() const { return fCoordinates.X(); }
+ Scalar y() const { return fCoordinates.Y(); }
+ Scalar r() const { return fCoordinates.R(); }
+ Scalar phi() const { return fCoordinates.Phi(); }
+ Scalar mag2() const { return fCoordinates.Mag2(); }
+ DisplacementVector2D unit() const {return Unit();}
+
+
+ private:
+
+ CoordSystem fCoordinates; // internal coordinate system
+
+
+ // the following methods should not compile
+
+ // this should not compile (if from a vector or points with different tag
+ template
+ explicit DisplacementVector2D( const DisplacementVector2D & ) {}
+
+ template
+ explicit DisplacementVector2D( const PositionVector2D & ) {}
+
+ template
+ DisplacementVector2D & operator=( const DisplacementVector2D & );
+
+
+ template
+ DisplacementVector2D & operator=( const PositionVector2D & );
+
+ template
+ DisplacementVector2D & operator+=(const DisplacementVector2D & );
+
+ template