mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
226 lines
8.4 KiB
Text
226 lines
8.4 KiB
Text
/-
|
|
QuaternionScalar.lean - Quaternion-based Dimensionless Scalar Field Set
|
|
and Bracketed PBACS Style Representation
|
|
|
|
Based on quaternionic algebra: q = q₀ + q₁i + q₂j + q₃k
|
|
where q₀ is the dimensionless scalar part representing:
|
|
- Temporal Identity (Hamilton's time interpretation)
|
|
- Metric of Alignment (cosine of half-angle rotation)
|
|
- Information Density (entropy/compression efficiency)
|
|
|
|
References:
|
|
- Chappell et al. (2016). Time As a Geometric Property of Space.
|
|
- Hanson (2020). Quaternion-based spatial-coordinate alignment.
|
|
- Quee (1983). Quaternion algebra in three-dimensional space.
|
|
-/
|
|
|
|
import Semantics.FixedPoint
|
|
|
|
namespace Semantics.QuaternionScalar
|
|
|
|
open Semantics.Q16_16
|
|
|
|
/-- Quaternion with dimensionless scalar part -/
|
|
structure Quaternion where
|
|
scalar : Q16_16 -- q₀: dimensionless scalar (time, alignment, density)
|
|
i : Q16_16 -- q₁: i-component
|
|
j : Q16_16 -- q₂: j-component
|
|
k : Q16_16 -- q₃: k-component
|
|
deriving Repr, DecidableEq, BEq
|
|
|
|
namespace Quaternion
|
|
|
|
/-- Create a quaternion from scalar and vector parts -/
|
|
def make (scalar i j k : Q16_16) : Quaternion :=
|
|
{ scalar := scalar, i := i, j := j, k := k }
|
|
|
|
/-- Zero quaternion -/
|
|
def zero : Quaternion :=
|
|
make Q16_16.zero Q16_16.zero Q16_16.zero Q16_16.zero
|
|
|
|
/-- Identity quaternion (scalar = 1, vector = 0) -/
|
|
def one : Quaternion :=
|
|
make Q16_16.one Q16_16.zero Q16_16.zero Q16_16.zero
|
|
|
|
/-- Vector part magnitude squared (|v|² = q₁² + q₂² + q₃²) -/
|
|
def vectorMagSq (q : Quaternion) : Q16_16 :=
|
|
q.i * q.i + q.j * q.j + q.k * q.k
|
|
|
|
/-- Full quaternion magnitude squared (|q|² = q₀² + |v|²) -/
|
|
def magSq (q : Quaternion) : Q16_16 :=
|
|
q.scalar * q.scalar + vectorMagSq q
|
|
|
|
/-- Quaternion addition -/
|
|
def add (x y : Quaternion) : Quaternion :=
|
|
mk (x.scalar + y.scalar) (x.i + y.i) (x.j + y.j) (x.k + y.k)
|
|
|
|
/-- Quaternion multiplication: q² = q₀² - |v|² + 2q₀v -/
|
|
def mul (x y : Quaternion) : Quaternion :=
|
|
let newScalar := x.scalar * y.scalar - x.i * y.i - x.j * y.j - x.k * y.k
|
|
let newI := x.scalar * y.i + x.i * y.scalar + x.j * y.k - x.k * y.j
|
|
let newJ := x.scalar * y.j - x.i * y.k + x.j * y.scalar + x.k * y.i
|
|
let newK := x.scalar * y.k + x.i * y.j - x.j * y.i + x.k * y.scalar
|
|
mk newScalar newI newJ newK
|
|
|
|
/-- Quaternion squaring -/
|
|
def sq (q : Quaternion) : Quaternion :=
|
|
mul q q
|
|
|
|
/-- Scalar part of quaternion (q₀) -/
|
|
def scalarPart (q : Quaternion) : Q16_16 :=
|
|
q.scalar
|
|
|
|
/-- Vector part of quaternion (v = q₁i + q₂j + q₃k) -/
|
|
def vectorPart (q : Quaternion) : Quaternion :=
|
|
make Q16_16.zero q.i q.j q.k
|
|
|
|
/-- Check if quaternion is a unit quaternion (|q| = 1) -/
|
|
def isUnit (q : Quaternion) : Bool :=
|
|
magSq q == Q16_16.one
|
|
|
|
/-- Cosine of half-angle for unit quaternions: q₀ = cos(θ/2) -/
|
|
def halfAngleCosine (q : Quaternion) : Q16_16 :=
|
|
if isUnit q then q.scalar else Q16_16.zero
|
|
|
|
/-- Information density interpretation (scalar as entropy density) -/
|
|
def informationDensity (q : Quaternion) : Q16_16 :=
|
|
q.scalar
|
|
|
|
/-- Temporal identity interpretation (scalar as time scale factor) -/
|
|
def temporalScale (q : Quaternion) : Q16_16 :=
|
|
q.scalar
|
|
|
|
instance : Add Quaternion where
|
|
add := add
|
|
|
|
instance : Mul Quaternion where
|
|
mul := mul
|
|
|
|
instance : Zero Quaternion where
|
|
zero := zero
|
|
|
|
instance : One Quaternion where
|
|
one := one
|
|
|
|
end Quaternion
|
|
|
|
/-- Bracketed PBACS style quaternion representation -/
|
|
structure BracketedQuaternion where
|
|
lowerScalar : Q16_16 -- Lower bound for scalar part
|
|
upperScalar : Q16_16 -- Upper bound for scalar part
|
|
valueScalar : Q16_16 -- Value for scalar part
|
|
lowerVector : Quaternion -- Lower bound for vector part
|
|
upperVector : Quaternion -- Upper bound for vector part
|
|
valueVector : Quaternion -- Value for vector part
|
|
scale : UInt32
|
|
deriving Repr, DecidableEq, BEq
|
|
|
|
namespace BracketedQuaternion
|
|
|
|
/-- Encode a bracketed quaternion from bounds and values -/
|
|
def encode (lowerScalar upperScalar valueScalar : Q16_16)
|
|
(lowerVector upperVector valueVector : Quaternion)
|
|
(scale : UInt32) : BracketedQuaternion :=
|
|
{
|
|
lowerScalar := lowerScalar,
|
|
upperScalar := upperScalar,
|
|
valueScalar := valueScalar,
|
|
lowerVector := lowerVector,
|
|
upperVector := upperVector,
|
|
valueVector := valueVector,
|
|
scale := scale
|
|
}
|
|
|
|
/-- Width of scalar bracket -/
|
|
def scalarWidth (b : BracketedQuaternion) : Q16_16 :=
|
|
b.upperScalar - b.lowerScalar
|
|
|
|
/-- Width of vector bracket (magnitude) -/
|
|
def vectorWidth (b : BracketedQuaternion) : Q16_16 :=
|
|
let lowerMag := Quaternion.magSq b.lowerVector
|
|
let upperMag := Quaternion.magSq b.upperVector
|
|
upperMag - lowerMag
|
|
|
|
/-- Check if scalar value is within bounds -/
|
|
def scalarInBounds (b : BracketedQuaternion) : Bool :=
|
|
b.lowerScalar.val <= b.valueScalar.val && b.valueScalar.val <= b.upperScalar.val
|
|
|
|
/-- Check if vector value is within bounds -/
|
|
def vectorInBounds (b : BracketedQuaternion) : Bool :=
|
|
let valMag := Quaternion.magSq b.valueVector
|
|
let lowerMag := Quaternion.magSq b.lowerVector
|
|
let upperMag := Quaternion.magSq b.upperVector
|
|
lowerMag.val <= valMag.val && valMag.val <= upperMag.val
|
|
|
|
/-- Bracketed quaternion addition -/
|
|
def bracketAdd (x y : BracketedQuaternion) : BracketedQuaternion :=
|
|
let newLowerScalar := x.lowerScalar + y.lowerScalar
|
|
let newValueScalar := x.valueScalar + y.valueScalar
|
|
let newUpperScalar := x.upperScalar + y.upperScalar
|
|
let newLowerVector := Quaternion.add x.lowerVector y.lowerVector
|
|
let newValueVector := Quaternion.add x.valueVector y.valueVector
|
|
let newUpperVector := Quaternion.add x.upperVector y.upperVector
|
|
encode newLowerScalar newUpperScalar newValueScalar
|
|
newLowerVector newUpperVector newValueVector
|
|
(UInt32.ofNat (Nat.max x.scale.toNat y.scale.toNat))
|
|
|
|
/-- Bracketed quaternion multiplication (conservative bounds) -/
|
|
def bracketMulConservative (x y : BracketedQuaternion) : BracketedQuaternion :=
|
|
-- Scalar bounds: [ls1*ls2 - max|v1||v2|, us1*us2 - min|v1||v2|]
|
|
let ls1 := x.lowerScalar
|
|
let us1 := x.upperScalar
|
|
let ls2 := y.lowerScalar
|
|
let us2 := y.upperScalar
|
|
let v1LowerMag := Quaternion.magSq x.lowerVector
|
|
let v1UpperMag := Quaternion.magSq x.upperVector
|
|
let v2LowerMag := Quaternion.magSq y.lowerVector
|
|
let v2UpperMag := Quaternion.magSq y.upperVector
|
|
|
|
let maxProduct := max (max (ls1*ls2) (ls1*us2)) (max (us1*ls2) (us1*us2))
|
|
let minProduct := min (min (ls1*ls2) (ls1*us2)) (min (us1*ls2) (us1*us2))
|
|
let maxVMag := max (max v1LowerMag v1UpperMag) (max v2LowerMag v2UpperMag)
|
|
let minVMag := min (min v1LowerMag v1UpperMag) (min v2LowerMag v2UpperMag)
|
|
|
|
let newLowerScalar := minProduct - maxVMag
|
|
let newUpperScalar := maxProduct - minVMag
|
|
let newValueScalar := x.valueScalar * y.valueScalar
|
|
|
|
-- Vector bounds (conservative)
|
|
let newLowerVector := Quaternion.mul x.lowerVector y.lowerVector
|
|
let newUpperVector := Quaternion.mul x.upperVector y.upperVector
|
|
let newValueVector := Quaternion.mul x.valueVector y.valueVector
|
|
|
|
encode newLowerScalar newUpperScalar newValueScalar
|
|
newLowerVector newUpperVector newValueVector
|
|
(UInt32.ofNat (Nat.max x.scale.toNat y.scale.toNat))
|
|
|
|
/-- Extract the central quaternion value -/
|
|
def centralValue (b : BracketedQuaternion) : Quaternion :=
|
|
Quaternion.mk b.valueScalar b.valueVector.i b.valueVector.j b.valueVector.k
|
|
|
|
/-- Check if bracket represents a unit quaternion range -/
|
|
def isUnitRange (b : BracketedQuaternion) (tolerance : Q16_16) : Bool :=
|
|
let centralMag := Quaternion.magSq (centralValue b)
|
|
let diff := centralMag - one
|
|
let absDiff := if diff.val >= 0 then diff else -diff
|
|
absDiff.val <= tolerance.val
|
|
|
|
/-- Temporal scale interpretation for bracketed quaternion -/
|
|
def bracketTemporalScale (b : BracketedQuaternion) : Q16_16 :=
|
|
b.valueScalar
|
|
|
|
/-- Information density interpretation for bracketed quaternion -/
|
|
def bracketInformationDensity (b : BracketedQuaternion) : Q16_16 :=
|
|
b.valueScalar
|
|
|
|
/-- Metric of alignment (cosine of half-angle) for bracketed quaternion -/
|
|
def bracketAlignmentMetric (b : BracketedQuaternion) : Q16_16 :=
|
|
if isUnitRange b (Q16_16.ofFloat 0.01) then b.valueScalar else Q16_16.zero
|
|
|
|
end BracketedQuaternion
|
|
|
|
#eval Quaternion.make (Q16_16.ofFloat 1.0) (Q16_16.ofFloat 0.0) (Q16_16.ofFloat 0.0) (Q16_16.ofFloat 0.0)
|
|
#eval Quaternion.magSq (Quaternion.make (Q16_16.ofFloat 1.0) (Q16_16.ofFloat 0.0) (Q16_16.ofFloat 0.0) (Q16_16.ofFloat 0.0))
|
|
#eval Quaternion.isUnit (Quaternion.make (Q16_16.ofFloat 1.0) (Q16_16.ofFloat 0.0) (Q16_16.ofFloat 0.0) (Q16_16.ofFloat 0.0))
|
|
|
|
end Semantics.QuaternionScalar
|