Skip to content

Discussion: algebra, and constructor #13

@mmikhasenko

Description

@mmikhasenko

This issue discusses mechanisms to enable four-vector arithmetics with a customary types.

Proposal

Make a customary types (not part of this package) to explain how constructor works if given just four-vector components. That would enable basic operations like

  • addition, subtraction,
  • boosts and rotations
    for wide class of objects (only four-vector components are transformed)

Form messages below @grasph

  1. We define an LVB.AbstractLorentzVector abtsract type for pure Lorentz vector, that is which do not have other properties than Lorentz vector components.
  2. We define LVB concrete types of LVB.AbstractLorentzVector for each supported coordinate systems. These types will be used by LVB when it needs an LVB.AbstractLorentzVector (see example code below). At the same time, the concrete type ctor will acts as as accessor to the bare vector.
  3. LVB overrides Base.:+(::Any, ::LVB.AbstractLorentzVector) and possibly Base.:+(::LVB.AbstractLorentzVector, ::Any), same for -. It is cleaner than in the previous definition example, because only one argument can have extra properties and therefore there is no ambiguities on how these properties are propagated.
  4. LVB provides also Lorentz transformations and scalar products.

This will looks like this for Base.:+, assuming the code in the LVB module,

abstract type AbtractLorentzVector end

# Note: if we go that way, I would prefer to use the shorter name
# PxPyPzE for the vector and the longer name e.g., PxPyPzECoord
# for the coordinate system.
struct PxPyPzEVec{T} <: AbtractLorentzVector
px::T
py::T
pz::T
energy::T
end

# Constructor from any type compliant with the kinematic interface
PxPyPzEVec(q) = PxPyPzEVec(px(q), py(q), pz(q), energy(q))

const XYZTVec{T} = PxPyPzEVec{T}

px(p::PxPyPzEVec) = p.px
py(p::PxPyPzEVec) = p.py
pz(p::PxPyPzEVec) = p.pz
energy(p::PxPyPzEVec) = p.energy
coordinate_system(PxPyPzEVec) = PxPyPzE

# Similar definitions for PtEtaPhiEVec{T}, PtEtaPhiMVec{T}
# ....

function Base.:+(p::Any, q::AbstractLorentzVector)
  px = px(p) + px(q)
  py = py(p) + py(q)
  pz = pz(p) + pz(q)
  energy = energy(p) + energy(q)
  materializer(p)(PxPyPzEVec(px, py, pz, energy))
end

# And possibly we define also (not clear to me if we should):
Base.:+(q::AbstractLorentzVector, p::Any) = Base.:+(p::Any, q::AbstractLorentzVector) 

Note: I think we need to require in the kinematic interface that all component accessors (px(), py(), pz(), energy() in case of PxPyPzE coordinate) return elements of the same type. In the above code, the ctor of PxPyPzEVec(::Any) assumes this. We could relax the requirements by asking that either they have the same type or promote_rule's are implemented, but I'm not convinced we need this extra sophistication.

Earlier discussion:

  • if we want to provide a default algebra implementation, then we need an abstract supertype is order to override the Base package operators. We could make inheritance from a LorentzVectorBase abstract type as optional.

  • Constructor from a LorentzVector. The constructor will need to take an argument of any type. It's probably ok. The Table.jl interface has a materializer() method that returns the "constructor". Maybe there is a reason for doing this way?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions