Содержание:
Фаза и прото-пространство.
Кватернионное представление.
Кватернионные роторы: R-поворот и D-буст.
Вращение Вигнера.
Прецессия Томаса.
Перепараметризация времени
Шпаргалка.
Алгоритм и пример.
Контроль по классической формуле.
Заключение.
Эта статья — продолжение разработки теории представления специальной теории относительности через вращение векторов градиента фазы в евклидовом фазовом пространстве с поледующей перепараметризацией времени.
В первой статье мы не упомянули, что сферически-гиперболический мост строится на отношении, найденном Кристофом Гудерманом (см. гудерманиан).
1. Фаза и прото-пространство
В самом общем смысле станем полагать фазу изменением скалярного поля в евклидовом пространстве неограниченной размерности. Эффекты наблюдаемого 3-пространственного характера тогда будут выражаться как изменение проекций вектора градиента фазы на пространственные оси наблюдателя, а проекция на остальные оси даст совокупно течение фазы объекта по времени.
Формально. Фазовое «прото-пространство» — евклидово (гильбертово) пространство ,
— евклидово скалярное произведение,
.
Фазовый поток задаётся вектором .
Наблюдатель фиксирует ортонормированную тройку пространственных осей
и соответствующее подпространство с ортогональными проекторами
и
.
Разложим фазовый вектор:
Наблюдаемая 3-компонента:
Остальные (ненаблюдаемые) компоненты суммируем по Пифагору в скаляр
Для ориентации вводим единичный
2. Кватернионное представление
Тогда кватернионное представление просто:
3. Кватернионные роторы: R-поворот и D-буст
R-поворот вокруг на угол
:
поворачивает только в .
D-вращение (буст) вдоль на угол
— обычный 2D-поворот в плоскости
:
Разложив по
(где
), получаем
Здесь геометрия дотошно.
Удобная связь с кинематикой:
Здесь подробно объяснена связь со специальной теорией относительности.
Скорость ⇄ D-ротор
Формулы. Пусть ,
,
. Тогда
Обратно, для единичного кватерниона :
4. Вращение Вигнера
Для двух D-роторoв положим
Они в общем случае не коммутируют. Выделим суммарный D-вклад как тот, который воспроизводит «наклон» временной оси:
Тогда ротор Вигнера — остаточный чистый R-поворот:
и наблюдаемое действие после компенсации :
Ось и угол. Пусть — мера коллинеарности бустов. Тогда
5. Прецессия Томаса
При медленно меняющемся направлении накопление D-вращений даёт угловую скорость
Для равномерной окружности: .
6. Перепараметризация времени
Геометрия роторов не меняется — меняется только «какие часы» ведут эволюцию. Достаточно выбрать параметр и использовать один из вариантов.
Варианты эволюции
По собственному времени
:
По лабораторному времени t:
По фазовой дуге
(евклидова норма в прото-пространстве):
Гиперболическая запись СТО
Для перехода к псевдоевклидовой метрике пространства Минковского:
где
Любые формулы с роторами
и
(включая Вигнера и Томаса) остаются теми же; меняются только
согласно выбранному режиму.
7. Шпаргалка
, где
,
.
R:
,
.
D:
,
,
,
.
Вигнер:
,
,
.
Томас:
.
8. Алгоритм и пример
Пусть D-роторы
Тогда
Пояснение кватернионного корня
Здесь — главная (principal) кватернионная корень-квадрат с неотрицательной скалярной частью; для единичного
:
Надёжная формула через . Для единичного кватерниона
:
Это устойчиво даже при (то есть
).
Python-скрипт (NumPy) import numpy as np # Кватернионы как массивы [w, x, y, z]; единичные роторы -> |q|=1 def qmul(a, b): w1, x1, y1, z1 = a w2, x2, y2, z2 = b return np.array([ w1*w2 — x1*x2 — y1*y2 — z1*z2, w1*x2 + x1*w2 + y1*z2 — z1*y2, w1*y2 — x1*z2 + y1*w2 + z1*x2, w1*z2 + x1*y2 — y1*x2 + z1*w2, ]) def qconj(q): # сопряжение (для единичных это же и обратный) w, x, y, z = q return np.array([w, -x, -y, -z]) def qnorm(q): return np.linalg.norm(q) def qnormalize(q, eps=1e-15): n = qnorm(q) return q if n < eps else q / n def qsqrt_unit(q, eps=1e-15): «»» Главная ветвь квадр. корня от единичного кватерниона q = [w, v]. Возвращает s, такое что s*s == q и Re(s) >= 0. «»» w, x, y, z = q w = float(w) v = np.array([x, y, z], dtype=float) n = qnorm(q) if abs(n — 1.0) > 1e-9: # На всякий случай нормируем w, v = (w/n), (v/n) if w > -1 + eps: s = np.sqrt(0.5*(1.0 + w)) if s < eps: # чисто векторный случай близко к w = -1 (редкий/неустойчивый) # выберем ось v/|v| и полуугол = pi/2 axis = v / (np.linalg.norm(v) + eps) return np.array([0.0, *(axis)]) # полуугол = pi/2 => [0, axis] vec = v / (2.0*s) return qnormalize(np.array([s, *vec])) else: # w ~ -1: корень почти чисто векторный; выберем ось v axis = v / (np.linalg.norm(v) + eps) return np.array([0.0, *(axis)]) def drotor(u, psi): «»» D-ротор: d = cos(psi/2) + u * sin(psi/2), где u — единичный 3-вектор. Возвращает кватернион [w, x, y, z]. «»» u = np.array(u, dtype=float) un = u / (np.linalg.norm(u) + 1e-15) c, s = np.cos(psi/2.0), np.sin(psi/2.0) return np.array([c, *(s*un)]) def raxis_angle(r, eps=1e-15): «»» Из ротора r (единичный кватернион) достать ось (3-вектор) и угол (рад). Для r = [w, v], угол = 2*atan2(|v|, w); ось = v/|v|. «»» r = qnormalize(r) w, vx, vy, vz = r v = np.array([vx, vy, vz]) vnorm = np.linalg.norm(v) angle = 2.0*np.arctan2(vnorm, w) axis = np.array([1.0, 0.0, 0.0]) if vnorm < eps else v / vnorm return axis, angle def wigner_rotor(u1, psi1, u2, psi2): «»» Главная функция: по двум D-бустам вернуть ротор Вигнера r_W и промежуточный суммарный D-ротор d_12. «»» d1 = drotor(u1, psi1) d2 = drotor(u2, psi2) L12 = qmul(d2, d1) L21 = qmul(d1, d2) T = qmul(L12, L21) # T = L12 * L21 (т.к. e_t = 1 => d e_t d = d^2) d12 = qsqrt_unit(T) # principal sqrt, Re(d12) >= 0 rW = qmul(qconj(d12), L12) # r_W = bar d12 * L12 return qnormalize(rW), qnormalize(d12) # Пример использования if __name__ == «__main__»: deg = np.deg2rad u1, psi1 = [1, 0, 0], deg(40) # буст 1: ось X, угол 40° u2, psi2 = [0, 1, 0], deg(30) # буст 2: ось Y, угол 30° rW, d12 = wigner_rotor(u1, psi1, u2, psi2) axis, angle = raxis_angle(rW) print(«d12 (sum D-rotor) =», d12) print(«rW (Wigner) =», rW) print(«axis =», axis, «angle_deg =», np.rad2deg(angle)) # sanity-check: L12 == d12 * rW, L21 == rW^{-1} * d12 (с точностью до числ. погрешности) d1 = drotor(u1, psi1) d2 = drotor(u2, psi2) L12 = qmul(d2, d1) L21 = qmul(d1, d2) lhs1 = L12 rhs1 = qmul(d12, rW) lhs2 = L21 rhs2 = qmul(qconj(rW), d12) print(«||L12 — d12*rW|| =», qnorm(lhs1 — rhs1)) print(«||L21 — rW^{-1}*d12|| =», qnorm(lhs2 — rhs2))
9. Контроль по классической формуле: формулы + Python-проверка
Классическая формула угла Вигнера (в рапидитах).
Пусть даны две скорости с модулями
и направлениями
.
Введём рапидиты , где
,
.
Угол между направлениями: .
Тогда ось Вигнера:
а угол:
Ниже — код, который:
строит
по униметрическому алгоритму (кватернионы/роторы),
считает
по формуле выше,
сравнивает ось/угол.
Python-скрипт (NumPy) import numpy as np # —— базовая кватернионная алгебра —— def qmul(a, b): w1, x1, y1, z1 = a w2, x2, y2, z2 = b return np.array([ w1*w2 — x1*x2 — y1*y2 — z1*z2, w1*x2 + x1*w2 + y1*z2 — z1*y2, w1*y2 — x1*z2 + y1*w2 + z1*x2, w1*z2 + x1*y2 — y1*x2 + z1*w2, ]) def qconj(q): w, x, y, z = q return np.array([w, -x, -y, -z]) def qnorm(q): return np.linalg.norm(q) def qnormalize(q, eps=1e-15): n = qnorm(q) return q if n < eps else q/n def qsqrt_unit(q, eps=1e-15): «»» Главная ветвь sqrt для единичного кватерниона q=[w,v], Re>=0. «»» q = qnormalize(q) w, vx, vy, vz = q v = np.array([vx, vy, vz]) vnorm = np.linalg.norm(v) if w >= 0: s = np.sqrt(0.5*(1.0 + w)) vec = v/(2.0*s) if s > eps else (v/(vnorm+eps)) return qnormalize(np.array([s, *vec])) else: # w ~ отриц., корень почти чисто-векторный axis = v/(vnorm+eps) if vnorm > eps else np.array([1.0,0.0,0.0]) return np.array([0.0, *axis]) def raxis_angle(r, eps=1e-15): r = qnormalize(r) w, x, y, z = r v = np.array([x, y, z]) vnorm = np.linalg.norm(v) angle = 2.0*np.arctan2(vnorm, w) axis = np.array([1.0,0.0,0.0]) if vnorm < eps else v/vnorm return axis, angle # —— параметризация D-ротора —— def psi_from_beta(beta): «»» Униметрический угол psi из β: β=sinψ, γ=1/cosψ. Численно устойчиво через полуугол: tan(ψ/2) = γβ/(γ+1). «»» beta = float(beta) if not (0 <= beta < 1): raise ValueError(«beta must be in [0,1)») gamma = 1.0/np.sqrt(1.0 — beta*beta) t = (gamma*beta)/(gamma+1.0) return 2.0*np.arctan(t) def drotor_from_velocity(v, c=1.0): v = np.array(v, dtype=float) speed = np.linalg.norm(v) if speed == 0: return np.array([1.0, 0.0, 0.0, 0.0]) u = v/speed beta = speed/float(c) psi = psi_from_beta(beta) c2, s2 = np.cos(psi/2.0), np.sin(psi/2.0) return np.array([c2, *(s2*u)]) # —— Wigner из двух скоростей по униметрии —— def wigner_rotor_from_velocities(v1, v2, c=1.0): d1 = drotor_from_velocity(v1, c) d2 = drotor_from_velocity(v2, c) L12 = qmul(d2, d1) L21 = qmul(d1, d2) # из условия d12 * e_t * d12 = L12 * e_t * L21, где e_t ≡ 1, получаем d12^2 = L12 L21 d12 = qsqrt_unit(qmul(L12, L21)) rW = qmul(qconj(d12), L12) return qnormalize(rW) # —— Классическая формула угла —— def wigner_angle_classic(v1, v2, c=1.0): v1 = np.array(v1, float); v2 = np.array(v2, float) u1 = v1/np.linalg.norm(v1) if np.linalg.norm(v1) > 0 else np.array([1.0,0.0,0.0]) u2 = v2/np.linalg.norm(v2) if np.linalg.norm(v2) > 0 else np.array([1.0,0.0,0.0]) cos_th = float(np.clip(np.dot(u2, u1), -1.0, 1.0)) sin_th = np.sqrt(1.0 — cos_th*cos_th) beta1 = np.linalg.norm(v1)/float(c) beta2 = np.linalg.norm(v2)/float(c) eta1 = np.arctanh(beta1) # rapidities eta2 = np.arctanh(beta2) sh1 = np.sinh(eta1/2.0); ch1 = np.cosh(eta1/2.0) sh2 = np.sinh(eta2/2.0); ch2 = np.cosh(eta2/2.0) num = sin_th * sh1 * sh2 den = ch1*ch2 + cos_th * sh1 * sh2 return 2.0 * np.arctan2(num, den) def axis_classic(v1, v2): v1 = np.array(v1, float); v2 = np.array(v2, float) u1 = v1/np.linalg.norm(v1) if np.linalg.norm(v1) > 0 else np.array([1.0,0.0,0.0]) u2 = v2/np.linalg.norm(v2) if np.linalg.norm(v2) > 0 else np.array([1.0,0.0,0.0]) a = np.cross(u2, u1) n = np.linalg.norm(a) return a/n if n > 0 else np.array([1.0,0.0,0.0]) # —— Демонстрация —— if __name__ == «__main__»: c = 1.0 v1 = np.array([0.6, 0.0, 0.0]) * c # 0.6c по X v2 = np.array([0.0, 0.5, 0.0]) * c # 0.5c по Y # униметрический расчёт rW = wigner_rotor_from_velocities(v1, v2, c) axis_u, phi_u = raxis_angle(rW) # классическая формула phi_cl = wigner_angle_classic(v1, v2, c) axis_cl = axis_classic(v1, v2) # сравнение (ось — до знака; сравниваем |dot|) axis_align = abs(np.dot(axis_u, axis_cl)) angle_err = abs(phi_u — phi_cl) print(f»phi_unimetry (deg) = {np.rad2deg(phi_u):.8f}») print(f»phi_classic (deg) = {np.rad2deg(phi_cl):.8f}») print(f»|axis dot| = {axis_align:.12f} (1.0 = совпало)») print(f»|angle diff| (deg) = {np.rad2deg(angle_err):.12e}») # простая проверка точности assert axis_align > 1 — 1e-10, «Оси не совпадают (с точностью до знака).» assert angle_err < 1e-10, «Углы не совпали в пределах машинной точности.»
10. Заключение
Выгоды использования кватернионной алгебры для рассчётов:
1) Концептуально проще
Один объект для всего. R-повороты и D-«бусты» — это единичные кватернионы, различаются только плоскостью/осью действия; композиция — обычное умножение.
Вигнер получается «по определению»: остаток после компенсации суммарного D-вклада — сразу ротор
Ось и угол берутся из одного ротора
:
— без матриц и диагонализаций.
2) Алгоритмически короче
«Одна строка» реально работает (см. выше). Для матриц Лоренца пришлось бы городить полярную/QR-факторизацию.
Стоимость операций: умножение кватернионов —
16 умножений + 12 сложений; умножение
—
64 умножений + 48 сложений.
Память: 4 числа вместо 16.
3) Численно устойчивее
Нет сингулярностей Эйлера (gimbal lock), малые углы считаются стабильно.
Нормализация — одно деление на норму; «дрейф» ортогональности у матриц требует дорогой реортогонализации.
Корень «правильной ветви» фиксируется условием
, без эвристик.
4) Прямой мост к «классике» SR
Вся геометрия — в евклидовой
; «гиперболическая» запись — это просто замена параметра
, где
.
Сверка с классической формулой Вигнера — одна арктангента (см. блок «Контроль по классике»).
5) Инженерные плюсы
Легко векторизуется и GPU-дружелюбно: пачки роторных умножений тривиально параллелятся.
Инкрементальные расчёты (накопление малых D-вращений и
) стабильны: нормализуешь каждый шаг — и готово.
Удобные градиенты по параметрам ротора (ось/полуугол) для оптимизаций и фильтров.
Итог: кватернионные роторы сводят кинематику Лоренца к паре дешёвых, устойчивых операций «умножение + нормализация», а Вигнер и Томас получаются буквально в несколько строк.
Естественно, при написании статьи вежливо экплуатировался ChatGPT.
Этот пост — продолжение популярного изложения статьи, текст которой доступен как препринт: Unimetry: A Phase-Space Reformulation of Special Relativity (скачать), Zenodo (открыть), DOI:10.5281/zenodo.17347794. Материал адаптирован из препринта по лицензии CC-BY 4.0. Пожалуйста, цитируйте оригинальный препринт.
Источник: habr.com


























