Решить полосчатую матричную систему уравнений
Мне нужно решить двумерное уравнение Пуассона, то есть систему уравнений в for AX=B, где A-матрица n-на-n, А B-вектор n-на-1. Будучи матрицей дискретизации для двумерной задачи Пуассона, я знаю, что только 5 диагоналей не будут нулевыми. Lapack не предоставляет функций для решения этой конкретной задачи, но у него есть функции для решения связанных матричных систем уравнений, а именно DGBTRF (для факторизации LU) и DGBTRS. Теперь 5 диагоналей: главная диагональ, первая диагональ. диагонали выше и ниже главной и двум диагоналям выше и ниже по диагонали м относительно главной диагонали. Прочитав документацию lapack о band storage, я узнал, что мне нужно создать матрицу (3*m+1)-by-n для хранения A в формате band storage, назовем эту матрицу AB. Теперь вопросы:
1) в чем разница между dgbtrs и dgbtrs_? Intel MKL предоставляет оба, но я не могу понять, почему
2) dgbtrf требует, чтобы Матрица хранения каналов была массивом. Должен Ли Я линеаризовать AB по строкам или по столбцам?
3) является ли это правильным способом вызова двух функций?
int n, m;
double *AB;
/*... fill n, m, AB, with appropriate numbers */
int *pivots;
int nrows = 3 * m + 1, info, rhs = 1;
dgbtrf_(&n, &n, &m, &m, AB, &nrows, pivots, &info);
char trans = 'N';
dgbtrs_(&trans, &n, &m, &m, &rhs, AB, &nrows, pivots, B, &n, &info);
2 ответа:
Он также предоставляет
DGBTRS
иDGBTRS_
. Это fortran administrativa, о которой вам не следует беспокоиться. Просто вызовитеdgbtrs
(причина в том, что на некоторых архитектурах имена подпрограмм fortran имеют подчеркивание, на других нет, и имена могут быть либо верхними, либо нижними буквами-Intel MKL#define
s справа отdgbtrs
).Процедуры LAPACK ожидают главные матрицы столбцов (т. е. Fortran style): хранить столбцы один за другим. Ленточное хранилище, которое вы должны использовать, не является жестким : http://www.netlib.org/lapack/lug/node124.html.
Мне это кажется хорошим, но, пожалуйста, попробуйте его на небольших проблемах заранее (кстати, всегда хорошая идея). Также убедитесь, что вы обрабатываете ненулевые
info
(это способ сообщения об ошибках).Лучший стиль-использовать
MKL_INT
вместо простогоint
, это typedef для правильного типа (может отличаться на некоторых архитектурах).Также не забудьте выделить память для
pivots
перед вызовомdgbtrf
.
Это может быть не по теме. Но для уравнения Пуассона решение на основе БПФ гораздо быстрее. Просто сделайте 2D FFT вашего потенциального поля, разделенного на- (k^2+lambda^2), а затем сделайте IFFT. лямбда-это небольшое число, чтобы избежать расхождения при k=0. 5-диагональное уравнение представляет собой ограниченную полосой аппроксимацию уравнения Пуассона, которая аппроксимирует дифференциальный оператор конечной разностью.