00001
00012 #ifndef __weight_hpp
00013 #define __weight_hpp
00014
00015 #include<ostream>
00016 #include<vector>
00017 #include<algorithm>
00018
00019 #include"util.hpp"
00020
00021
00022 namespace graphgen{
00023
00041 struct value_type{
00042 enum weight_value_type{
00043 weight,
00044 ratio,
00045 logweight,
00046 logratio,
00047 one
00048 };
00049 };
00050
00064 template<value_type::weight_value_type WV>
00065 class vertex_weight {
00066 private:
00067
00069 static double uniform( qint ){ return 1; };
00070
00071 public:
00072
00074 typedef double (*one_point_f)( qint );
00075
00077 static const bool logarithmic = ( (WV == value_type::logweight) || (WV == value_type::logratio) );
00078
00080 vertex_weight(): f(uniform), qlimit(), weights(qlimit,0), ratios(qlimit,0) {};
00081
00083 vertex_weight( one_point_f F ): f(F), qlimit(0), weights(qlimit,0), ratios(qlimit,0) {};
00084
00088 vertex_weight( one_point_f F , qint qtable ): f(F), qlimit(0), weights(qlimit,0), ratios(qlimit,0)
00089 {
00090 resize(qtable);
00091 };
00092
00094 template<value_type::weight_value_type WVC>
00095 vertex_weight( const vertex_weight<WVC>& );
00096
00097
00099 double r( qint q ) const { return ratios[q]; }
00100
00102 double p( qint q ) const { return weights[q]; }
00103
00106 double ratio( qint q ) const;
00107
00110 double weight( qint q ) const;
00111
00112
00118 void resize( qint limit ){
00119 weights.resize(limit);
00120 ratios.resize(limit);
00121
00122 if(limit>qlimit) for( qint q = qlimit; q<limit; q++ ){
00123 weights[q] = weight( q );
00124 ratios[q] = ratio( q );
00125
00126 qlimit++;
00127 }
00128
00129 qlimit = limit;
00130 }
00131
00133 qint limit() const { return qlimit; }
00134
00137 std::ostream& print( std::ostream& os, qint limit=0 ) const {
00138 os << "# q_i" << tab
00139 << "weight" << tab << "ratio" << std::endl;
00140
00141 if(limit==0) limit = qlimit;
00142
00143 for( qint q=0; q<limit; q++ )
00144 os << q << tab
00145 << weight(q) << tab
00146 << ratio(q) << std::endl;
00147
00148 return os;
00149 }
00150
00151
00152 private:
00153
00155 const one_point_f f;
00156
00158 qint qlimit;
00159
00161 std::vector<double> weights;
00163 std::vector<double> ratios;
00164 };
00165
00166
00180 template<value_type::weight_value_type WV>
00181 class link_weight {
00182 public:
00183
00185 typedef double (*two_point_f)( qint, qint );
00186
00187
00189 static const bool logarithmic = ( (WV == value_type::logweight) || (WV == value_type::logratio) ) ;
00190
00191
00193 link_weight(): f(&uniform), qlimit(0), weights(qlimit,0), ratios(qlimit,0) {};
00194
00195
00197 link_weight( two_point_f F ): f(F), qlimit(0), weights(qlimit,0), ratios(qlimit,0) {};
00198
00199
00201 link_weight( two_point_f F , qint qtable ): f(F), qlimit(0), weights(qlimit,0), ratios(qlimit,0) {
00202 resize(qtable);
00203 };
00204
00205
00207 template<value_type::weight_value_type WVC>
00208 link_weight( const link_weight<WVC>& );
00209
00210
00212 double r( qint q1, qint q2 ) const { return p(q1+1,q2)/p(q1,q2); }
00213
00214
00216 double p( qint q1, qint q2 ) const { return weights[index(q1,q2)]; };
00217
00218
00220 double ratio( qint q1, qint q2 ) const;
00221
00222
00224 double weight( qint q1, qint q2 ) const;
00225
00226
00232 void resize( qint limit ){
00233 weights.resize( index(limit-1,limit-1)+1 );
00234 ratios.resize( index(limit-1,limit-1)+1 );
00235
00236 if(limit>qlimit) for( qint q1 = qlimit; q1<limit; q1++ ) {
00237 for( qint q2 = 0; q2<limit; q2++ ){
00238 if(q2<=q1)
00239 weights[index(q1,q2)] = weight( q1,q2 );
00240
00241 ratios[index(q1,q2)] = ratio( q1,q2 );
00242 }
00243 qlimit++;
00244 }
00245
00246 qlimit = limit;
00247 }
00248
00249
00251 qint limit() const { return qlimit; }
00252
00255 std::ostream& print( std::ostream& os, qint limit=0 ) const {
00256 os << "# q_i" << tab << "q_j" << tab
00257 << "weight" << tab << "ratio" << std::endl;
00258
00259 if(limit==0) limit=qlimit;
00260
00261 for( qint q1=0; q1<limit; q1++ ){
00262 for( qint q2=0; q2<limit; q2++ )
00263 os << q1 << tab << q2 << tab
00264 << weight(q1,q2) << tab
00265 << ratio(q1,q2) << std::endl;
00266
00267 os << std::endl;
00268 }
00269
00270 return os;
00271 }
00272
00273 private:
00274
00276 double uniform( qint, qint ){ return 1; };
00277
00279 const two_point_f f;
00280
00282 qint qlimit;
00283
00285 qint index( qint q1, qint q2 ) const { return ltm_index(q1,q2); }
00286
00288 std::vector<double> weights;
00290 std::vector<double> ratios;
00291 };
00292
00293
00294 static vertex_weight<value_type::one> uniform_weight;
00295
00296
00301 template<value_type::weight_value_type WVC> static
00302 std::ostream&operator<<( std::ostream&os, const vertex_weight<WVC>& w )
00303 {
00304 return w.print(os);
00305 }
00306
00311 template<value_type::weight_value_type WVC> static
00312 std::ostream&operator<<( std::ostream&os, const link_weight<WVC>& w )
00313 {
00314 return w.print( os );
00315 }
00316 }
00317
00318 #endif