00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef FUNCTOR_H
00021 #define FUNCTOR_H
00022
00023
00024 #include "model/metacircuit.h"
00025
00026 #include <complex>
00027 #include <map>
00028
00029
00030 namespace sapecng
00031 {
00032
00033
00034
00035 struct functor
00036 {
00037
00038 public:
00039 std::pair< std::vector<double>, std::vector<double> >
00040 operator()
00041 (
00042 const metacircuit::expression& numerator,
00043 const metacircuit::expression& denominator,
00044 std::map< std::string, double > values
00045 )
00046 {
00047 std::map< int, double > real_num = synthesis(numerator, values);
00048 std::map< int, double > real_den = synthesis(denominator, values);
00049 return op(real_num, real_den);
00050 }
00051
00052 protected:
00053 virtual std::pair< std::vector<double>, std::vector<double> >
00054 op(std::map< int, double > num, std::map< int, double > den) = 0;
00055
00056 private:
00057 std::map< int, double >
00058 synthesis(
00059 const metacircuit::expression& expr,
00060 std::map< std::string, double > values
00061 )
00062 {
00063 std::map< int, double > syn;
00064
00065 for(metacircuit::expression::const_iterator
00066 eit = expr.begin(); eit != expr.end(); ++eit)
00067 {
00068 double value = 0.;
00069 for(metacircuit::degree_expression::const_iterator dit =
00070 eit->second.begin(); dit != eit->second.end(); ++dit)
00071 {
00072 double sub_value = dit->first;
00073 for(std::list<std::string>::const_iterator
00074 it = dit->second.begin(); it != dit->second.end(); ++it)
00075 sub_value *= values[*it];
00076
00077 value += sub_value;
00078 }
00079 syn[eit->first] += value;
00080 }
00081
00082 return syn;
00083 }
00084
00085 };
00086
00087
00088
00089 struct frequency_range_functor: public functor
00090 {
00091
00092 public:
00093 frequency_range_functor(std::pair< double, double > range, double step)
00094 : range_(range), step_(step) { }
00095
00096 protected:
00097 virtual double apply( std::complex<double> v ) = 0;
00098
00099 private:
00100 std::pair< std::vector<double>, std::vector<double> >
00101 op(std::map< int, double > num, std::map< int, double > den)
00102 {
00103 std::pair< std::vector<double>, std::vector<double> > plot;
00104 if(step_ > 0 && range_.first <= range_.second)
00105 {
00106 for(double cnt = range_.first; cnt < range_.second; cnt += step_)
00107 {
00108 std::complex<double> cnum = compute(num, cnt);
00109 std::complex<double> cden = compute(den, cnt);
00110
00111 plot.first.push_back(cnt);
00112 plot.second.push_back( apply(cnum / cden) );
00113 }
00114 }
00115
00116 return plot;
00117 }
00118
00119 std::complex<double>
00120 compute(
00121 std::map< int, double > expr,
00122 double step
00123 )
00124 {
00125 std::complex<double> cvalue(0., 0.);
00126 for(std::map< int, double >::const_iterator it = expr.begin();
00127 it != expr.end(); ++it)
00128 {
00129 bool real = (it->first % 2 == 0);
00130 double value =
00131 std::pow(-1., ((it->first - (real ? 0 : 1)) / 2))
00132 * std::pow(2. * 4.0 * std::atan(1.0) * step, it->first)
00133 * it->second;
00134
00135 if(real)
00136 cvalue += std::complex<double>(value, 0.);
00137 else
00138 cvalue += std::complex<double>(0., value);
00139 }
00140
00141 return cvalue;
00142 }
00143
00144 private:
00145 std::pair< double, double > range_;
00146 double step_;
00147
00148 };
00149
00150
00151
00152 struct magnitude: public frequency_range_functor
00153 {
00154
00155 public:
00156 magnitude(std::pair< double, double > range, double step)
00157 : frequency_range_functor(range, step) { }
00158
00159 private:
00160 double apply( std::complex<double> v ) { return std::abs(v); }
00161
00162 };
00163
00164
00165
00166 struct phase: public frequency_range_functor
00167 {
00168
00169 public:
00170 phase(std::pair< double, double > range, double step)
00171 : frequency_range_functor(range, step) { }
00172
00173 private:
00174 double apply( std::complex<double> v ) { return std::arg(v); }
00175
00176 };
00177
00178
00179
00180 struct gain: public frequency_range_functor
00181 {
00182
00183 public:
00184 gain(std::pair< double, double > range, double step)
00185 : frequency_range_functor(range, step) { }
00186
00187 private:
00188 double apply( std::complex<double> v )
00189 { return (20. * std::log10( std::abs(v) )); }
00190
00191 };
00192
00193
00194
00195 struct loss: public frequency_range_functor
00196 {
00197
00198 public:
00199 loss(std::pair< double, double > range, double step)
00200 : frequency_range_functor(range, step) { }
00201
00202 private:
00203 double apply( std::complex<double> v )
00204 { return (20. * std::log10((1. / std::abs(v) ))); }
00205
00206 };
00207
00208
00209
00210 extern
00211 std::list< std::pair< double, double > >
00212 rpoly_adapter(const std::map< int, double >& p);
00213
00214 struct zeros: public functor
00215 {
00216
00217 private:
00218 std::pair< std::vector<double>, std::vector<double> >
00219 op(std::map< int, double > num, std::map< int, double > den)
00220 {
00221 std::pair< std::vector<double>, std::vector<double> > ret;
00222
00223 std::list< std::pair< double, double > > pts = rpoly_adapter(num);
00224 for(std::list< std::pair< double, double > >::const_iterator
00225 i = pts.begin(); i != pts.end(); ++i)
00226 {
00227 ret.first.push_back(i->first);
00228 ret.second.push_back(i->second);
00229 }
00230
00231 return ret;
00232 }
00233
00234 };
00235
00236 struct poles: public functor
00237 {
00238
00239 private:
00240 std::pair< std::vector<double>, std::vector<double> >
00241 op(std::map< int, double > num, std::map< int, double > den)
00242 {
00243 std::pair< std::vector<double>, std::vector<double> > ret;
00244
00245 std::list< std::pair< double, double > > pts = rpoly_adapter(den);
00246 for(std::list< std::pair< double, double > >::const_iterator
00247 i = pts.begin(); i != pts.end(); ++i)
00248 {
00249 ret.first.push_back(i->first);
00250 ret.second.push_back(i->second);
00251 }
00252
00253 return ret;
00254 }
00255
00256 };
00257
00258
00259
00260 }
00261
00262
00263 #endif // FUNCTOR_H