-----------------------------------------------------------------------------
-- |
--
-- Quaternion operations implemented for Floats and Doubles.
--
-- The types QDouble and QFloat have the same representation as corresponding @Vector t 4@.
-- This means, you can do a cheap conversion between the types.
--
-- However, arithmetic instances, such as Num and Floating are implemented in substentially different ways.
-- For example, fromInteger fills a vector fully but sets only real part to a quaternion:
--
-- >>> 1 = vec4 1 1 1 1
-- >>> 1 = packQ 0 0 0 1
--
-- All other numeric operations for vectors are element-wise, but for quaternions I have implemented
-- the actual quaternion math.
-- In most of the cases, you can think of these as being operations on complex numbers,
-- where the role of imaginary @i@ is played by a 3D vector.
-- Some of the operations are ambiguous for quaternions;
-- for example $$\sqrt{-1} = \pm i$$, but also $$\sqrt{-1} = \pm j$$,
-- and $$\sqrt{-1} = \pm k$$, and any other unit quaterion with zero real part.
-- In cases like this, I stick to the @i@-th axis:  $$\sqrt{-1} := i$$
-----------------------------------------------------------------------------
module Numeric.Quaternion
( Quaternion (..)
, Quater(Quater)
, QDouble, QFloat
) where

import Numeric.DataFrame.Internal.Backend  ()
import Numeric.Quaternion.Internal
import Numeric.Quaternion.Internal.QDouble
import Numeric.Quaternion.Internal.QFloat