Problem mit Default-Templateparameter



  • Hi,

    ich wollte meine Matrixklasse um Möglichkeiten zur QR und LR-Zerlegung erweitern. Nun stehe ich vor einem Problem: Den Gauß-Algorithmus will ich auf einer NxN Matrix durchführen um die bloße LR-Zerlegung zu bestimmen. Ich will aber auch, dass man ihn auf einer Nx(N+1)-Matrix durchführen kann, wenn man nur einen b-Vektor hat und sich das Vorwärtseinsetzen sparen will. Da der Code ansonsten völlig identisch ist dachte ich, dass es sinnvoller ist das alles in einer Funktion zu behandeln.

    Mein erster Ansatz war folgender:

    // gauss (ohne pivotisierung)
    template<unsigned N, unsigned B, typename Type>
    void gaussElimination(Matrix<N, N + B, Type>& a)
    {
    	for(unsigned i = 0; i != (N - 1) && a[i][i] != 0; ++i)
    	{
    		for(unsigned j = i + 1; j != N; ++j)
    		{
    			a[j][i] /= a[i][i];
    			for(unsigned k = i + 1; k != (N + B); ++k)
    				a[j][k] -= a[j][i] * a[i][k];
    		}
    	}
    }
    

    Das Problem ist, dass B explizit angegeben werden muss, weil der Compiler (gcc) das nicht implizit erkennen will. Dann habe ich folgende Zusatzfunktionen eingeführt...

    template<unsigned N, typename Type>
    void gaussElimination(Matrix<N, N, Type>& a)
    {
    	gaussElimination<N, 0, Type>(a);
    }
    
    template<unsigned N, typename Type>
    void gaussElimination(Matrix<N, N + 1, Type>& a)
    {
    	gaussElimination<N, 1, Type>(a);
    }
    

    Das funktioniert auch hervorragend, aber ist das wirklich notwendig gewesen? Welche Lösungen fallen euch sonst noch ein?

    Gruß,

    Christian



  • MaSTaH schrieb:

    Mein erster Ansatz war folgender:

    // gauss (ohne pivotisierung)
    template<unsigned N, unsigned B, typename Type>
    void gaussElimination(Matrix<N, N + B, Type>& a)
    {
    	for(unsigned i = 0; i != (N - 1) && a[i][i] != 0; ++i)
    	{
    		for(unsigned j = i + 1; j != N; ++j)
    		{
    			a[j][i] /= a[i][i];
    			for(unsigned k = i + 1; k != (N + B); ++k)
    				a[j][k] -= a[j][i] * a[i][k];
    		}
    	}
    }
    

    Das Problem ist, dass B explizit angegeben werden muss, weil der Compiler (gcc) das nicht implizit erkennen will.

    Was daran liegt, dass Matrix<N, N+B, Type> ein sogenannter "nondeduced context" ist. Allgemein wird ein Name wie S<I + X> nie verwendet um einen Nontype Parameter I herzuleiten.



  • HumeSikkins schrieb:

    Was daran liegt, dass Matrix<N, N+B, Type> ein sogenannter "nondeduced context" ist. Allgemein wird ein Name wie S<I + X> nie verwendet um einen Nontype Parameter I herzuleiten.

    Ist denn meine zweite Idee in Ordnung (mit den 2 kurzen Zusatzfunktionen), oder kann es dadurch zu irgendwelchen Problemen kommen (z.B. auf anderen Compilern)?



  • MaSTaH schrieb:

    HumeSikkins schrieb:

    Was daran liegt, dass Matrix<N, N+B, Type> ein sogenannter "nondeduced context" ist. Allgemein wird ein Name wie S<I + X> nie verwendet um einen Nontype Parameter I herzuleiten.

    Ist denn meine zweite Idee in Ordnung (mit den 2 kurzen Zusatzfunktionen),

    Jup.

    oder kann es dadurch zu irgendwelchen Problemen kommen (z.B. auf anderen Compilern)?

    Ich würde mal behaupten, dass es mindestens einen Compiler auf dieser Welt gibt, der hier Probleme bekommt 🙂



  • Danke! Jetzt kann ich wenigstens ruhigen Gewissens weiter machen 😉 .


Anmelden zum Antworten