Гиперкомплексная обработка сигналов: преобразование Фурье и алгебра оптических операций через октонионы
В современной цифровой обработке сигналов преобразование Фурье является фундаментальным инструментом. Но что если мы хотим анализировать не просто одномерные аудиосигналы или двумерные изображения, а сложные многомерные данные, где каждый элемент содержит информацию о цвете, поляризации, пространственных координатах и других параметрах? Причем нам может потребоваться изменять все параметры сигнала связанным, физически допустимым образом.
Здесь на помощь приходят октонионы - 8-мерные гиперкомплексные числа, позволяющие компактно представлять и анализировать такие сложные данные.
Что такое октонионы?
Октонионы (или октавы) - это расширение комплексных чисел и кватернионов. В отличие от кватернионов, которые имеют 4 компоненты, октонионы имеют 8 компонент и обладают свойством неассоциативности. В Julia мы можем работать с ними с помощью пакета Octonions.jl
.
Pkg.add("Octonions")
Создадим анализируемый сигнал
Рассмотрим реализацию октонионного преобразования Фурье для обработки многомерных сигналов.
В отличие от обычного вектора, октонион (8-мерное гиперкомплексное число) может компактно кодировать:
-
Поляризацию (2 компоненты — линейная и круговая),
-
Цвет (3 компоненты — RGB или спектральные характеристики),
-
Фазовую информацию (1 компонента),
-
Пространственные координаты (2 компоненты — например, угол падения и глубину).
Такое представление сохраняет взаимосвязи между параметрами, которые теряются при раздельном анализе (представление в виде векторов).
using Octonions, FFTW, LinearAlgebra
# Создаем октонионный сигнал (8-канальный)
function create_octonion_signal(n)
[Octonion(randn(8)...) for _ in 1:n]
end
Октонионы здесь работают как «контейнеры», сохраняющие естественные соотношения между физическими параметрами света, что критично для точного анализа и обработки.
Но если разложить все октонионы на 8 скалярных компонент, то мы получим такую матрицу:
oc_to_vec(o) = [o.s, o.v1, o.v2, o.v3, o.v4, o.v5, o.v6, o.v7]
heatmap( hcat([oc_to_vec(o) for o in (create_octonion_signal(100))]... ) )
Октонионное преобразование Фурье
Дальше реализуем два метода - прямое и обратное преобразование Фурье для октонионов.
# Октонионное преобразование Фурье
function octonion_fft(signal)
# Преобразуем вектор из октонионов в 8 векторов скаляров
components = eachrow(hcat([oc_to_vec(o) for o in signal]...))
# Применяем стандартное FFT к каждой компоненте
transformed_components = [fft(c) for c in components]
# Собираем действительную и мнимую часть в октонионы
transformed_re = [Octonion([real(transformed_components[j][k]) for j in 1:8]...) for k in 1:n]
transformed_im = [Octonion([imag(transformed_components[j][k]) for j in 1:8]...) for k in 1:n]
return transformed_re, transformed_im
end
# Обратное преобразование
function octonion_ifft(signal_re, signal_im)
complex_matrix = [[ Complex(si,sr) for (si,sr) in zip(oc_to_vec(vi),oc_to_vec(vr))] for (vi,vr) in zip(signal_re,signal_im)]
components = eachrow(hcat(complex_matrix...))
transformed_components = [ifft(c) for c in components]
[Octonion([real(transformed_components[j][k]) for j in 1:8]...) for k in 1:n]
end
Теперь передадим в наши преобразования вектор из 256 октонионов, проведем преобразование в частотную область и обратно и посмотрим, какая ошибка у нас наберется от этих операций.
# Пример использования
n = 256
signal = create_octonion_signal(n)
(transformed_re, transformed_im) = octonion_fft(signal)
reconstructed = octonion_ifft(transformed_re, transformed_im)
# Проверка точности восстановления
recovery_err = norm([signal[i] - reconstructed[i] for i in 1:n])
println("Ошибка восстановления: ", recovery_err)
При обратном преобразовании Фурье (ifft
) мы работаем с комплексным спектром сигнала, но итоговый восстановленный сигнал должен быть вещественным (поскольку исходные данные — это физические измерения, такие как интенсивность света или амплитуда волны).
Практическое применение
Такой подход может быть полезен для:
-
Обработки цветных изображений с дополнительными характеристиками (глубина, поляризация)
-
Анализа многомерных физических данных (например, метеорологических измерений)
-
Сжатия сложных сигналов с сохранением взаимосвязей между компонентами
Примеры сигналов для анализа могут включать информацию со следующих устройств:
-
Поляризационная камера — данные о распределении поляризации света в сцене, где каждый пиксель содержит информацию об угле и эллиптичности поляризации.
-
Гиперспектральные изображения — сотни спектральных каналов, которые можно сжать до 8 ключевых компонент.
-
Лидарные данные — расстояние, интенсивность и поляризация отраженного сигнала для автономных автомобилей.
-
Голография — амплитуда и фаза световой волны, восстанавливающей 3D-объект.
Применение октонионов в оптике
Октонионы — это не просто 8D-векторы, а алгебраическая структура с некоммутативным и неассоциативным умножением. В оптике это позволяет:
-
Кодировать взаимозависимые параметры
Например, поляризация (линейная/круговая) математически связана с фазой и направлением распространения волны. В векторном представлении эти связи теряются, а в октонионной алгебре сохраняются через правила умножения базисных единицe₁...e₇
. -
Учитывать нелинейные эффекты
Умножение октонионов автоматически моделирует:-
Вращение плоскости поляризации в кристаллах
-
Фазовые сдвиги при преломлении
-
Взаимодействие спектральных компонент
-
-
Сжимать представление
8D-октонион компактнее тензорного описания тех же параметров (например, матриц Джонса-Мюллера для поляризации + отдельно RGB + фаза).
При желании можно создать алгебру оптических операций, базирующуюся на октонионах, имеющею все обозначенные выше преимущества.
Следующая программа показывает, как применение поляризации к пучку света с круговой поляризацией меняет сразу амплитуду, фазу и поляризацию входного сигнала.
using Octonions
struct OpticalField
oct::Octonion{Float64}
end
# Оператор прохождения через поляризатор
function apply_polarizer(field::OpticalField, angle::Float64)
# Поляризатор как октонион с e₂ (линейная поляризация)
pol = Octonion(1.0, cos(2angle), sin(2angle), 0, 0, 0, 0, 0)
OpticalField(field.oct * pol / 2)
end
# Пример: свет с круговой поляризацией (e₄)
input = OpticalField(Octonion(0, 0, 0, 1.0, 0, 0, 0, 0))
output = apply_polarizer(input, π/4) # Поляризатор под 45°
# Результат содержит корректную связь амплитуды/фазы/поляризации
println(output.oct) # Компоненты e₂ и e₃ теперь не нулевые
Октонионы дают естественное представление оптических полей именно благодаря своей алгебраической структуре. В отличие от векторов, они:
-
Запрещают физически невозможные операции (например, независимое изменение фазы и поляризации)
-
Сокращают вычислительную сложность — одна октонионная операция заменяет серию матричных преобразований
-
Сохранют геометрические инварианты автоматически, без ручной проверки условий.
Заключение
Хотя октонионное преобразование Фурье требует больше вычислений, чем классическое, оно открывает новые возможности для анализа сложных многомерных данных. В будущем, с развитием квантовых вычислений и специализированных процессоров, такие методы могут стать стандартным инструментом в обработке сигналов.
В оптике октонионы дают естественное представление оптических полей именно благодаря своей алгебраической структуре.
Julia с ее производительностью и удобством работы с абстрактными типами данных идеально подходит для экспериментов с гиперкомплексными числами и разработки новых алгоритмов на их основе.