LCOV - code coverage report
Current view: top level - Preamplifier - TransistorClassAFilter.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 106 111 95.5 %
Date: 2021-02-18 20:07:22 Functions: 13 15 86.7 %

          Line data    Source code
       1             : /**
       2             : * \file TransistorClassAFilter.cpp
       3             : */
       4             : 
       5             : #include <ATK/Preamplifier/TransistorClassAFilter.h>
       6             : #include <ATK/Preamplifier/TransistorFunction.h>
       7             : #include <ATK/Utility/fmath.h>
       8             : #include <ATK/Utility/SimplifiedVectorizedNewtonRaphson.h>
       9             : #include <ATK/Utility/VectorizedNewtonRaphson.h>
      10             : 
      11             : #include <cassert>
      12             : 
      13             : namespace ATK
      14             : {
      15             :   template <typename DataType_>
      16             :   class TransistorClassAFilter<DataType_>::TransistorClassAFunction
      17             :   {
      18             :     const DataType_ Rp;
      19             :     const DataType_ Rg1;
      20             :     const DataType_ Rg2;
      21             :     const DataType_ Ro;
      22             :     const DataType_ Rk;
      23             :     const DataType_ Vbias;
      24             :     const DataType_ Cg;
      25             :     const DataType_ Co;
      26             :     const DataType_ Ck;
      27             : 
      28             :     DataType_ ickeq;
      29             :     DataType_ icgeq;
      30             :     DataType_ icoeq;
      31             : 
      32             :     TransistorFunction<DataType_>& transistor_function;
      33             :   public:
      34             :     using DataType = DataType_;
      35             :     using Vector = Eigen::Matrix<DataType, 4, 1>;
      36             :     using Matrix = Eigen::Matrix<DataType, 4, 4>;
      37             : 
      38             :     std::pair<DataType, DataType> exp_y0;
      39             : 
      40             :     template<typename T>
      41           1 :     TransistorClassAFunction(DataType dt, DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType Vbias, DataType Cg, DataType Co, DataType Ck, TransistorFunction<DataType_>& transistor_function, const T& default_output)
      42           1 :       :Rp(1 / Rp), Rg1(1 / Rg1), Rg2(1 / Rg2), Ro(1 / Ro), Rk(1 / Rk), Vbias(Vbias), Cg(2 / dt * Cg), Co(2 / dt * Co), Ck(2 / dt * Ck), ickeq(2 / dt * Ck * default_output[1]), icgeq(2 / dt * -Cg * default_output[4]), icoeq(-2 / dt * Co * default_output[2]), transistor_function(transistor_function)
      43             :     {
      44           1 :     }
      45             : 
      46        4800 :     Vector estimate(gsl::index i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output)
      47             :     {
      48        4800 :       return affine_estimate(i, input, output);
      49             :     }
      50             : 
      51        4800 :     Vector affine_estimate(gsl::index i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output)
      52             :     {
      53        4800 :       std::pair<DataType, DataType> exp_y1 = std::make_pair(fmath::exp((output[3][i - 1] - output[0][i - 1]) / transistor_function.Vt), fmath::exp((output[3][i - 1] - output[2][i - 1]) / transistor_function.Vt));
      54             : 
      55        4800 :       auto Ib = transistor_function.Lb(exp_y1);
      56        4800 :       auto Ic = transistor_function.Lc(exp_y1);
      57             : 
      58        4800 :       auto Ib_Vbe = transistor_function.Lb_Vbe(exp_y1);
      59        4800 :       auto Ib_Vbc = transistor_function.Lb_Vbc(exp_y1);
      60             : 
      61        4800 :       auto Ic_Vbe = transistor_function.Lc_Vbe(exp_y1);
      62        4800 :       auto Ic_Vbc = transistor_function.Lc_Vbc(exp_y1);
      63             : 
      64           0 :       Vector y0(-ickeq - (Ib - Ib_Vbe * (output[3][i - 1] - output[0][i - 1]) - Ib_Vbc * (output[3][i - 1] - output[2][i - 1]) + Ic - Ic_Vbe * (output[3][i - 1] - output[0][i - 1]) - Ic_Vbc * (output[3][i - 1] - output[2][i - 1])),
      65        4800 :         -icoeq,
      66           0 :         Vbias * Rp - (Ic - Ic_Vbe * (output[3][i - 1] - output[0][i - 1]) - Ic_Vbc * (output[3][i - 1] - output[2][i - 1])),
      67        4800 :         input[0][i] * Cg - icgeq + Vbias * Rg1 - (Ib - Ib_Vbe * (output[3][i - 1] - output[0][i - 1]) - Ib_Vbc * (output[3][i - 1] - output[2][i - 1])));
      68             : 
      69        4800 :       Matrix M;
      70        9600 :       M << -(Ib_Vbe + Ic_Vbe) - (Rk + Ck), 0, -(Ib_Vbc + Ic_Vbc), (Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc),
      71        4800 :         0, Ro + Co, Ro, 0,
      72        4800 :         -Ic_Vbe, Ro, -Ic_Vbc + Ro + Rp, (Ic_Vbe + Ic_Vbc),
      73        9600 :         -Ib_Vbe, 0, -Ib_Vbc, (Ib_Vbc + Ib_Vbe) + Rg2 + Rg1 + Cg;
      74             : 
      75        9600 :       return M.inverse() * y0;
      76             :     }
      77             : 
      78        4800 :     void update_state(gsl::index i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output)
      79             :     {
      80        4800 :       ickeq = 2 * Ck * output[1][i] - ickeq;
      81        4800 :       icgeq = 2 * Cg * (input[0][i] - output[4][i]) - icgeq;
      82        4800 :       icoeq = -2 * Co * output[2][i] - icoeq;
      83        4800 :     }
      84             : 
      85        8944 :     Vector operator()(gsl::index i, const DataType* const * ATK_RESTRICT input, DataType* const * ATK_RESTRICT output, const Vector& y1)
      86             :     {
      87        8944 :       std::pair<DataType, DataType> exp_y1 = std::make_pair(fmath::exp((y1(3) - y1(0)) / transistor_function.Vt), fmath::exp((y1(3) - y1(2)) / transistor_function.Vt));
      88             : 
      89        8944 :       auto Ib = transistor_function.Lb(exp_y1);
      90        8944 :       auto Ic = transistor_function.Lc(exp_y1);
      91             : 
      92        8944 :       auto Ib_Vbe = transistor_function.Lb_Vbe(exp_y1);
      93        8944 :       auto Ib_Vbc = transistor_function.Lb_Vbc(exp_y1);
      94             : 
      95        8944 :       auto Ic_Vbe = transistor_function.Lc_Vbe(exp_y1);
      96        8944 :       auto Ic_Vbc = transistor_function.Lc_Vbc(exp_y1);
      97             : 
      98        8944 :       auto f1 = Ib + Ic + ickeq - y1(0) * (Rk + Ck);
      99        8944 :       auto f2 = icoeq + (y1(1) + y1(2)) * Ro + y1(1) * Co;
     100        8944 :       auto f3 = Ic + (y1(1) + y1(2)) * Ro + (y1(2) - Vbias) * Rp;
     101        8944 :       auto f4 = Ib + icgeq + y1(3) * Rg2 + (y1(3) - Vbias) * Rg1 + (y1(3) - input[0][i]) * Cg;
     102             : 
     103        8944 :       Vector F(f1,
     104             :         f2,
     105             :         f3,
     106             :         f4);
     107             : 
     108        8944 :       Matrix M;
     109       17888 :       M << -(Ib_Vbe + Ic_Vbe) - (Rk + Ck), 0, -(Ib_Vbc + Ic_Vbc), (Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc),
     110        8944 :         0, Ro + Co, Ro, 0,
     111        8944 :         -Ic_Vbe, Ro, -Ic_Vbc + Ro + Rp, (Ic_Vbe + Ic_Vbc),
     112       17888 :         -Ib_Vbe, 0, -Ib_Vbc, (Ib_Vbc + Ib_Vbe) + Rg2 + Rg1 + Cg;
     113             : 
     114       17888 :       return M.inverse() * F;
     115             :     }
     116             : 
     117             :   };
     118             : 
     119             :   template <typename DataType_>
     120             :   class TransistorClassAInitialFunction
     121             :   {
     122             :     const DataType_ Rp;
     123             :     const DataType_ Rg1;
     124             :     const DataType_ Rg2;
     125             :     const DataType_ Ro;
     126             :     const DataType_ Rk;
     127             :     const DataType_ Vbias;
     128             : 
     129             :     TransistorFunction<DataType_>& transistor_function;
     130             :   public:
     131             :     using DataType = DataType_;
     132             :     using Vector = Eigen::Matrix<DataType, 3, 1>;
     133             :     using Matrix = Eigen::Matrix<DataType, 3, 3>;
     134             : 
     135           1 :     TransistorClassAInitialFunction(DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType Vbias, TransistorFunction<DataType_>& transistor_function)
     136           1 :       :Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), Vbias(Vbias), transistor_function(transistor_function)
     137             :     {
     138           1 :     }
     139             : 
     140           9 :     Vector operator()(const Vector& y1)
     141             :     {
     142           9 :       std::pair<DataType, DataType> exp_y1 = std::make_pair(fmath::exp((y1(2) - y1(1)) / transistor_function.Vt), fmath::exp((y1(2) - y1(0)) / transistor_function.Vt));
     143             : 
     144           9 :       auto Ib = transistor_function.Lb(exp_y1);
     145           9 :       auto Ic = transistor_function.Lc(exp_y1);
     146             : 
     147           9 :       auto Ib_Vbe = transistor_function.Lb_Vbe(exp_y1);
     148           9 :       auto Ib_Vbc = transistor_function.Lb_Vbc(exp_y1);
     149             : 
     150           9 :       auto Ic_Vbe = transistor_function.Lc_Vbe(exp_y1);
     151           9 :       auto Ic_Vbc = transistor_function.Lc_Vbc(exp_y1);
     152             : 
     153           9 :       auto R = 1 / (1 / Rg1 + 1 / Rg2);
     154           9 :       Vector F(y1(0) - Vbias + Ic * Rp,
     155           9 :         y1(1) - (Ib + Ic) * Rk,
     156           9 :         Ib * R + y1(2) - Vbias / Rg1 * R);
     157             : 
     158           9 :       Matrix M;
     159          18 :       M << 1 - Ic_Vbc * Rp, -Ic_Vbe * Rp, (Ic_Vbe + Ic_Vbc) * Rp,
     160           9 :         (Ib_Vbc + Ic_Vbc) * Rk, 1 + (Ib_Vbc + Ic_Vbc) * Rk, -(Ib_Vbe + Ic_Vbe + Ib_Vbc + Ic_Vbc) * Rk,
     161          18 :         -Ib_Vbc * R, -Ib_Vbe * R, 1 + (Ib_Vbe + Ib_Vbc) * R;
     162             : 
     163          18 :       return M.inverse() * F;
     164             :     }
     165             :   };
     166             : 
     167             :   template <typename DataType>
     168           1 :   TransistorClassAFilter<DataType>::TransistorClassAFilter(DataType Rp, DataType Rg1, DataType Rg2, DataType Ro, DataType Rk, DataType Vbias, DataType Cg, DataType Co, DataType Ck, TransistorFunction<DataType>&& transistor_function)
     169           1 :     :Parent(1, 5), Rp(Rp), Rg1(Rg1), Rg2(Rg2), Ro(Ro), Rk(Rk), Vbias(Vbias), Cg(Cg), Co(Co), Ck(Ck), transistor_function(std::move(transistor_function))
     170             :   {
     171           1 :     input_delay = output_delay = 1;
     172           1 :   }
     173             : 
     174             :   template <typename DataType>
     175           0 :   TransistorClassAFilter<DataType>::TransistorClassAFilter(TransistorClassAFilter&& other)
     176           0 :     :Parent(std::move(other)), Rp(other.Rp), Rg1(other.Rg1), Rg2(other.Rg2), Ro(other.Ro), Rk(other.Rk), Vbias(other.Vbias), Cg(other.Cg), Co(other.Co), Ck(other.Ck), transistor_function(std::move(other.transistor_function))
     177             :   {
     178           0 :   }
     179             : 
     180             :   template <typename DataType>
     181           1 :   TransistorClassAFilter<DataType>::~TransistorClassAFilter()
     182             :   {
     183           1 :   }
     184             : 
     185             :   template<typename DataType_>
     186           1 :   void TransistorClassAFilter<DataType_>::setup()
     187             :   {
     188           1 :     Parent::setup();
     189           1 :     optimizer = std::make_unique<VectorizedNewtonRaphson<TransistorClassAFunction, 4, nb_max_iter, true>>(TransistorClassAFunction(static_cast<DataType>(1. / input_sampling_rate),
     190           1 :       Rp, Rg1, Rg2, Ro, Rk, //R
     191           1 :       Vbias, // Vbias
     192           1 :       Cg, Co, Ck, // C
     193           1 :       transistor_function, // transistor
     194           1 :       default_output));
     195           1 :   }
     196             : 
     197             :   template<typename DataType_>
     198           1 :   void TransistorClassAFilter<DataType_>::full_setup()
     199             :   {
     200           1 :     Eigen::Matrix<DataType, 3, 1> y0;
     201           1 :     y0 << Vbias, 0, 0;//VBias * Rg2 / Rg1;
     202             : 
     203             :                       // setup default_output
     204           1 :     SimplifiedVectorizedNewtonRaphson<TransistorClassAInitialFunction<DataType_>, 3, 10> custom(TransistorClassAInitialFunction<DataType_>(
     205           1 :       Rp, Rg1, Rg2, Ro, Rk, //R
     206           1 :       Vbias, // VBias
     207           1 :       transistor_function // transistor
     208           1 :       ), std::move(y0));
     209             : 
     210           1 :     auto stable = custom.optimize();
     211             : 
     212           1 :     default_output[0] = 0;
     213           1 :     default_output[1] = stable(1);
     214           1 :     default_output[2] = -stable(0);
     215           1 :     default_output[3] = stable(0);
     216           1 :     default_output[4] = stable(2);
     217             : 
     218           1 :     Parent::full_setup();
     219           1 :   }
     220             : 
     221             :   template<typename DataType_>
     222           1 :   void TransistorClassAFilter<DataType_>::process_impl(gsl::index size) const
     223             :   {
     224           1 :     assert(input_sampling_rate == output_sampling_rate);
     225             : 
     226        4801 :     for (gsl::index i = 0; i < size; ++i)
     227             :     {
     228        4800 :       optimizer->optimize(i, converted_inputs.data(), outputs.data() + 1);
     229        4800 :       outputs[0][i] = outputs[2][i] + outputs[3][i];
     230        4800 :       optimizer->get_function().update_state(i, converted_inputs.data(), outputs.data());
     231             :     }
     232           1 :   }
     233             : 
     234             :   template<typename DataType_>
     235           1 :   TransistorClassAFilter<DataType_> TransistorClassAFilter<DataType_>::build_standard_filter(DataType_ Rp, DataType_ Rg1, DataType_ Rg2, DataType_ Ro,
     236             :     DataType_ Rk, DataType_ Vbias, DataType_ Cg, DataType_ Co, DataType_ Ck, TransistorFunction<DataType_> function)
     237             :   {
     238             :     return TransistorClassAFilter<DataType_>(Rp, Rg1, Rg2, Ro, Rk, Vbias, Cg, Co, Ck,
     239           1 :       std::move(function) // transistor
     240           1 :       );
     241             :   }
     242             : 
     243             : #if ATK_ENABLE_INSTANTIATION
     244             :   template class TransistorClassAFilter<float>;
     245             : #endif
     246             :   template class TransistorClassAFilter<double>;
     247             : }

Generated by: LCOV version TK-3.3.0-4-gdba42eea