Эффективный способ решения для X в AX=B в MATLAB, когда A и B-большие матрицы

у меня есть проблема, которая требует решения для X на AX=B. A имеет порядок 15000 x 15000 и является разреженным и симметричным. B является 15000 X 7500 и не является разреженным. Каков самый быстрый способ решения для X?

Я могу придумать 2 способа.

  1. простым способом, X = AB
  2. используя цикл for,

    invA = Aspeye(size(A))
    for i = 1:size(B,2)
        X(:,i) = invA*B(:,i);
    end
    

есть ли лучший способ, чем выше двух? Если нет, то какой из них лучше между двух я упомянул?

4 ответов


первое - никогда, когда-нибудь вычислить обратный от A. То есть никогда разреженный, за исключением случаев, когда A является диагональной матрицей. Попробуйте для простой трехдиагональной матрицы. Эта строка сама по себе убивает ваш код - память и производительность. И вычисление обратного численно менее точно, чем другие методы.

как правило, \ должно работать на вас отлично. MATLAB распознает, что ваша матрица разрежена и выполняет разреженную факторизацию. Если вы дайте матрицу B как правая сторона, производительность намного лучше, чем если бы вы решали только одну систему уравнений с b вектор. Так что вы делаете это правильно. Единственная другая техническая вещь, которую вы можете попробовать здесь, - это явно вызвать lu, chol или ldl, в зависимости от матрицы у вас есть, и выполните замену назад/вперед самостоятельно. Может, сэкономишь немного времени.

дело в том, что методы решения систем линейных уравнений, особенно разреженные системы, сильно зависят от проблемы. Но почти в любом (разреженном) случае, я полагаю, факторизация системы 15k должна занять лишь долю секунды. В наши дни это не большая система. Если ваш код медленный, это, вероятно, означает, что ваш фактор больше не является разреженным. Вы должны убедиться, что ваша матрица правильно порядок для минимизации заполнения (добавлены ненулевые записи) во время разреженной факторизации. Это решающий шаг. Посмотрите at эта страница для некоторых тестов и объяснений о том, как упорядочить вашу систему. И кратко взгляните на пример переупорядочения в это так нити.


поскольку вы можете ответить себе, какой из двух быстрее, я попробую предложить следующие варианты. Решите его с помощью GPU. Множество деталей можно найти в интернете, в том числе это Так пост, a бенчмаркинг matlab A / b, etc. Кроме того, есть надстройка MATLAB LAMG (Lean Алгебраическая Многосеточная). LAMG быстрый график решатель Лапласа. Он может решить Ax=b в O (m) времени и хранения.


если ваша матрица A является симметричной положительно определенной, то вот что вы можете сделать, чтобы решить систему эффективно и стабильно:

  • сначала вычислить разложение Холецкого, A=L*L'. Поскольку у вас есть разреженная матрица, и вы хотите использовать ее для ускорения инверсии, вы не должны применять chol непосредственно, что разрушит шаблон разреженности. Вместо этого используйте один из описанных методов переупорядочивания здесь.
  • затем решить систему X = L'\(L\B)

наконец, если вы не имеете дело с потенциальными комплексными значениями, то вы можете заменить все L' by L.', что дает немного больше ускорения, потому что он просто пытается транспонировать вместо вычисления комплексного сопряженного.

Другой альтернативой будет предварительно обусловленный метод сопряженного градиента,pcg в Matlab. Это очень популярно на практике, потому что вы можете обменять скорость на точность, т. е. дать ей меньше количество итераций, и это даст вам (обычно довольно хорошо) приближенное решение. Вам также никогда не нужно хранить матрицу A явно, но просто иметь возможность вычислять матрично-векторное произведение с A, Если ваша матрица не влезает в память.


Если это займет вечность, чтобы решить в ваших тестах, вы, вероятно, собираетесь в виртуальную память для решения. Квадратная (полная) матрица 15k потребует 1,8 гигабайта ОЗУ для хранения в памяти.

>> 15000^2*8
ans =
      1.8e+09

вам понадобится серьезная ОЗУ для решения этой проблемы, а также 64-разрядная версия MATLAB. Никакая факторизация не поможет вам, если у вас недостаточно оперативной памяти для решения проблемы.

Если ваша матрица действительно разрежена, то вы используете разреженную форму MATLAB для ее хранения? Если нет, тогда MATLAB не знает, что матрица разрежена, и не использует разреженную факторизацию.

насколько разрежен A? Многие считают, что матрица, наполовину заполненная нулями, "разрежена". Это было бы пустой тратой времени. На матрице такого размера, нужно что-то, что составляет более 99% нулей, чтобы действительно получить от разреженной факторизации матрицы. Это из-за заполнения. В противном случае результирующая факторизованная матрица почти всегда почти полна.

Если вы не можете получить больше ОЗУ (RAM cheeeeeeeeep вы знаете, конечно, как только вы считаете время, которое вы потратили впустую, пытаясь решить эту проблему), то вам нужно будет попробовать итеративный решатель. Поскольку эти инструменты не факторизуют вашу матрицу, если она действительно разрежена, то они не войдут в виртуальную память. Это огромная экономия.

С итерационным инструменты часто требуют прекондиционер, чтобы как можно лучше работать, это может занять некоторое исследование, чтобы найти лучшие предобусловливатель.