メインページ | ネームスペース一覧 | クラス階層 | 構成 | Directories | ファイル一覧 | ネームスペースメンバ | 構成メンバ | ファイルメンバ | 関連ページ

TVector.h

説明を見る。
00001 #ifndef PTMATRIX_TVECTOR_H
00002 #define PTMATRIX_TVECTOR_H
00003 /** @file TVector.h
00004     テンプレートによるN次元ベクトルの定義.
00005     要素の型とサイズをテンプレートの引数にすることで,
00006     管理情報をメモリに持たずに,一般の行列を扱う.
00007     配列をキャストしてベクトルにすることもできる.*/
00008 #include <algorithm>
00009 #include <iosfwd>
00010 #include <math.h>
00011 #include <assert.h>
00012 #include <stddef.h>
00013 #include <vector>
00014 #ifdef _MSC_VER
00015  #define for if(0); else for
00016  #pragma warning (disable: 4786)
00017  #pragma warning (disable: 4200)
00018 #endif
00019 
00020 #ifdef __BORLANDC__
00021  #pragma warn -8027
00022 #endif
00023 
00024 
00025 namespace PTM {;
00026 
00027 #ifdef _WIN32
00028  #pragma pack(push, 4)
00029  
00030  #ifdef _DEBUG
00031   #pragma optimize ("awgity", on)
00032  #endif
00033  #pragma inline_recursion(on)
00034  #pragma inline_depth(255)
00035 #endif
00036 
00037 #if defined _MSC_VER && _MSC_VER < 1300
00038 /*  VisualC++のテンプレート対策.
00039     VCはどうやら,テンプレート引数に同じ型の引数を複数つくると,全部最初の
00040     引数の値をとるらしい.これでは,size_t を2つ以上渡すことができない.
00041     そこで,サイズがnになるクラスを作って, sizeof でサイズを取り出すことで
00042     複数の size_t を引数で渡すようにする.*/
00043  template <size_t N> class TVectorDim{
00044     char dim[N];
00045  };
00046  #define DIMTYPE        class
00047  #define DIMENC(n)      PTM::TVectorDim<((n)+1)>
00048  #define DIMDEC(T)      ((sizeof(T)-1))
00049  #define DIMDEF(T, t)   typedef T t
00050  #define TYPENAME
00051 
00052 #else
00053  // 他のコンパイラにはそんな変な問題はないようだ
00054  #define DIMTYPE size_t
00055  #define DIMENC(n) (n)
00056  #define DIMDEC(n) (n)
00057  #define DIMDEF(T, t) static const size_t t = T
00058  #define TYPENAME typename
00059 #endif
00060 
00061 template <size_t N>
00062 class TVecDim{
00063 public:
00064     DIMDEF(DIMENC(N), SIZE);
00065     DIMDEF(DIMENC(N), STRIDE);
00066 };
00067 
00068 template <size_t STR, class EXP, class RET, class E, class Z=E>
00069 class TVectorDesc{
00070 public:
00071     DIMDEF(DIMENC(STR), STRIDE);    ///<    stride
00072     typedef EXP     exp_type;       ///<    実体
00073     typedef RET     ret_type;       ///<    返り値の型
00074     typedef E       element_type;   ///<    要素の型
00075     typedef Z       zero;           ///<    zero(0) が 要素の型の0を返す型
00076 };
00077 template <class EXP, class RET, class E, class Z=E>
00078 class VectorDesc{
00079 public:
00080     typedef EXP     exp_type;       ///<    実体
00081     typedef RET     ret_type;       ///<    返り値の型
00082     typedef E       element_type;   ///<    要素の型
00083     typedef Z       zero;           ///<    zero(0) が 要素の型の0を返す型
00084 };
00085 
00086 ///@name 演算.
00087 //@{
00088 template <class D> class VectorImp;
00089 template <DIMTYPE N, class D> class TVectorBase;
00090 /** ベクトルの要素を全てvにする.
00091     @param v 要素型の値.    */
00092 template <class D>
00093 void clear(VectorImp<D>& a, const TYPENAME D::element_type v= D::zero(0)){
00094     for(size_t i=0; i<a.size(); ++i) a.item(i) = v;
00095 }
00096 /** 代入(a = b).
00097     @param b 同じサイズのベクトル.  */
00098 template <class AD, class BD>
00099 void assign(VectorImp<AD>& a, const VectorImp<BD>& b) {
00100     a.resize(b.size());
00101     assert(a.size() == b.size());
00102     for(size_t i=0; i<a.size(); ++i) a.item(i) = b.item(i);
00103 }
00104 /// 代入(a = b) 2要素専用
00105 template <class AD, class BD>
00106 void assign(TVectorBase<DIMENC(2), AD>& a, const TVectorBase<DIMENC(2), BD>& b) {
00107     assert(a.size() == b.size());
00108     a.item(0) = b.item(0);
00109     a.item(1) = b.item(1);
00110 }
00111 /// 代入(a = b) 3要素専用
00112 template <class AD, class BD>
00113 void assign(TVectorBase<DIMENC(3), AD>& a, const TVectorBase<DIMENC(3), BD>& b) {
00114     assert(a.size() == b.size());
00115         typedef TYPENAME AD::element_type ET;
00116     a.item(0) = ET(b.item(0));
00117     a.item(1) = ET(b.item(1));
00118     a.item(2) = ET(b.item(2));
00119 }
00120 /// 代入(a = b) 4要素専用
00121 template <class AD, class BD>
00122 void assign(TVectorBase<DIMENC(4), AD>& a, const TVectorBase<DIMENC(4), BD>& b) {
00123     assert(a.size() == b.size());
00124     a.item(0) = (TYPENAME AD::element_type)b.item(0);
00125     a.item(1) = (TYPENAME AD::element_type)b.item(1);
00126     a.item(2) = (TYPENAME AD::element_type)b.item(2);
00127     a.item(3) = (TYPENAME AD::element_type)b.item(3);
00128 }
00129 /** 代入(*this = b).
00130     @param b 同じサイズのベクトル.  */
00131 template <class AD>
00132 void assign(VectorImp<AD>& a, const TYPENAME AD::element_type* b) {
00133     for(size_t i=0; i<a.size(); ++i) a.item(i) = b[i];
00134 }
00135 /** 加算(*this += b).
00136     @param b 同じサイズのベクトル.  */
00137 template <class AD, class BD>
00138 void add(VectorImp<AD>& a, const VectorImp<BD>& b){
00139     assert(b.size() ==a. size());
00140     for(size_t i=0; i<a.size(); ++i) a.item(i) += (TYPENAME AD::element_type) b.item(i);
00141 }
00142 /** 減算(*this -= b).
00143     @param b 同じサイズのベクトル.  */
00144 template <class AD, class BD>
00145 void sub(VectorImp<AD>& a, const VectorImp<BD>& b){
00146     assert(b.size() == a.size());
00147     for(size_t i=0; i<a.size(); ++i) a.item(i) -= (TYPENAME AD::element_type) b.item(i);
00148 }
00149 /** 定数倍(*this *= b).
00150     @param b 要素型.                */
00151 template <class AD>
00152 void multi(VectorImp<AD>& a, const TYPENAME AD::element_type& b){
00153     for(size_t i=0; i<a.size(); ++i) a.item(i) *= b;
00154 }
00155 /** 定数倍(*this *= b).
00156     @param b 要素型.                */
00157 template <class AD, class BD>
00158 void multi_each(VectorImp<AD>& a, const VectorImp<BD>& b){
00159     for(size_t i=0; i<a.size(); ++i) a.item(i) *= b.item(i);
00160 }
00161 /** 定数分の1(*this /= b).
00162     @param b 要素型.                */
00163 template <class AD>
00164 void div(VectorImp<AD>& a, const TYPENAME AD::element_type& b){
00165     for(size_t i=0; i<a.size(); ++i) a.item(i) /= b;
00166 }
00167 /** 内積(return *this * b).
00168     @param  b   同じサイズのベクトル.
00169     @return     内積の値(要素型)    */
00170 template <class AD, class BD>
00171 TYPENAME AD::element_type dot(const VectorImp<AD>& a, const VectorImp<BD>& b){
00172     assert(b.size() == a.size());
00173     typedef TYPENAME AD::zero zero;
00174     TYPENAME AD::element_type rv = zero(0);
00175     for(size_t i=0; i<a.size(); ++i) rv += a.item(i)*b.item(i);
00176     return rv;
00177 }
00178 template <class AD, class BD>
00179 TYPENAME AD::element_type dot(const TVectorBase<DIMENC(3), AD>& a, const TVectorBase<DIMENC(3), BD>& b){
00180         typedef TYPENAME AD::element_type ET;
00181     return ET(a.item(0)*b.item(0) + a.item(1)*b.item(1) + a.item(2)*b.item(2));
00182 }
00183 /** 比較(return *this == b).
00184     @param  b   同じサイズのベクトル.
00185     @return     bool値. */
00186 template <class AD, class BD>
00187 bool equal(const VectorImp<AD>& a, const VectorImp<BD>& b){
00188     if (b.size() != a.size()) return false;
00189     for(size_t i=0; i<a.size(); ++i){
00190         if (a.item(i) != b.item(i)) return false;
00191     }
00192     return true;
00193 }
00194 
00195 /** 要素ごとの最小値(min(*this, b)).
00196     @param b 同じサイズのベクトル.  */
00197 template <class AD, class BD>
00198 void element_min_impl(VectorImp<AD>& a, const VectorImp<BD>& b){
00199     assert(b.size() == a.size());
00200     for(size_t i=0; i<a.size(); ++i) a.item(i) = std::min(a.item(i), b.item(i));
00201 }
00202 template <class AD, class BD>
00203 TYPENAME AD::ret_type element_min(const VectorImp<AD>& a, const VectorImp<BD>& b){
00204     TYPENAME AD::ret_type r(a);
00205     element_min_impl(r, b);
00206     return r;
00207 }
00208 /** 要素ごとの最大値(max(*this, b)).
00209     @param b 同じサイズのベクトル.  */
00210 template <class AD, class BD>
00211 void element_max_impl(VectorImp<AD>& a, const VectorImp<BD>& b){
00212     assert(b.size() == a.size());
00213     for(size_t i=0; i<a.size(); ++i) a.item(i) = std::max(a.item(i), b.item(i));
00214 }
00215 template <class AD, class BD>
00216 TYPENAME AD::ret_type element_max(const VectorImp<AD>& a, const VectorImp<BD>& b){
00217     TYPENAME AD::ret_type r(a);
00218     element_max_impl(r, b);
00219     return r;
00220 }
00221 /// クリッピングする(bとeを頂点とする矩形内に収まるようにする).
00222 template <class AD, class BD, class ED>
00223 void clip(const VectorImp<AD>& a, const VectorImp<BD>& b, const VectorImp<ED>& e){
00224     for(size_t i=0; i<a.size(); ++i){
00225         if (a.item(i) < b.item(i)) a.item(i) = b.item(i);
00226         if (a.item(i) > e.item(i)) a.item(i) = e.item(i);
00227     }
00228 }
00229 //@}
00230 
00231 
00232 template<size_t SZ, size_t STR, class OD> class TVectorSlice;
00233 template<size_t SZ, class OD> class TSubVector;
00234 template<class D> class EVectorSlice;
00235 template<class D> class EVectorRange;
00236 /// ベクトルの演算などの実装
00237 template <class D>
00238 class VectorImp{
00239 public:
00240     typedef D desc;
00241     typedef TYPENAME desc::exp_type exp_type;
00242     typedef TYPENAME desc::ret_type ret_type;
00243     typedef TYPENAME desc::element_type element_type;
00244     typedef TYPENAME desc::zero zero;
00245     /// コンストラクタ
00246     VectorImp(){}
00247 
00248     ///@name 基本操作.
00249     //@{
00250     /// 実体の取得
00251     exp_type& exp(){ return *(exp_type*)this; }
00252     const exp_type& exp() const { return *(const exp_type*)this; }
00253     /// n番目の要素を返す(基数は0).
00254     element_type& item(size_t n){ return exp().item_impl(n); }
00255     const element_type& item(size_t n) const { return exp().item_impl(n); }
00256     /// サイズの取得
00257     size_t size() const { return exp().size_impl(); }
00258     /// サイズの設定
00259     void resize(size_t sz){ exp().resize_impl(sz); }
00260     /// ストライドの取得
00261     size_t stride(){ return exp().stride_impl(); }
00262     //@}
00263     
00264     ///@name 部分ベクトル
00265     //@{
00266     /** スライスを返す.テンプレート版
00267         このベクトルのSZ::OFFSET要素から SZ::OFFSET + SZ::SIZE要素までの
00268         部分ベクトルへの参照を返す.
00269         @param  SZ::OFFSET  部分ベクトルの最初の要素の位置.
00270         @param  SZ::SIZE    部分ベクトルのサイズ.
00271         @return SZ で指定されたベクトルへの参照を返す.  */
00272     template <class SZ> TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&
00273     t_slice(SZ){ return (TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&)item(DIMDEC(SZ::OFFSET)); }
00274     template <class SZ> const TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&
00275     t_slice(SZ) const { return (TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&)item(DIMDEC(SZ::OFFSET)); }
00276     /// 部分ベクトルを返す.テンプレート版
00277     template <class SZ> TSubVector<DIMDEC(SZ::SIZE), desc>&
00278     sub_vector(SZ){ return (TSubVector<DIMDEC(SZ::SIZE), desc>&)item(DIMDEC(SZ::OFFSET)); }
00279     template <class SZ> const TSubVector<DIMDEC(SZ::SIZE), desc>&
00280     sub_vector(SZ) const { return (TSubVector<DIMDEC(SZ::SIZE), desc>&)item(DIMDEC(SZ::OFFSET)); }
00281     /** スライスを返す.サイズだけテンプレート版
00282         このベクトルの off 要素から off + SZ::SIZE要素までの
00283         部分ベクトルへの参照を返す.
00284         @param  SZ::OFFSET  部分ベクトルの最初の要素の位置.
00285         @param  SZ::SIZE    部分ベクトルのサイズ.
00286         @return SZ で指定されたベクトルへの参照を返す.  */
00287     template <class SZ> TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&
00288     t_slice(size_t off, SZ){ return (TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&)item(off); }
00289     template <class SZ> const TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&
00290     t_slice(size_t off, SZ) const { return (TVectorSlice<DIMDEC(SZ::SIZE), DIMDEC(SZ::STRIDE), desc>&)item(off); }
00291     /// 部分ベクトルを返す.サイズだけテンプレート版
00292     template <class SZ> TSubVector<DIMDEC(SZ::SIZE), desc>&
00293     sub_vector(size_t off, SZ){ return (TSubVector<DIMDEC(SZ::SIZE), desc>&)item(off); }
00294     template <class SZ> const TSubVector<DIMDEC(SZ::SIZE), desc>&
00295     sub_vector(size_t off, SZ) const { return (TSubVector<DIMDEC(SZ::SIZE), desc>&)item(off); }
00296     
00297     /// 部分ベクトルを返す.変数版
00298     EVectorSlice<element_type> v_range(size_t off, size_t sz){
00299         return EVectorSlice<element_type>(sz, stride(), &item(off));
00300     }
00301     EVectorSlice<element_type> v_range(size_t off, size_t sz) const {
00302         return EVectorSlice<element_type>(sz, stride(), &item(off));
00303     }
00304     /// ベクトルのスライスを返す.
00305     EVectorSlice<element_type> v_slice(size_t off, size_t sz, size_t str){
00306         return EVectorSlice<element_type>(sz, stride()*str, &item(off));
00307     }
00308     EVectorSlice<element_type> v_slice(size_t off, size_t sz, size_t str) const {
00309         return EVectorSlice<element_type>(sz, stride()*str, &item(off));
00310     }
00311     //@}
00312     
00313     ///@name 演算.
00314     //@{
00315     /** ベクトルの要素を全てvにする.
00316         @param v 要素型の値.    */
00317     void clear(const element_type v=zero(0)){ PTM::clear(exp(), v); }
00318     /** 代入(*this = b).
00319         @param b 同じサイズのベクトル.  */
00320     template <class B>
00321         void assign(const VectorImp<B>& b) { PTM::assign(exp(), b.exp()); }
00322     /** 代入(*this = b).
00323         @param b 同じサイズのベクトル.  */
00324     void assign(const element_type* b) { PTM::assign(exp(), b); }
00325     /** 加算(*this += b).
00326         @param b 同じサイズのベクトル.  */
00327     template <class B>
00328         void add(const VectorImp<B>& b){ PTM::add(exp(), b.exp()); }
00329     /** 減算(*this -= b).
00330         @param b 同じサイズのベクトル.  */
00331     template <class B>
00332         void sub(const VectorImp<B>& b){ PTM::sub(exp(), b.exp()); }
00333     /** 定数倍(*this *= b).
00334         @param b 要素型.                */
00335     void multi(const element_type& b){ PTM::multi(exp(), b); }
00336     /** 定数分の1(*this /= b).
00337         @param b 要素型.                */
00338     void div(const element_type& b){ PTM::div(exp(), b); }
00339     /** 内積(return *this * b).
00340         @param  b   同じサイズのベクトル.
00341         @return     内積の値(要素型)    */
00342     template <class B>
00343         element_type dot(const VectorImp<B>& b) const { return PTM::dot(exp(), b.exp()); }
00344     /** 比較(return *this == b).
00345         @param  b   同じサイズのベクトル.
00346         @return     bool値. */
00347     template <class B>
00348         bool equal(const VectorImp<B>& b) const { return PTM::equal(exp(), b.exp()); }
00349 
00350     /** 要素ごとの最小値(min(*this, b)).
00351         @param b 同じサイズのベクトル.  */
00352     template <class B>
00353         void element_min(const VectorImp<B>& b){ element_min_impl(exp(), b.exp()); }
00354     /** 要素ごとの最大値(max(*this, b)).
00355         @param b 同じサイズのベクトル.  */
00356     template <class B>
00357         void element_max(const VectorImp<B>& b){ element_max_impl(exp(), b.exp()); }
00358     /// ベクトルのノルム(大きさ)の2乗を返す.
00359     element_type square() const { return PTM::dot(exp(),exp()); }
00360     /// ベクトルのノルム(大きさ)を返す.
00361     element_type norm() const { return element_type( sqrt(square()) ); }
00362     /// 単位ベクトルにする.
00363     void unitize(){ div(norm()); }
00364     /// クリッピングする(bとeを頂点とする矩形内に収まるようにする).
00365     template <class BD, class ED>
00366         void clip(const VectorImp<BD>& b, const VectorImp<ED>& e){ clip(exp(), b.exp(), e.exp()); }
00367     //@}
00368 
00369     ///@name 入出力
00370     //@{
00371     /** 表示.
00372         @param os 出力先ストリーム  */
00373     void print(std::ostream& os, char* sep="( )") const {
00374         if (sep[0]) os << sep[0];
00375         if (size()){ os.width(6); os << item(0); }
00376         for(size_t i=1; i<size(); ++i){
00377             if (sep[1]) os << sep[1];
00378             os.width(6); os << item(i);
00379         }
00380         if (sep[2]) os << sep[2];
00381     }
00382     /** 表示.
00383         @param is 入力元ストリーム  */
00384     template <class T>
00385     void input(T& is) {
00386         is >> std::ws;
00387         if (is.peek() != '('){
00388             is.setstate(std::ios::badbit);
00389             return;
00390         }
00391         is.get();
00392         std::vector<element_type> v;
00393         while(1){
00394             v.push_back(element_type());
00395             is >> v.back();
00396             if (!is.good()) break;
00397             if (size()<v.size()) resize(v.size());
00398             if (size()<v.size()) break;
00399         }
00400         v.pop_back();
00401         for(unsigned i=0; i<v.size(); ++i){
00402             item(i) = v[i];
00403         }
00404         is.clear();
00405         is >> std::ws;
00406         if (is.peek() == ')'){
00407             is.get();
00408             return;
00409         }
00410         is.setstate(std::ios::badbit);
00411     }
00412     //@}
00413 
00414     ///@name 演算子
00415     //@{
00416     /// [] 演算子(基数は0).
00417     template <class I> element_type& operator[] (I n) { return item(n); }
00418     /// [] 演算子(基数は0) (const 版).
00419     template <class I> const element_type& operator[] (I n) const { return item(n); }
00420     /// element_type * への変換
00421     operator element_type* (){ return &item(0); }
00422     operator const element_type* () const { return &item(0); }
00423     /** ベクトルのスカラー倍(return this * b).
00424         @param  b   要素型
00425         @return thisと同じベクトル型    */
00426     ret_type operator * (element_type b) const { ret_type rv(*this); rv.multi(b); return rv; }
00427     /** ベクトルのスカラー分の1(return this / b).
00428         @param  b   要素型
00429         @return thisと同じベクトル型    */
00430     ret_type operator / (element_type b) const { ret_type rv(*this); rv.div(b); return rv; }
00431     /** += 演算子(*this = *this + b).
00432         @param b サイズが等しいベクトル型.  */
00433     template <class BD>
00434     ret_type operator+= (const VectorImp<BD>& b) { add(b); return *this; }
00435     /** -= 演算子(*this = *this - b)
00436         @param b サイズが等しいベクトル型.  */
00437     template <class BD>
00438     ret_type operator-= (const VectorImp<BD>& b) { sub(b); return *this; }
00439     /** *= 演算子 (*this = *this * b)
00440         @param b 要素型.    */
00441     template <class T> ret_type operator*= (T b) { multi(element_type(b)); return *this; }
00442     /** /= 演算子 (*this = 1/b * *this).
00443         @param b 要素型.    */
00444     template <class T> ret_type operator/= (T b) { div(element_type(b)); return *this; }
00445     /** - 演算子 (return -*this).   */
00446     ret_type operator- () const { ret_type r(*this); r*=element_type(-1); return r; }
00447     /// 単位ベクトルを返す.
00448     ret_type unit() const { ret_type r(*this); r.unitize(); return r; }
00449     //@}
00450 protected:
00451     /// バッファの初期化.何もしない.
00452     void init_buffer(){}
00453     /// デフォルトコンストラクタ
00454     void set_default(){}
00455 };
00456 
00457 /// 次元をテンプレートで持つベクトルの基本型
00458 template<DIMTYPE N, class D>
00459 class TVectorBase: public VectorImp<D> {
00460 protected:
00461     TVectorBase(){}
00462 public:
00463     DIMDEF(N, SIZE);
00464     size_t size_impl() const { return DIMDEC(N); }
00465     void resize_impl(size_t sz) { assert(sz==DIMDEC(N)); }
00466 };
00467 
00468 
00469 /** ベクトル型派生クラスに必要なメンバの定義.
00470     派生クラスを作るたびに,このマクロを使ってメンバを作る.
00471     デフォルトコンストラクタ, 同じサイズのベクトルによる
00472     初期化・代入などが定義される.
00473     @param  THIS    新たに宣言する派生クラスの型名.
00474     @see    TVector */
00475 #define DEF_VECTOR_BASIC_MEMBER(THIS)                                       \
00476     typedef THIS this_type;         /*  このクラスの型を定義しておく. */    \
00477     typedef TYPENAME desc::element_type element_type;                       \
00478     typedef TYPENAME desc::ret_type ret_type;                               \
00479     /*  コピーコンストラクタ    */                                          \
00480     THIS& operator =(const THIS& b){                                        \
00481         assign(b); return *this;                                            \
00482     }                                                                       \
00483     /*  ベクトル b を代入   */                                              \
00484     template <class D>                                                      \
00485     THIS& operator =(const PTM::VectorImp<D>& b){                           \
00486         exp().assign(b); return *this;                                      \
00487     }                                                                       \
00488     /*  ベクトル b を加算   */                                              \
00489     template <class D>                                                      \
00490     THIS& operator +=(const PTM::VectorImp<D>& b){                          \
00491         exp().add(b); return *this;                                         \
00492     }                                                                       \
00493     /*  ベクトル b を加算   */                                              \
00494     template <class D>                                                      \
00495     THIS& operator -=(const PTM::VectorImp<D>& b){                          \
00496         exp().sub(b); return *this;                                         \
00497     }                                                                       \
00498     /*  要素数が等しい配列 p の代入 */                                      \
00499     THIS& operator =(const element_type* p){                                \
00500         exp().assign(p);                                                    \
00501         return *this;                                                       \
00502     }                                                                       \
00503 
00504 #define DEF_TVECTOR_BASIC_MEMBER(THIS)                                      \
00505     DEF_VECTOR_BASIC_MEMBER(THIS)                                           \
00506     /*  ベクトル b による初期化     */                                      \
00507     template <class D>                                                      \
00508     THIS(const PTM::VectorImp<D>& b){init_buffer(); assign(b);}             \
00509     /*  要素数が等しい配列 p による初期化   */                              \
00510     THIS(const element_type* p){                                            \
00511         assign(p);                                                          \
00512     }                                                                       \
00513     /*  デフォルトコンストラクタ    */                                      \
00514     THIS(){ init_buffer(); set_default(); }                                 \
00515 
00516 //----------------------------------------------------------------------------
00517 /** 部分ベクトル型作成のためのユーティリティークラス.
00518     TVecDim<次元数> で部分ベクトル型を取得できる。  */
00519 template <const size_t SOFF, const size_t SDIM>
00520 class TSubVectorDim{
00521 public:
00522     DIMDEF(DIMENC(SOFF),    OFFSET);
00523     DIMDEF(DIMENC(SDIM),    SIZE);
00524     DIMDEF(DIMENC(1),       STRIDE);
00525 };
00526 //----------------------------------------------------------------------------
00527 /** ベクトル型. TVector<3, float> v; のように使う
00528     @param  N   要素数.
00529     @param  T   要素の型.
00530     @see        TVector型の演算子
00531 */
00532 template <size_t N, class T>
00533 class TVector:public TVectorBase<DIMENC(N), TVectorDesc<1, TVector<N,T>, TVector<N,T>, T> >{
00534 public:
00535     DIMDEF(DIMENC(1), STRIDE);
00536     typedef TVectorDesc<1, TVector<N,T>, TVector<N,T>, T> desc; ///<    型情報
00537     typedef TVectorBase<DIMENC(N),desc> base_type;              ///<    基本クラス型
00538     /** 継承されない基本的なメンバの定義.
00539         @see ::DEF_TVECTOR_BASIC_MEMBER */
00540     DEF_TVECTOR_BASIC_MEMBER(TVector);
00541 private:
00542     element_type data[N];                                       ///<    データ
00543 public: 
00544     /// 要素のアクセス
00545     T& item_impl(size_t i){ return data[i]; }
00546     /// 要素のアクセス
00547     const T& item_impl(size_t i) const { return data[i]; }
00548     /// ストライド
00549     size_t stride_impl() const { return 1; }
00550 };
00551 
00552 template<size_t SZ, size_t STR, class OD>
00553 class TVectorSlice: public TVectorBase<DIMENC(SZ),
00554     TVectorDesc< STR*DIMDEC(OD::STRIDE), 
00555         TVectorSlice<SZ, STR, OD>, TVector<SZ, TYPENAME OD::element_type>, TYPENAME OD::element_type, TYPENAME OD::zero> > {
00556 public:
00557     DIMDEF(DIMENC(SZ), SIZE);
00558     DIMDEF(DIMENC(STR), STRIDE);
00559     typedef void array_type;
00560     typedef void const_array_type;
00561     typedef TVectorDesc< STR*DIMDEC(OD::STRIDE), TVectorSlice<SZ, STR, OD>, TVector<SZ, TYPENAME OD::element_type>, TYPENAME OD::element_type, TYPENAME OD::zero> desc;
00562     typedef TVectorBase<DIMENC(SZ), desc> base_type;
00563     /// 継承されない基本的なメンバの定義  @see ::DEF_VECTOR_BASIC_MEMBER
00564     DEF_VECTOR_BASIC_MEMBER(TVectorSlice);
00565     /// 要素のアクセス
00566     element_type& item_impl(size_t i){ return data[i][0]; }
00567     const element_type& item_impl(size_t i) const { return data[i][0]; }
00568     /// ストライド
00569     size_t stride_impl() const { return DIMDEC(STRIDE); }
00570 protected:
00571     element_type data[DIMDEC(SIZE)][DIMDEC(STRIDE)];
00572 };
00573 
00574 
00575 template<size_t SZ, class OD>
00576 class TSubVector: public TVectorBase<DIMENC(SZ),
00577     TVectorDesc< DIMDEC(OD::STRIDE), TSubVector<SZ, OD>, TVector<SZ, TYPENAME OD::element_type>, TYPENAME OD::element_type, TYPENAME OD::zero> > {
00578 public:
00579     DIMDEF(DIMENC(SZ), SIZE);
00580     DIMDEF(OD::STRIDE, STRIDE);
00581     typedef void array_type;
00582     typedef void const_array_type;
00583     typedef TVectorDesc< DIMDEC(OD::STRIDE), TSubVector<SZ, OD>, TVector<SZ, TYPENAME OD::element_type>, TYPENAME OD::element_type, TYPENAME OD::zero> desc;
00584     typedef TVectorBase<DIMENC(SZ), desc> base_type;
00585     /// 継承されない基本的なメンバの定義  @see ::DEF_VECTOR_BASIC_MEMBER
00586     DEF_VECTOR_BASIC_MEMBER(TSubVector);
00587     /// 要素のアクセス
00588     element_type& item_impl(size_t i){ return data[i][0]; }
00589     const element_type& item_impl(size_t i) const { return data[i][0]; }
00590     /// ストライド
00591     size_t stride_impl() const { return DIMDEC(STRIDE); }
00592 protected:
00593     element_type data[DIMDEC(SIZE)][DIMDEC(STRIDE)];
00594 };
00595 
00596 //----------------------------------------------------------------------------
00597 
00598 /** ベクトル型. VVector<float> v; のように使う
00599     @param  T   要素の型.
00600     @see        TVector型の演算子
00601 */
00602 template <class T>
00603 class VVector:public VectorImp<TVectorDesc<1, VVector<T>,VVector<T>,T> >{
00604 public:
00605     typedef TVectorDesc<1,VVector<T>,VVector<T>,T> desc;
00606     typedef VectorImp<desc> base_type;
00607     /** 継承されない基本的なメンバの定義.
00608         @see ::DEF_VECTOR_BASIC_MEMBER  */
00609     DEF_VECTOR_BASIC_MEMBER(VVector);
00610     /// 基本型の定義
00611     typedef element_type* array_type;
00612     typedef const element_type* const_array_type;
00613 private:
00614     /// メモリの実体
00615     array_type data;
00616     ///
00617     size_t size_;
00618 public:
00619     /// デフォルトコンストラクタ
00620     VVector(){
00621         init_buffer();
00622         set_default();
00623     }
00624     /// コピーコンストラクタ
00625     VVector(const VVector& s){
00626         init_buffer();
00627         resize(s.size_);
00628         memcpy(data, s.data, sizeof(element_type) * size_);
00629     }
00630     template <class D>
00631     VVector(const VectorImp<D>& b){
00632         init_buffer();
00633         assign(b);
00634     }
00635     /// 
00636     ~VVector(){
00637         delete [] data;
00638     }
00639     /// ベクトルのサイズ.
00640     size_t size_impl() const { return size_; }
00641     /// ベクトルのサイズの設定
00642     void resize_impl(size_t s){
00643         if (s > size_){
00644             delete data;
00645             data = new element_type[s];
00646         }
00647         size_ = s;
00648     }
00649     /// ストライド
00650     size_t stride_impl() const { return 1; }
00651     /// 要素のアクセス
00652     T& item_impl(size_t i){ return data[i]; }
00653     /// 要素のアクセス
00654     const T& item_impl(size_t i) const { return data[i]; }
00655 protected:
00656     void init_buffer(){data=0; size_=0;}
00657 };
00658 
00659 /** ベクトル型. EVector<float> v; のように使う
00660     @param  T   要素の型.
00661     @see        Vector型の演算子
00662 */
00663 template <class T>
00664 class ConstEVector:public VectorImp< TVectorDesc<1, ConstEVector<T>, VVector<T>,T,T> >{
00665 public:
00666     typedef TVectorDesc<1, ConstEVector<T>,VVector<T>,T,T> desc;
00667     typedef VectorImp<desc> base_type;
00668     /** 継承されない基本的なメンバの定義.
00669         @see ::DEF_VECTOR_BASIC_MEMBER  */
00670     DEF_VECTOR_BASIC_MEMBER(ConstEVector);
00671     typedef const element_type* array_type;
00672 private:
00673     /// メモリの実体
00674     array_type data;
00675     ///
00676     size_t size_;
00677 public:
00678     ///
00679     ConstEVector(array_type v, size_t sz):data(v), size_(sz){}
00680     //
00681     ConstEVector(size_t sz, size_t str, array_type v):data(v), size_(sz){ assert(str==1);}
00682     /// ベクトルのサイズ.
00683     size_t size_impl() const { return size_; }
00684     /// ベクトルのサイズの設定
00685     void resize_impl(size_t s){
00686         assert(size_ == s);
00687     }
00688     /// 要素のアクセス
00689     const T& item_impl(size_t i) const { return data[i]; }
00690     /// ストライド
00691     size_t stride_impl() const { return 1; }
00692 };
00693 template <class T>
00694 class EVector:public VectorImp< TVectorDesc<1, EVector<T>, VVector<T>,T,T> >{
00695 public:
00696     typedef ConstEVector<T> const_type;
00697     typedef TVectorDesc<1, EVector<T>,VVector<T>,T,T> desc;
00698     typedef VectorImp<desc> base_type;
00699     /** 継承されない基本的なメンバの定義.
00700         @see ::DEF_VECTOR_BASIC_MEMBER  */
00701     DEF_VECTOR_BASIC_MEMBER(EVector);
00702     typedef element_type* array_type;
00703 private:
00704     /// メモリの実体
00705     array_type data;
00706     ///
00707     size_t size_;
00708 public:
00709     ///
00710     EVector(size_t sz, array_type v):data(v), size_(sz){}
00711     EVector(size_t sz, size_t str, array_type v):data(v), size_(sz){ assert(str==1); }
00712     /// ベクトルのサイズ.
00713     size_t size_impl() const { return size_; }
00714     /// ベクトルのサイズの設定
00715     void resize_impl(size_t s){
00716         assert(size_ == s);
00717     }
00718     /// 要素のアクセス
00719     const T& item_impl(size_t i) const { return data[i]; }
00720     T& item_impl(size_t i) { return data[i]; }
00721     /// ストライド
00722     size_t stride_impl() const { return 1; }
00723 };
00724 template<class T>
00725 class ConstEVectorSlice: public VectorImp< VectorDesc<ConstEVectorSlice<T>, VVector<T>, T> >{
00726 public:
00727     typedef void array_type;
00728     typedef void const_array_type;
00729     typedef VectorDesc<EVectorSlice<T>, VVector<T>, T> desc;
00730     typedef VectorImp<desc> base_type;
00731     /// 継承されない基本的なメンバの定義.   @see ::DEF_VECTOR_BASIC_MEMBER
00732     DEF_VECTOR_BASIC_MEMBER(ConstEVectorSlice);
00733     ///
00734     ConstEVectorSlice(size_t sz, size_t str, const T* d):data(d), size_(sz), stride_(str){}
00735     ///
00736     ConstEVectorSlice(const ConstEVectorSlice& v):data(v.data), size_(v.size_), stride_(v.stride_){}
00737     /// 要素のアクセス
00738     element_type& item_impl(size_t i){ return data[index(i)]; }
00739     /// 要素のアクセス
00740     const element_type& item_impl(size_t i) const { return data[index(i)]; }
00741     /// サイズ
00742     size_t size_impl() const { return size_; }
00743     /// サイズの設定
00744     void resize_impl(size_t sz) { size_ = sz; }
00745     /// ストライド
00746     size_t stride_impl() const { return stride_; }
00747 protected:
00748     const element_type* data;
00749     size_t size_;
00750     size_t stride_;
00751     /// 元の行列へのアクセス
00752     size_t index(size_t i) const { return i*stride_; }
00753 };
00754 template<class T>
00755 class EVectorSlice: public VectorImp< VectorDesc<EVectorSlice<T>, VVector<T>, T> >{
00756 public:
00757     typedef ConstEVectorSlice<T> const_type;
00758     typedef void array_type;
00759     typedef void const_array_type;
00760     typedef VectorDesc<EVectorSlice<T>, VVector<T>, T> desc;
00761     typedef VectorImp<desc> base_type;
00762     /// 継承されない基本的なメンバの定義.   @see ::DEF_VECTOR_BASIC_MEMBER
00763     DEF_VECTOR_BASIC_MEMBER(EVectorSlice);
00764     ///
00765     EVectorSlice(size_t sz, size_t str, T* d):data(d), size_(sz), stride_(str){}
00766     ///
00767     EVectorSlice(const EVectorSlice& v):data(v.data), size_(v.size_), stride_(v.stride_){}
00768     /// 要素のアクセス
00769     element_type& item_impl(size_t i){ return data[index(i)]; }
00770     /// 要素のアクセス
00771     const element_type& item_impl(size_t i) const { return data[index(i)]; }
00772     /// サイズ
00773     size_t size_impl() const { return size_; }
00774     /// サイズの設定
00775     void resize_impl(size_t sz) { size_ = sz; }
00776     /// ストライド
00777     size_t stride_impl() const { return stride_; }
00778 protected:
00779     element_type* data;
00780     size_t size_;
00781     size_t stride_;
00782     /// 元の行列へのアクセス
00783     size_t index(size_t i) const { return i*stride_; }
00784 };
00785 
00786 //----------------------------------------------------------------------------
00787 //  グローバル関数・演算子
00788 
00789 /** ベクトルの和(return a + b).
00790     @param  a   ベクトル型
00791     @param  b   aと同じ次元数のベクトル型
00792     @return     aと同じ次元数のTVector型    */
00793 template <class AD, class BD>
00794 TYPENAME AD::ret_type operator + (const VectorImp<AD>& a, const VectorImp<BD>& b) {
00795     TYPENAME AD::ret_type rv(a);
00796     rv.add(b);
00797     return rv;
00798 }
00799 /** ベクトルの差(return a - b).
00800     @param  a   ベクトル型
00801     @param  b   aと同じ次元数のベクトル型
00802     @return     aと同じ次元数のベクトル型   */
00803 template <class AD, class BD>
00804 TYPENAME AD::ret_type operator - (const VectorImp<AD>& a, const VectorImp<BD>& b) {
00805     TYPENAME AD::ret_type rv(a);
00806     rv.sub(b);
00807     return rv;
00808 }
00809 /** スカラーとベクトルの積(return a * b).
00810     @param  a   ベクトル型
00811     @param  b   要素型
00812     @return     ベクトル型  */
00813 template <class BD>
00814 typename BD::ret_type operator * (const TYPENAME BD::element_type& a, const VectorImp<BD>& b) {
00815     TYPENAME BD::ret_type r(b);
00816     r.multi(a);
00817     return r;
00818 }
00819 
00820 /** ベクトルの内積(return a * b).
00821     @param  a   ベクトル型
00822     @param  b   aと同じ次元数のベクトル型
00823     @return     要素型  */
00824 template <class AD, class BD>
00825 typename AD::element_type operator * (const VectorImp<AD>& a, const VectorImp<BD>& b) {
00826     return a.dot(b);
00827 }
00828 
00829 /** 比較(return a == b).
00830     @param  a   ベクトル型
00831     @param  b   要素型aと同じ次元数のベクトル型
00832     @return     bool    */
00833 template <class AD, class BD>
00834 bool operator == (const VectorImp<AD>& a, const VectorImp<BD>& b) { return a.equal(b); }
00835 /** 比較(return a != b).
00836     @param  a   ベクトル型
00837     @param  b   要素型aと同じ次元数のベクトル型
00838     @return     bool    */
00839 template <class AD, class BD>
00840 bool operator != (const VectorImp<AD>& a, const VectorImp<BD>& b) { return !a.equal(b); }
00841 
00842 /// ストリームに書式付で出力する.
00843 template <class BD>
00844 std::ostream& operator << (std::ostream& os, const VectorImp<BD>& v){
00845     v.print(os);
00846     return os;
00847 }
00848 /// ストリームから書式付で入力する.
00849 template <class BD>
00850 std::istream& operator >> (std::istream& is, VectorImp<BD>& v){
00851     v.input(is);
00852     return is;
00853 }
00854 /** 2次元ベクトルの外積(return a x b).
00855     @param  a   2次元ベクトル型
00856     @param  b   2次元ベクトル型
00857     @return     要素型  */
00858 template <class AD, class BD>
00859 typename AD::element_type cross (const TVectorBase<DIMENC(2), AD>& a, const TVectorBase<DIMENC(2), BD>& b) {
00860     return a[0] * b[1] - a[1] * b[0];
00861 }
00862 template <class AD, class BD>
00863 typename AD::element_type operator % (const TVectorBase<DIMENC(2), AD>& a, const TVectorBase<DIMENC(2), BD>& b) {
00864     return cross(a, b);
00865 }
00866 template <class AD, class BD>
00867 typename AD::element_type operator ^ (const TVectorBase<DIMENC(2), AD>& a, const TVectorBase<DIMENC(2), BD>& b) {
00868     return cross(a, b);
00869 }
00870 
00871 /** 3次元ベクトルの外積(return a x b).
00872     @param  a   3次元ベクトル型
00873     @param  b   3次元ベクトル型
00874     @return     3次元ベクトル型 */
00875 template <class AD, class BD>
00876 TYPENAME AD::ret_type cross (const TVectorBase<DIMENC(3), AD>& a, const TVectorBase<DIMENC(3), BD>& b) {
00877     TYPENAME AD::ret_type r;
00878     typedef TYPENAME AD::element_type ADET;
00879     r[0] = ADET(a[1] * b[2] - a[2] * b[1]);
00880     r[1] = ADET(a[2] * b[0] - a[0] * b[2]);
00881     r[2] = ADET(a[0] * b[1] - a[1] * b[0]);
00882     return r;
00883 }
00884 
00885 template <class AD, class BD>
00886 TYPENAME AD::ret_type operator % (const TVectorBase<DIMENC(3), AD>& a, const TVectorBase<DIMENC(3), BD>& b) {
00887     return cross(a, b);
00888 }
00889 template <class AD, class BD>
00890 TYPENAME AD::ret_type operator ^ (const TVectorBase<DIMENC(3), AD>& a, const TVectorBase<DIMENC(3), BD>& b) {
00891     return cross(a, b);
00892 }
00893 
00894 
00895 #ifdef _WIN32
00896  #ifdef _DEBUG
00897   #pragma optimize ("", on)
00898   #pragma auto_inline(off)
00899   #pragma inline_recursion(off)
00900  #endif
00901  #pragma pack(pop)
00902 #endif
00903 
00904 }   //  namespace PTM
00905 #endif
00906 

Springheadに対してSun Apr 16 01:57:58 2006に生成されました。  doxygen 1.4.1