Samplen aus Wkt.-Vektor


  • Mod



  • O.k. Ich versuch mein Bestes:

    Also ich mache eine Motif-Suche in DNA-Sequenzen. Jede Sequenz hat eine Länge L. Der Vector mit den Wahrscheinlichkeiten gibt zu jeder Position in der Sequenz die Wkt. an, dass das Motifes an der jeweiligen Position vorkommt.

    Vector {0.3, 0.1, 0.1, 0.1, 0.2, 0.2}
    -> Motif an Position 1 hat Wkt. 0.3, an Position 2 Wkt 0.1 usw.

    Diese Motif-Suche ist in ein Gibbs-Sampler eingebaut. Das Samplen der Start-Positionen ist also notwendig. Das Samplen in diesem Zusammenhang bedeutet, das Zeihen einer Startposition aus der jeweiligen diskreten Verteilung, die von dem Vektor repräsentiert wird.

    Ich hoffe, das war verständlich. Bin leider nicht allzu gut im erklären.



  • SeppJ schrieb:

    http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution

    Ich danke für den Beitrag, nur kommt beim Ausführen des Bsp.-Codes ein Runtime-Error. what(): random_device::random_device(const std::string&)
    Ich benutze MinGW und weiss leider nicht wo der Fehler liegt.



  • Zeig mal Code.


  • Mod

    ComputerCarl schrieb:

    SeppJ schrieb:

    http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution

    Ich danke für den Beitrag, nur kommt beim Ausführen des Bsp.-Codes ein Runtime-Error. what(): random_device::random_device(const std::string&)
    Ich benutze MinGW und weiss leider nicht wo der Fehler liegt.

    Fehler in MinGW:
    http://stackoverflow.com/questions/15725677/c0x-random-device-with-stdruntime-error
    http://stackoverflow.com/questions/12351062/threads-in-g/12351142#12351142
    Also einfachster Fix für dich wäre, einen der anderen Generatoren der Standardbibliothek zu benutzen. Für wissenschaftliches Rechnen möchtest du wahrscheinlich ohnehin einen Generator mit standardisierter Implementierung, nicht das std::random_device, welches einfach ein anderer Name für den Standardzufallsgenerators des Systems ist (was dann wer weiß was für ein Generator sein kann).



  • Nathan schrieb:

    Zeig mal Code.

    Also hier das Samplen in meiner Implementierung. Ich hab es schnell auf das nötigste reduziert, damit es leichter zu lesen ist:

    // Funktion zum Bestimmen der Summe von logarithmierten Werten
    double log_of_sums(vector<double> &summands, unsigned short summands_size) {
        double res = 0;
        double find_max = -1 * numeric_limits<double>::max();
    
        for(int i = 0; i < summands_size; i++) {
              if(find_max < summands[i])
              find_max = summands[i];
        }
    
        for(unsigned short i = 0; i < summands_size; i++) {
              res += exp(summands[i] - find_max);
        }
    
        return log(res) + find_max;
    }
    
    // das Samplen (auf das noetigste reduziert)
    tmp_sum;				         // <- Vektor mit Wkt's.
    double r = log((double) rand() / (RAND_MAX));
    
    for(unsigned short u_i = 0; u_i < tmp_sum.size(); u_i++ ) {
         if(u_i > 0) {
                if(r <= this->log_of_sums(tmp_sum, u_i))
                      this->start_pos[i] = u_i-1;
                      u_i = tmp_sum.size();
                }
         }
    }
    

    @SeppJ:
    Danke. Ich komme mir immer wieder wie ein totaler Anfänger vor, wenn ich höre wieviele Details es bei sowas zu beachten gibt.



  • Eigentlich meinte ich den mit discrete_distribution, aber ist nun auch egal.


  • Mod

    ComputerCarl schrieb:

    @SeppJ:
    Danke. Ich komme mir immer wieder wie ein totaler Anfänger vor, wenn ich höre wieviele Details es bei sowas zu beachten gibt.

    Du machst eine Bachelor-/Master-/Promotionsarbeit? Dann sieh es als Teil der Ausbildung an, solche Sachen zu lernen. Bei dieser Art Arbeit geht es schließlich genau darum, nicht so sehr um die Ergebnisse. Beim Bacheler natürlich mehr noch als bei der Promotion.



  • ComputerCarl schrieb:

    SeppJ schrieb:

    http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution

    Ich danke für den Beitrag, nur kommt beim Ausführen des Bsp.-Codes ein Runtime-Error. what(): random_device::random_device(const std::string&)
    Ich benutze MinGW und weiss leider nicht wo der Fehler liegt.

    std::random_device rd("mt19937");
    

    Das sollte dann klappen. random_device's Konstruktor wirft eine Exception, wenn er den übergebenen String mit dem Namen für die Engine von der Implementierung nicht akzeptiert wird.



  • Ändert bei mir leider nichts. Gleiche Fehlermeldung.
    Ich schau einfach mal weiter, was ich finde. Meine alternativ Implementierung funktioniert ja eigentlich ausreichend gut. Aber danke für die Hilfe.


  • Mod

    ComputerCarl schrieb:

    Ändert bei mir leider nichts. Gleiche Fehlermeldung.
    Ich schau einfach mal weiter, was ich finde. Meine alternativ Implementierung funktioniert ja eigentlich ausreichend gut. Aber danke für die Hilfe.

    Probier mal genau diesen Quellcode (Copy&Paste):

    #include <iostream>
    #include <map>
    #include <random>
    
    int main()
    {
        std::mt19937 gen;
        std::discrete_distribution<> d({40, 10, 10, 40});
        std::map<int, int> m;
        for(int n=0; n<10000; ++n) {
            ++m[d(gen)];
        }
        for(auto p : m) {
            std::cout << p.first << " generated " << p.second << " times\n";
        }
    }
    

    Der sollte, egal auf welchem Computer, die folgende Ausgabe erzeugen:

    0 generated 4026 times
    1 generated 943 times
    2 generated 1048 times
    3 generated 3983 times
    


  • Funktioniert mit genau der gleichen Ausgabe.
    Ich schau mal wie das für mein Bsp. funktioniert. Danke


Anmelden zum Antworten