% lcfilter.mの後半。前半の後ろに挿入し、UTF-8でテキストファイルとして拡張子.mで保存してください。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% フィルタ設計
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i = sqrt(-1);
if !(type == 4)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Butterworth, Chebyshev and Besselフィルタ設計
% 以下で必要となる変数: powerpoly, order
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% powerpolyのs平面での根の左半分を得る
rootsofpower = roots(powerpoly);
rootsofpower = i * rootsofpower; % 90°回転させ、s平面に変換する
rootsofpowerforsort = [real(rootsofpower) rootsofpower];
rootsofpowerforsort = sortrows(rootsofpowerforsort, 1);
rootsofpower = rootsofpowerforsort(1:order, 2);
H_s = poly(rootsofpower);
H_s = real(H_s); % これがs平面での電圧伝達多項式(√電力)の分母になる
% s平面での電圧伝達多項式の共役を得る
mx = [order:-1:0];
mx = (-1 * ones(1, order+1)) .^ mx;
H_s_conj = H_s .* mx;
%--------------------------------------------------------
% 電力伝達多項式にするために、共役同士を掛け算する(もともとあった電力伝達多項式をそのまま用いないのは、もともとの式ではs平面の右側にも根がある式になっているため、実際の伝達多項式としては成立しないので、このようにする)
%--------------------------------------------------------
H_s_square = real(conv(H_s, H_s_conj));
%--------------------------------------------------------
%★★★★★★★★ ここ重要 ★★★★★★★★
%ここまでで得られた答え(H_s_square)は根から多項式を得たものになっているので、実際の電力伝達率ではない。
% そこで電力伝達率 Power_Transfer_Ratioと得られた答えの定数項(DC)を用いて、正しい電力伝達率に変換する(とくにRS ≠ RLのときに重要な考え方)
%--------------------------------------------------------
inverse_dc_att = (1/Power_Transfer_Ratio)/H_s_square(1,end);
H_s_square = H_s_square * inverse_dc_att;
% 不要な計算誤差残差を取り去る
mask = mod([length(H_s_square):-1:1],2);
H_s_square = H_s_square .* mask;
%--------------------------------------------------------
% これによりH_s_squareが、RS = RLのときの電力伝達率を基準の1Wとしたときの電力伝達多項式として得られる
%--------------------------------------------------------
else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Elliptic フィルタ設計
% 以下で必要となる変数: elpnum, elpden
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
H_s = poly(elpden);
% s平面での電圧伝達多項式(分母)の共役を得る
mx = [order:-1:0];
mx = (-1 * ones(1, order+1)) .^ mx;
H_s_conj = H_s .* mx;
H_s_square = real(conv(H_s, H_s_conj));
H_s_num = poly(elpnum);
% s平面での電圧伝達多項式(分子)の共役を得る
order_num = length(H_s_num)-1;
mx = [order_num:-1:0];
mx = (-1 * ones(1, order_num+1)) .^ mx;
H_s_num_conj = H_s_num .* mx; %奇数次項はゼロなのでやってもやらなくても同じ
H_s_num_square = real(conv(H_s_num, H_s_num_conj));
% H_s_num_squareの長さをH_s_squareにそろえる
if (length(H_s_square) == length(H_s_num_square))
vectone = [];
else
vectone = zeros(1, length(H_s_square)-length(H_s_num_square));
end
H_s_num_square = [vectone H_s_num_square];
inverse_dc_att = (1/Power_Transfer_Ratio) * H_s_num_square(1,end)/H_s_square(1,end);
H_s_square = H_s_square * inverse_dc_att;
% 不要な計算誤差残差を取り去る
mask = mod([length(H_s_square):-1:1],2);
H_s_square = H_s_square .* mask;
%--------------------------------------------------------
% H_s_num_square
% ここまでで電力伝達関数が ---------------- として得られた
% H_s_square
%--------------------------------------------------------
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 正規化された反射電力(反射係数Γの自乗)を計算する(Power_Transfer_Ratioの係数がかかっているので、実際の正規化された反射電力になっている)
% ref_sq_num 1
%Γ^2 = ----------------- = 1 - -----------------
% ref_sq_denom H_s_square
%
% Elliptic フィルタの場合
% ref_sq_num H_s_num_square
%Γ^2 = ----------------- = 1 - -----------------
% ref_sq_denom H_s_square
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if !(type == 4) % Butterworth, Chebyshev, Besselのケース
H_s_num_square = [zeros(1, length(H_s_square)-1) 1];
else % Elliptic case
H_s_num_square = H_s_num_square;
end
%Γ^2の分子を計算
ref_sq_num = H_s_square - H_s_num_square;
% 不要な計算誤差残差を取り去る
ref_sq_num = ref_sq_num .* mask;
%Γ^2の分母
ref_sq_denom = H_s_square;
%--------------------------------------------------------
%以降ではPower_Transfer_Ratioは使用していない(以降の同様の説明部分を参照のこと)
%--------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PLOT 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 電力伝達多項式を用いてプロットする
close all
if PLOT1 % 1 にした場合にプロットし、0だとプロットしない
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
s = i * logspace(-2, 3, 10001); % s = jωとする
accum_num = polyval(H_s_num_square, s);
accum_denom = polyval(H_s_square, s);
plotacccum = 10*log10(abs(accum_num)) - 10*log10(abs(accum_denom));
semilogx(abs(s), plotacccum)
xlabel('Normalized Angular Frequency')
ylabel('Transfer Level [dB]')
grid on
topofY = plotacccum(1,1);
topofY = ceil(topofY/ripple)*ripple + 3 * ripple;
botofY = topofY - 10 * ripple;
yticks([botofY:ripple:topofY]);
set(gca, 'FontSize', 18);
axis([0.01 100 botofY topofY])
figure
semilogx(abs(s), plotacccum)
xlabel('Normalized Angular Frequency')
ylabel('Transfer Level [dB]')
grid on
set(gca, 'FontSize', 18);
axis([0.01 100 -80 5])
end
%--------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PLOT 2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 反射電力多項式を用いてプロットする
if PLOT2 % 1 にした場合にプロットし、0だとプロットしない
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
s = i * logspace(-2, 3, 10001); % s = jωとする
accum_num = polyval(ref_sq_num, s);
accum_denom = polyval(ref_sq_denom, s);
figure
plotacccum = 10*log10(abs(accum_num)) - 10*log10(abs(accum_denom));
semilogx(abs(s), plotacccum)
xlabel('Normalized Angular Frequency')
ylabel('Reflection Level [dB]')
set(gca, 'FontSize', 18);
botofY = floor(plotacccum(1,1)) - 2;
axis([0.01 100 botofY 2])
grid on
end
%--------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 第2ステップ
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%--------------------------------------------------------
% ここまでで、反射電力(反射係数Γの自乗)の多項式が得られた。
%
% ref_sq_num 1
%Γ^2 = ----------------- = 1 - -----------------
% ref_sq_denom H_s_square
%
% Elliptic フィルタの場合
% ref_sq_num H_s_num_square
%Γ^2 = ----------------- = 1 - -----------------
% ref_sq_denom H_s_square
%
% このうちの分母、分子それぞれ半数の根をとる(ルートをとることとほぼ同義)ことにより、
% 実際の反射係数Γの多項式を得る
%
% reflectpolynum
% Γ = ----------------------------
% reflectpolydenom
% として計算する。
%--------------------------------------------------------
rootsofnum = roots(ref_sq_num);
rootsofnumforsort = [real(rootsofnum) rootsofnum];
rootsofnumforsort = sortrows(rootsofnumforsort, 1);
rootsofnum = rootsofnumforsort(1:order, 2); % s平面の左半分の根を得る
%=================================================
%
% 半分の根から、反射係数Γの分子多項式を計算する
reflectpolynum = real(poly(rootsofnum));
%=================================================
% 反射係数Γの分母多項式を計算する(H_sと同じになるので、そのまま代入)
reflectpolydenom = H_s;
%=================================================
% これにより反射係数Γの有利関数多項式が以下に得られる
%
% reflectpolynum
% Γ = ----------------------------
% reflectpolydenom
%
%
%★★★★★★★★ ここ重要 ★★★★★★★★
% ここで根から多項式に変換した結果では、Power_Transfer_Ratioは使用していない
%「根から多項式をつくると最上位が1になりPower_Transfer_Ratioが必要なのでは?」
% 「分母はH_sをそのまま使っているけれども、合っている?」という疑問が出てくる
% この理由は反射電力(反射係数Γの自乗)の式、ref_sq_numとref_sq_denomの最高次
% の項の係数が同じ大きさになっているため(分子が1 - H_s_squereであり、分母
% がH_s_squereで、定数項のみが引き算されるから)、Γ^2の分母分子の比と、Γ
% の分母分子の比、それぞれの比は変わらない。
% 反射係数ということで、比なので係数Power_Transfer_Ratioは関係ない。
% また分子であるref_sq_numの根から計算された反射係数分子多項式reflectpolynum
% と、reflectpolydenomであるH_sも、H_s = poly(rootsofpower)で根から計算された
% 多項式、それぞれの最高次の係数は同じになるため、全体として辻褄があう
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PLOT 3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%反射係数多項式を用いてプロットする(正しく動作しているかの確認のため)
if PLOT3 % 1 にした場合にプロットし、0だとプロットしない
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
s = i * logspace(-2, 3, 10001); % s = jωとする
accum_num = polyval(reflectpolynum, s);
accum_denom = polyval(reflectpolydenom, s);
figure
plotacccum = 20*log10(abs(accum_num)) - 20*log10(abs(accum_denom));
semilogx(abs(s), plotacccum)
xlabel('Normalized Angular Frequency')
ylabel('Reflection Level [dB]')
set(gca, 'FontSize', 18);
botofY = floor(plotacccum(1,1)) - 2;
% axis([0.01 100 botofY 2])
axis([0.01 100 -0.003 0.001])
grid on
end
%--------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ここまでの処理で得られた反射係数有利関数多項式
%
% reflectpolynum
% Γ = ----------------------------
% reflectpolydenom
%
% つづいて入力端からみたインピーダンスの有利関数多項式を
% 1 +/- reflectpolynum/reflectpolydenom
% Zin = Rs --------------------------------------
% 1 -/+ reflectpolynum/reflectpolydenom
% ただしRs = 1
% で計算し、Butterworth, Chebyshev, Besselのケースでは連分数を計算することで、
% またEllipticのケースでは別の計算方法を用いることで、それぞれの素子定数を得る
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ラダー素子定数を計算する
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if type == 4
% Ellipticの場合、ゼロ周波数を計算する
elpnum = imag(elpnum);
elpnum = sort(elpnum);
elpnum = i * elpnum(floor(order/2+1):end,1);
end
for a = [1 2]
switch(a)
case 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%1回目のループでは、入力インピーダンス有利関数多項式ケース1 (+Γ)を計算
% 1 + reflectpolynum/reflectpolydenom num
% Zin = Rs -------------------------------------- = -----
% 1 - reflectpolynum/reflectpolydenom den
% ただし Rs = 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
num = reflectpolydenom + reflectpolynum;
den = reflectpolydenom - reflectpolynum;
case 2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%2回目のループでは、入力インピーダンス有利関数多項式ケース2 (ーΓ)を計算
% 1 - reflectpolynum/reflectpolydenom num
% Zin = Rs -------------------------------------- = -----
% 1 + reflectpolynum/reflectpolydenom den
% ただし Rs = 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
num = reflectpolydenom - reflectpolynum;
den = reflectpolydenom + reflectpolynum;
end
%----------------------------------------------------
% 分子の高次のべきで係数がゼロの項を削除
num = removehead(num);
% 分母の高次のべきで係数がゼロの項を削除
den = removehead(den);
%----------------------------------------------------
if 0 % Print impedance equation or not
fprintf(char(10))
fprintf('vvvvvvvvvvvvvvvvvvvv Input impedance equation vvvvvvvvvvvvvvvvvvvv')
fprintf(char(10))
num
den
fprintf('^^^^^^^^^^^^^^^^^^^^ END ^^^^^^^^^^^^^^^^^^^^')
fprintf(char(10))
end
if (length(num) > length(den))
fprintf(char(10))
fprintf('===== Calculate T type %d th ladder for RS = 1 ohm and Omega = 1 rad/sec =====', order)
fprintf(char(10))
fprintf('Arm element is created first')
fprintf(char(10))
IsTtype = 1;
else
fprintf(char(10))
fprintf('===== Calculate PIE type %d th ladder for RS = 1 ohm and Omega = 1 rad/sec =====', order)
fprintf(char(10))
fprintf('Shunt element is created first')
fprintf(char(10))
IsTtype = 0;
temp = den; % 分母と分子を交換(逆数にする)
den = num;
num = temp;
end
if !(type == 4)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Butterworth, Chebyshev and Besselフィルタの素子定数
% Zin = num/den
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
iter = 1;
while(length(den) > 1)
[quo reminder] = deconv(num, den);
num = den; %◆分母を分子に移動
%----------------------------------------------------
% 余りのうちの高次のべきで係数がゼロの項を削除して、分母の変数に代入
reminder = removehead(reminder);
den = reminder; %◆あまり(分子)を分母に移動
%----------------------------------------------------
fprintf('Number %d element ', iter)
if (mod(iter,2) == 1)
if (IsTtype == 1)
fprintf('is Arm L element of %2.6d H',quo(1))
else
fprintf('is Shunt C element %2.6d F', quo(1))
end
else
if (IsTtype == 1)
fprintf('is Shunt C element %2.6d F', quo(1))
else
fprintf('is Arm L element %2.6d H', quo(1))
end
end
fprintf(char(10))
iter = iter + 1;
end
fprintf('Last element ')
if ((IsTtype == 1) && (mod(order,2) == 1))
fprintf ('is Arm L element of %2.6d H',num(1)/den)
fprintf(char(10))
fprintf ('and load impedance of %2.6d Ohm',num(2)/den)
else
fprintf ('is Shunt C element %2.6d F', num(1)/den)
fprintf(char(10))
fprintf ('and load conductance of %2.6d Siemence (%2.6d Ohm)',num(2)/den, den/num(2))
end
fprintf(char(10))
else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Ellipticフィルタの素子定数を計算する
% Zin = num/den
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
iter = 1;
while(length(den) > 1) %分母の次数が0次のみになるまで実行
if (mod(iter,2) == 1)
% -----------------------------------------------
% 単一素子の計算
% T型を例にしてインピーダンスで示しているが、π型の場合はアドミッタンスになるので、ZをYで読み替える
% 連分数展開でできる他のフィルタより、このEllipticのケースのほうが厄介だった
% 共振部分 Zres(Yも同じ) = sL + 1/sC = (s^2 LC + 1)/sC = (s^2 + ω^2)/(s/L)
% があるので、Z1stにs = ω_res = s_zero(ゼロ点による直列共振)を代入して計算したリアクタンス(アドミッタンス)が最初の単一素子の大きさになる
% -----------------------------------------------
% Ellipticのゼロ周波数を代入。ゼロ点であるelpnumは低い周波数から並んでいる。低い周波数から計算
if (floor(iter/2)+1 <= length(elpnum))
omega = elpnum(floor(iter/2)+1, 1);
else
omega = 1;
% 最後のエレメントを計算するときオーバになってしまうので、1を代入しておく
end
% -----------------------------------------------
% L = Z1st(s)にs = ω_res = s_zeroを代入してLを求める(ちゃんと都合よく実数部のみが残る)。
% なおπ型の場合はCが主要素子として求まる
% -----------------------------------------------
% 分子にs = s_zeroを代入して計算
Ztemp_num_calc = obtainZYvalue(num, omega);
% 分母にs = s_zeroを代入して計算
Ztemp_den_calc = obtainZYvalue(den, omega);
SingleElement = Ztemp_num_calc/(Ztemp_den_calc * omega);
% 余計な計算誤差を取り去る
SingleElement = real(SingleElement);
%単一素子SingleElementを除外した残りの共振回路から負荷を見たインピーダンス(もしくはアドミッタンス)
% Zright_remain = Z1st - s * SingleElement
tmp = conv([SingleElement 0], den);
num = num - tmp;
% -----------------------------------------------
% Zright_remain = num/den
% -----------------------------------------------
else
% -----------------------------------------------
% 共振素子の計算(ゼロ)。
% T型を例にしてインピーダンスで示しているが、π型の場合はアドミッタンスになるので、ZをYで読み替える
% 共振部分 Zres(Yも同じ) = sL + 1/sC = (s^2 LC + 1)/sC = (s^2 + ω^2)/(s/L)
% ※ 一応、π型の並列共振も示しておく。Yosc = sC + 1/sL = (s^2 LC + 1)/sL = (s^2 + ω^2)/(s/C)で、π型のアーム並列共振部はCが主要パラメータになる
%
% ここでω^2 = 1/LC。【重要】このωは伝達関数の分子のゼロ点で位置は定数として決まるが、ここのωは虚数ではなく実数
% あくまでも「ω^2 = 1/LC」であり、虚数として考えていない(あとでs = s_zeroと代入するが、そこは虚数)
% 1/Zright_remain = 1/Zres + 1/Znext となるので、1/Znext = 1/Zright_remain - 1/Zres
% Zright_remainは、(s^2 + ω^2)で直列共振するため、(s^2 + ω^2)で分母を因数分解できる。
% 残りのインピーダンスを素子形状がどうであれ、その部分をZtempとすれば、
% Zright_remain = [Ztemp(s^2 + ω^2)]と因数分解できる
%(Ztemp = Zright_remain/(s^2 + ω^2)となり、インピーダンスの分母がゼロになることで直列共振)。
% これにより
% 1/Znext = 1/Zright_remain - 1/Zres = 1/[Ztemp(s^2 + ω^2)] - (s/L)/(s^2 + ω^2)
% 両辺に(s^2 + ω^2)を掛けると
% (s^2 + ω^2)/Znext = 1/Ztemp - (s/L)となるので、
% ① Zright_remain = Ztemp(s^2 + ω^2)から、Ztemp = Zright_remain/(s^2 + ω^2)を計算し、
% sに-jω = s_zero(ω, s_zeroはすでにゼロ点で最初から求まっているので)を代入することで、0 = 1/Ztemp - (s/L)から、
% ② s = s_zero(虚数)でL = s_zero ZtempでLを求めることができる
% ③ Cはω^2 = 1/LCよりC = 1/Lω^2
%これで共振部分 Zres(Yも同じ)の定数が求まる
%
% ④ 1/Znext = 1/Zright_remain - 1/ZresでZnextを計算すればよい
% なお(s^2 + ω^2)/Znext = 1/Ztemp - (s/L)を使える。
% 右辺を変換し、逆数をとり、(s^2 + ω^2)で割れば共振部分を除外した、残りの素子部分のインピーダンスZnextを計算できる
% -----------------------------------------------
% Ellipticのゼロ周波数を代入。ゼロ点であるelpnumは低い周波数から並んでいる。さきに低い周波数から計算
omega = elpnum(round(iter/2), 1);
% -----------------------------------------------
% ステップ① Ztemp = Zright_remain/(s^2 + ω^2)を割り算で計算する(ZでもYでも同じ計算になる)。
% 実際はZright_remainの分子を(s^2 + ω^2)で割り、Ztemp_numを得る
% Zright_remain = num/den
% Ztemp = Zright_remain/(s^2 + ω^2) = Ztemp_num/den
% -----------------------------------------------
[Ztemp_num reminder] = deconv(num, [1 0 abs(omega^2)]);
% reminderに計算誤差が少し残るが使わない
% -----------------------------------------------
% ステップ② L = s x Ztemp(s = omega)でLを求める(複素数になるが、ちゃんと都合よく実数部のみが残る)。なおπ型の場合はCが主要素子として求まる
% -----------------------------------------------
% 分子にs = wを代入して計算
Ztemp_num_calc = obtainZYvalue(Ztemp_num, omega);
% 分母にs = wを代入して計算
Ztemp_den_calc = obtainZYvalue(den, omega);
PrimaryElement = omega * Ztemp_num_calc/Ztemp_den_calc;
PrimaryElement = real(PrimaryElement); %虚数部の計算誤差残差を削除
% -----------------------------------------------
% ステップ③ CをC = 1/Lω^2で計算する。なおπ型の場合はLが二次素子として求まる
% -----------------------------------------------
SecondalyElement = 1/(PrimaryElement*abs(omega^2));
% -----------------------------------------------
% ④ F = 1/Znext = 1/Zright_remain - 1/ZresでZnextを計算する
% T型を例にしてインピーダンスで示しているが、π型の場合はアドミッタンスになるので、ZをYで読み替える
% (s^2 + ω^2)/Znext = 1/Ztemp - (s/L), L = PrimaryElementを使う
% Ztemp_num
% Ztemp = ------------
% den
%
% Fnum s^2 + ω^2 den s
% F = ----- = --------- = --------- - ---
% Fden Znext Ztemp_num L
%として計算していく
% -----------------------------------------------
Fden = PrimaryElement * Ztemp_num; % F = Fnum/Fdenの分母
Fnum_1 = PrimaryElement * den; % F = Fnum/Fdenの分子第1項
Fnum_2 = conv([1 0], Ztemp_num); % F = Fnum/Fdenの分子第2項
% ベクトル計算のため、分子1項、2項の多項式ベクトルの長さをそろえる
len_Fnum_1 = length(Fnum_1);
len_Fnum_2 = length(Fnum_2);
if len_Fnum_1 > len_Fnum_2
Fnum_2 = [zeros(1,(len_Fnum_1 - len_Fnum_2)) Fnum_2];
else
if len_Fnum_1 < len_Fnum_2
Fnum_1 = [zeros(1,(len_Fnum_2 - len_Fnum_1)) Fnum_1];
end
end
Fnum = Fnum_1 - Fnum_2;
% -----------------------------
% s^2 + ω^2 Fnum
% --------- = F = -----
% Znext Fden
% が得られた
% Znext = (s^2 + ω^2)Fden/Fnum
% を計算する
% -----------------------------
num = conv(Fden, [1 0 abs(omega^2)]);
den = Fnum;
% -----------------------------
% den
% Znext = -----
% num
% が得られた
DC_impedance = num(1,end)/den(1,end);
% 因数分解して分母分子で共通になる項を取り去る
% 分子多項式の方が次数が高い
rootsofnum = roots(num);
rootsofden = roots(den);
rootsofnum_remain = rootsofnum;
rootsofden_remain = rootsofden;
% 分子の根と分母の根が同じな場合、その分母の根をゼロにする
% とりあえず誤差(差異)を0.01%とした。多項式が高次になるほど誤差が増える。11次ではだいぶ合わない
for p = 1:length(rootsofnum)
for q = 1:length(rootsofden)
if abs(rootsofnum(p) - rootsofden(q)) < 1e-4
rootsofnum_remain(p) = 0;
rootsofden_remain(q) = 0;
end
end
end
% ゼロになった根を取り去る
tmp = [];
for n = 1:length(rootsofnum_remain)
if !(rootsofnum_remain(n) == 0)
tmp = [tmp; rootsofnum_remain(n)];
end
end
rootsofnum_remain = tmp;
tmp = [];
for n = 1:length(rootsofden_remain)
if !(rootsofden_remain(n) == 0)
tmp = [tmp; rootsofden_remain(n)];
end
end
rootsofden_remain = tmp;
% 再度分母・分子を有理関数にする
num = poly(rootsofnum_remain);
den = poly(rootsofden_remain);
% 根から多項式を得たため、DC項を補正
DC_compensate = DC_impedance* den(1,end)/num(1,end);
num = DC_compensate * num;
end
fprintf('Number %d element ', iter)
if (mod(iter,2) == 1)
if (IsTtype == 1)
fprintf('is Arm L element of %2.6d H',SingleElement)
else
fprintf('is Shunt C element %2.6d F', SingleElement)
end
else
if (IsTtype == 1)
if !(type == 4) %Ellipse以外
fprintf('is Shunt C element %2.6d F', quo(1))
else %Ellipse
fprintf('is Shunt Series L %2.6d H and C %2.6d F',PrimaryElement, SecondalyElement)
end
else
if !(type == 4) %Ellipse以外
fprintf('is Arm L element %2.6d H', quo(1))
else %Ellipse
fprintf('is Arm Parallel C %2.6d F and L %2.6d H',PrimaryElement, SecondalyElement)
end
end
end
fprintf(char(10))
iter = iter + 1;
end
fprintf('Last element ')
if ((IsTtype == 1) && (mod(order,2) == 1))
fprintf ('is Arm L element of %2.6d H',num(1)/den)
fprintf(char(10))
fprintf ('and load impedance of %2.6d Ohm',num(2)/den)
else
fprintf ('is Shunt C element %2.6d F', num(1)/den)
fprintf(char(10))
fprintf ('and load conductance of %2.6d Siemence (%2.6d Ohm)',num(2)/den, den/num(2))
end
fprintf(char(10))
end
fprintf(char(10)')
fprintf(char(10)')
end
24. LCフィルタ設計MATLAB/GNU Octave mファイルに戻る
LCフィルタ設計のTOPに戻る

