Я должен вычислить nullspace нескольких тысяч маленьких матриц (8x9, не 4x3, как я записал ранее), параллельно (CUDA). Все ссылки указывают на SVD, но алгоритм в числовых рецептах кажется очень дорогим, и дает мне много вещей кроме пустого пространства, в котором я действительно не нуждаюсь. Разве Исключение Гаусса является действительно не опцией? Есть ли какие-либо другие наиболее часто используемые методы?
Чтобы ответить на ваш вопрос напрямую ... да! QR-разложение!
Пусть A - матрица размера m на n с рангом n. QR-разложение находит ортонормированную матрицу Q размером m на m и верхнетреугольную матрицу R размером m на n такие, что A = QR. Если мы определим Q = [Q1 Q2], где Q1 - размер m на n, а Q2 - размер m на (m-n), то столбцы Q2 образуют нулевое пространство A ^ T.
QR-разложение вычисляется с помощью вращений Грама-Шмидта, Гивенса или отражений Хаусхолдера. У них разные свойства стабильности и количество операций.
Вы правы: СВД - дорогое удовольствие! Я не могу говорить о том, что использует современный материал, но когда я слышу «вычислить нулевое пространство» (РЕДАКТИРОВАТЬ: таким образом, чтобы мне было просто понять), я думаю, что QR.
В шутку:
#include <stdio.h>
int main (int argc, char *argv[])
{
size_t sizeofInt = sizeof (int);
int i;
union
{
int x;
char c[sizeof (int)];
} original, swapped;
original.x = 0x12345678;
for (i = 0; i < sizeofInt; i++)
swapped.c[sizeofInt - i - 1] = original.c[i];
fprintf (stderr, "%x\n", swapped.x);
return 0;
}
-121--787915- this.TextBox3.Text = Последовательность .Формат («{0: MM.dd.yyyy}», DateTime.Now);
-121--1507725-Я думаю, что самое главное для CUDA - найти алгоритм, который не зависит от условного ветвления (которое довольно медленно на графическом оборудовании). Простота, если операторы, которые можно оптимизировать в условное назначение, намного лучше (или можно использовать оператор?:).
При необходимости Вы должны уметь выполнять определенную форму поворота с помощью условного назначения. На самом деле, может быть сложнее определить, как сохранить результат: Если ваша матрица имеет недостаток ранга, что вы хотите, чтобы ваша программа CUDA сделала с ней?
Если вы предполагаете, что ваша матрица 4x3 на самом деле не является дефицитом ранга, вы можете найти ваш (один) нулевой вектор без каких-либо условий вообще: матрица достаточно мала, чтобы можно было эффективно использовать правило Крамера.
На самом деле, поскольку вы на самом деле не заботитесь о масштабе вашего нулевого вектора, вам не нужно делить на определитель - вы можете просто взять определители миноров:
x1 x2 x3
M = y1 y2 y3
z1 z2 z3
w1 w2 w3
|y1 y2 y3| |x1 x2 x3| |x1 x2 x3| |x1 x2 x3|
-> x0 = |z1 z2 z3| y0 = -|z1 z2 z3| z0 = |y1 y2 y3| w0 = -|y1 y2 y3|
|w1 w2 w3| |w1 w2 w3| |w1 w2 w3| |z1 z2 z3|
Обратите внимание, что эти определители 3x3 являются просто тройными продуктами; можно сохранить вычисления, повторно используя перекрестные продукты.
Устранение гауссова - это достаточно быстро для матриц 4x3. IIRC Я сделал около 5 миллионов в секунду с Java без параллелизма. С такой небольшой проблемой ваша лучшая ставка - кодировать рутину (ряд уменьшить и т. Д.) Сами; В противном случае вы будете тратить большую часть времени, получая данные в правильный формат для внешней рутины.
«Кажется очень дорогим» - какие данные у вас есть, что поддерживает это?
Может быть, Блок Lanczos - это ответ, который вы ищете.
Или, может быть, это .
Оба JAMA, так и Apache Commons Math имеют реализации SVD в Java. Почему бы не взять их и попробовать их? Получите некоторые реальные данные для вашего дела вместо впечатлений. Это не будет стоить вам много, так как код уже написан и протестирован.
Мне было интересно, связаны ли матрицы, а не просто случайны, так что искомые нулевые пространства можно рассматривать как одномерные касательные к кривой в N -пространство (N = 9). Если это так, вы можете ускорить процесс, используя метод Ньютона для решения последовательных экземпляров системы квадратных уравнений Ax = 0, | x | ^ 2 = 1, начиная с предыдущего вектора нулевого пространства. Метод Ньютона использует первые производные, чтобы сходиться к решению, и поэтому будет использовать метод исключения Гаусса для решения систем 9x9. Использование этого метода потребует, чтобы вы могли делать небольшие шаги от матрицы к матрице, например, изменяя параметр.
Таким образом, идея состоит в том, что вы инициализируете использование SVD для первой матрицы, но после этого вы переходите от матрицы к матрице, используя вектор нулевого пространства единицы в качестве отправной точки для итерации для следующей. Вам понадобится одна или две итерации, чтобы добиться сходимости. Если у вас нет согласия, используйте SVD для перезапуска. Если у вас есть такая ситуация, это намного быстрее, чем начинать заново с каждой матрицы.
Я использовал это давным-давно, чтобы отобразить контуры в решениях наборов 50 x 50 квадратных уравнений, связанных с поведением электроэнергетических систем.