Оптимизация многообразия
Optim.jl поддерживает минимизацию функций, определенных в римановых многообразиях, то есть с простыми ограничениями, такими как нормализация и ортогональность. Основная идея таких алгоритмов заключается в том, чтобы спроецировать каждый повтор метода минимизации без ограничений обратно на многообразие. Для этого нужно передать оптимизатору именованный аргумент manifold
.
Пример
Вот простой тестовый случай, в котором мы минимизируем отношение Рэлея <x, A x>
симметричной матрицы A
при ограничении ||x|| = 1
, находя собственный вектор, связанный с наименьшим собственным значением A
.
n = 10
A = Diagonal(range(1, stop=2, length=n))
f(x) = dot(x,A*x)/2
g(x) = A*x
g!(stor,x) = copyto!(stor,g(x))
x0 = randn(n)
manif = Optim.Sphere()
Optim.optimize(f, g!, x0, Optim.ConjugateGradient(manifold=manif))
Поддерживаемые решатели и многообразия
Поддерживаются все методы оптимизации первого порядка.
На данный момент поддерживаются следующие многообразия.
-
Плоское: евклидово пространство, используется по умолчанию. Стандартная оптимизация без ограничений.
-
Сферическое: сферическое ограничение
||x|| = 1
, гдеx
является вещественным или комплексным массивом любой размерности. -
Штифеля: многообразие Штифеля матриц размером N x n с ортогональными столбцами, например
X'*X = I
.
Следующие метамногообразия строят многообразия из уже существующих:
-
PowerManifold: идентичные копии указанного многообразия
-
ProductManifold: произведение двух (потенциально разных) многообразий
См. test/multivariate/manifolds.jl
с примерами использования.
Реализовать новые многообразия так же просто, как добавить методы project_tangent!(M::YourManifold,g,x)
и retract!(M::YourManifold,x)
. При реализации другого многообразия или метода оптимизации не забудьте отправить запрос на вытягивание.