Vektor nur teilweise ansprechen



  • Hallo,
    ich suche nach einer Möglichkeit einen Vektor nur teilweise anzusprechen. Und zwar möchte ich zwei Vektoren in einer for-Schleife multiplizieren. Beim ersten Durchlauf sollen nur die beiden ersten Zahlen der Vektoren multipliziert werden, beim zweiten die zwei ersten usw. Habe das jetzt mit zwei for-Schleifen gelöst die die Vektoren als neue Speichern je nach dem bei welchem Durchlauf wir uns befinden, aber zwei for-Schleifen in einer for-Schleife machen das ganze ziemlich langsam, bzw lässt das mein Programm abstürzen.
    Ach und ich arbeite mit der Eigen-bibliothek. Hat jemand eine Ahnung ob es möglich ist den Vektor a an der Stelle 0 bis k anzusprechen? Ich kenne es bisher nämlich nur eine stelle oder den ganzen Vektor anzusrpechen.
    Anbei mal meine Lösung mit den for-Schleifen

    PotReihVar PotReihVar::operator*(PotReihVar b)
    {
    
    	PotReihVar c;
    
    	int s = b.xI.size(); 
    	c.xI = xI;
    	VectorXd vecb(s); //stehender Vektor
    	VectorXd veca(s); //liegender Vektor 
    	for (int i = 0; i < s; i++)
    	{
    		vecb(i) = b.xI[s-i];
    	}
    
    	for (int i = 0; i < s; i++)
    	{
    		veca(i) = xI[i];
    	}
    
    	for (int k = 0; k < s; k++)
    	{
    		VectorXd dummya(s);
    		VectorXd dummyb(s);
    		for (int a = 0; a < k; a++)
    		{
    
    			dummya(a) = veca(a);
    		}
    		for (int b = 0; b < k; b++)
    		{
    
    			dummyb(b) = veca(b);
    		}
    		double res = dummya.transpose() * dummyb;
    
    		c.set_one_xI(res, k);			
    	}
    
    	return c;
    }
    


  • Wenn dein Programm abstürzt hast du erstmal andere Probleme als Performance. Was sagt denn der Debugger dazu?

    Was mir auf den ersten Blick auffällt, dein Dummy Vektoren haben immer die komplette Größe s, auch wenn du nur den ein Element da rein schiebst. Was steht denn dann in den anderen Einträgen? Ich habe länger nicht mehr mit Eigen gearbeitet, initialisiert der dann automatisch mit 0?

    Wenn du eh immer durch iterierst wäre es wahrscheinlich auch schneller, wenn du dann direkt die Multiplikation selber machst, bevor du umkopierst und dann multiplizierst.

    Was mir ansonsten noch einfällt, Eigen hat auch Typ RowVectorXd, daraus ginge direkt hervor was du haben willst und du müsstest das transpose nicht mehr machen.



  • Bei der Schleife

    for (int i = 0; i < s; i++) 
        { 
            vecb(i) = b.xI[s-i]; 
        }
    

    sprichst du bei i=0 das Element b.xI[s] an. Das dürfte falsch sein.



  • Ihr habt beide Recht, den Fehler hab ich behoben, jetzt stürzt auch nichts mehr ab allerdings und beim ersten durchlauf klappt ist, ist mein xI aber mit mehr als einem wert befüllt schafft er es nur den ersten in den neuen vektor zu kopieren, da muss ich mich noch mal schlau machen.

    PotReihVar PotReihVar::operator*(PotReihVar b)
    {
    
    	PotReihVar c;
    
    	int s = b.xI.size(); 
    	c.xI = xI;
    	VectorXd vecb(s); //stehender Vektor
    	VectorXd veca(s); //liegender Vektor 
    
    	for (int i = 0; i < s; i++)
    	{
    		veca(i) = xI[i];
    	}
    
    	for (int i = 0; i < s; i++)
    	{
    		vecb(i) = b.xI[(s-1)-i];
    	}
    
    	for (int k = 0; k < s; k++)
    	{
    		VectorXd dummya(s);
    		VectorXd dummyb(s);
    		for (int a = 0; a <= k; a++)
    		{
    
    			dummya(a) = veca(a);
    		}
    		for (int b = 0; b <= k; b++)
    		{
    
    			dummyb(b) = vecb(b);
    		}
    		double res = dummya.transpose() * dummyb;
    
    		c.set_one_xI(res, k);			
    	}
    
    	return c;
    }
    

    so sieht es jetzt aus und wie gesagt für den ersten klappt es, für den zweiten xI Wert aber nicht mehr



  • Was ist xI denn für eine Datenstruktur?

    Wenn es auch ein Vektor ist sollte:

    veca = xI
    

    reichen.
    Du könntest auch direkt von Xi in deine Dummy Vektoren kopieren. So kopierst du 2x. Einmal in veca und vecb und dann in dummya und dummyb.

    Ansonsten könnte die Funktion reverse() für dich noch interessant sein um deinen vecb zu erzeugen.



  • ah super, reverse() hilft tatsächlich. So funktioniert auch alles! Sind zwar noch immer viel for-Schleifen aber das richtige Ergebnis kommt raus. Kopieren muss ich weil ich zuerst nur die ersten Einträge des Vektors, dann die beiden zweiten usw anspreche, bei Matlab kann man das ja umsetzten in dem man den vektor von 0 bis k anspricht, bei C++ hab ich da aber noch keien ähnliche Lösung zu finden können bis auf eben diese for-Schleife



  • Was ich meinte ist sowas:

    for (int k = 0; k < s; k++)
        {
            VectorXd dummya(k+1);
            VectorXd dummyb(k+1);
            for (int a = 0; a <= k; a++)
            {
    
                dummya[a] = xI[a];
                dummyb[a] = b.Xi.reverse()[a];
            }
    
            double res = dummya.transpose() * dummyb;
    
            c.set_one_xI(res, k);          
        }
    

    (Achtung: Nicht getestet)

    Edit: Grade gesehen, es gibt bei Eigen die Klasse VectorBlock die könnte für dich auch interessant sein.

    Edit 2: Tippfehler


Log in to reply