FIR ফিল্টার ডিজাইন ট্রেড-অফ — অর্ডার বনাম পারফরম্যান্স
এই পাঠে যা শিখবেন
- ফিল্টার অর্ডার (ট্যাপ সংখ্যা) বাড়ালে/কমালে ঠিক কী কী পরিবর্তন হয় — একটি সত্যিকারের পাশাপাশি তুলনা
- প্যাসব্যান্ড ফ্ল্যাটনেস, স্টপব্যান্ড এটেনুয়েশন, ও ট্রানজিশন-ব্যান্ড প্রস্থের মধ্যে সম্পর্ক
- কেন এই উন্নতি "বিনামূল্যে" নয় — কম্পিউটেশন কস্টের সাথে সরাসরি সম্পর্ক (L33-এর O(M) থেকে সংযুক্ত)
- বাস্তব ডিজাইন সিদ্ধান্তে কীভাবে এই ট্রেড-অফ বিবেচনা করতে হয়
১ · ট্যাপ সংখ্যা কেন গুরুত্বপূর্ণ
L31-এ আমরা M=31 ট্যাপের একটি ফিল্টার ডিজাইন করেছিলাম এবং দেখেছিলাম এটি ৬০ Hz উপাদান −৪১.২৭ dB দমন করে,
১০ Hz প্রায় অক্ষত রেখে। কিন্তু M-এর মান কীভাবে বেছে নেওয়া হয়েছিল? এই পাঠে আমরা সরাসরি
দেখব — একই কাটঅফ ফ্রিকোয়েন্সিতে, ভিন্ন M বেছে নিলে ফলাফল কীভাবে বদলায়। উইন্ডোড-সিংক
পদ্ধতিতে (L31), ফিল্টারের দৈর্ঘ্য সরাসরি নিয়ন্ত্রণ করে সিংক ফাংশনের কতটুকু অংশ রাখা হচ্ছে — বেশি ট্যাপ
মানে সিংকের আরও বেশি "লব" (lobe) রাখা, যা তাত্ত্বিকভাবে আদর্শ ব্রিক-ওয়াল রেসপন্সের আরও কাছাকাছি নিয়ে যায়।
২ · কোড দিয়ে পাশাপাশি তুলনা
নিচে একই ডিজাইন ফাংশন দিয়ে দুটি ফিল্টার তৈরি করা হয়েছে — একটি ছোট (M=11) ও একটি বড়
(M=41) — উভয়ই fs=200 Hz-এ fc=30 Hz কাটঅফের লো-পাস, এবং L31-এর একই ১০ Hz + ৬০ Hz টেস্ট
সিগন্যালে প্রয়োগ করা হয়েছে (গ্রুপ ডিলে ট্রিম করে, L31-এর পদ্ধতিতে)।
import math
fs = 200.0
f_lo = 10.0
f_hi = 60.0
N = 60
x = [math.sin(2*math.pi*f_lo*n/fs) + math.sin(2*math.pi*f_hi*n/fs) for n in range(N)]
fc = 30.0
fc_norm = fc/fs
def sinc_lp(d, fc_norm):
if d == 0:
return 2*fc_norm
return math.sin(2*math.pi*fc_norm*d)/(math.pi*d)
def design_filter(M):
center = (M-1)//2
h_ideal = [sinc_lp(n-center, fc_norm) for n in range(M)]
w = [0.54 - 0.46*math.cos(2*math.pi*n/(M-1)) for n in range(M)]
return [h_ideal[n]*w[n] for n in range(M)], center
def convolve(a, b):
ny = len(a)+len(b)-1
y = [0.0]*ny
for n in range(ny):
s = 0.0
for k in range(len(b)):
if 0 <= n-k < len(a):
s += b[k]*a[n-k]
y[n] = s
return y
def dft_mag_at(sig, f, fs):
Ns = len(sig)
total = sum(sig[n]*complex(math.cos(-2*math.pi*f*n/fs), math.sin(-2*math.pi*f*n/fs)) for n in range(Ns))
return abs(total)/Ns
mag_in_lo = dft_mag_at(x, f_lo, fs)
mag_in_hi = dft_mag_at(x, f_hi, fs)
results = {}
for M in [11, 41]:
h, center = design_filter(M)
y_full = convolve(x, h)
y = y_full[center:center+N]
mag_out_lo = dft_mag_at(y, f_lo, fs)
mag_out_hi = dft_mag_at(y, f_hi, fs)
atten_lo = 20*math.log10(mag_out_lo/mag_in_lo)
atten_hi = 20*math.log10(mag_out_hi/mag_in_hi)
results[M] = h
print(f"M={M:>3} taps | প্যাসব্যান্ড (10Hz) এটেনুয়েশন: {atten_lo:>7.4f} dB | স্টপব্যান্ড (60Hz) এটেনুয়েশন: {atten_hi:>7.2f} dB")
print()
print("ট্রানজিশন শার্পনেস -- |H(f)| সরাসরি ফিল্টারের উপর মূল্যায়ন করা (কোনো ইনপুট সিগন্যাল ছাড়াই):")
def freq_response(h, f_norm):
Nh = len(h)
return sum(h[n]*complex(math.cos(-2*math.pi*f_norm*n), math.sin(-2*math.pi*f_norm*n)) for n in range(Nh))
print(f"{'f (Hz)':>7} | {'M=11':>10} | {'M=41':>10}")
for f_probe in [25, 30, 32, 35, 40, 45]:
row = [abs(freq_response(results[M], f_probe/fs)) for M in [11, 41]]
print(f"{f_probe:>7} | {row[0]:>10.6f} | {row[1]:>10.6f}")
f=25 Hz-এ M=41-এর ম্যাগনিটিউড এখনও 0.9226 (প্রায় সম্পূর্ণ পাস), কিন্তু M=11-এর
মাত্র 0.6366 (ইতিমধ্যে কমতে শুরু করেছে); আর কাটঅফের ঠিক উপরে f=40 Hz-এ M=41
প্রায় শূন্য (0.0023), অথচ M=11 তখনও উল্লেখযোগ্য (0.2420)। অর্থাৎ M=41-এর
ট্রানজিশন অঞ্চল M=11-এর চেয়ে অনেক সংকীর্ণ ও তীক্ষ্ণ — একটি সত্যিকারের, সরাসরি কম্পিউটেড প্রমাণ।
৩ · বিনামূল্যে নয় — কম্পিউটেশন কস্টের দিকটা
L33-এ দেখা হয়েছিল একটি M-ট্যাপ FIR ফিল্টার প্রতিটি আউটপুট নমুনায় প্রায় Mটি গুণ-যোগ করে।
তাই M=11 থেকে M=41-এ যাওয়া মানে প্রতি নমুনায় গণনা প্রায় ৪ গুণ বেশি — একটি রিয়েল-টাইম
সিস্টেমে (যেমন একটি এমবেডেড অডিও ডিভাইস) এটি ব্যাটারি খরচ, ল্যাটেন্সি, বা প্রসেসর লোডের উপর সরাসরি প্রভাব
ফেলতে পারে। তাছাড়া বেশি ট্যাপ মানে বেশি গ্রুপ ডিলে ((M-1)/2 নমুনা) — M=41-এ ২০ নমুনার ডিলে,
M=11-এ মাত্র ৫ নমুনা — যা লাইভ অডিও/কমিউনিকেশন সিস্টেমে শ্রবণযোগ্য/অনুভবযোগ্য বিলম্ব তৈরি করতে পারে।
শার্প ট্রানজিশন, গভীর স্টপব্যান্ড এটেনুয়েশন, সমতল প্যাসব্যান্ড — কিন্তু বেশি গণনা ও বেশি গ্রুপ ডিলে।
দ্রুত গণনা, কম ডিলে, কম মেমোরি — কিন্তু চওড়া ট্রানজিশন, কম গভীর এটেনুয়েশন, বেশি প্যাসব্যান্ড রিপল।
FIR ফিল্টার ডিজাইনে "সেরা" ফিল্টার বলে কিছু নেই — শুধু প্রয়োগের চাহিদার সাথে মেলানো একটি ভারসাম্য আছে। একটি স্লো, উচ্চ-নির্ভুলতার অফলাইন বিশ্লেষণে M=৫০০+ ট্যাপ ব্যবহার করা সহজেই যুক্তিসঙ্গত হতে পারে, কিন্তু একটি ব্যাটারি-চালিত রিয়েল-টাইম ডিভাইসে M=১০-২০ ট্যাপের বেশি না যাওয়াই বুদ্ধিমানের কাজ হতে পারে। এই ট্রেড-অফ M8-এ (L35 থেকে) IIR ফিল্টারের সাথে তুলনার সময়ও ফিরে আসবে — IIR প্রায়ই একই শার্পনেস অনেক কম কোয়েফিসিয়েন্টে অর্জন করতে পারে, কিন্তু লিনিয়ার ফেজ ও নিঃশর্ত স্ট্যাবিলিটির সুবিধা হারিয়ে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ কোড সেলের ফলাফলে M=41-এর প্যাসব্যান্ড এটেনুয়েশন (−০.০০৯৮ dB) M=11-এর (−০.৬৬৩১ dB) চেয়ে অনেক ভালো কেন — সরাসরি সিংক-উইন্ডো তত্ত্ব দিয়ে ব্যাখ্যা করুন।
M=41-এর ফিল্টার সিংক ফাংশনের অনেক বেশি "লব" ধরে রাখে (২০টি করে দুই পাশে, বনাম M=11-এ মাত্র ৫টি) — তাই এটি আদর্শ (ideal), অসীম-দৈর্ঘ্যের সিংক ফাংশনের অনেক কাছাকাছি একটি approximation। উইন্ডো ফাংশনের প্রান্তে হওয়া "কাটা"-জনিত ত্রুটি (L24-এর স্পেকট্রাল লিকেজের সাথে সম্পর্কিত) M=41-এ আনুপাতিকভাবে অনেক কম, তাই প্যাসব্যান্ডে রিপল কম, রেসপন্স আরও সমতল।
প্র ০২ যদি M আরও বাড়িয়ে ১০১ ট্যাপ করা হয়, তাহলে স্টপব্যান্ড এটেনুয়েশন কি সীমাহীনভাবে বাড়তেই থাকবে?
ট্রানজিশন-ব্যান্ডের শার্পনেস ও কিছুটা এটেনুয়েশনের গভীরতা M বাড়ানোর সাথে উন্নত হতে থাকবে, কিন্তু একটি নির্দিষ্ট উইন্ডো ফাংশনের (এখানে হ্যামিং) নিজস্ব একটি "সর্বোচ্চ সম্ভাব্য স্টপব্যান্ড এটেনুয়েশন" সীমা আছে — এটি মূলত উইন্ডোর সাইড-লোবের আকৃতির উপর নির্ভর করে, M-এর উপর নয় (এটি একটি সুপরিচিত, স্ট্যান্ডার্ড উইন্ডো-ডিজাইন তত্ত্ব)। হ্যামিং উইন্ডোর জন্য এই সীমা প্রায় −৫৩ dB-এর কাছাকাছি — এর বেশি এটেনুয়েশন চাইলে M বাড়ানো নয়, বরং ভিন্ন একটি উইন্ডো ফাংশন (যেমন ব্ল্যাকম্যান) দরকার হয়।
প্র ০৩ একটি ব্যাটারি-চালিত হিয়ারিং-এইড ডিভাইসের জন্য ফিল্টার ডিজাইন করতে হলে, M=১১ আর M=৪১-এর মধ্যে কোনটি বেছে নেবেন এবং কেন?
সম্ভবত M=১১-এর কাছাকাছি একটি ছোট ফিল্টার — একটি হিয়ারিং-এইডে কম ব্যাটারি খরচ ও কম শ্রবণযোগ্য বিলম্ব (ব্যবহারকারী নিজের কথা আর ফিল্টার-করা আউটপুটের মধ্যে বিলম্ব অনুভব করলে অস্বস্তিকর হয়) সাধারণত এটেনুয়েশনের সামান্য ক্ষতির চেয়ে বেশি গুরুত্বপূর্ণ। এটাই ঠিক এই পাঠের মূল বার্তা — সঠিক পছন্দ সবসময় প্রয়োগের সুনির্দিষ্ট চাহিদার উপর নির্ভর করে, কোনো সার্বজনীন "সঠিক উত্তর" নেই।
অনুশীলন
-
চিন্তা করুন: কোড সেলে
for M in [11, 41]:-এ একটি তৃতীয় মান21যোগ করলে ([11, 21, 41]), M=21-এর প্যাসব্যান্ড ও স্টপব্যান্ড এটেনুয়েশন M=11 আর M=41-এর মধ্যে কোথায় পড়বে বলে আপনার ধারণা?M=21-এর ফলাফল আনুমানিকভাবে M=11 আর M=41-এর মাঝামাঝি হবে — প্যাসব্যান্ড এটেনুয়েশন −০.৬৬ আর −০.০১ dB-এর মধ্যে কোথাও, স্টপব্যান্ড এটেনুয়েশন −৩২.৭ আর −৪০.৪ dB-এর মধ্যে কোথাও। ট্যাপ সংখ্যা বাড়ার সাথে উন্নতি একঘেয়েভাবে (monotonically) হয়, লাফিয়ে নয়।
-
পরীক্ষা করুন: কোড সেলে
for M in [11, 41]:-কেfor M in [11, 21, 41]:-এ পরিবর্তন করে Run চেপে আপনার হিসেব যাচাই করুন।রান করলে M=21-এর সারি M=11 আর M=41-এর মাঝামাঝি একটি মান দেখাবে (উভয় এটেনুয়েশনেই) — নিশ্চিত করে যে ফিল্টার কর্মক্ষমতা ট্যাপ সংখ্যার সাথে ক্রমাগত (smoothly), লাফিয়ে নয়, উন্নত হয়। মনে রাখবেন দ্বিতীয় টেবিলের
resultsডিকশনারিতেও M=21 যোগ করতে চাইলে ট্রানজিশন-শার্পনেস লুপেও[11, 41]-কে[11, 21, 41]-এ বদলাতে হবে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- IIR ফিল্টার — রিকার্সিভ স্ট্রাকচার পরবর্তী পাঠ · M8 M7 (FIR) শেষ — এখন M8 শুরু, IIR ফিল্টারের রিকার্সিভ কাঠামো ও কেন এটি প্রায়ই অনেক কম ট্যাপে একই শার্পনেস অর্জন করতে পারে।
- FIR ফিল্টার — লিনিয়ার ফেজ ও উইন্ডোয়িং দিয়ে ডিজাইন M7 রিভিউ এই পাঠের ডিজাইন পদ্ধতির মূল ভিত্তি — সিংক ফাংশন ও হ্যামিং উইন্ডো।
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ স্যাম্পলিং, কনভোলিউশন, Z-ট্রান্সফর্ম, DTFT/DFT, FFT, FIR/IIR ফিল্টার ডিজাইন, মাল্টিরেট প্রসেসিং, স্পেকট্রাল এস্টিমেশন, র্যান্ডম সিগন্যাল প্রসেসিং, বাস্তব প্রয়োগ ও ক্যাপস্টোন।