resolver

12

Estoy transfiriendo un código existente de MATLAB a C ++ y tengo un sistema lineal para resolver (en lugar de la forma más típica )A x = bxA=bAx=b

La matriz es densa y de forma general, pero no es mayor que 1000x1000. Entonces, en MATLAB, la solución o la notación de barra diagonal encuentran la soluciónAmrdivide(b,A)x = b/A;

¿Cómo debo resolver esto en mi código C ++ usando rutinas BLAS y LAPACK?

Estoy familiarizado con la rutina LAPACK DGESVque resuelve para .xAx=bx

Entonces, un pensamiento que tenía es hacer algunas manipulaciones usando identidades de transposición de matriz:

(xA)T=bT

ATxT=bT

xT=(AT)1bT

Luego resuelva la forma final utilizando la DGESVoperación de la transpuesta . (por lo que cuesta transponer y cuesta resolver el sistema) AATA

¿Existe un enfoque más eficiente o mejor ?

Estoy trabajando con clases de matrices y vectores, así como la implementación de BLAS de la biblioteca BOOST uBLAS, así como enlaces a las rutinas de la biblioteca LAPACK. He estado usando esta configuración con éxito para otras operaciones y espero encontrar una solución limitada a estas bibliotecas.

Además, debo tener en cuenta que solo estoy realizando este tipo de operación unas pocas veces durante la configuración del código, por lo que el rendimiento no es una preocupación crítica.

Tal vez esto MATLAB documentación sobre mrdividees de gran ayuda para los demás.

NoahR
fuente

Respuestas:

10

Respuesta trivial para el cuadrado : use which resuelve también para cuando .A T x = bAdgesvxATx=bTRANS = 'T'

Tenga en cuenta que con BLAS o LAPACK casi no tiene que transponer (intercambiando elementos en la memoria) una matriz: la mayoría de las subrutinas tienen un TRANSargumento para acomodar la operación en la matriz de transposición o en una matriz almacenada con un diseño de memoria diferente. (La transposición es equivalente a cambiar el diseño de la memoria contigua Fortran a una contigua C y viceversa).

Stefano M
fuente
Gracias por la respuesta y explicación! He trabajado muy poco con LAPACK y ahora sé buscar la opción TRANS. Tengo problemas para que el argumento TRANS funcione boost::numeric::bindings::lapack::gesvx(), pero esto no es parte de mi pregunta aquí. Si tengo éxito, volveré con una nota sobre cómo hacerlo.
NoahR
Tengo una solución de trabajo usando gesvx(), aunque no sin algunos tropiezos en el camino. Cuando el argumento TRANS es 'T', la documentación de LAPACK dice que gesvxresuelve , pero realmente resuelve porque se espera que la forma de los argumentos de entrada y estén en su -transpuesta de forma. Entonces, el argumento se transpone, mientras que y no. Genial, eso es más conveniente. Si alguien más se topa con esto tratando de usar enlaces numéricos de impulso, diré que no he podido obtener la interfaz de transposición utilizada en esta solución. para trabajar a través de los enlaces. A T X T = B T X B A X BATX=BATXT=BTXBAXB
NoahR
Ok, encontré el truco para usar el gesvxformulario de transposición boost::numeric::bindings. Envuelva la matriz transpuesta en la función. Esto identifica el parámetro como tipo de transposición : ATtrans()boost::numeric::bindings::lapack::gesvx( FACT, boost::numeric::bindings::trans(Atransposed), af, ipiv, equed, r, c, b, x, rcond, ferr, berr );
NoahR
0

Puede calcular el pseudo inverso de , usando la descomposición QR de SVD, que están incluidos en LAPACK.A

xA=bxQR=bx=bR1QT

Esto funcionará para cualquier rectangular .A

Gil
fuente
3
Si es rectangular (no cuadrado), entonces también lo es , y la expresión no está definida. R R - 1ARR1
Geoff Oxberry