PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : zgeev.c in C einbinden unter Linux



Spinecho
01-02-2006, 10:49
Hallo,

ich möchte in C++ ein nichthermitesches Eigenwertproblem lösen und dazu die Routine ZGEEV des LAPACK-Pakets verwenden, das in Fortran programmiert ist. Die nötigen Bibliotheken sind installiert.

Um nicht das gesamte CLAPACK zu installieren (was ich bisher erfolglos versucht habe), habe ich mir bei netlib lediglich den Source-Code von zgeev.c
inkl. aller benötigten BLAS-Dateien heruntergeladen (auch diverse BLAS und CBLAS Bibliotheken, sowie die GSL sind installiert).

Da ich bisher keine Erfahrung mit sowas habe, lautet meine Frage: Wie binde ich dieses zgeev.c etc. in ein Projekt (z.B. mit KDevelop) ein, so dass ich die Routine dann aufrufen kann?

Die Dateien von netlib liegen in zwei Ordern, blas und clapack.

Der Inhalt von 'blas' ist

blas2test.f dlamch.f xerbla.f

und der Inhalt von 'clapack' sind zwei Ordner 'complex16' und 'double', die die jeweiligen Dateien für komplexe bzw. reelle Zahlen enthalten. Im Ordner 'complex16' befindet sich

blaswrap.h zgebak.c zgeev.c zgehrd.c zlacgv.c zladiv.c zlahrd.c zlanhs.c zlarf.c zlarft.c zlascl.c zlassq.c ztrevc.c zunghr.c
f2c.h zgebal.c zgehd2.c zhseqr.c zlacpy.c zlahqr.c zlange.c zlarfb.c zlarfg.c zlarfx.c zlaset.c zlatrs.c zung2r.c zungqr.c

wovon ich zgeev.c benötige.

Ich hoffe, jemand kann mir helfen!

Herzlichen Dank,

Spinecho

Andi_Rostock
02-02-2006, 14:43
Ich habe auch ne Weile gebraucht um mit Lapack und Co klar zu kommen.
Hast Du die lapack Bibliotheken auf deinem Rechner installiert? Wenn ja, dann ist die Sache gaaanz einfach.
Folgendes Beispiel kannste mit
gcc -o runme test.c -lm -llapack
compilen.

Zum Beispiel: Anwendung eines Newton-Verfahrens



#include <stdio.h>
#include <stdlib.h>
#include <math.h>


// Compile with gcc -o outname test.c -lm -llapack

// hier wird der Header fuer die benoetigte Funktion aufgerufen. Aufruf wie bei lapack nur mit _ am Ende
extern void dgetrf_(int *rows, int *columns, double *A, int *LDA, int *IPIV, int *INFO);
//extern void dgetrs_()
extern void dgetrs_( char *trans, int *n, int *nrhs, double *a, int *lda, int *ipiv, double *x, int *ldb, int *info );

void function(double *x, double *F){
F[0]=pow(x[0],2)+pow(x[1],2)-1.;
F[1]=2.*x[0]*x[1]-1.;
}

void jacobian(double *x, double *A){
// JAC[0][0]=A[0];
// JAC[0][1]=A[2];
// JAC[1][0]=A[1];
// JAC[1][1]=A[3];

A[0]=2.*x[0];A[2]=2.*x[1];
A[1]=2.*x[1];A[3]=2.*x[0];

}

int main(void)
{
int i,k;
double x[2],F[2],JAC[2][2],dx[2],norm2,norm1,norm0;
double A[2*2], FF[2],xx[2];
int IPIV[2], It,It2,r;
int n, LDA,info;
char trans='N';
float Relax;

n=2;
LDA=2;

// Startwerte
x[0]=0.5;
x[1]=1;

// Vektor für die Pivotierung
IPIV[0]=0;
IPIV[1]=0;
norm0=1.;
It=0;
// Iterationen
do {
norm1=norm0;

It=It+1;
// Berechnung von F
function(x,F);

// Berechnung der Jacobimatrix
jacobian(x,A);

// Lineares GLS
// J *d=-F
//1. Pivotisieren
dgetrf_(&n,&n,A,&LDA, IPIV,&info);

// 2. Loesen
for (i=0;i<2;i++){
// printf("%i\n",IPIV[i]);
dx[i]=-F[i];
}
// Lösung steckt in dx
// Lösen mittels Pivotisierter A-Matrix und IPIV Vektor
dgetrs_(&trans, &n, &n, A, &LDA, IPIV, dx, &LDA, &info);

// Berechnung der Norm von F(x)
norm0=pow(F[0],2)+pow(F[1],2);
//norm0=pow(dx[0],2)+pow(dx[1],2);
// Bestimmung von Relax
// Berechne F(x+dx)
r=0;
It2=0;
do{
Relax=1./pow(2.,r);
for (i=0;i<n;i++)
xx[i]=x[i]+Relax*dx[i];

function(xx,FF);

norm2=pow(FF[0],2)+pow(FF[1],2);
r=r+1;
It2=It2+1;

}while((norm2>(1.-Relax/8)*norm0)&&It2<10);

// Berechnung der neuen x Werte
for (i=0;i<2;i++){

x[i]=x[i]+Relax*dx[i];

}

// Ausgabe: Iteration und Änderung der Norm
printf("%i %e\n",It,fabs(norm1-norm0));
}while (fabs(norm1-norm0)>1.e-20&&It<100);
// Lösung sollte sein: x[0]=sqrt(0.5), x[1]=sqrt(0.5)
printf("Ergebnis: x[0]=%f*sqrt(0.5), x[1]=%f*sqrt(0.5)\n",x[0]/sqrt(0.5),x[1]/sqrt(0.5));
return EXIT_SUCCESS;
}



Wenn Du lapack nicht installiert hast, sondern die ganzen clapack geschichten verwenden willst, dann kannste Die doch einfach mit deinem Projekt mitkompilieren, oder?

Viele Grüße,
Andi