resolver

12

Estou portando um código existente do MATLAB para C ++ e tenho um sistema linear para resolver (em vez da forma mais típica A x = b )xA=bAx=b

A matriz é densa e de forma geral, mas não é maior que 1000x1000. Portanto, no MATLAB, a solução é encontrada pela função ou pela notação de barraAmrdivide(b,A)x = b/A;

Como devo resolver isso no meu código C ++ usando as rotinas BLAS e LAPACK?

Estou familiarizado com a rotina LAPACK, DGESVque resolve para x .Ax=bx

Então, um pensamento que tive foi fazer algumas manipulações usando identidades de transposição de matriz:

(xA)T=bT

ATxT=bT

xT=(AT)1bT

Em seguida, resolver a forma final utilizando DGESVa operar na transposta . (portanto, custo para transpor A e custo para resolver o sistema)ATA

Existe uma abordagem mais eficiente ou melhor ?

Estou trabalhando com classes matriciais e vetoriais, bem como com a implementação BLAS da biblioteca BOOST uBLAS, bem como com ligações às rotinas da biblioteca LAPACK. Eu tenho usado essa configuração com sucesso para outras operações e espero encontrar uma solução limitada a essas bibliotecas.

Além disso, devo observar que só estou executando esse tipo de operação algumas vezes durante a configuração do código, portanto, o desempenho não é uma preocupação crítica.

Talvez isso MATLAB documentação on mrdivideé útil para os outros.

NoahR
fonte

Respostas:

10

AdgesvxATx=bTRANS = 'T'

Observe que com BLAS ou LAPACK você dificilmente precisa transpor (trocando elementos na memória) uma matriz: a maioria das sub-rotinas possui um TRANSargumento para acomodar a operação na matriz de transposição ou em uma matriz armazenada com um layout de memória diferente. (Transposição é equivalente a alterar o layout de memória contígua ao Fortran para um contíguo C e vice-versa.)

Stefano M
fonte
Obrigado pela resposta e explicação! Eu trabalhei muito pouco com o LAPACK e agora sei procurar a opção TRANS. Estou tendo problemas para resolver o argumento TRANS boost::numeric::bindings::lapack::gesvx(), mas isso não faz parte da minha pergunta aqui. Se eu tiver sucesso, voltarei com uma nota sobre como fazê-lo.
NoahR
gesvx()gesvxATX=BATXT=BTXBAXBnão são. Ótimo, isso é mais conveniente. Se mais alguém se deparar com isso tentando usar ligações numéricas de impulso, direi que não consegui obter a interface de transposição usada neste soln. para trabalhar com as ligações.
NoahR
gesvxboost::numeric::bindingsATtrans()boost::numeric::bindings::lapack::gesvx( FACT, boost::numeric::bindings::trans(Atransposed), af, ipiv, equed, r, c, b, x, rcond, ferr, berr );
0

A

xA=bxQR=bx=bR1QT

A

Gil
fonte
3
ARR1