QSapecNG
 All Classes Functions Enumerations Properties
functor.hpp
00001 /*
00002     SapecNG - Next Generation Symbolic Analysis Program for Electric Circuit
00003     Copyright (C) 2009, Michele Caini
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
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]; // 0-default drives from standard C++
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
 All Classes Functions Enumerations Properties