% zi_lcfilter.m UTF-8でテキストファイルとし、拡張子.mで保存してください。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LC filter design with zero soure impedance or infinite load impedance
% for Butterworth, Chebyshev, and Bessel
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all
% 電力伝達多項式をプロットするか
PLOT1 = 0; % 1 にした場合にプロットし、0だとプロットしない
fprintf(char(10))
fprintf('LC filter design with zero soure impedance or infinite load impedance')
fprintf(char(10))
fprintf('for Butterworth, Chebyshev, and Bessel')
fprintf(char(10))
fprintf(char(10))
fprintf('Butterworth = 1')
fprintf(char(10))
fprintf('Chebyshev = 2')
fprintf(char(10))
fprintf('Bessel = 3')
fprintf(char(10))
fprintf(char(10))
%--------------------------------------------------------
type = 0;
st = "Enter filter type number: ";
while !(type == 1 || type == 2 || type == 3)
type = input(st);
end
% フィルタの次数を設定
order = 0;
switch(type)
case 2
st = "Enter filter order (Odd number) 3 to 9: ";
otherwise
st = "Enter filter order 2 to 9: ";
end
while !(order > 1 && order < 10)
order = input(st);
if ((type == 2) && mod(order, 2) == 0)
fprintf(char(10))
fprintf('Error!')
fprintf(char(10))
fprintf('Even order Chebyshev filter can not be generated.')
fprintf(char(10))
fprintf('Because even order should have assigned ripple level attenuation at DC.')
fprintf(char(10))
fprintf('Enter odd order number please.')
fprintf(char(10))
fprintf(char(10))
order = 0;
end
end
% ChebyshevフィルタのリプルをdBで設定
ripple = 0;
switch(type)
case 2
st = "Enter Chebyshev ripple in dB (0.01 to 3): ";
while !(ripple >= 0.01 && ripple <= 3)
ripple = input(st);
end
end
fprintf(char(10)')
fprintf(char(10)')
switch(type)
case 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Butterworth filter カーブ
% Butterworth特性を自乗し、それを逆数とした電力伝達多項式を得る
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i = sqrt(-1);
powerpoly = [1 zeros(1, (2 * order - 1)) 1];
ripple = 1; % PLOT 1でプロットするための一時的な設定
case 2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Chebyshev filter カーブ
% Chebyshev特性を自乗し、それを逆数とした電力伝達多項式を得る
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i = sqrt(-1);
% dBで入力したChebyshev リプルを実電力リプル率にする
e = 10^(ripple/10);
e = e - 1;
e = sqrt(e);
% Chebyshev多項式を漸化式として得る
% 漸化式の関係は
% T_n+1(x) = 2x T_n(x) - T_n-1(x)
tminus1 = [zeros(1, order) 1];
tminus0 = [tminus1 0];
tminus0 = tminus0(2:order+2);
for n = 2:order
tn = 2 * [tminus0 0];
tn = tn(2:order+2);
tn = tn - tminus1;
tminus1 = tminus0;
tminus0 = tn;
end
% Tn^2 (電力)を得る
tn2 = conv(tn, tn);
powerpoly = e^2 * tn2;
powerpoly = powerpoly + [zeros(1, order*2) 1];
case 3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Bessel filter カーブ
% Bessel 特性を自乗し、それを逆数とした電力伝達多項式を得る
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i = sqrt(-1);
% ベッセルフィルタはいきなりs平面での多項式で以下のようにあらわされる
powerpolyP = [];
for n = 0:order
powerpolyP = [powerpolyP (factorial(order + n)/(factorial(order - n)*factorial(n)))*(1/2)^n*i^(order - n)];
end
% 0次の次数で正規化
powerpolyP = powerpolyP/powerpolyP(1, order + 1);
% s平面での多項式の共役を得る
powerpolyN = [];
for n = 0:order
powerpolyN = [powerpolyN (factorial(order + n)/(factorial(order - n)*factorial(n)))*(1/2)^n*(-i)^(order - n)];
end
% 0次の次数で正規化
powerpolyN = powerpolyN/powerpolyN(1, order + 1);
% 自乗して電力伝達多項式を得る
powerpoly = conv(powerpolyP, powerpolyN);
powerpoly = real(powerpoly);
ripple = 1; % PLOT 1でプロットするための一時的な設定
% ω = 1 rad/secにおける減衰量を計算する
mpx = [];
for n = 2*order:-1:0
mpx = [(-1)^n mpx];
end
att = powerpoly * mpx';
att = -10 * log10(att);
fprintf('Attenuation at omega = 1 is %d2.3 dB', att)
fprintf(char(10))
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ここまでで伝達多項式powerpolyを得た。
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PLOT 1
% 電力伝達多項式を用いてプロットする
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
close all
if PLOT1 % 1 にした場合にプロットし、0だとプロットしない
s = i * logspace(-2, 3, 10001); % s = jωとする
accum_num = freqresponse(H_s_num_square, s);
accum_denom = freqresponse(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
%--------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% フィルタ設計
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i = sqrt(-1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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平面での電圧伝達多項式(√電力)の分母になる
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ラダー素子定数を計算する
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
num = [];
den = [];
for n = 1 : length(H_s)
if mod(n, 2) == 1
num = [num H_s(1, n)];
den = [den 0];
else
num = [num 0];
den = [den H_s(1, n)];
end
end
num_org = removehead(num);
den_org = removehead(den);
num = num_org;
den = den_org;
for a = 1:2
if a == 1
fprintf('===== Calculate T type %d th ladder for RS = 0 ohm, RS = 1 ohm and Omega = 1 rad/sec =====', order)
fprintf(char(10))
fprintf('From output, 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, RL = inf ohm and Omega = 1 rad/sec =====', order)
fprintf(char(10))
fprintf('From input, Shunt element is created first.')
fprintf(char(10))
IsTtype = 0;
den = den_org;
num = num_org;
IsTtype = 0;
end
iter = 1;
lc = [];
while(length(den) > 1)
[quo reminder] = deconv(num, den);
lc = [lc quo(1)];
num = den; %◆分母を分子に移動
%----------------------------------------------------
% 余りのうちの高次のべきで係数がゼロの項を削除して、分母の変数に代入
den = removehead(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 ('at input port is Arm L element of %2.6d H',num(1)/den)
fprintf(char(10))
fprintf ('and source impedance of %2.6d Ohm',num(2)/den)
else
fprintf ('at output port 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
24. LCフィルタ設計MATLAB/GNU Octave mファイルに戻る
LCフィルタ設計のTOPに戻る

