#ifndef __BASE_H__ #define __BASE_H__ #include #include #include #include #include #include "util/util.h" #include "param/matrix.h" template class Values { protected: typedef Values self_t; public: static unsigned variables(){ return Variables; } virtual FloatT &operator[](unsigned i) = 0; virtual bool good() const = 0; }; /** * * 値の具体的な定義はMatrixによるものとする */ template class MatrixValues : public Values, public Matrix{ protected: typedef Values values_t; typedef Matrix matrix_t; typedef FloatT float_t; typedef MatrixValues self_t; public: MatrixValues() : matrix_t(values_t::variables(), 1){} MatrixValues(matrix_t &m) : matrix_t(m){} virtual ~MatrixValues(){} virtual float_t &operator[](unsigned i){ return matrix_t::operator()(i, 0); } std::string join(const char *separator, unsigned precision = 8) const { std::stringstream ss; ss << std::setprecision(precision); if(Variables > 0){ ss << const_cast(this)->self_t::operator[](0); for(unsigned i(1); i < Variables; i++){ ss << separator << const_cast(this)->self_t::operator[](i); } } return ss.str(); } bool good() const { for(unsigned i(0); i < Variables; i++){ FloatT v(const_cast(this)->self_t::operator[](i)); if(std::isnan(v) || !std::finite(v)){return false;} } return true; } }; #define MAKE_VALUES(name, variables, float_t, options) \ class name : public MatrixValues{ \ protected: \ typedef name self_t; \ typedef MatrixValues super_t; \ template \ struct AliasItem { \ static const int index(const char *alias){ \ return AliasItem::index(alias); \ } \ }; \ template \ struct AliasItem { \ static const int index(const char *alias){ \ return -1; \ } \ }; \ public: \ name() : super_t(){} \ name(super_t::matrix_t &m) : super_t(m){} \ virtual ~name(){} \ options; \ public: \ static const int index(const char *alias){ \ return AliasItem::index(alias); \ } \ }; #define MAKE_ALIAS(name, i) \ public: \ super_t::float_t &name(){return super_t::operator[](i);} \ static const unsigned index_ ## name(){return i;} \ protected: \ template \ struct AliasItem { \ static const int index(const char *alias){ \ if(std::strcmp(alias, #name) == 0){return i;} \ else{return AliasItem::index(alias);} \ } \ }; template class MaskedValues : public BaseType { protected: typedef BaseType super_t; typedef MaskedValues self_t; public: typedef std::vector index_table_t; typedef typename super_t::float_t float_t; typedef std::map index_table_void_t; protected: static index_table_t index_table; static index_table_void_t index_table_void; public: static index_table_t &unmasked(){ return index_table; } static index_table_void_t &masked(){ return index_table_void; } static unsigned variables(){ return index_table.size(); } static void init(){ for(unsigned i(0); i < super_t::variables(); i++){ index_table.push_back(i); } } /** * 指定のインデックスの値をマスクします。 * * @param index インデックス * @param init_value マスクされた値の初期値 * @return (bool) マスクが成功した場合true、以外false。 */ static bool mask(unsigned index, const float_t &init_value){ for(index_table_t::iterator it(index_table.begin()); it != index_table.end(); ++it){ if(*it == index){ index_table.erase(it); index_table_void.insert( index_table_void_t::value_type(index, init_value)); return true; } } return false; } /** * 指定のインデックスの値をマスクします。 * * @param index インデックス * @return (bool) マスクが成功した場合true、以外false。 */ static bool mask(unsigned index){ return mask(index, float_t(0)); } /** * 指定のインデックスの値をアンマスクします。 * * @param index インデックス * @return (bool) マスクが成功した場合true、以外false。 */ static bool unmask(unsigned index){ { index_table_void_t::iterator it(index_table_void.find(index)); if(it == index_table_void.end()){ return false; } index_table_void.erase(it); } index_table_t::iterator it(index_table.begin()); do{ if(*it > index){break;} }while((++it) != index_table.end()); index_table.insert(it, index); return true; } MaskedValues() : super_t() { for(index_table_void_t::iterator it(index_table_void.begin()); it != index_table_void.end(); ++it){ super_t::operator[](it->first) = it->second; } } MaskedValues(const super_t &base) : super_t(base) {} ~MaskedValues(){} virtual float_t &operator[](unsigned i){ return super_t::operator[](self_t::index_table[i]); } MaskedValues &operator=(const super_t &base){ super_t::operator=(base); return *this; } }; template typename MaskedValues::index_table_t MaskedValues::index_table = typename MaskedValues::index_table_t(); template typename MaskedValues::index_table_void_t MaskedValues::index_table_void = typename MaskedValues::index_table_void_t(); #endif /* __BASE_H__ */