Что такое простой алгоритм для вычисления SVD матрицы?
В идеале мне нужен численно устойчивый алгоритм, но я бы хотел увидеть как простые, так и не очень простые реализации. Код C принят.
Любые ссылки на документы или код?
Что такое простой алгоритм для вычисления SVD матрицы?
В идеале мне нужен численно устойчивый алгоритм, но я бы хотел увидеть как простые, так и не очень простые реализации. Код C принят.
Любые ссылки на документы или код?
Ответы:
См. Https://math.stackexchange.com/questions/861674/decompose-a-2d-arbitrary-transform-into-only-scaling-and-rotation (извините, я бы добавил это в комментарий, но я зарегистрировался просто чтобы опубликовать это, я пока не могу оставлять комментарии).
Но так как я пишу это как ответ, я также напишу метод:
Это разбивает матрицу следующим образом:
Единственное, на что следует обратить внимание при использовании этого метода, это то, что или для atan2.G = F= 0 ЧАС= E= 0
Я сомневаюсь, что это может быть более надежным, чем это( Обновление: см. Ответ Алекса Эфтимиадеса!).Ссылка: http://dx.doi.org/10.1109/38.486688 (предоставлена там Рахулом), которая находится в нижней части этого сообщения в блоге: http://metamerist.blogspot.com/2006/10/linear-algebra -дль-график-вундеркинды-svd.html
Обновление: Как отметил @VictorLiu в комментарии, может быть отрицательным. Это происходит тогда и только тогда, когда определитель входной матрицы также отрицателен. Если это так, и вы хотите положительные значения единственного числа, просто возьмите абсолютное значение .sY sY
источник
@Pedro Gimeno
«Я сомневаюсь, что это может быть более надежным, чем это».
Вызов принят.
Я заметил, что обычный подход заключается в использовании тригонометрических функций, таких как atan2. Интуитивно понятно, что не должно быть необходимости использовать функции триггера. Действительно, все результаты заканчиваются синусами и косинусами арктанов, которые можно упростить до алгебраических функций. Это заняло много времени, но мне удалось упростить алгоритм Педро, чтобы использовать только алгебраические функции.
Следующий код Python делает свое дело.
источник
y1
= 0,x1
= 0,h1
= 0 иt1
= 0/0 =NaN
.GSL имеет СВД 2-на-2 решателя , лежащая в основе часть QR - разложения основного алгоритма SVD для
gsl_linalg_SV_decomp
. Смотритеsvdstep.c
файл и ищитеsvd2
функцию. У функции есть несколько особых случаев, она не совсем тривиальна, и, похоже, она делает несколько вещей, чтобы быть численно осторожной (например, использовать,hypot
чтобы избежать переполнений).источник
ChangeLog
файле есть немного, если вы скачаете GSL. И вы можете посмотреть наsvd.c
детали общего алгоритма. Кажется, что единственная истинная документация относится к функциям, вызываемым пользователем, высокого уровня, напримерgsl_linalg_SV_decomp
.Когда мы говорим «численно устойчивый», мы обычно имеем в виду алгоритм, в котором мы делаем такие вещи, как поворот, чтобы избежать распространения ошибок. Однако для матрицы 2x2 вы можете записать результат в терминах явных формул - то есть записать формулы для элементов SVD, которые указывают результат только в терминах входных данных , а не в терминах ранее вычисленных промежуточных значений . Это означает, что у вас может быть отмена, но нет распространения ошибки.
Дело просто в том, что для систем 2x2 беспокоиться о надежности не нужно.
источник
Этот код основан на бумаге Blinn в , Эллис бумаги , СВД лекции и дополнительных расчетов. Алгоритм подходит для регулярных и сингулярных вещественных матриц. Все предыдущие версии работают на 100% так же, как и эта.
источник
Мне нужен алгоритм, который имеет
Напомним, что
Вычисление диагонализационного вращения может быть выполнено путем решения следующего уравнения:
где
Идеи из:
http://www.cs.utexas.edu/users/inderjit/public_papers/HLA_SVD.pdf
http://www.math.pitt.edu/~sussmanm/2071Spring08/lab09/index.html
http: // www.lucidarme.me/singular-value-decomposition-of-a-2x2-matrix/
источник
Я использовал описание на http://www.lucidarme.me/?p=4624 для создания этого кода C ++. Матрицы принадлежат библиотеке Eigen, но вы можете легко создать свою собственную структуру данных из этого примера:
Со стандартной функцией знака
Это приводит к точно таким же значениям, что и
Eigen::JacobiSVD
(см. Https://eigen.tuxfamily.org/dox-devel/classEigen_1_1JacobiSVD.html ).источник
S2 = hypot( a*a + b*b - c*c - d*d, 2*(a*c + b*d))
источник
Для моих личных нужд я попытался выделить минимальные вычисления для 2x2 SVD. Я думаю, что это, вероятно, одно из самых простых и быстрых решений. Вы можете найти подробности в моем личном блоге: http://lucidarme.me/?p=4624 .
Преимущества: просто, быстро, и вы можете рассчитать одну или две из трех матриц (S, U или D), если вам не нужны эти три матрицы.
Недостатком является использование atan2, которое может быть неточным и может потребовать внешней библиотеки (тип. Math.h).
источник
Вот реализация решения 2x2 SVD. Я основал это на коде Виктора Лю. Его код не работал для некоторых матриц. Я использовал эти два документа в качестве математического справочника для решения: pdf1 и pdf2 .
Матричный
setData
метод находится в главном порядке строк. Внутренне я представляю данные матрицы в виде двумерного массива, заданного выражениемdata[col][row]
.источник