11 constexpr AD::DiffVar<double, 2>
x(1, 1, 0);
12 constexpr AD::DiffVar<double, 2> y(2, 0, 1);
14 constexpr
auto f =
x * y;
17 auto tanh = AD::tanh(1 + 2 *
x);
19 std::cout <<
"f\n" << f << std::endl;
20 std::cout <<
"sin\n" <<
sin << std::endl;
21 std::cout <<
"sin2\n" << sin2 << std::endl;
22 std::cout <<
"tanh2\n" << tanh << std::endl;
42 constexpr T alpha_f = 0.99;
43 constexpr T alpha_r = 0.02;
45 constexpr T I_es = 2e-14;
46 constexpr T V_Te = 26e-3;
47 constexpr T I_cs = 99e-14;
48 constexpr T V_Tc = 26e-3;
50 T control_v_be = base_v_be;
51 T control_v_bc = base_v_bc;
53 T control_i_e = -I_es * (std::exp(control_v_be / V_Te) - 1) +
54 alpha_r * I_cs * (std::exp(control_v_bc / V_Tc) - 1);
55 T control_i_c = alpha_f * I_es * (std::exp(control_v_be / V_Te) - 1) -
56 I_cs * (std::exp(control_v_bc / V_Tc) - 1);
58 T control_g_ee = (I_es / V_Te) * std::exp(control_v_be / V_Te);
59 T control_g_ec = alpha_r * (I_cs / V_Tc) * std::exp(control_v_bc / V_Tc);
60 T control_g_ce = alpha_f * (I_es / V_Te) * std::exp(control_v_be / V_Te);
61 T control_g_cc = (I_cs / V_Tc) * std::exp(control_v_bc / V_Tc);
63 T control_I_e = control_i_e + control_g_ee * control_v_be -
64 control_g_ec * control_v_bc;
65 T control_I_c = control_i_c - control_g_ce * control_v_be +
66 control_g_cc * control_v_bc;
68 results.
g_ee = control_g_ee;
69 results.
g_ec = control_g_ec;
70 results.
g_ce = control_g_ce;
71 results.
g_cc = control_g_cc;
73 results.
I_e = control_I_e;
74 results.
I_c = control_I_c;
82 constexpr T alpha_f = 0.99;
83 constexpr T alpha_r = 0.02;
85 constexpr T I_es = 2e-14;
86 constexpr T V_Te = 26e-3;
87 constexpr T I_cs = 99e-14;
88 constexpr T V_Tc = 26e-3;
89 using ADT = AD::DiffVar<T, 2>;
91 ADT ad_v_be = ADT(base_v_be, 1, 0);
92 ADT ad_v_bc = ADT(base_v_bc, 0, 1);
94 ADT ad_i_e = -I_es * (AD::exp(ad_v_be / V_Te) - 1) +
95 alpha_r * I_cs * (AD::exp(ad_v_bc / V_Tc) - 1);
96 ADT ad_i_c = alpha_f * I_es * (AD::exp(ad_v_be / V_Te) - 1) -
97 I_cs * (AD::exp(ad_v_bc / V_Tc) - 1);
100 T ad_g_ee = -ad_i_e[1];
101 T ad_g_ec = ad_i_e[2];
102 T ad_g_ce = ad_i_c[1];
103 T ad_g_cc = -ad_i_c[2];
105 T ad_I_e = ad_i_e[0] + ad_g_ee * ad_v_be[0] - ad_g_ec * ad_v_bc[0];
106 T ad_I_c = ad_i_c[0] - ad_g_ce * ad_v_be[0] + ad_g_cc * ad_v_bc[0];
108 results.
g_ee = ad_g_ee;
109 results.
g_ec = ad_g_ec;
110 results.
g_ce = ad_g_ce;
111 results.
g_cc = ad_g_cc;
113 results.
I_e = ad_I_e;
114 results.
I_c = ad_I_c;
118 [[clang::optnone]]
void
121 constexpr T I_es = 2e-14;
122 constexpr T V_Te = 26e-3;
123 constexpr T I_cs = 99e-14;
124 constexpr T V_Tc = 26e-3;
129 T V_bc_crit = V_Tc * std::log(V_Tc / (I_cs * std::sqrt(2)));
130 T V_be_crit = V_Te * std::log(V_Te / (I_es * std::sqrt(2)));
132 std::array<T, 6> base_v_be_vec = {0, 1, 2, 3, 4, 5};
133 std::array<T, 6> base_v_bc_vec = {0, 1, 2, 3, 4, 5};
136 size_t controlAccumulate = 0;
137 size_t autoDiffAccumulate = 0;
139 for (
auto base_v_be : base_v_be_vec) {
140 for (
auto base_v_bc : base_v_bc_vec) {
141 std::cout <<
"base_v_be=" << std::setw(10) << base_v_be
142 <<
", base_v_bc=" << std::setw(10) << base_v_bc << std::endl;
144 base_v_be = std::min(V_be_crit, base_v_be);
145 base_v_bc = std::min(V_bc_crit, base_v_bc);
147 auto startTime = std::chrono::high_resolution_clock::now();
148 for (
size_t i = 0;
i < 10000;
i++) {
151 auto endTime = std::chrono::high_resolution_clock::now();
152 auto timeTaken = std::chrono::duration_cast<std::chrono::microseconds>(
155 controlAccumulate += timeTaken;
157 std::cout << std::setw(15) << timeTaken <<
" us | ";
159 startTime = std::chrono::high_resolution_clock::now();
160 for (
size_t i = 0;
i < 10000;
i++) {
163 endTime = std::chrono::high_resolution_clock::now();
164 timeTaken = std::chrono::duration_cast<std::chrono::microseconds>(
167 autoDiffAccumulate += timeTaken;
169 std::cout << std::setw(15) << timeTaken <<
" us" << std::endl;
173 std::cout <<
"g_ee | control=" << std::setw(15) << controlResults.
g_ee
174 <<
" | autoDiff=" << std::setw(15) << autoDiffResults.
g_ee
176 std::cout <<
"g_ec | control=" << std::setw(15) << controlResults.
g_ec
177 <<
" | autoDiff=" << std::setw(15) << autoDiffResults.
g_ec
179 std::cout <<
"g_ce | control=" << std::setw(15) << controlResults.
g_ce
180 <<
" | autoDiff=" << std::setw(15) << autoDiffResults.
g_ce
182 std::cout <<
"g_cc | control=" << std::setw(15) << controlResults.
g_cc
183 <<
" | autoDiff=" << std::setw(15) << autoDiffResults.
g_cc
186 std::cout <<
"I_e | control=" << std::setw(15) << controlResults.
I_e
187 <<
" | autoDiff=" << std::setw(15) << autoDiffResults.
I_e
189 std::cout <<
"I_c | control=" << std::setw(15) << controlResults.
I_c
190 <<
" | autoDiff=" << std::setw(15) << autoDiffResults.
I_c
193 assert(
std::abs(controlResults.
I_e - autoDiffResults.
I_e) < 1e-12);
194 assert(
std::abs(controlResults.
I_c - autoDiffResults.
I_c) < 1e-12);
198 std::cout << std::setw(15) << controlAccumulate <<
" us | ";
199 std::cout << std::setw(15) << autoDiffAccumulate <<
" us" << std::endl;
212 constexpr T alpha = 1.3;
213 constexpr T beta0 = 0.42;
214 constexpr T gamma = 0.0005;
215 constexpr T delta = 0.3;
216 constexpr T xi = 0.06;
217 constexpr T lambda = 1.5;
218 constexpr T mu = 0.0;
219 constexpr T zeta = 0.18;
220 constexpr T Vto = -2.4;
226 auto Vgst = V_gs - (1 + beta * beta) * Vto + gamma * V_ds;
227 auto Veff = 0.5 * (Vgst + std::pow(std::pow(Vgst, 2) + delta * delta, 0.5));
228 auto power = lambda / (1 + mu * std::pow(V_ds, 2) + xi * Veff);
229 auto area = alpha * V_ds * (1 + zeta * Veff);
230 auto f1 = std::tanh(area);
231 auto Ids_lim = beta * std::pow(Veff, power);
232 auto Idrain = Ids_lim *
f1;
235 auto dVeff_dVgs = 0.5 * (1 + Vgst * std::pow(Vgst * Vgst + delta * delta, -0.5));
236 auto dpower_dVgs = -lambda * xi * dVeff_dVgs * std::pow(power / lambda, 2);
237 auto df_dVgs = std::pow(1 / cosh(area), 2) * alpha * V_ds * zeta * dVeff_dVgs;
238 toRet.diff1 = Idrain *
239 (power * (dVeff_dVgs / Veff) + std::log(Veff) * dpower_dVgs) +
242 auto dVeff_dVds = 0.5 * (gamma + std::pow(Vgst * Vgst + delta * delta, -0.5) *
244 auto dpower_dVds = -lambda * (2 * mu * V_ds + xi * dVeff_dVds) *
245 std::pow(power / lambda, 2);
246 auto df_dVds = std::pow(1 / cosh(area), 2) * alpha *
247 (1 + zeta * (V_ds * dVeff_dVds + Veff));
248 toRet.diff2 = Idrain *
249 (power * (dVeff_dVds / Veff) + std::log(Veff) * dpower_dVds) +
256 constexpr T alpha = 1.3;
257 constexpr T beta0 = 0.42;
258 constexpr T gamma = 0.0005;
259 constexpr T delta = 0.3;
260 constexpr T xi = 0.06;
261 constexpr T lambda = 1.5;
262 constexpr T mu = 0.0;
263 constexpr T zeta = 0.18;
264 constexpr T Vto = -2.4;
266 using ADT = AD::DiffVar<T, 2>;
267 ADT V_gs(V_gs_in, 1, 0);
268 ADT V_ds(V_ds_in, 0, 1);
271 auto Vgst = V_gs - (1 + beta * beta) * Vto + gamma * V_ds;
272 auto Veff = 0.5 * (Vgst + AD::sqrt(AD::pow(Vgst, 2) + delta * delta));
273 auto power = lambda / (1 + mu * AD::pow(V_ds, 2) + xi * Veff);
274 auto area = alpha * V_ds * (1 + zeta * Veff);
275 auto f1 = AD::tanh(area);
276 auto Ids_lim = beta * AD::pow(Veff, power);
281 [[clang::optnone]]
void
283 using ADT = AD::DiffVar<T, 2>;
284 std::vector<T> V_gs_in_vec = {0, 1, 2, 3};
285 std::vector<T> V_ds_in_vec = {0, 1, 2, 3};
286 size_t controlAccumulate = 0;
287 size_t autoDiffAccumulate = 0;
288 for (
auto V_gs_in : V_gs_in_vec) {
289 for (
auto V_ds_in : V_gs_in_vec) {
290 ADT autoDiffResult(0);
292 auto startTime = std::chrono::high_resolution_clock::now();
293 for (
size_t i = 0;
i < 10000;
i++) {
296 auto endTime = std::chrono::high_resolution_clock::now();
297 auto timeTaken = std::chrono::duration_cast<std::chrono::microseconds>(
300 autoDiffAccumulate += timeTaken;
301 std::cout << std::setw(15) << timeTaken <<
" us | ";
303 startTime = std::chrono::high_resolution_clock::now();
304 for (
size_t i = 0;
i < 10000;
i++) {
307 endTime = std::chrono::high_resolution_clock::now();
308 timeTaken = std::chrono::duration_cast<std::chrono::microseconds>(
311 controlAccumulate += timeTaken;
312 std::cout << std::setw(15) << timeTaken <<
" us" << std::endl;
314 std::cout <<
"V_gs: " << V_gs_in <<
" V_ds: " << V_ds_in <<
" "
316 std::cout << std::setw(15) <<
res.var <<
" ";
317 std::cout << std::setw(15) <<
res.diff1 <<
" ";
318 std::cout << std::setw(15) <<
res.diff2 << std::endl;
319 std::cout << std::setw(15) << autoDiffResult[0] <<
" ";
320 std::cout << std::setw(15) << autoDiffResult[1] <<
" ";
321 std::cout << std::setw(15) << autoDiffResult[2] << std::endl
323 assert(
std::abs(
res.var - autoDiffResult[0]) < 1e-12);
324 assert(
std::abs(
res.diff1 - autoDiffResult[1]) < 1e-12);
325 assert(
std::abs(
res.diff2 - autoDiffResult[2]) < 1e-12);
328 std::cout << std::setw(15) << autoDiffAccumulate <<
" us | ";
329 std::cout << std::setw(15) << controlAccumulate <<
" us" << std::endl;
333 main(
int argc,
char * argv[]) {
336 testBJTModel<double>();
338 transistorTest<double>();
int main(int argc, char *argv[])
void testBasicOutput_NoCheck()
void testBJTModelAutoDiff(const T &base_v_be, const T &base_v_bc, BJTResults< T > &results)
void testBJTModelControl(const T &base_v_be, const T &base_v_bc, BJTResults< T > &results)
void transistorTestAudoDiff(T V_gs_in, T V_ds_in, AD::DiffVar< T, 2 > &toRet)
void transistorTestControl(T V_gs_in, T V_ds_in, TransistorTestResult< T > &toRet)
Extract these output variables res
Obtain iteration resiudes for model x
end if abs(real(dotprod))>rstoerst rstoerst
a namespace to hold the messiness of my auto-differentiator