FFTW Library installieren unter Suse
-
Hallo Leute,
Mich interessiert, ob jemand Erfahrungen mit der Implementierung der FFTW library hat. Ich habe die Version 3.2.2 runtergeladen und Probleme sie einzubinden. Ich habe sie mit den Befehlen
./configure
gmake
make installinstalliert und auch den Testlauf durchlaufen. Werden bei der Installation die libraries in die richtigen Ordner geschoben? Ich kriege jedenfalls beim compilieren einer .c-Datei, die die library fftw.h mit den Befehl
#include <fftw.h>
einbindet, vom gcc
nach eingabe des Befehls
gcc fft_test.c
ausgegeben, dass die Datei oder der Ordner nicht gefunden wurde. Kann mir jemand helfen? Vielleicht mache icn nur Anfängerfehler für Grundlagenfragen.Das ist mein erstes großes C/C++ Projekt.
Grüße,
die Inge
-
hallo Inge,
die datei zum einbinden heißt bei mir fftw3.h und befindet sich bei mir im ordner /usr/include, kannst ja mal schauen ob das bei dir so ist. bei shared librarys was fftw ja sein soll genügt es idr. nicht nur den header anzugeben sondern du mußt dem compiler in deinem fall gcc mitteilen wo er die functionen die in der *.h datei declariert sind findet.
versuch mal
#include <fftw3.h> statt #include <fftw.h> und gcc fft_test.c -lfftw3 statt gcc fft_test.c
hoffe ich konnte helfen
-l ist ein kleines L
lg lolo
-
Hallo,
Danke lolo für den Hinweis.Die Datei steht wirklich nicht im include Ordner drin. Muss ich diese lib erstmal mit expliziten Befehlen einfügen? Leider steht in den tutorials nichts weiter drin.
Grüße
Inge
-
wenn du die folgende zeile in die console eingibst bekommst du eine auflistung aller verzeichnisse welche durchsucht werden wenn du #include <...> in deinem quelltext schreibst und es mit gcc übersetzt.
echo | gcc -v -x c - 2>&1 1>/dev/null | grep -B 100 "End of search list" | grep -A 100 "> search starts here"
in einem dieser verzeichnisse muß sich die datei fftw3.h befinden in welchem ist dabei egal.
folgendes gibt dir eine mit doppelpunkten separierte liste der verzeichnisse in denen nach der shared library gesucht wird.
echo | gcc -v -x c - 2>&1 1>/dev/null | grep "LIBRARY_PATH"
bei mir wurde die datei fftw3.h in dem ordner /usr/local/include erstellt.
und die libraray (libfftw3.la ist das richtig?) befindet sich in /usr/local/libund noch ein kleiner link zum schmökern http://www.network-theory.co.uk/docs/gccintro/gccintro_21.html
lg lolo
-
"wenn du die folgende zeile in die console eingibst"
sollte natürlich heißen
"wenn du die folgende zeile in die console kopierst"
-
Wenn du etwas selbst kompilierst, findest du die Sachen im Normalfall in /usr/local/ wieder und nicht in /usr/. Also /usr/local/include, /usr/local/lib, /usr/local/bin etc.
Aber man sollte nach Möglichkeiten nicht selbst kompilieren, sondern die fertigen Pakete der Distribution nehmen. Mit SuSE kenne ich mich nicht aus. Aber da sollte es auch einen einfachen Paketinstaller (in YaST) geben, wo du mal nach fftw suchen solltest.
Für die Linker- und Compiler-Optionen verwendet man am besten man: pkg-config. Probier mal
pkg-config --list-all | grep fftw
und dann
gcc `pkg-config fftw3 --libs --cflags` foo.c
Ansonsten kannst du mit -I<pfad> den Includepfad und mit -L<pfad> den Bibliothekspfad setzen.
-
Vielen Dank noch einmal für die Hilfe. Die FFTW_Lib lässt sich unter Suse einfach mit Yast einfach downloaden. Danke für den Hinweis. Das erleichtert einiges und speichert die Bibliotheken und Headerfiles in die richtigen Ordner. Damit hat also alles geklappt. Ich beschreibe hier mal dokumentarisch die wichtigsten Funktionen anhand eines Beispiels aus dem Internet.
http://www.elisanet.fi/~d635415/webroot/FFTW_example/index.html
/* **************************************************** * FFTW example * Markus Nentwig, 2007 * This program is in the public domain * ****************************************************/ #include <stdio.h> #include <math.h> #include <complex.h> #include <fftw3.h> #include <stdlib.h> int main(void){ /* **************************************************** * Allocate memory * ****************************************************/ int n=128; fftw_complex* b1=fftw_malloc(sizeof(fftw_complex)*n); fftw_complex* b2=fftw_malloc(sizeof(fftw_complex)*n);
Die beiden letzten Commandozeilen allokieren Speicher für zwei Variablen, die dem komplexen Datentyp entsprechen, der für die dft gebraucht wird. Dabei sind b1 und b2 entweder Ein- oder Ausgangsvariablen, je nach Funktion.
fftw_plan p1=fftw_plan_dft_1d(n, b1, b2, FFTW_FORWARD, FFTW_ESTIMATE); fftw_plan p2=fftw_plan_dft_1d(n, b2, b1, FFTW_BACKWARD, FFTW_ESTIMATE);
Diese zwei Funktionen bilden den Plan. Der Plan ermittelt wahrscheinlich alle wichtigen Parameter wie Frequenzen etc, die für die dft gebraucht werden. So genau weiß ich das nicht, weil ich die genauen Algorithmen nicht kenne. Die Funktion hat folgende Argumente.
Das Ausgangsargumente sind p1 und p2, die jeweiligen Pläne der dfts.
Die Eingangsaurgumente kommen in folgender Reihenfolge:
p_ = fftw_plan_dft_1d (Anzahl der Samples, allokierte Eingangsgröße
, allokierte Ausgangsgröße, Richtung der Trafo ,Art der Trafo)Richtung der Trafo ist vom Freq-bereich in den Zeitbereich FFTW_FORWARD und umgekehrt FFTW_BACKWARD.
Zudem gibt es zwei Arten der Trafo:
FFTW_ESTIMATE und FFTW_MEASUREMENT.Bei FFTW_ESTIMATE wird mehr geschätzt was die Laufzeit veringert aber auch die Genauigkeit. Mit FFTW_MEASUREMENT ist es genau umgekehrt.
p1 ist der Plan für eine Fouriertrafo und p2 für die entsprechende Rücktrafo.
int i; for (i=0; i < n; ++i){ b1[i]=sin((double)i/(double)n*2.0*M_PI); }
b1 ist ein simpler Sinus.
fftw_execute(p1); for (i=0; i < n; ++i){ printf("%1.7f\t%1.7f\n", creal(b2[i]), cimag(b2[i])); };
fftw_execute führt die Fouriertrafo vom Sinus durch. b2 ist dann das Freq-spek. vom Sinus, das von -n/2 bis n/2 ausgegeben wird.
fftw_execute(p2); printf("\n"); for (i=0; i < n; ++i){ printf("%1.7f\t%1.7f\n", creal(b1[i]), cimag(b1[i])); }; fftw_destroy_plan(p1); fftw_destroy_plan(p2); fftw_free(b1); fftw_free(b2); return 0; }
Anschließend wird die inverse dft durchgeführt und der Sinus wieder ausgegeben. Daraufhin werden die Pläne und Variablen (und Pointer) gelöscht und der Speicher freigegeben.
Für nichtequidistanze Signale (Samplefrequenz ist unregelmäßig) gibt es die nonuniform FT Bibliotheken von Daniel Potts. Man läd die Bibliothek hier
http://www-user.tu-chemnitz.de/~potts/nfft/download.php runter und öffnet den tar-File mittar nfft-x.y.z.tar.gz
Anschließend geht man in den Ordner der durch die Entpackung im Verzeichnis entsteht.
cd nfft-x.y.z
und konfiguriert mit
./configure
anschließend wird mit make (was dieser Befehl genau macht weiß ich nicht) ein make File erstellt. Danach installiert man im Normalfall mit
make install
die Bibliothek. Sie werden in die richtigen Ordner geschoben.Bei Suse gibt es aber Zugriffsberechtigungsprobleme, die aber mit dem Befehl
su
und anschließender root-Codeeingabe umgangen werden. Anschließend kann der make install Befehl ausgeführt werden und der su-Modus mit exit beendet werden. Es gibt ein Beispiel als Download auf der selben Seite um die lib zu testen. Ich habe den c-File mit
gcc simple_test.c -lutil -lnfft3
versucht zu kompilieren. Ich erhalte aber die Fehlermeldung
simple_test.c:27:18: error: util.h: Datei oder Verzeichnis nicht gefunden
obwohl sich die Datei im Unterordner der vom gcc durchsuchten Daten befindet. Kann hier das Problem liegen? Ich bitte um Hilfe.
Mfg Inge
-
scheint so als wär das beispiel für die version 2.x...
util wird nicht gelinkt, sondern nur als header file verwendet
dein compile aufruf müßte so in der richtung aussehen...
gcc simple_test.c -lnfft3 -lfftw3 -lm
und statt
#include "util.h" versuch mal #include "nfft3util.h"
lg lolo
-
Hm... ich habe die util.h einfach ersetzt und
gcc simple_test.c -lnfft3
reingehaun dann hautes hin. Danke für die Hinweise Lolo. Kleine Frage hierzu hätte ich aber noch. Was ist denn
-lm
und warum muss man nicht jede angegebene Header-datei mit beim Kompilierungsbefehl in die Konsole einhämmern?
Zudem habe ich das Gefühl, dass im Quelltext simple_test.c keine einheitliche Variablenvergabe gemacht wird.
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <complex.h> #include "nfft3util.h" #include "nfft3.h" void simple_test_nfft_1d(void) { nfft_plan p; int N=14; int M=19;
Das macht Sinn das N die Anzahl der Samples im Zeitbereich sind und M diejenigen im Freq.-bereich. Zumindest werden entsprechenden Zahlen ausgegeben.
nfft_init_1d(&p,N,M); nfft_vrand_shifted_unit_double(p.x,p.M_total); if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); nfft_vrand_unit_complex(p.f_hat,p.N_total); nfft_vpr_complex(p.f_hat,p.N_total,"given Fourier coefficients, vector f_hat"); ndft_trafo(&p); nfft_vpr_complex(p.f,p.M_total,"ndft, vector f"); nfft_trafo(&p); nfft_vpr_complex(p.f,p.M_total,"nfft, vector f"); ndft_adjoint(&p); nfft_vpr_complex(p.f_hat,p.N_total,"adjoint ndft, vector f_hat"); nfft_adjoint(&p); nfft_vpr_complex(p.f_hat,p.N_total,"adjoint nfft, vector f_hat"); nfft_finalize(&p); } void simple_test_nfft_2d(void) { int K,N[2],n[2]; double t;
Aber hier hörts auf. K ist die Anzahl der ausgegebenen Samples sowohl transformmiert als auch rücktransformiert. Was sind N und n dann? Groß-K ist auch in der Dokumentation nirgends erwähnt. Hat jemand schon einmal damit gearbeitet? Ich habe da echt Probleme...
nfft_plan p; N[0]=70; n[0]=128; N[1]=50; n[1]=128; K=12; t=nfft_second(); nfft_init_guru(&p, 2, N, N[0]*N[1], n, 4, PRE_PHI_HUT| PRE_PSI| MALLOC_F_HAT| MALLOC_X| MALLOC_F | FFTW_INIT| FFT_OUT_OF_PLACE, FFTW_ESTIMATE| FFTW_DESTROY_INPUT); nfft_vrand_shifted_unit_double(p.x,p.d*p.M_total); if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p); nfft_vrand_unit_complex(p.f_hat,p.N_total); t=nfft_second()-t; nfft_vpr_complex(p.f_hat,K, "given Fourier coefficients, vector f_hat (first few entries)"); printf(" ... initialisation took %e seconds.\n",t); t=nfft_second(); ndft_trafo(&p); t=nfft_second()-t; nfft_vpr_complex(p.f,K,"ndft, vector f (first few entries)"); printf(" took %e seconds.\n",t); t=nfft_second(); nfft_trafo(&p); t=nfft_second()-t; nfft_vpr_complex(p.f,K,"nfft, vector f (first few entries)"); printf(" took %e seconds.\n",t); t=nfft_second(); ndft_adjoint(&p); t=nfft_second()-t; nfft_vpr_complex(p.f_hat,K,"adjoint ndft, vector f_hat (first few entries)"); printf(" took %e seconds.\n",t); t=nfft_second(); nfft_adjoint(&p); t=nfft_second()-t; nfft_vpr_complex(p.f_hat,K,"adjoint nfft, vector f_hat (first few entries)"); printf(" took %e seconds.\n",t); nfft_finalize(&p); } int main(void) { system("clear"); printf("1) computing an one dimensional ndft, nfft and an adjoint nfft\n\n"); simple_test_nfft_1d(); getc(stdin); system("clear"); printf("2) computing a two dimensional ndft, nfft and an adjoint nfft\n\n"); simple_test_nfft_2d(); return 1; }
Nuja bei den Mehrdimensionalitäten wird es sowieso ganz schön heftig. Da hätte ich so viele Fragen... Wenn ich was brauchbares habe, mache ich noch ein deutsches Tutorial hier zurecht. Vll kanns ja jemand gebrauchen...
Grüße,
die Inge
-
So liebe Leute,
nachdem ich mich ausführlich mit der fftw und der nfft bib beschäftigt habe, möchte ich gern einige kleine Ergs mitgeben.
Man muss ein paar Kniffs können, um die Funktionen zum laufen zu bekommen. Das sind nun folgende.
Erstens ein paar Begrifflichkeiten.
NFFT heißt nonequispaced fast fouriertransformation. die Lib findet man auf der HP der TU Chemnitz und ist unter der Leitung von Prof Daniel Potts geschrieben worden. Man findet sie einfach, wenn man mal googlet.
Das erste was man beachten muss ist die Begrifflichkeit NFFT und inverse NFFT. Meist wird für die normale FFT die Wandlung von Abtastdaten in Frequenzdaten bezeichnet. Hier ist es aber genau UMGEKEHRT. Sprich man fängt im Frequenzbereich an. Nehmen wir der einfachheit halber einen double complex Datensatz input mit der Anzahl der Frequenzen der Dimensionen die in N gespeichert sind .
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <complex.h> #include "nfft3util.h" #include "nfft3.h" int N[2] = {f1, f2}; int n[2] = {n1, n2}; int M = n1*n2; ///input ist der gegebene Datensatz woher auch immer, f1 und f2 die zughörigen f /*n beinhaltet die Anzzahl der gegebenen Punkte im t Bereich,die erhalten werden sollen*/ //M Anzahl aller Punkte (in der lib doku auch knoten genannt)
Ähnlich wie in der fftw bib wird hier mit Plänen gearbeitet.
nfft_plan p; int h1 ,h2 ,d; // h1 h2 Hilfsvariablen, d = Dimension
Diese Plane werden initialisiert. In unserem Falle 2d
nfft_init_2d(&p,N[0],N[1],M);
weitere initialisierungen hier:
http://www-user.tu-chemnitz.de/~potts/nfft/guide3/html/node40.html
Was einem bestimmt schon aufgefallen ist, hier läuft alles über 1d Pointer. D.H. man muss sich entsprechend in diese Thematik reinarbeiten. Als nächstes müssen die Koordinaten der Punkte oder Knoten hergegeben werden. Die müssen in der Reihenfolge übergeben werden, wie die zu erhaltenen Funktionswerte entstehen sollen. Man übergibt quasi ein d*M großes Array, das wie folgt ausieht
array1d[d*j + t] [e]equiv[/e] array2d[j][d] // t ist die jweilige Dimension die gerade eingeliefert wird und j der gerade genutzte Punkt. j [e]epsilon[/e] M.
Anschließend wird ein Fenster erstellt, welches für die weitere Verabeitung notwendig wird. Dies geschieht aber nur, wenn einige flags gesetzt sind, die ich aber nicht weiter ausführen werde.
if(p.nfft_flags & PRE_ONE_PSI) nfft_precompute_one_psi(&p);
Nun werden die Inputdaten übergeben. Da diese hoffentlich in einem 1d Pointer verpackt sind, reicht hierfür folgender Ausdruck:
for(h1=0;h1<M;h1++) p.f_hat[h1] = input[h1];
Nun wird die Transformation durchgeführt und die Daten können au p.f entnommen werden, wie Input eingefügt wurde. Anschließe muss derPlan noch zerstört werden. Man kann ihn abdr mehrfach nutzen und die Trafo durchführen. Einfach veränderten Input eingeben und fertsch is der Lack.
nfft_trafo(&p); nfft_finalize(&p);
Als nächstes kommt die inverse NFFT quasi die eigentliche Fouriertrafo wie sie allgemeingebräuchlich ist. Dies geht aber nicht so einfach rückwärts. hier wurde ein Standard Gauss Verfahren angewandt, nämlich die Methode der kleinsten Fehlerquadrate. Aber dazu später mehr. Is ja spät genug.
Grüße die Inge
PS: Hier ein wenig was zum Handling mit 1d pointer und arrays:
http://www.fftw.org/fftw3_doc/Dynamic-Arrays-in-C.html#Dynamic-Arrays-in-C