Как позвонить в UMFPACK как MATLAB?

Проблема

Я хочу решить общую систему линейных уравнений A * x = b. Матрица m-by-m является редкой, реальной, квадратной, несколько плохо обусловленной, несимметричной, но она сингулярна (ранг (A) == m-1), поскольку x известен только до аддитивной постоянной,

Я могу создать матрицу A, указав ее ненулевые записи в трех векторах (i, j и v), таких, что A(i(k),j(k)) = v(k):

A = sparse( i, j, v, m, m );

Исходное уравнение

Я могу решить это исходное уравнение следующим образом:

x = A \ b;

Если я хочу уникальное решение, я могу наложить ограничение (скажем, x (4) == 3.14159) после вычисления неединственного решения:

x = x - x(4) + 3.14159;

Модифицированное уравнение

Я могу создать новую полноразмерную матрицу C, добавив дополнительное ограничение единственности следующим образом:

% Add the constraint x(4) == 3.14159
extraRow = zeros(1,m);
extraRow(4) = 1.0;
C = [A; extraRow];    % Add to the matrix A
d = [b; 3.14159];     % Add to the RHS vector, b

% Solve C*y = d for y
y = C \ d;

Числовые

Я понимаю, что когда я решаю эти уравнения через x = A \ b или y = C \ b, MATLAB интерпретирует \ как команду mldivide() (), который проводит некоторые тесты на матрице и определяет оптимальный алгоритм для решения этой процедуры (см. ссылку для подробностей).

Эти детали сделаны подробными во время выполнения, установив параметры разрешающей матрицы MATLAB через spparms('spumoni',2)

Когда я вычисляю x и/или y, я замечаю следующее:

  • MATLAB использует разложение LU через UMFPACK V5.4.0 для квадратного, m-by-m исходного уравнения.
  • MATLAB использует QR-декомпозицию через SuiteSparseQR 1.1.0 для модифицированного уравнения m-by- (m + 1).

Оба UMFPACK и SuiteSparseQR входят в пакет программного обеспечения SuiteSparse (ссылка).

(Неожиданно решение модифицированного уравнения дает больше ошибок, чем исходное уравнение. Несмотря на то, что эта ошибка все еще находится на приемлемом низком пороге).

Моя проблема

Теперь, когда я могу решить эту проблему в MATLAB, я хочу сделать это в Fortran. К сожалению, команда MATLAB mldivide() - это черный ящик, в котором я не вижу, как он устанавливает или вызывает процедуры SuiteSparse.

Учитывая, что у меня есть три разреженных вектора в Fortran (90+), как показано ниже, как я могу решить проблему с помощью SuiteSparse?

В качестве альтернативы, кто-нибудь знает какие-либо подпрограммы обертки F90, которые взаимодействуют с UMFPACK, чтобы сделать это проще?

Я более чем счастлив, если кто-то может помочь с этим - либо с помощью исходного уравнения, либо с помощью модифицированного уравнения. (Если вы поможете с одним, я, вероятно, мог бы получить другого.)

subroutine solveSparseMatrixEqnViaSuiteSparse( m, n, nnz, i, j, v, x )
    implicit none

    integer, intent(in)                   :: m     ! sparse matrix rows
    integer, intent(in)                   :: n     ! sparse matrix columns
    integer, intent(in)                   :: nnz   ! number of nonzero entries
    integer, dimension(1:nnz), intent(in) :: i     ! row indices of nonzero entries
    integer, dimension(1:nnz), intent(in) :: j     ! column indices of nonzero entries
    real*8,  dimension(1:nnz), intent(in) :: v     ! values of nonzero entries
    real*8,  dimension(1:n), intent(out)  :: x     ! solution vector

    ! I have no idea what to do next! 

end function solveSparseMatrixEqnViaSuiteSparse

Что меня путает:

  • Что MATLAB делает за кулисами, чтобы настроить вызов SuiteSparse? (Он, похоже, не документирован....)
  • Что нужно сделать, чтобы вызвать SuiteSparse из Fortran? (Я, вероятно, мог бы извлечь наибольшую выгоду из этой демонстрации, учитывая достаточно времени, но странно, что он вызывает процедуры несколько раз....)

Примечание. Хотя я задаю этот вопрос с конкретной проблемой (кто не является!?), я считаю, что это достаточно общее, чтобы быть полезным и для других.

Ответ 1

Я могу ответить на ваш вопрос. Я студент PhD, работающий над UMFPACK под руководством д-ра Тима Дэвиса, и мы не используем fortran.

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

Я не знаю, предоставил ли Dr Davis интерфейс fortran для самого UMFPACK. Мы также не используем fortran в нашей группе. Однако я знаю, что вы можете использовать SuiteSparse интерфейс matlab. Перейдите в /SuiteSparse/UMFPACK/MATLAB и вы можете использовать различные интерфейсы, и вам не нужно быть знакомым с его базовым кодом C. Вы можете вызвать любую функцию напрямую. Есть функция MATLAB mex, и вы можете отлаживать и выполнять код, если хотите.

Здесь есть fortran-обертка для UMFPACK [http://geo.mff.cuni.cz/~lh/Fortran/UMFPACK/README.html], но она устарела, и я не думаю, что поддерживает последнюю версию UMFPACK