পাঠ ০৯ · ৫৭-এর মধ্যে · মডিউল ৩
Home / Courses / Digital Signal Processing / কনভোলিউশন

কনভোলিউশন — মূল অপারেশন

Convolution — the core operation
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • কনভোলিউশনের সংজ্ঞা এবং "মুভিং ওয়েটেড সাম" হিসেবে এর স্বজ্ঞাগত অর্থ
  • "ফ্লিপ, স্লাইড, মাল্টিপ্লাই, সাম" — কনভোলিউশন গণনার ধাপগুলো ধাপে ধাপে বোঝা
  • একটি ছোট উদাহরণে হাতে-গণনা করে তারপর Python কোড দিয়ে যাচাই করা
  • কনভোলিউশন এই কোর্সের বাকি অংশে (FIR/IIR ফিল্টার, ম্যাচড ফিল্টারিং, ইমেজ প্রসেসিং) কীভাবে বারবার ফিরে আসবে তার একটি প্রাথমিক ধারণা

১ · কনভোলিউশন কী — একটি মুভিং ওয়েটেড সাম

M1-এ শেখা হয়েছিল একটি LTI সিস্টেমLinear Time-Invariant সিস্টেম — এমন একটি সিস্টেম যা লিনিয়ারিটি ও টাইম-ইনভ্যারিয়েন্স দুটো শর্তই পূরণ করে (L04-এ বিস্তারিত)। সম্পূর্ণভাবে তার ইমপালস রেসপন্সসিস্টেমে একটি একক ইউনিট-ইমপালস ইনপুট দিলে যে আউটপুট পাওয়া যায় — এই একটি সিকোয়েন্স দিয়েই একটি LTI সিস্টেমের সম্পূর্ণ আচরণ বর্ণনা করা সম্ভব। h[n] দিয়ে বর্ণনা করা যায়। প্রশ্ন হলো — যদি আমরা জানি একটি সিস্টেম একক ইমপালসে কীভাবে সাড়া দেয়, তাহলে সেই সিস্টেম যেকোনো ইনপুট সিগন্যাল x[n]-এ কীভাবে সাড়া দেবে তা কীভাবে বের করব? উত্তর হলো কনভোলিউশন:

$$y[n] = \sum_{k=-\infty}^{\infty} x[k]\,h[n-k]$$

এই সূত্রটিকে সবচেয়ে সহজভাবে বোঝা যায় একটি মুভিং ওয়েটেড সাম হিসেবে — প্রতিটি আউটপুট স্যাম্পল y[n] হলো ইনপুটের কিছু স্যাম্পলের একটি ওয়েটেড গড়, যেখানে ওয়েট আসে h থেকে, এবং কোন স্যাম্পলগুলো নেওয়া হচ্ছে তা পরিবর্তিত হয় n-এর সাথে সাথে (তাই "মুভিং")।

ফ্লিপ ও স্লাইড
h[n-k] মানে h-কে k-অক্ষে উল্টে (flip) দিয়ে n পরিমাণ শিফট করা — তারপর এটি x[k]-এর উপর দিয়ে স্লাইড করানো হয়, প্রতিটি পজিশনে মাল্টিপ্লাই-অ্যান্ড-সাম করে একটি আউটপুট স্যাম্পল বের হয়।
শিফটেড ইমপালস রেসপন্সের যোগফল
বিকল্পভাবে ভাবা যায় — প্রতিটি ইনপুট স্যাম্পল x[k] একটি স্কেলড, শিফটেড ইমপালস রেসপন্স x[k]\cdot h[n-k] তৈরি করে; সবগুলো একসাথে যোগ করলেই আউটপুট।
ফিল্টারিং = কনভোলিউশন
একটি ডিজিটাল ফিল্টার আসলে একটি নির্দিষ্ট ইমপালস রেসপন্স h[n] নিয়ে গঠিত — সিগন্যালকে "ফিল্টার করা" মানেই সিগন্যালকে সেই h[n]-এর সাথে কনভলভ করা (M7-M8-এ বিস্তারিত)।

২ · প্রথম হাতে-গণনা করা উদাহরণ

ধরা যাক একটি খুবই সাধারণ ২-ট্যাপ স্মুথিং ফিল্টার — এর ইমপালস রেসপন্স h = [0.5, 0.5], অর্থাৎ প্রতিটি আউটপুট স্যাম্পল হলো বর্তমান ও তার ঠিক আগের ইনপুট স্যাম্পলের গড়। ইনপুট সিগন্যাল x = [1, 3, 2, 5, 4]। হাতে হিসেব করলে, y[0] = x[0]\cdot h[0] = 1 \times 0.5 = 0.5, আর y[1] = x[0]\cdot h[1] + x[1]\cdot h[0] = 1\times 0.5 + 3\times 0.5 = 2.0 — অর্থাৎ প্রতিটি পজিশনে h-এর দুটো ওয়েট ইনপুটের ওভারল্যাপিং স্যাম্পলগুলোর সাথে গুণ হয়ে যোগ হচ্ছে। নিচের কোড সেলে এই পুরো প্রক্রিয়াটি একটি নেস্টেড লুপ দিয়ে জেনুইনভাবে গণনা করা হয়েছে।

Python
h = [0.5, 0.5]        # ইমপালস রেসপন্স -- বর্তমান ও আগের স্যাম্পলের গড় (২-ট্যাপ স্মুথিং ফিল্টার)
x = [1, 3, 2, 5, 4]   # ইনপুট সিগন্যাল

N = len(x) + len(h) - 1     # আউটপুটের দৈর্ঘ্য (L10-এ বিস্তারিত প্রমাণ)
y = [0.0] * N
for n in range(N):
    total = 0.0
    for k in range(len(x)):
        if 0 <= n - k < len(h):     # শুধু বৈধ (overlapping) k-এর জন্য যোগ করা হয়
            total += x[k] * h[n - k]
    y[n] = total

print("x =", x)
print("h =", h)
print()
print(f"{'n':>3} | {'y[n]':>6}")
for n in range(N):
    print(f"{n:>3} | {y[n]:>6.2f}")

    
কোডটি প্রকৃতপক্ষে দেয় y = [0.5, 2.0, 2.5, 3.5, 4.5, 2.0] — মোট ৬টি স্যাম্পল (ইনপুট ৫টি + ফিল্টার ২টি − ১ = ৬, এই নিয়মের পূর্ণ প্রমাণ ও যাচাই L10-এ)। লক্ষ্য করুন y[2] = x[1]\cdot h[1] + x[2]\cdot h[0] = 3\times 0.5 + 2\times 0.5 = 2.5 — উপরে হাতে করা হিসেবের সাথে ঠিক মিলে যায়। এই আউটপুট আসলে ইনপুটের একটি "স্মুথ" করা সংস্করণ — প্রতিটি মান তার প্রতিবেশী স্যাম্পলের সাথে গড় করা হয়েছে, যা একটি সাধারণ লো-পাস ফিল্টারের আচরণের মতো।

৩ · কেন এটি DSP-এর "মূল অপারেশন"

মূল কথা · Key takeaway

কনভোলিউশনকে "মূল অপারেশন" বলা হয় কারণ এই একটি সূত্রই DSP-এর প্রায় প্রতিটি প্রয়োগে ফিরে আসে — FIR ফিল্টার ডিজাইনে ফিল্টার ট্যাপগুলোর সাথে সিগন্যালকে কনভলভ করা হয় (M7), ম্যাচড ফিল্টারিং-এ একটি টেমপ্লেটের সাথে কোরিলেশন (যা কনভোলিউশনেরই একটি নিকটাত্মীয়, L11-এ বিস্তারিত) ব্যবহার করে সিগন্যাল ডিটেক্ট করা হয় (M11/L50), এমনকি ইমেজ প্রসেসিং-এও একই আইডিয়া দুই ডাইমেনশনে প্রসারিত করা হয় (M12/L53)। L10-এ আমরা এই একই অপারেশনের একটি সম্পূর্ণ, সাধারণ (general) ইমপ্লিমেন্টেশন লিখব এবং কঠোরভাবে যাচাই করব।

পরবর্তী পাঠে (L10) আমরা কনভোলিউশনের ফলাফলের দৈর্ঘ্য কেন সবসময় len(x) + len(h) - 1 হয় তা প্রমাণ করব, এবং একটি সম্পূর্ণ, পুনঃব্যবহারযোগ্য convolve() ফাংশন লিখে আরেকটি উদাহরণে হাতে-গণনার সাথে মিলিয়ে যাচাই করব।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ উপরের উদাহরণে h = [0.5, 0.5]-কে যদি h = [1, 0] করা হতো, তাহলে আউটপুট y কেমন হতো বলে মনে হয়?

h = [1, 0] মানে y[n] = x[n]\cdot 1 + x[n-1]\cdot 0 = x[n] — অর্থাৎ আউটপুট ইনপুটের হুবহু কপি হবে (শুধু শেষে একটি অতিরিক্ত শূন্য যোগ হবে দৈর্ঘ্যের নিয়ম মেনে)। এই h-কে বলা হয় আইডেন্টিটি ইমপালস রেসপন্স — এটি ইউনিট ইমপালস [1]-এরই একটি শিফট করা রূপ, যা কোনো পরিবর্তন না করেই সিগন্যাল পাস করে দেয়।

প্র ০২ "ফ্লিপ ও স্লাইড" — কনভোলিউশনে h-কে কেন ফ্লিপ করতে হয়? ফ্লিপ না করলে কী হতো (অর্থাৎ সরাসরি x[k]\cdot h[n+k] করলে)?

ফ্লিপ করাটা আসে সূত্রের সংজ্ঞা থেকেই — h[n-k]-এ k বাড়লে ইনডেক্স কমে, যা ফ্লিপের সমতুল্য। ফ্লিপ না করে সরাসরি যোগ করলে সেটি কনভোলিউশন নয়, বরং কোরিলেশন হয়ে যায় (L11-এ বিস্তারিত) — দুটোর গাণিতিক ফলাফল আলাদা, যদিও h সিমেট্রিক (যেমন এই পাঠের [0.5, 0.5]) হলে ফ্লিপ করা আর না করার ফলাফল কাকতালীয়ভাবে একই হয়ে যায়।

প্র ০৩ একটি LTI সিস্টেমের ইমপালস রেসপন্স জানা থাকলে কি সেই সিস্টেমের যেকোনো ইনপুটের জন্য আউটপুট বের করা সম্ভব? কেন এটি এত শক্তিশালী একটি ধারণা?

হ্যাঁ — এটাই LTI সিস্টেম থিওরির কেন্দ্রীয় ফলাফল। যেকোনো সিগন্যালকে শিফটেড ইউনিট ইমপালসের একটি যোগফল হিসেবে লেখা যায় (x[n] = \sum_k x[k]\,\delta[n-k]), আর লিনিয়ারিটি ও টাইম-ইনভ্যারিয়েন্স (L04) নিশ্চিত করে যে প্রতিটি শিফটেড ইমপালসের রেসপন্স হবে একইভাবে শিফটেড ইমপালস রেসপন্স — তাই সবগুলো যোগ করলেই মোট আউটপুট, যা ঠিক কনভোলিউশন সূত্র। অর্থাৎ একটি মাত্র সিকোয়েন্স (h[n]) পুরো সিস্টেমকে সম্পূর্ণভাবে বর্ণনা করে।

অনুশীলন

  1. চিন্তা করুন: উপরের কোড সেলে y[3]-এর মান হাতে হিসেব করুন — সূত্র y[3] = x[2]\cdot h[1] + x[3]\cdot h[0] ব্যবহার করে (মনে রাখুন x = [1, 3, 2, 5, 4], h = [0.5, 0.5])।

    y[3] = x[2]\times h[1] + x[3]\times h[0] = 2\times 0.5 + 5\times 0.5 = 1.0 + 2.5 = 3.5।

  2. পরীক্ষা করুন: উপরের কোড সেলটি Run চেপে চালান এবং y[3]-এর প্রিন্ট করা মান আপনার হাতে-করা হিসেবের সাথে মেলে কিনা যাচাই করুন।

    রান করলে টেবিলে n=3 | y[n]=3.50 দেখাবে — আপনার হাতে-করা হিসেব ৩.৫-এর সাথে ঠিক মিলে যায়। এই "প্রথমে হাতে হিসেব, তারপর কোড দিয়ে যাচাই" পদ্ধতিটি এই কোর্সে বারবার ব্যবহার করা হবে — L10-এ আমরা এই একই পদ্ধতি একটি সম্পূর্ণ সাধারণ কনভোলিউশন ফাংশনের জন্য প্রয়োগ করব।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
অ্যানালগ-টু-ডিজিটাল ও ডিজিটাল-টু-অ্যানালগ কনভার্সন