• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            qiezi的學習園地

            AS/C/C++/D/Java/JS/Python/Ruby

              C++博客 :: 首頁 :: 新隨筆 ::  ::  :: 管理 ::

            矩陣就不用再解釋了,寫成泛型主要是為了幾個方便:
            1、方便在棧上分配空間。由于維度在編譯期已知,所以可以做到在棧上分配空間。當然如果這個對象是new出來的,自然是在堆上分配,這里說的是在棧上分配這個對象時,矩陣元素所占用的空間也在棧上分配。
            2、方便在編譯期檢查非法的矩陣運算。C++模板的強大推導能力可以在編譯期推導出結果矩陣的維度。
            3、泛型類在方法內聯上具有優勢。

            這個矩陣類為了能夠直接從數組賦值,使用了一個ArrayPorxy類(可參考《Imperfect C++》)。

            代碼如下:

            template? < class ?T,? int ?D1,? int ?D2 = 1 >
            class ?ArrayProxy
            {
            ????T
            * ?data;
            public :
            ????ArrayProxy(T?(
            & value)[D1][D2])
            ????????:?data(
            & value[ 0 ][ 0 ])
            ????{
            ????}

            ????ArrayProxy(T?(
            & value)[D1 * D2])
            ????????:?data(value)
            ????{
            ????}

            ????T
            * ?getData()? const
            ????{
            ????????
            return ?data;
            ????}
            };

            這個只是簡單的實現。

            因為我基本上不使用這個矩陣類,所以只完成幾個簡單功能:
            1、從數組賦值:
            int a[][3] = {{1,2,3}, {4,5,6}};
            Matrix<int, 2, 3> m1(a);

            int a[] = {1,2,3, 4,5,6};
            Matrix<int, 2, 3> m1(a);
            Matrix<int, 3, 2> m2(a);
            Matrix<int, 6, 1> m3(a);
            Matrix<int, 1, 6> m4(a);

            2、矩陣乘法:
            Matrix<int, 2, 3> m1;
            Matrix<int, 2, 4> m2;
            // m1 * m2? <== 編譯錯誤,維度不匹配
            Matrix<int, 3, 5> m3;
            Matrix<int, 2, 5> m4 = m1 * m3; // <== 合法
            // m3 * m1; // <== 編譯錯誤,維度不匹配

            源碼如下:

            template?<class?T,?int?R,?int?C>
            class?Matrix
            {
            ????T?matrix[R][C];

            public:
            ????
            //?Big?three
            ????Matrix(void)
            ????{
            ????????memset(matrix,?
            0,?sizeof(matrix));
            ????}

            ????Matrix(
            const?Matrix&?rhs)
            ????{
            ????????memcpy(matrix,?rhs.matrix,?
            sizeof(matrix));
            ????}

            ????Matrix
            &?operator?=(const?Matrix&?rhs)
            ????{
            ????????memcpy(matrix,?rhs.matrix,?
            sizeof(matrix));
            ????????
            return?*this;
            ????}

            public:
            ????Matrix(
            const?ArrayProxy<T,R,C>&?arr)
            ????{
            ????????memcpy(matrix,?arr.getData(),?
            sizeof(matrix));
            ????}

            ????
            ~Matrix(void)
            ????{
            ????}

            public:
            ????T?
            get(int?r,?int?c)?const
            ????{
            ????????assert(c?
            <?C?&&?c?>=?0?&&?r?<?R?&&?r?>=?0);
            ????????
            return?matrix[r][c];
            ????}

            ????
            void?set(int?r,?int?c,?T?v)
            ????{
            ????????assert(c?
            <?C?&&?c?>=?0?&&?r?<?R?&&?r?>=?0);
            ????????matrix[r][c]?
            =?v;
            ????}

            ????
            int?getCols?()?const
            ????{
            ????????
            return?C;
            ????}

            ????
            int?getRows?()?const
            ????{
            ????????
            return?R;
            ????}

            ????
            bool?operator?==?(const?Matrix&?rhs)?const
            ????{
            ????????
            return?memcmp(matrix,?rhs.matrix,?sizeof(matrix))?==?0;
            ????}

            ????
            bool?operator?!=?(const?Matrix&?rhs)?const
            ????{
            ????????
            return?!(*this?==?rhs);
            ????}
            };

            template?
            <class?T,?int?R,?int?C,?int?C1>
            Matrix
            <T,R,C1>?operator*?(const?Matrix<T,R,C>&?lhs,?const?Matrix<T,C,C1>&?rhs)
            {
            ????Matrix
            <T,R,C1>?result;
            ????
            for?(int?r=0;?r<R;?++r)
            ????{
            ????????
            for?(int?c=0;?c<C1;?++c)
            ????????{
            ????????????
            int?value?=?0;
            ????????????
            for?(int?i=0;?i<C;?++i)
            ????????????{
            ????????????????value?
            +=?lhs.get(r,i)?*?rhs.get(i,c);
            ????????????}
            ????????????result.
            set(r,c,value);
            ????????}
            ????}
            ????
            return?result;
            }

            測試代碼:

            int?main()
            {
            ????{
            ????????
            //?測試初始化
            ????????Matrix<int,?3,?4>?m1;
            ????????Matrix
            <int,?3,?4>?m2(m1);
            ????????Matrix
            <int,?3,?4>?m3?=?m1;
            ????????Matrix
            <int,?3,?4>?m4;
            ????????m4?
            =?m1;

            ????????
            for?(int?i=0;?i<3;?i++)
            ????????????
            for?(int?j=0;?j<4;?j++)
            ????????????{
            ????????????????assert?(m1.
            get(i,?j)?==?0);
            ????????????????assert?(m2.
            get(i,?j)?==?0);
            ????????????????assert?(m3.
            get(i,?j)?==?0);
            ????????????????assert?(m4.
            get(i,?j)?==?0);
            ????????????}

            ????????
            int?a[]?=?{1,2,3,4,?5,6,7,8,?9,10,11,12};
            ????????Matrix
            <int,?3,?4>?m5(a);

            ????????
            int?b[3][4]?=?{?{1,2,3,4},
            ????????????????????????{
            5,6,7,8},
            ????????????????????????{
            9,10,11,12}};

            ????????Matrix
            <int,?3,?4>?m6(b);

            ????????Matrix
            <int,?3,?4>?m7(m5);
            ????????Matrix
            <int,?3,?4>?m8?=?m5;
            ????????Matrix
            <int,?3,?4>?m9;
            ????????m9?
            =?m5;

            ????????
            for?(int?i=0;?i<3;?i++)
            ????????????
            for?(int?j=0;?j<4;?j++)
            ????????????{
            ????????????????assert?(m5.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m6.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m7.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m8.
            get(i,?j)?==?i*4+j+1);
            ????????????????assert?(m9.
            get(i,?j)?==?i*4+j+1);
            ????????????}

            ????????
            //?維數不匹配,編譯錯誤
            ????????
            //?Matrix<int,?4,?5>?m10?=?m9;
            ????????int?c[][2]?=?{{1,2},?{2,3}};
            ????????
            //?數組大小不匹配,編譯錯誤
            ????????
            //Matrix<int,?3,?4>?m10(c);
            ????????int?d[]?=?{1,2};
            ????????
            //?數組大小不匹配,編譯錯誤
            ????????
            //Matrix<int,?3,?4>?m11(d);

            ????????
            //?乘法維數不合適,無法相乘
            ????????
            //m1?*?m2;

            ????????Matrix
            <int,4,3>?m12;
            ????????
            //?匹配,可以相乘
            ????????Matrix<int,?3,?3>?m13?=?m1?*?m12;

            ????????Matrix
            <int,?8,?3>?m14;
            ????????
            //?無法相乘
            ????????
            //Matrix<int,?3,?3>?m15?=?m1?*?m14;
            ????????
            //?可以相乘
            ????????Matrix<int,?8,?4>?m15?=?m14?*?m1;
            ????}

            ????{
            ????????
            //?檢查點乘
            ????????int?a[2][5]?=?{{1,2,3,4,5},?{6,7,8,9,10}};
            ????????Matrix
            <int,?2,?5>?m1(a);

            ????????
            int?b[5][3]?=?{{1,2,3},?{4,5,6},?{7,8,9},?{10,11,12},?{13,14,15}};
            ????????Matrix
            <int,?5,?3>?m2(b);

            ????????
            int?c[2][3]?=?{{135,150,165},?{310,350,390}};
            ????????Matrix
            <int,?2,?3>?m3(c);

            ????????Matrix
            <int,?2,?3>?m4?=?m1?*?m2;
            ????????assert(m4?
            ==?m3);

            ????????cout?
            <<?m4.get(0,0)?<<?endl;
            ????}

            ????
            return?0;
            }

            補充:
            1、加法、減法只需要2個矩陣維度相同即可。
            template?<class?T,?class?R,?class?C>
            Matrix
            <T,R,C>?operator+?(const?Matrix<T,R,C>&?lhs,?const?Matrix<T,R,C>&?rhs)
            {
            ???
            //?
            }

            2、由于1x1的矩陣可以看成一個標量,矩陣與標量運算結果維數與原矩陣相同,可以重載來實現。
            template?<class?T,?class?R,?class?C>
            Matrix
            <T,R,C>?operator*?(const?Matrix<T,R,C>&?lhs,?const?Matrix<T,1,1>&?rhs)
            {
            ????
            //?
            }

            3、由于類型泛化,可能某些合理的運算無法進行,比如float型矩陣,與一個int型標量運算等。這些最好是借助類型萃取等手段,推導出運算以后的類型。(c++0x中包含自動獲取運算結果類型的關鍵字typeof,等幾年就可以用了:)。GCC編譯器中已有實現,不過似乎有BUG)。

            4、其它。泛型實現可能會有一些考慮不周的地方,強類型有強類型的好處,不過必須要有完整的泛型算法支撐,否則難以使用。也可以把泛型矩陣類從一個普通矩陣類派生,這樣更容易寫出通用算法,不過在實現上可能要借助于運行期多態,對于矩陣類來說并不合適。

            5、其它。。前面說C++的模板相當強大,D語言模板到目前為止似乎已經完全實現了C++模板的功能,還增加了一些比如字符串值參模板等特性,比C++模板功能更多。在代碼編寫上,由于可以編寫靜態判斷語句(編譯期)以及靜態斷言,編寫模板比C++更容易。有時間可以試試用它寫個矩陣類,純粹是興趣,這些東西真的很難用到,現成的庫也挺多。

            6、其它。。。c++0x要提供“template typedef”,也就是可以這樣定義:
            template <int R, int C> typedef Matrix<int, R, C> MatrixInt;? // 定義類型,維度不定
            template <class T> typedef Matrix<T, 4, 4> Matrix4x4; // 定義維度,類型不定
            由此可以出定義行向量、列向量、標量等,當然實際使用起來可能沒那么舒服了。
            posted on 2006-04-13 13:52 qiezi 閱讀(875) 評論(1)  編輯 收藏 引用 所屬分類: C++
            久久九九久精品国产免费直播| 亚洲乱码中文字幕久久孕妇黑人| 浪潮AV色综合久久天堂| 亚洲第一极品精品无码久久| 国产亚洲精品美女久久久| 91久久精品国产成人久久| 综合久久一区二区三区| 久久婷婷激情综合色综合俺也去| 亚洲精品国产成人99久久| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 精品久久亚洲中文无码| 国产精品久久午夜夜伦鲁鲁| 欧美激情精品久久久久久久九九九 | 色综合久久夜色精品国产| 久久精品国产亚洲av高清漫画 | 久久国产乱子伦精品免费午夜| 99精品国产免费久久久久久下载 | 人人狠狠综合久久亚洲高清| 国产精品久久久久9999高清| 中文字幕亚洲综合久久菠萝蜜| 狠狠色丁香婷婷综合久久来| 7777精品久久久大香线蕉| 久久久久九九精品影院| 久久―日本道色综合久久| 中文字幕人妻色偷偷久久| 久久久久成人精品无码| 99久久精品国产毛片| 99久久这里只有精品| 亚洲AV无码久久精品蜜桃| 亚洲伊人久久综合影院| 久久久综合香蕉尹人综合网| 国内精品久久久久久麻豆| 国产精品久久久久天天影视| 日韩av无码久久精品免费| 久久久国产打桩机| 久久精品国产亚洲AV忘忧草18| 怡红院日本一道日本久久| 久久精品国产99国产精偷 | 99久久国产亚洲高清观看2024| 欧美精品一区二区精品久久| 国产精品久久自在自线观看|