Keresés

Új hozzászólás Aktív témák

  • jattila48

    aktív tag

    válasz jattila48 #2851 üzenetére

    A némileg optimalizált változat:

    #ifndef _MATRIX_
    #define _MATRIX_

    #include <assert.h>
    #include <iostream>

    static struct dummy_type{}dummy;

    template<typename T,int n,int m> class my_matrix{
    public:
    typedef T scalar_type;

    my_matrix(const dummy_type &){}

    my_matrix(const my_matrix& mm){
    std::cout << "copy ctor" << std::endl;
    int i,j;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    matrix[i][j]=mm.matrix[i][j];
    }
    }
    }

    explicit my_matrix(T x=T()){
    int i,j;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    matrix[i][j]=x;
    }
    }
    }

    my_matrix & operator=(const my_matrix &mm){
    int i,j;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    matrix[i][j]=mm.matrix[i][j];
    }
    }
    return *this;
    }

    my_matrix & operator+=(const my_matrix &mm){
    int i,j;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    matrix[i][j]+=mm.matrix[i][j];
    }
    }
    return *this;
    }

    my_matrix & operator*=(T c){
    int i,j;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    matrix[i][j]*=c;
    }
    }
    return *this;
    }

    my_matrix operator+(const my_matrix &mm) const{
    //return my_matrix(*this)+=mm;
    my_matrix t(dummy);
    int i,j;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    t.matrix[i][j]=matrix[i][j]+mm.matrix[i][j];
    }
    }
    return t;
    }

    my_matrix operator*(T c) const{
    my_matrix t(dummy);
    int i,j;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    t.matrix[i][j]=c*matrix[i][j];
    }
    }
    return t;
    }

    const T & operator()(int i,int j) const{
    assert(i<n && j<m && i>=0 && j>=0);
    return matrix[i][j];
    }

    T & operator()(int i,int j){
    return const_cast<T &>(static_cast<const my_matrix *>(this)->operator()(i,j));
    }
    private:
    T matrix[n][m];
    };
    /*
    template<typename T> T operator+(T a, T b){
    return T(a)+=b;
    }
    */
    template<typename T,int n,int m,int k> my_matrix<T,n,m> operator*(const my_matrix<T,n,k> &a,const my_matrix<T,k,m> &b){
    my_matrix<T,n,m> c(dummy);
    int i,j,l;
    for(i=0;i<n;++i){
    for(j=0;j<m;++j){
    T s=T();
    for(l=0;l<k;++l){
    s+=a(i,l)*b(l,j);
    }
    c(i,j)=s;
    }
    }
    return c;
    }

    template<typename T> T operator*(typename T::scalar_type c,T &A){
    return A*c;
    }

    #endif

    Ebben már nincs fölösleges copy ctor hívás. Csak a my_matrix-ot érték szerint visszaadó fv.-ek hívják a copy ctort, legalábbis debug verzióban vagy nem C++11 kompatibilis fordítóval fordítva, de az újabb fordítók az RVO miatt ezt is ki optimalizálják (copy elision. mindig!). A dummy_type típusú dummy változó csak a megfelelő ctor overload kiválasztása miatt lett bevezetve. A my_matrix(const dummy_type &) ctor semmit nem csinál, ez csak a megfelelő méretű inicializálatlan elemű üres mátrix létrehozására kell. Az előző verzióban erre a copy vagy default ctort kellett használni, azonban amikor az így létrehozott mátrix elemei (pl. összeadással) amúgy is felül lesznek írva, fölösleges az elemek inicializálása. Ez a ctor persze nem használható "rendes" objektum létrehozására, mert az így létrehozott objektum önmagában használhatatlan. Célszerű lenne ezért private-ba tenni, de akkor az ezt hívó free fv-eknek friend-nek kéne lenni (TODO). A default ctort is lehetett volna így használni, azonban akkor ezzel nem lehetne objektumot létrehozni. A mátrix szorzáson is lehetne gyorsítani pl. úgy, hogy a * operatort az összes különböző méretű, azonos skalár típusú my_matrix friend-jévé tesszük, és nem az elemkiválasztó operator()(int,int)-t hívjuk, hanem közvetlenül a matrix[j]-ket, de ekkor el kéne tárolni a my_matrix osztályban az n,m méret template argumentumokat. Valamivel gyorsabb lenne, azonban lényegesen rondább is.

Új hozzászólás Aktív témák