Maztrix Zeilenweise an Funktion übergeben bei ungleicher Spaltendimension



  • Hallo

    Ich habe ein Problem bei dem ich nicht weiss wie es sinnvoll gelöst werden kann.

    Ich habe eine 2-dimensionale Vektor Matrix mit M Zeilen und N+1 Spalten.

    Ferner habe ich eine Funktion geschrieben, welche als Eingabe einen N-dimensionalen Vektor hat und als Ausgabe ebenfalls einen N-dimensionalen Vektor. Die Eingabe Vektoren haben in jeder Komponente nur 0 oder 1. Meine Funktion hat folgende Abbildungsvorschrift: 0 |-> -1 und 1 |->1, realisiert durch 2*x-1 für x in {0,1}

    Nun möchte ich die Matrix Zeilenweise an meine Funktion übergeben. Das Problem: Die erste Spalte muss dabei getrennt sein, damit die Dimensionen passen. Ein Beispiel: Die Matrix sei:

    1 0 0 0 0 
    2 1 0 0 0 
    3 0 1 0 0 
    1 1 1 0 0 
    2 0 0 1 0
    

    Dann möchte ich in einer Schleife

    Funktion(0 0 0 0)
    Funktion(1 0 0 0)
    Funktion(0 1 0 0)
    Funktion(0 0 1 0)
    

    Um dies zu erreichen:

    1 -1 -1 -1 -1 
    2  1 -1 -1 -1 
    3 -1  1 -1 -1 
    1  1  1 -1 -1 
    2 -1 -1  1 -1
    

    Sprich die 1. Spalte der Matrix bleibt unverändert und der Rest wird zeilenweise neu berecnet.

    Was ist da ein eleganter Weg das zu realisieren?

    Danke und Grüße



  • Du willst also nur einen Teil eines Vectors übergeben?
    Wir wäre es dann mit gsl::span? Siehe https://github.com/Microsoft/GSL

    Aber, was hier viel besser wäre: du übergibst nicht den vector, sondern wie anderswo in der stl üblich einen begin- und end-Iterator. Dann rufst du deine Funktion nämlich einfach mit zeile.begin() + 1 , zeile.end() auf und fertig.



  • Ich habe bis dato noch nicht mit Iteratoren gearbeitet. Ich habe vorhin in meinem Buch dazu gelesen. Dachte mir fange klein an und versuche die Matrix erstmal auszugeben. Das hat geklappt und zwar so:

    for(i=0; i<Var._SampleSize; i++){
      for(std::vector<int>::iterator it=CSpace[i].begin(); it != CSpace[i].end(); it++){
        std::cout << *it << " ";
      }
    std::cout << std::endl;
    }
    

    Var._SampleSize ist die Anzahl der Zeilen der Matrix. CSpace ist der Name der Matrix.

    Wie kann ich nun so iterieren, dass das erste Element übersprungen wird?

    Sprich meine derzeitige Ausgabe ist:

    0 0 0 0 0 
    0 1 0 0 0 
    0 0 1 0 0 
    0 1 1 0 0 
    0 0 0 1 0 
    0 1 0 1 0 
    0 0 1 1 0 
    0 1 1 1 0 
    0 0 0 0 1 
    0 1 0 0 1 
    0 0 1 0 1 
    0 1 1 0 1 
    0 0 0 1 1 
    0 1 0 1 1 
    0 0 1 1 1 
    0 1 1 1 1
    

    und was ich erstmal versuchen möchte ist:

    0 0 0 0 
    1 0 0 0 
    0 1 0 0 
    1 1 0 0 
    0 0 1 0 
    1 0 1 0 
    0 1 1 0 
    1 1 1 0 
    0 0 0 1 
    1 0 0 1 
    0 1 0 1 
    1 1 0 1 
    0 0 1 1 
    1 0 1 1 
    0 1 1 1 
    1 1 1 1
    

    Danke und Grüße

    NACHTRAG

    Mein Gott das ist ja viel simpler als erwartet. Einfach +1 an die begin() Methode 🙂

    Jetzt versuche ich das in eine Funktion zu übergeben.



  • Ersetze, wie ich oben schrieb, begin() durch begin()+1.

    Also:

    for (auto it = CSpace[i].begin() + 1; it != CSpace[i].end(); ++it) {
        std::cout << *it << " ";
    }
    

    (ich hab den Typen der Einfachheit mal durch auto ersetzt sowie post- in pre-increment geändert)

    Achtung: Code setzt CSpace[i].empty() == false voraus.



  • Habe ich bereits erledigt 🙂

    Ich komme aber noch nicht dahinter wie ich das jetzt an meine Funktion übergebe

    Das hier ist falsch:

    for(i=0; i<Var._SampleSize; i++){  
       for(std::vector<int>::iterator it=CSpace[i].begin()+1; it != CSpace[i].end(); it++){
          BinToBip(CSpace[i].begin() + 1, CSpace[i].end());
       }
    }
    


  • Ich habe das Problem jetzt so gelöst bekommen, dass ich in jedem Container den Wert habe berechnen lassen, was sonst die Funktion hätte machen sollen. Also:

    for(i=0; i<Var._SampleSize; i++){  
       for(auto it=CSpace[i].begin()+1; it != CSpace[i].end(); it++){
          *it=2*(*it)-1;
       }
    }
    

    Trotzdem würde ich sehr gerne wissen wie ich das an meine Funktion übergeben kann wie ursprünglich gedacht. Diese nimmt ja nur einen Vektor an.

    Danke für die Hilfe und Geduld und viele Grüße 🙂



  • Wenn Deine Matrix eine Matrix im mathematischen Sinne ist, kannst Du (wenn mich meine LA Künste nicht trügen) auch mit der Matrix

    1 0 0 0 0
    0 2 0 0 0
    0 0 2 0 0
    0 0 0 2 0
    0 0 0 0 2
    

    multiplizieren und die Matrix

    0 1 1 1 1
    0 1 1 1 1
    0 1 1 1 1
    0 1 1 1 1
    0 1 1 1 1
    

    abziehen.
    Vorausgesetzt, da stehen wirklich nur Nullen und Einsen in den rechten Spalten.


Anmelden zum Antworten