パラメータの作成は,たとえば次のようにします.
> t12AU7 <- list(G=0.0005533071, muc=13.08962, alpha=0.584886, Ego=0.8900572, + Cgp=1.5e-12, Ci=1.6e-12, Co=0.4e-12) # リストの作成 > t12AU7 # リストの表示 $G [1] 0.0005533071 $muc [1] 13.08962 $alpha [1] 0.584886 ...Cgp 等は,モデルのパラメータではありませんが, RのデータからSPICEのプログラムを生成する際に使用します.
これから,プレート電流,相互コンダクタンス,内部抵抗,増幅率を 求める関数を作成していきますが, すべての関数でパラメータを第1の引数に指定します. 第2の引数にはプレート電圧 Ep を, 第3の引数にはグリッド電圧 Eg を指定します. 五極管の場合は,第4の引数にスクリーングリッド電圧 Eg2 を指定します. プレート電圧とグリッド電圧にはベクトルを指定でき, 一回の関数呼び出しで複数の点の特性を同時に求めることができるようにします.
1 "Ip" <- 2 function(p, Ep, Eg) 3 { 4 # 三極管のプレート電流を返す 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 9 Ip.sub(p, Ep, Eg)$ip 10 } 11 12 "Ip.sub" <- 13 function(p, Ep, Eg) 14 { 15 # 三極管のプレート電流、グリッド電流等を返す 16 # p: パラメータ 17 # Ep: プレート電圧 18 # Eg: グリッド電圧 19 # 返値 20 # $ip: プレート電流 21 # $ig: グリッド電流 22 # $mum: 最大の mu 23 # $Egg: 実効グリッド電圧 24 25 Egg <- Eg + p$Ego # (B.23) 26 Ep <- pmax(Ep, 0) 27 ik <- 0 * Ep # カソード電流 28 ig <- 0 * Ep # (Ep >> Eg のときの)グリッド電流 29 a <- if (p$alpha == 1) Inf else 1/(1 - p$alpha) # (B.24) 30 b <- 1.5 - a # (B.25) 31 c <- 3 * p$alpha - 1 # (B.26) 32 G.p <- p$G * (c * a / 3)^b # (B.27) 33 mum <- a / 1.5 * p$muc # (B.6) 34 35 # グリッド電流のパラメータが存在しない場合は推定値を用いる 36 G.lim <- if (is.null(p$G.lim)) G.p * (1 + 1/mum)^1.5 else p$G.lim # (B.21) 37 Ig.ratio <- if (is.null(p$Ig.ratio)) 0.5/(1 + 1/mum)^1.5 else p$Ig.ratio # (B.20) 38 39 # カソード電流 40 gm <- Egg <= 0 # Egg が負の場合 41 estm <- pmax(Egg + Ep/p$muc, 0) 42 ik[gm] <- p$G * (ifelse(Ep == 0, 0, (c / 2 / p$muc * Ep)^b) * 43 (1.5 / a * estm)^a)[gm] # (B.28) 44 45 gp <- Egg > 0 # Egg が正の場合 46 estp <- pmax(Egg + Ep/mum, 0) 47 ik[gp] <- (G.p * estp^1.5)[gp] # (B.28) 48 49 # グリッド電流 50 Eg <- pmax(Eg, 0) 51 ig <- Ig.ratio * G.lim * Eg^1.5 * (Eg / ifelse(Eg > 0, (Ep + Eg), 1) * 1.2 + 0.4) # (B.29) 52 53 # プレート電流の上限 54 iplim <- (1 - Ig.ratio) * G.lim * Ep^1.5 # (B.30) 55 # プレート電流 56 ip <- pmax(pmin(ik - ig, iplim), 0) # (B.31) 57 58 list(ip=ip, ig=ig, mum=mum, Egg=Egg) 59 }プレート電流は,他の特性を求める時にも使用します. その際に,途中で求めた結果も利用するので, そのための関数を Ip.sub とします. Ip は Ip.sub の結果から,成分 ip を取り出して返します.
1 "Ig" <- 2 function(p, Ep, Eg) 3 { 4 # 三極管のグリッド電流を返す 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 9 Ip.sub(p, Ep, Eg)$ig 10 }Ip.sub で計算したグリッド電流の値を抜き出して返します.
1 "gm" <- 2 function(p, Ep, Eg) 3 { 4 # 三極管の相互コンダクタンスを求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 9 i <- Ip.sub(p, Ep, Eg) 10 ifelse(i$ip <= 0, NA, 11 ifelse(i$Egg <= 0, i$ip / (1 - p$alpha) / (i$Egg + Ep/p$muc), 12 i$ip * 1.5 / (i$Egg + Ep/i$mum))) 13 }プレート電流が0のときは,相互コンダクタンスは定義されないので, NA を返します. それ以外はモデルの式をそのままインプリメントしています. プレート電流が飽和電流で制限される領域では,正しい答えを返していませんが, そのような領域の gm を求めても無意味なので, そのままにしてあります. これらの特徴は,以下の関数にもあてはまります.
1 "rp" <- 2 function(p, Ep, Eg) 3 { 4 # 三極管のプレート抵抗を求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 9 i <- Ip.sub(p, Ep, Eg) 10 ifelse(i$ip <= 0, NA, 11 ifelse(i$Egg <= 0, (1-p$alpha) / 12 ((1-3*p$alpha)/2/Ep + 1/p$muc/(i$Egg + Ep/p$muc)) / i$ip, 13 (i$mum * i$Egg + Ep)/(1.5 * i$ip))) 14 }
1 "mu" <- 2 function(p, Ep, Eg) 3 { 4 # 三極管の増幅率を求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 9 i <- Ip.sub(p, Ep, Eg) 10 ifelse(i$ip <= 0, NA, 11 ifelse(i$Egg <= 0, 1/((3-3*p$alpha)/2/p$muc + (1-3*p$alpha)/2 * i$Egg/Ep), i$mum)) 12 }
1 "Ipp" <- 2 function (p, Ep, Eg, Eg2) 3 { 4 # 五極管のスクリーングリッド電流を返す 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 10 Ipp.sub(p, Ep, Eg, Eg2)$ip 11 } 12 13 "Ipp.sub" <- 14 function(p, Ep, Eg, Eg2) 15 { 16 # 五極管のプレート電流を返す 17 # p: パラメータ 18 # Ep: プレート電圧 19 # Eg: グリッド電圧 20 # Eg2: スクリーングリッド電圧 21 # 返値 22 # $ip: プレート電流 23 # $ig: グリッド電流 24 # $ig2: スクリーングリッド電流 25 26 # プレート電圧のベクトルの長さと 27 # スクリーングリッド電圧のベクトルの長さを揃える 28 Eg2 <- Eg2 + 0*Ep 29 Ep <- Ep + 0*Eg2 30 31 Egg <- Eg + p$Ego # (B.23) 32 Ep <- pmax(Ep, 0) 33 ik <- 0 * Ep # カソード電流格納領域 34 ig <- 0 * Ep # グリッド電流格納領域 35 a <- 1/(1 - p$alpha) # (B.24) 36 b <- 1.5 - a # (B.25) 37 c <- 3 * p$alpha - 1 # (B.26) 38 G.p <- p$G * (c * a / 3)^b # (B.27) 39 mum <- a / 1.5 * p$muc # (B.6) 40 41 # グリッド電流のパラメータが存在しない場合は推定値を用いる 42 Ig.ratio <- if (is.null(p$Ig.ratio)) 0.5/(1 + 1/mum)^1.5 else p$Ig.ratio # (B.20) 43 G.lim <- if (is.null(p$G.lim)) G.p * (1 + 1/mum)^1.5 else p$G.lim # (B.21) 44 45 # カソード電流 46 gm <- Egg <= 0 # Egg が負の場合 47 estm <- pmax(Egg + Eg2/p$muc, 0) 48 ik[gm] <- p$G * (ifelse(Eg2 == 0, 0, (c / 2 / p$muc * Eg2)^b) * 49 (1.5 / a * estm)^a)[gm] # (B.32) 50 51 gp <- Egg > 0 # Egg が正の場合 52 estp <- pmax(Egg + Eg2/mum, 0) 53 ik[gp] <- (G.p * estp^1.5)[gp] # (B.32) 54 55 # グリッド電流 56 Eg <- pmax(Eg, 0) 57 ig <- Ig.ratio * G.lim * Eg^1.5 * (Eg / ifelse(Eg > 0, (Ep + Eg), 1) * 1.2 + 0.4) # (B.33) 58 59 # 第2グリッド電圧よりプレート電圧が低い場合のカソード電流の減少 60 f <- 1 - 0.4 * (exp(-Ep/Eg2*15)-exp(-15)) # (B.34) 61 ik2 <- f * (ik - ig) # (B.37) 62 63 # スクリーングリッド電流の分配比率 64 g <- (1 - p$g2.r) * (1 - Ep/(Ep+10))^1.5 + p$g2.r # (B.38) 65 ig2.th <- g * ik2 # (B.39) 66 67 # プレート抵抗を加味したカソード電流 68 h <- (Ep - p$Ea) / (Eg2 - p$Ea) # (B.42) 69 ik3 <- h * ik2 # (B.43) 70 # カソードエミッションの制限 71 iklim <- (1 - Ig.ratio) * G.lim * pmax(Ep, Eg2)^1.5 # (B.46) 72 ik4 <- pmin(ik3, iklim) # (B.47) 73 74 # プレート電流の制限 75 iplim <- (1 - Ig.ratio) * G.lim * Ep^1.5 # (B.30) 76 # プレート電流 77 ip <- pmax(pmin(ik4 - ig2.th, iplim), 0) # (B.48) 78 # スクリーングリッド電流 79 ig2 <- pmax(ik4 - ip, 0) # (B.49) 80 81 list(ip=ip, ig=ig, ig2=ig2, ik=ik4, 82 mum=mum, Egg=Egg, a=a, b=b, c=c, f=f, g=g, h=h) 83 }
1 "Igp" <- 2 function(p, Ep, Eg, Eg2) 3 { 4 # 五極管のグリッド電流を返す 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 10 Ipp.sub(p, Ep, Eg, Eg2)$ig 11 }
1 "Ig2" <- 2 function (p, Ep, Eg, Eg2) 3 { 4 # 五極管のスクリーングリッド電流を返す 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 10 Ipp.sub(p, Ep, Eg, Eg2)$ig2 11 }
1 "gmp" <- 2 function(p, Ep, Eg, Eg2) 3 { 4 # 五極管の相互コンダクタンスを求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 10 i <- Ipp.sub(p, Ep, Eg, Eg2) 11 ifelse(i$ip <= 0, NA, 12 ifelse(i$Egg <= 0, i$ip * i$a / (i$Egg + Eg2/p$muc), 13 i$ip * 1.5 / (i$Egg + Eg2/i$mum))) 14 }
1 "rpp" <- 2 function(p, Ep, Eg, Eg2) 3 { 4 # 五極管プレート抵抗を求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 10 i <- Ipp.sub(p, Ep, Eg, Eg2) 11 df <- 6 / Eg2 * exp(-15*Ep/Eg2) 12 dg <- -15 * (1 - p$g2.r) * (1 - Ep/(Ep + 10))^0.5 / (Ep^2 + 20*Ep + 100) 13 dh <- 1/(Eg2 - p$Ea) 14 ifelse(i$ip <= 0, NA, 1/(i$ip * (df/i$f + (dh - dg)/(i$h - i$g)))) 15 }
1 "mup" <- 2 function(p, Ep, Eg, Eg2) 3 { 4 # 五極管の増幅率を求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 10 i <- Ipp.sub(p, Ep, Eg, Eg2) 11 df <- 6/Eg2*exp(-15*Ep/Eg2) 12 dg <- -15 * (1 - p$g2.r) * (1 - Ep/(Ep + 10))^0.5 / (Ep^2 + 20*Ep + 100) 13 dh <- 1/(Eg2 - p$Ea) 14 ifelse(i$ip <= 0, NA, 15 ifelse(i$Egg <= 0, i$a / (i$Egg + Eg2/p$muc), 16 1.5 / (i$Egg + Eg2/i$mum)) / (df/i$f + (dh - dg)/(i$h - i$g))) 17 }
1 "rg2" <- 2 function(p, Ep, Eg, Eg2) 3 { 4 # 五極管のスクリーングリッド内部抵抗を求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 10 i <- Ipp.sub(p, Ep, Eg, Eg2) 11 df <- -6 * Ep / Eg2^2 * exp(-15*Ep/Eg2) 12 ifelse(i$ig2 <= 0, NA, 13 1 / (i$ig2 * (df/i$f + i$b / Eg2 + i$a / (p$muc * i$Egg + Eg2)))) 14 }
1 "mug12" <- 2 function(p, Ep, Eg, Eg2) 3 { 4 # g1-g2増幅率を求める 5 # p: パラメータ 6 # Ep: プレート電圧 7 # Eg: グリッド電圧 8 # Eg2: スクリーングリッド電圧 9 # 返値 10 # [1]: プレート電流が一定の g1-g2 増幅率 11 # [2]: スクリーングリッド電流が一定の g1-g2 増幅率 12 13 i <- Ipp.sub(p, Ep, Eg, Eg2) 14 df <- -6 * Ep/Eg2^2 * exp(-15*Ep/Eg2) 15 dg <- -15 * (1 - p$g2.r) * (1 - Ep/(Ep + 10))^0.5 / (Ep^2 + 20*Ep + 100) 16 dh <- -(Ep - p$Ea) / (Eg2 - p$Ea)^2 17 u <- i$a / (i$Egg + Eg2/p$muc) 18 l <- df/i$f + dh/(i$h - i$g) + i$b/Eg2 + i$a/(p$muc * i$Egg + Eg2) 19 m <- ifelse(i$ig2 <= 0, NA, ifelse(i$Egg <= 0, u / l, NA)) 20 m2 <- gmg2(p, Ep, Eg, Eg2)[1] * rg2(p, Ep, Eg, Eg2)[1] 21 c(m, m2) 22 }μg1-g2 は,定義によって2種類あります. プレート電流を一定とした場合の増幅率が第一の要素として, スクリーングリッド電流を一定とした場合の増幅率が第二の要素として返されます.