users scalapack netlib libreria guide and c++ fortran lapack

scalapack - Entendiendo las llamadas de LAPACK en C++ con un ejemplo simple



libreria blas (3)

Soy un principiante con la interfaz de LAPACK y C ++ / Fortran. Necesito resolver problemas de ecuaciones lineales y valores propios utilizando LAPACK / BLAS en Mac OS-X Lion. OS-X Lion proporciona bibliotecas optimizadas BLAS y LAPACK (en / usr / lib) y estoy vinculando estas bibliotecas en lugar de descargarlas desde netlib.

Mi programa (reproducido a continuación) está compilando y ejecutándose bien, pero me está dando respuestas incorrectas. He investigado en la web y Stackoverflow y el problema puede tener que ver con la forma en que C ++ y Fortran almacenan las matrices en diferentes formatos (fila mayor frente a columna principal). Sin embargo, como verá en mi ejemplo, la matriz simple para mi ejemplo debería verse idéntica en C ++ y fortran. De todos modos aquí va.

Digamos que queremos resolver el siguiente sistema lineal:

x + y = 2

x - y = 0

La solución es (x, y) = (1,1). Ahora traté de resolver esto usando Lapack como sigue

// LAPACK test code #include<iostream> #include<vector> using namespace std; extern "C" void dgetrs(char *TRANS, int *N, int *NRHS, double *A, int *LDA, int *IPIV, double *B, int *LDB, int *INFO ); int main() { char trans = ''N''; int dim = 2; int nrhs = 1; int LDA = dim; int LDB = dim; int info; vector<double> a, b; a.push_back(1); a.push_back(1); a.push_back(1); a.push_back(-1); b.push_back(2); b.push_back(0); int ipiv[3]; dgetrs(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info); std::cout << "solution is:"; std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl; std::cout << "Info = " << info << std::endl; return(0); }

Este código fue compilado de la siguiente manera:

g++ -Wall -llapack -lblas lapacktest.cpp

Sin embargo, al ejecutar esto, obtengo la solución como (-2,2) que obviamente es incorrecta. He intentado todas las combinaciones de reorganización de fila / columna de mi matriz a . También observe que la representación matricial de a debe ser idéntica en los formatos de fila y columna. Creo que hacer que este sencillo ejemplo funcione me ayudará a comenzar con LAPACK y cualquier ayuda será apreciada.


Para aquellos que no quieren molestarse con Accelerate Framework, les proporciono el código de Stephen Canon (gracias a él, por supuesto) con nada más que un enlace de biblioteca puro

// LAPACK test code //compile with: g++ main.cpp -llapack -lblas -o testprog #include <iostream> #include <vector> using namespace std; extern "C" void dgetrf_(int* dim1, int* dim2, double* a, int* lda, int* ipiv, int* info); extern "C" void dgetrs_(char *TRANS, int *N, int *NRHS, double *A, int *LDA, int *IPIV, double *B, int *LDB, int *INFO ); int main() { char trans = ''N''; int dim = 2; int nrhs = 1; int LDA = dim; int LDB = dim; int info; vector<double> a, b; a.push_back(1); a.push_back(1); a.push_back(1); a.push_back(-1); b.push_back(2); b.push_back(0); int ipiv[3]; dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info); dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info); std::cout << "solution is:"; std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl; std::cout << "Info = " << info << std::endl; return(0); }

Y sobre el manual, hay una versión completa en PDF disponible en el sitio web de Intel. Aquí hay una muestra de su documentación HTML.

http://software.intel.com/sites/products/documentation/hpc/mkl/mklman/GUID-A02DB70F-9704-42A4-9071-D409D783D911.htm


Si desea utilizar LAPACK de C ++, es posible que desee echar un vistazo a FLENS . Define las interfaces de bajo y alto nivel para LAPACK, pero también reimplementa algunas funciones de LAPACK.

Con la interfaz FLENS-LAPACK de bajo nivel, puede usar sus propios tipos de matriz / vector (si tienen un diseño de memoria compatible con LAPACK). Tu llamada de dgetrf se vería así:

info = lapack::getrf(NoTrans, dim, nrhs, a.begin(), LDA, ipiv);

y para los dgetrs

lapack::getrs(NoTrans, dim, nrhs, a.begin(), LDA, ipiv, b.begin(), LDB);

Por lo tanto, las funciones FLENS-LAPACK de bajo nivel están sobrecargadas con respecto a los tipos de elementos. En consecuencia, la función LAPACK sgetrs , dgetrs , cgetrs , zgetrs encuentran en la interfaz de bajo nivel de FLENS-LAPACK lapack::getrs . También pasa los parámetros por valor / referencia y no como puntero (por ejemplo, LDA lugar de &LDA ).

Si utiliza los tipos de matriz FLENS, puede codificarlo como

info = lapack::trf(NoTrans, A, ipiv); if (info==0) { lapack::trs(NoTrans, A, ipiv, b); }

O simplemente utiliza la función dgesv controlador LAPACK

lapack::sv(NoTrans, A, ipiv, b);

Aquí una lista de las funciones del controlador FLENS-LAPACK .

Descargo de responsabilidad: Sí, FLENS es mi bebé! Eso significa que codifiqué alrededor del 95% y cada línea de código valió la pena.


dgetrf factorizar la matriz (llamando a dgetrf ) antes de poder resolver el sistema utilizando dgetrs . Alternativamente, puede usar la rutina dgesv , que realiza ambos pasos por usted.

Por cierto, no necesita declarar las interfaces usted mismo, están en los encabezados de Accelerate:

// LAPACK test code #include <iostream> #include <vector> #include <Accelerate/Accelerate.h> using namespace std; int main() { char trans = ''N''; int dim = 2; int nrhs = 1; int LDA = dim; int LDB = dim; int info; vector<double> a, b; a.push_back(1); a.push_back(1); a.push_back(1); a.push_back(-1); b.push_back(2); b.push_back(0); int ipiv[3]; dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info); dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info); std::cout << "solution is:"; std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl; std::cout << "Info = " << info << std::endl; return(0); }