Anzeige:
Ergebnis 1 bis 13 von 13

Thema: Übergabe von C++ Vektoren an Fortran

  1. #1
    Registrierter Benutzer
    Registriert seit
    06.11.2006
    Beiträge
    28

    Übergabe von C++ Vektoren an Fortran

    Hallo Leute,

    ich bin ein Anfänger in der Programmierung, und soll gleich mit zwei Sprachen und dem Austausch von Variablen anfangen. Manchmal wird überschätzt, was in kurzer Zeit möglich ist. Hier mein Problem:

    Ich habe mehrere Vektoren mit integer Werten. Außerdem lasse ich einen Vektor mit Zufallszahlen erstellen, der immer Stellen ausgibt, an denen die zwei anderen Vektoren vertauscht werden. push_back ist dafür der richtige Befehl denke ich. In C++ habe ich jetzt aber nichts gefunden, mit dem man einen Teil eines Vektors einem anderen zuweisen kann, wie es zum Beispiel in Fortran geht:

    vektor2[1:10] = vektor1 [12:22]

    Dehalb möchte ich jetzt die zwei Integer Vektoren und den Kombinationsvektor an Fortran übergeben, dort neu kombinieren und an c++ zum weiterarbeiten zurückgeben. Allerdings schaffe ich nur einen einzelnen Wert an Fortran zu übergeben, aber nicht einen Vektro.

    Ich wäre jetzt sehr dankbar, wenn mir jemand sagen könnte, wie ich das entweder in c++ lösen kann, oder wie ich einen vektoren an eine Fortran Subroutine übergebe und dann wieder einen Vektor zurückbekomme.

    Gruß,
    Aui

  2. #2
    Registrierter Benutzer Avatar von Berufspenner
    Registriert seit
    30.03.2002
    Ort
    Hamburg
    Beiträge
    567
    Zitat Zitat von aui Beitrag anzeigen
    In C++ habe ich jetzt aber nichts gefunden, mit dem man einen Teil eines Vektors einem anderen zuweisen kann, wie es zum Beispiel in Fortran geht:
    Vielleicht verstehe ich dein Problem/Vorhaben nicht ganz, aber du kannst doch mittels Indexoperator (eckige klammern []) ganz einfach auf jedes einzelne Element eines Vektors zugreifen.
    C und C++

  3. #3
    Registrierter Benutzer
    Registriert seit
    06.11.2006
    Beiträge
    28
    Hallo Berufspenner,

    das ist es ja genau, ich will nicht auf einen einzelnen Wert zugreifen, sondern immer auf ein Teilfeld. Der Kombinationsvektor gibt den Anfange bzw. das Ende des Teilfeldes an.

    Aui

  4. #4
    Registrierter Benutzer Avatar von Berufspenner
    Registriert seit
    30.03.2002
    Ort
    Hamburg
    Beiträge
    567
    Zitat Zitat von aui Beitrag anzeigen
    Hallo Berufspenner,

    das ist es ja genau, ich will nicht auf einen einzelnen Wert zugreifen, sondern immer auf ein Teilfeld. Der Kombinationsvektor gibt den Anfange bzw. das Ende des Teilfeldes an.

    Aui
    Mir ist nichts dergleichen bekannt, dass man ganze Teilbereiche eines Vektors verschieben kann. Das ist stabilitätsbedingt aber auch ein vorteil, weil so jedes Element vorher geprüft werden müsste und so die Gefahr minimiert wird, auf nicht existente Elemente zu zugreifen. Du wirst Teile eines Vektors also mit einer Schleife elementweise kopieren müssen.
    C und C++

  5. #5
    Registrierter Benutzer
    Registriert seit
    06.11.2006
    Beiträge
    28
    Hallo Berufspenner,

    genau das wollte ich nicht, weil ich dafür 2,4 *10^18 Abfragen brauche. Mit der Vorgehensweise von Fortran nur 3*10^12 Operationen. Dadurch ergibt sich ein ernormer Rechenzeitvorteil, und deshalb wollte ich ja wissen, wie man einen Vektor an Fortran übergibt. Die anderen Sachen sind in C++ leichter zu programmieren. Deshalb nehme ich das ja auch für Zufallszahlen und so.

    Aui

  6. #6
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Hallo,

    um welchen Datentyp handelt es sich denn konkret bei dem Vektor? Ist das ein einfaches Int-Array?

    Gruß, Florian
    Ein gebrechlich Wesen ist der X-Server.

  7. #7
    Registrierter Benutzer
    Registriert seit
    06.11.2006
    Beiträge
    28
    Hallo,

    der Vektor in c++ ist definiert als:

    vector<unsigned int> recomb;

    und in Fortran als:

    integer*4, allocatable :: recomb( : )
    Geändert von aui (07-10-2008 um 11:25 Uhr)

  8. #8
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    In C++ habe ich jetzt aber nichts gefunden, mit dem man einen Teil eines Vektors einem anderen zuweisen kann, wie es zum Beispiel in Fortran geht:

    vektor2[1:10] = vektor1 [12:22]
    Ich kenne mich mit Fortran nicht aus. Werden dabei in vektor2 die bisherigen Elemente nach hinten verschoben, oder werden sie überschrieben?
    Im ersten Fall kannst du dafür die Memberfunktion "insert" eines C++ Vectors verwenden, ungefähr in der Art von "vektor2.insert(vektor2.begin() + X, vektor1.begin() + A, vektor1.begin() + B)", wobei X, A, und B Offsets sind, die natürlich innerhalb der jeweiligen Sequenzen liegen müssen.
    Im zweiten Fall, also wenn Elemente überschrieben werden sollen, dann geht das mit std::copy aus dem Header "<algorithm>", ähnlich wie in "std::copy(vektor1.begin() + A, vektor1.begin() + B, vektor2.begin() + X)". In diesem Fall muss vektor2 unbedingt groß genug sein, um von Index X an noch B - A Elemente aufnehmen zu können.

  9. #9
    Registrierter Benutzer
    Registriert seit
    06.11.2006
    Beiträge
    28
    Hallo,

    habe mich wohl schlecht ausgedrückt. Ich baue eine Schleife, die entsprechend der Anzahl der Elemente im Rekombinationsvektor wiederholt wird. Im neuen Vektor sind die Positionen 0 bis x mit Werten aus dem VektorA bestetzt, die Positionen x+1 bis y mit Werten aus dem VektorB, die Positionen y+1 bis z wieder mit Werten aus VektorA und so weiter.so hätte ich das ganze gerne zugeordnet. In Fortran ist das eben ganz einfach. Da kann man Teilfelder wie in R ansprechen. Einfach Feld[0:x] = VektorA[0:x]

    Gruß,
    Aui

  10. #10
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Aui, würde es dir etwas ausmachen, deinen bisherigen C++ code zum Bearbeiten der Vektoren zu posten? Dann könnte ich mal schauen, ob mir Verbesserungen einfallen - natürlich kann ich nichts garantieren.

    Übrigens noch mal zum zweiten Teil deiner ursprünglichen Frage (bezüglich Austausch Fortran/C++): Wenn "v" ein std::vector ist, dann kannst du mit dem Ausdruck "&v.front()" einen Zeiger auf den Inhalt bekommen (*). Die Elemente liegen zusammenhängend im Speicher, wie in einem C Array. Wenn du eine Methode hast um C Arrays zwischen C++ und Fortran auszutauschen, dann solltest du diese also benutzen können.

    *: Zumindest für "std::vector<unsigned int>" gilt das, wenn der Vektor nicht leer ist.

  11. #11
    Registrierter Benutzer
    Registriert seit
    06.11.2006
    Beiträge
    28
    Hallo locus vivendi,

    also mit deinem Hinweis klappt das jetzt. Das Problem war, dass ich nicht die Zeiger weitergegeben habe, sondern die Werte des Vektors. Den Code poste ich in Kürze, dann können isch das merh ansehen.

    Danke derweil,

    Aui

  12. #12
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Könnte man das nicht auch mit memcpy/memmove lösen? Erscheint mir etwas sauberer als der Weg über eine zweite Programmiersprache (gibt es bei der Vermengung von C/C++ mit Fortran überhaupt eine Typsicherheit?).
    Ein gebrechlich Wesen ist der X-Server.

  13. #13
    Registrierter Benutzer
    Registriert seit
    06.11.2006
    Beiträge
    28
    Hallo Leute,

    hier kommen jetzt die Programme, wenn auch mit einiger Verspätung. Das letzte mal wurde ich leider abgewürgt. Und meine Antwort hat sich in Nirwana verloren. So, also ich habe die beiden Programme hier angehängt, ebenso, wie die Library MersenneTwister.h. Die Anhänge müssen dann nur noch um ihrer .txt beraubt werden, soll heißen, einfach umbenennen. Bei Kompilieren bin ich folgendermaßen vorgegangen:

    Zuerst alles in einen Ordner kopieren, dann die Fortran-Datei mit dem Befehl:

    gfortran -O -c recombination.f95

    Das erzeugt eine .o Datei im selben Ordner, dann mit folgendem Statement alles zu einer ausführbaren Datei zusammenpacken:

    g++ -O -Lgfortran -o basis basis.cpp recombination.o

    basis reicht dann, um die Maschine anzuwerfen.

    In Wirklichkeit läuft das ganze mit numSNP = 80000 und generation = 1000. Aber für das Beispiel sollte das reichen. Das Problem mit der Kombitabilität der Variablen ist eigentlich beschränkt auf den Speicherplatzbedarf. Soll heißen, wenn man einen Wert übergibt, der 2 byte belegt, muss man dafür auch in Fortran eine Variable definieren, die 2 byte ausfüllt. Und hier war mein unsprünliches Problem. Ich hatte definiert:

    vector<bool> animal, parent1, parent2

    Das ganze dann auch schön als _bitwise übergeben. Aber in Fortran95 gibt es anscheinend keine Definition mit dem Typ bit. Jedenfalls habe ich nichts gefunden. Falls jemand Lust hat damit ein wenig herumzuspielen, gerne.

    Gruß,

    Aui

    PS: Wenn ich Zeit habe, packe ich das ganze noch in Objekte. Ist dann ein wenig schöner, und auch allgemeiner verwendbar.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •