[erledigt] Template: Differenzvektor



  • Hallo,

    ich habe nach langer Zeit mal wieder eine Frage. Ausgehend davon, dass mathematische Vektoren auch in C++ ihre Entsprechung mittels std::vector finden, möchte ich nun ein Template konzipieren, dass den Differenzvektor berechnet, also y=x_1x_2\vec y = \vec{x}\_1 - \vec{x}\_2

    Die Zugehörige Funktion sieht bisher so aus

    std::vector<double> 
      diff_vec( std::vector<double>::iterator first1,
                std::vector<double>::iterator last1,
                std::vector<double>::iterator first2 )
    {
      std::vector<double> result;
      while( first1 != last1 ) {
        result.push_back( (*first1) - (*first2) );
        ++first1; ++first2;
      }
      return std::move( result );
    }
    

    Jetzt ist mein erster Versuch eines Templates folgender

    template <typename T>
      std::vector<double>  diff_vec( T first1, T last1,
                                     T first2 )
    {
      std::vector<double> result;
      while( first1 != last1 ) {
        result.push_back( (*first1) - (*first2) );
        ++first1; ++first2;
      } 
      return std::move( result );
    }
    

    Und jetzt Frage: Geht das noch abstrakter? Also dass ich den Container nicht angeben muss? Ich meine dasselbe würde doch auch mit std::list funktionieren. Es benötigt nur einen Random Access Iterator?

    Viele Grüße,
    Klaus



  • Der verallgemeinerte Container ist ein Iterator.

    template <typename InputIter1, typename InputIter2, typename OutputIter>
    OutputIter diff_vec( InputIter1 first1, InputIter1 last1,
                         InputIter2 first2,
                         OutputIter out )
    {
      while( first1 != last1 ) {
        *out = (*first1) - (*first2);
        ++first1; ++first2;
        ++out;
      }
      return out; // eigentlich egal, aber um konsistent zur STL zu sein.
    }
    

    In der inneren Schleife kannst du die Klammern um die Dereferenzierung weglassen, das sieht sonst so anfängerartig aus.

    K&R-Style:

    while( first1 != last1 )
        *out++ = *first1++ - *first2++;
    

    Würde ich hier sogar so machen.



  • Ach ja, aufrufen kannst du dann mit std::back_inserter.

    auto v1 = std::array<int, 3>{1,2,3};
    auto v2 = std::deque<int>{1,2,3};
    auto v3 = std::list<int>();
    diff_vec(v1.begin(), v1.end(), v2.begin(), std::back_inserter(v3));
    


  • template <typename InputIter1, typename InputIter2, typename OutputIter, typename Func>
    OutputIter diff_vec( InputIter1 first1, InputIter1 last1,
                         InputIter2 first2,
                         OutputIter out, Func func )
    {
      while( first1 != last1 ) {
        *out = func(*first1, *first2);
        ++first1; ++first2;
        ++out;
      }
      return out; // eigentlich egal, aber um konsistent zur STL zu sein.
    }
    

    Die Differenz Operation kann man noch generisch machen.

    Und dann fällt einem auf, dass es sowas shcon gibt in numeric. Heisst zum Beispiel std::inner_product.



  • Skym0sh0 schrieb:

    Und dann fällt einem auf, dass es sowas shcon gibt in numeric. Heisst zum Beispiel std::inner_product.

    inner_product kann das genauso gut wie std::for_each. Möglich mit Hacks, aber nicht dafür vorgesehen.



  • Gibts nicht std::valarray für soetwas?
    Hab ich zwar noch nie verwendet und kenne auch keinen, ders getan hat, aber eigentlich ist es für soetwas.


  • Mod

    Skym0sh0 schrieb:

    Und dann fällt einem auf, dass es sowas shcon gibt in numeric. Heisst zum Beispiel std::inner_product.

    inner_product erzeugt ein skalares T.
    Hier wäre ein ganz normales transform angebracht.



  • Klaus82 schrieb:

    Ausgehend davon, dass mathematische Vektoren auch in C++ ihre Entsprechung mittels std::vector finden,

    Ich hau Dich mit dem Struppi.
    http://www.cplusplus.com/reference/valarray/valarray/operators/



  • Hallo zusammen,

    vielen Dank für die regen Antworten. 🙂

    raiter schrieb:

    In der inneren Schleife kannst du die Klammern um die Dereferenzierung weglassen, das sieht sonst so anfängerartig aus.

    Nun, ich habe mich an dieser Notation orientiert.

    Nathan schrieb:

    Gibts nicht std::valarray für soetwas?
    Hab ich zwar noch nie verwendet und kenne auch keinen, ders getan hat, aber eigentlich ist es für soetwas.

    In der Tat. Dieses Argument ist natürlich unschlagbar. Ich weiß, dass ich mich damals gefragt hatte wozu diese Container benötigt werden und habe sie mental add acta gelegt. Hab ich mich selbst reingelegt. 😉

    volkard schrieb:

    Klaus82 schrieb:

    Ausgehend davon, dass mathematische Vektoren auch in C++ ihre Entsprechung mittels std::vector finden,

    Ich hau Dich mit dem Struppi.
    http://www.cplusplus.com/reference/valarray/valarray/operators/

    Diese Anspielung an Struppi verstehe ich nicht. 😕

    Viele Grüße,
    Klaus.



  • Klaus82 schrieb:

    volkard schrieb:

    Klaus82 schrieb:

    Ausgehend davon, dass mathematische Vektoren auch in C++ ihre Entsprechung mittels std::vector finden,

    Ich hau Dich mit dem Struppi.
    http://www.cplusplus.com/reference/valarray/valarray/operators/

    Diese Anspielung an Struppi verstehe ich nicht. 😕

    Damit wollte dir Volki sagen, daß du besser aufhörst neue Räder zu erfinden und lieber hingehst in den Struppi liest.



  • Klaus82 schrieb:

    volkard schrieb:

    Klaus82 schrieb:

    Ausgehend davon, dass mathematische Vektoren auch in C++ ihre Entsprechung mittels std::vector finden,

    Ich hau Dich mit dem Struppi.
    http://www.cplusplus.com/reference/valarray/valarray/operators/

    Diese Anspielung an Struppi verstehe ich nicht. 😕

    Meinte damit Die C++-Programmiersprache | ISBN: 382731660X.

    Wegen seiner Masse will man damit nicht gehauen werden. In dem steht sowas drin und es ist sehr wertvoll, ein dickes Buch zu haben, wo quasi alles kurz mal angesprochen wird. Leider muss man es mehrmals lesen.


  • Mod

    Wegen seiner Masse will man damit nicht gehauen werden.

    😃 👍


Anmelden zum Antworten