সিস্টেম — লিনিয়ারিটি, টাইম-ইনভ্যারিয়েন্স ও LTI সিস্টেম
এই পাঠে যা শিখবেন
- একটি "সিস্টেম" DSP-এর ভাষায় ঠিক কী বোঝায় এবং কীভাবে $y[n] = T\{x[n]\}$ লেখা হয়
- লিনিয়ারিটির সুপারপজিশন শর্ত এবং তা কোডে যাচাই করার পদ্ধতি
- টাইম-ইনভ্যারিয়েন্সের শিফট-ইনভ্যারিয়েন্স শর্ত এবং তা কোডে যাচাই করার পদ্ধতি
- LTI সিস্টেম কেন এত গুরুত্বপূর্ণ — এই কোর্সের বাকি অংশের ভিত্তি হিসেবে এর ভূমিকা
১ · সিস্টেম কী
DSP-এর ভাষায় একটি সিস্টেমSystemএকটি নিয়ম বা অপারেশন $T$ যা একটি ইনপুট সিগন্যাল $x[n]$-কে একটি আউটপুট সিগন্যাল $y[n]$-এ রূপান্তর করে। হলো এমন একটি নিয়ম $T$ যা একটি ইনপুট সিগন্যাল $x[n]$ নিয়ে একটি আউটপুট সিগন্যাল
$$y[n] = T\{x[n]\}$$
তৈরি করে। একটি সিস্টেম হতে পারে সরল, যেমন $y[n] = 2x[n]$ (শুধু দ্বিগুণ করা), বা জটিল, যেমন একটি ফিল্টার যা আউটপুটের জন্য একাধিক পূর্ববর্তী ইনপুট মান মিলিয়ে হিসেব করে। L02-এ আমরা দেখেছি সিগন্যাল আসলে একটি সংখ্যার তালিকা ($x[n]$) — সিস্টেম হলো সেই তালিকাকে নতুন একটি তালিকায় রূপান্তরের নিয়ম। এই কোর্সের বাকি অংশের প্রায় সবকিছুই — কনভোলিউশন, ফিল্টার, Z-ট্রান্সফর্ম — এই ধারণার উপর দাঁড়িয়ে।
২ · লিনিয়ারিটি — সুপারপজিশন শর্ত
একটি সিস্টেম লিনিয়ার (linear)Linear systemএমন একটি সিস্টেম যা সুপারপজিশন শর্ত পূরণ করে: $T\{ax_1[n]+bx_2[n]\} = aT\{x_1[n]\}+bT\{x_2[n]\}$ — যেকোনো দুটো ইনপুটের ওয়েটেড যোগফলের আউটপুট, আলাদাভাবে প্রসেস করে ওয়েটেড যোগফল নেওয়ার সমান। হয় যদি যেকোনো দুটো ইনপুট সিগন্যাল $x_1[n]$, $x_2[n]$ এবং যেকোনো স্কেলার $a$, $b$-এর জন্য
$$T\{a\,x_1[n] + b\,x_2[n]\} = a\,T\{x_1[n]\} + b\,T\{x_2[n]\}$$
সমান হয়। বাম পাশ মানে — আগে দুটো ইনপুটকে ওয়েটেড যোগফল করে তারপর সিস্টেমে পাঠানো। ডান পাশ মানে — আগে প্রতিটি ইনপুট আলাদাভাবে সিস্টেমে পাঠিয়ে তারপর আউটপুটগুলোর ওয়েটেড যোগফল নেওয়া। যদি এই দুই পাশ সবসময় সমান হয়, সিস্টেমটি লিনিয়ার — আর এই শর্তটি কোডে সরাসরি দুই পাশ আলাদাভাবে গণনা করে তুলনা করে পরীক্ষা করা যায়, কোনো অনুমান ছাড়াই।
৩ · টাইম-ইনভ্যারিয়েন্স — শিফট শর্ত
একটি সিস্টেম টাইম-ইনভ্যারিয়েন্টTime-invariant systemএমন একটি সিস্টেম যার আচরণ সময়ের সাথে বদলায় না -- ইনপুট $k$ স্যাম্পল শিফট করলে আউটপুটও ঠিক একইভাবে $k$ স্যাম্পল শিফট হয়, নতুন কোনো বিকৃতি ছাড়া। হয় যদি ইনপুটকে $k$ স্যাম্পল শিফট করলে আউটপুটও ঠিক একইভাবে $k$ স্যাম্পল শিফট হয়ে যায় — অর্থাৎ
$$x[n] \to y[n] \quad \Rightarrow \quad x[n-k] \to y[n-k] \quad \text{সব } k \text{-এর জন্য}$$
অর্থাৎ সিস্টেমটি "কবে" ইনপুট আসছে তা নিয়ে ভাবে না — শুধু ইনপুটের প্যাটার্ন নিয়ে ভাবে। এটি পরীক্ষা করতে দুটো ভিন্ন পথে একই আউটপুট বানিয়ে তুলনা করা হয়: (ক) আগে সিস্টেম চালিয়ে তারপর ফলাফল শিফট করা, বনাম (খ) আগে ইনপুট শিফট করে তারপর সিস্টেম চালানো। দুটো পথের আউটপুট মিললে সিস্টেম টাইম-ইনভ্যারিয়েন্ট।
ওয়েটেড যোগফলের ইনপুটে সিস্টেম চালানো = আলাদা চালিয়ে ওয়েটেড যোগফল নেওয়া। স্কেলিং ও অ্যাডিটিভিটি — দুটোই সত্য হতে হবে।
শিফট করে সিস্টেম চালানো = সিস্টেম চালিয়ে শিফট করা। সিস্টেমের "নিয়ম" ধ্রুবক, সময়-নির্ভর নয়।
একইসাথে লিনিয়ার ও টাইম-ইনভ্যারিয়েন্ট। এই শ্রেণীর সিস্টেম সম্পূর্ণভাবে তার ইমপালস রেসপন্স দিয়ে বর্ণনা করা যায় (M3-এ বিস্তারিত)।
৪ · একটি সত্যিকারের ডেমো — দুটো সিস্টেম পরীক্ষা করা
নিচের কোড সেল দুটো সরল সিস্টেম নিয়ে লিনিয়ারিটি পরীক্ষা করে: $y[n]=2x[n]$ (স্কেলিং) আর $y[n]=x[n]^2$ (স্কোয়ারিং)। দুই ক্ষেত্রেই সুপারপজিশন শর্তের দুই পাশ সত্যিই আলাদাভাবে গণনা করা হয়েছে — কোনটি লিনিয়ার তা অনুমান করা হয়নি।
x1 = [1.0, 2.0, 3.0, 4.0]
x2 = [0.5, -1.0, 2.0, 0.0]
a, b = 2.0, 3.0
def system_linear(x):
return [2.0 * v for v in x] # y[n] = 2*x[n]
def system_nonlinear(x):
return [v**2 for v in x] # y[n] = x[n]^2
def combine(a, xa, b, xb):
return [a*xa[n] + b*xb[n] for n in range(len(xa))]
x_comb = combine(a, x1, b, x2) # a*x1 + b*x2 (ইনপুট মেশানো)
print(f"x1={x1}\nx2={x2}\na={a}, b={b}")
print(f"a*x1+b*x2 = {x_comb}\n")
print("-- System 1: y[n] = 2*x[n] --")
lhs1 = system_linear(x_comb) # T(a*x1+b*x2)
rhs1 = [a*v1 + b*v2 for v1, v2 in zip(system_linear(x1), system_linear(x2))] # a*T(x1)+b*T(x2)
print(f"T(a*x1+b*x2) = {lhs1}")
print(f"a*T(x1)+b*T(x2) = {rhs1}")
match1 = all(abs(lhs1[n]-rhs1[n]) < 1e-9 for n in range(len(lhs1)))
print(f"match: {match1} -> {'LINEAR' if match1 else 'NOT LINEAR'}\n")
print("-- System 2: y[n] = x[n]^2 --")
lhs2 = system_nonlinear(x_comb)
rhs2 = [a*v1 + b*v2 for v1, v2 in zip(system_nonlinear(x1), system_nonlinear(x2))]
print(f"T(a*x1+b*x2) = {lhs2}")
print(f"a*T(x1)+b*T(x2) = {rhs2}")
match2 = all(abs(lhs2[n]-rhs2[n]) < 1e-9 for n in range(len(lhs2)))
print(f"match: {match2} -> {'LINEAR' if match2 else 'NOT LINEAR (সুপারপজিশন ফেল)'}")
print(f"per-sample পার্থক্য: {[round(abs(lhs2[n]-rhs2[n]),4) for n in range(len(lhs2))]}")
[7.0, 2.0, 24.0, 16.0] — সুপারপজিশন সত্যিই মিলেছে
(LINEAR)। কিন্তু $y[n]=x[n]^2$-এর জন্য বাম পাশ [12.25, 1.0, 144.0, 64.0]
আর ডান পাশ [2.75, 11.0, 30.0, 32.0] — সম্পূর্ণ ভিন্ন সংখ্যা, প্রতি স্যাম্পলে পার্থক্য
[9.5, 10.0, 114.0, 32.0] (NOT LINEAR)। কারণটা স্পষ্ট — স্কোয়ারিং একটি
নন-লিনিয়ার অপারেশন, তাই $(ax_1+bx_2)^2 \neq a x_1^2 + b x_2^2$ (ক্রস-টার্ম $2ab\,x_1 x_2$ হারিয়ে যায়)।
এবার টাইম-ইনভ্যারিয়েন্স পরীক্ষা করা যাক দুটো ভিন্ন সিস্টেম দিয়ে — একটি সরল মুভিং-এভারেজ-এর মতো সিস্টেম $y[n] = 0.5x[n] + 0.5x[n-1]$ (যা M3-এ ডিফারেন্স ইকুয়েশন হিসেবে বিস্তারিত আসবে), আর একটি স্পষ্টভাবে সময়-নির্ভর সিস্টেম $y[n] = n \cdot x[n]$।
x3 = [1.0, 2.0, 3.0, 4.0, 5.0, 0.0]
shift = 2
def shift_signal(x, k):
return [0.0]*k + x[:len(x)-k] # ডানে k স্যাম্পল শিফট, বামে জিরো-প্যাড
def system_avg(x):
y = []
for n in range(len(x)):
prev = x[n-1] if n-1 >= 0 else 0.0
y.append(0.5*x[n] + 0.5*prev) # y[n] = 0.5*x[n] + 0.5*x[n-1]
return y
def system_time_varying(x):
return [n * x[n] for n in range(len(x))] # y[n] = n*x[n] -- সরাসরি n-এর উপর নির্ভরশীল
print(f"x[n] = {x3}, shift k={shift}")
x3_shifted = shift_signal(x3, shift)
print(f"x[n-{shift}] = {x3_shifted}\n")
print("-- System: y[n] = 0.5*x[n] + 0.5*x[n-1] --")
y_then_shift = shift_signal(system_avg(x3), shift) # shift(T(x))
y_shift_then = system_avg(x3_shifted) # T(shifted x)
print(f"shift(T(x[n])) = {y_then_shift}")
print(f"T(x[n-{shift}]) = {y_shift_then}")
match3 = all(abs(y_then_shift[n]-y_shift_then[n]) < 1e-9 for n in range(len(x3)))
print(f"match: {match3} -> {'TIME-INVARIANT' if match3 else 'NOT time-invariant'}\n")
print("-- System: y[n] = n * x[n] --")
y_then_shift2 = shift_signal(system_time_varying(x3), shift)
y_shift_then2 = system_time_varying(x3_shifted)
print(f"shift(T(x[n])) = {y_then_shift2}")
print(f"T(x[n-{shift}]) = {y_shift_then2}")
match4 = all(abs(y_then_shift2[n]-y_shift_then2[n]) < 1e-9 for n in range(len(x3)))
print(f"match: {match4} -> {'TIME-INVARIANT' if match4 else 'NOT time-invariant'}")
print(f"per-sample পার্থক্য: {[round(abs(y_then_shift2[n]-y_shift_then2[n]),4) for n in range(len(x3))]}")
[0.0, 0.0, 0.5, 1.5, 2.5, 3.5] দেয় —
TIME-INVARIANT। কিন্তু $y[n]=n \cdot x[n]$-এর জন্য "শিফট-তারপর-সিস্টেম" দেয়
[0.0, 0.0, 0.0, 2.0, 6.0, 12.0], আর "সিস্টেম-তারপর-শিফট" দেয়
[0.0, 0.0, 2.0, 6.0, 12.0, 20.0] — সত্যিই ভিন্ন, per-sample পার্থক্য
[0.0, 0.0, 2.0, 4.0, 6.0, 8.0] (NOT time-invariant)। কারণ স্পষ্ট — এই
সিস্টেম আউটপুট গণনায় সরাসরি $n$ (পরম সময়) ব্যবহার করে, তাই ইনপুট কখন আসছে তার উপর সিস্টেমের আচরণ
নিজেই বদলে যায়।
$y[n]=0.5x[n]+0.5x[n-1]$ সিস্টেমটি লিনিয়ারও (নিজে যাচাই করুন — এটি ঠিক $y[n]=2x[n]$-এর মতোই একটি ওয়েটেড-যোগফল অপারেশন, তাই সুপারপজিশন পাস করবে) এবং টাইম-ইনভ্যারিয়েন্টও — অর্থাৎ এটি একটি LTI সিস্টেম। এই কোর্সের M3 থেকে M8 পর্যন্ত (কনভোলিউশন, ডিফারেন্স ইকুয়েশন, Z-ট্রান্সফর্ম, ফ্রিকোয়েন্সি রেসপন্স, FIR/IIR ফিল্টার) প্রায় সবকিছুই বিশেষভাবে LTI সিস্টেম নিয়ে কাজ করে — কারণ এই শ্রেণীর সিস্টেম একটি মাত্র বৈশিষ্ট্য (ইমপালস রেসপন্স) দিয়ে সম্পূর্ণভাবে বর্ণনা করা যায়, যা M3/L12-এ শেখা হবে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ একটি সিস্টেম $y[n] = x[n] + 5$ (প্রতিটি স্যাম্পলে ধ্রুবক ৫ যোগ করা) কি লিনিয়ার? চিন্তা করে তারপর উত্তর দেখুন।
না, লিনিয়ার নয় — যদিও এটি "সরল" দেখায়। ধরুন $x_1=[0]$, $x_2=[0]$, $a=b=1$। বাম পাশ: $T\{1\cdot0+1\cdot0\} = T\{0\} = 0+5=5$। ডান পাশ: $1\cdot T\{0\}+1\cdot T\{0\} = (0+5)+(0+5)=10$। $5 \neq 10$ — সুপারপজিশন ফেল করে। এই ধরনের সিস্টেমকে অ্যাফাইন (affine) বলা হয় — লিনিয়ার প্লাস একটি ধ্রুবক অফসেট, কিন্তু গাণিতিক অর্থে সত্যিকার লিনিয়ার নয়, কারণ $x[n]=0$ ইনপুটে আউটপুট শূন্য হওয়া উচিত (লিনিয়ারিটির একটি প্রয়োজনীয় ফলাফল), যা এখানে হয় না।
প্র ০২
উপরের ডেমোর system_avg সিস্টেমটি ($y[n]=0.5x[n]+0.5x[n-1]$) কি ইনপুটের
ভবিষ্যৎ মান ($x[n+1]$) ব্যবহার করে? এই ধরনের সিস্টেমকে কী বলা হয়?
না — এটি শুধু $x[n]$ (বর্তমান) আর $x[n-1]$ (অতীত) ব্যবহার করে, কখনো $x[n+1]$ (ভবিষ্যৎ) নয়। এই বৈশিষ্ট্যকে কজালিটি (causality) বলা হয় — একটি কজাল সিস্টেমের আউটপুট শুধু বর্তমান ও অতীত ইনপুটের উপর নির্ভর করে, ভবিষ্যতের উপর নয়। বাস্তব-সময়ের (real-time) যেকোনো সিস্টেমকে অবশ্যই কজাল হতে হয় (M3/L13-এ বিস্তারিত)।
প্র ০৩
একটি সিস্টেম লিনিয়ার কিন্তু টাইম-ভ্যারিয়েন্ট (time-invariant নয়) হতে পারে কি? উপরের
system_time_varying ($y[n]=n \cdot x[n]$) কি এমন একটি উদাহরণ?
হ্যাঁ, লিনিয়ারিটি আর টাইম-ইনভ্যারিয়েন্স সম্পূর্ণ স্বাধীন বৈশিষ্ট্য। $y[n]=n \cdot x[n]$ আসলে লিনিয়ার — প্রতিটি $n$-এ শুধু $x[n]$-কে একটি ধ্রুবক (যদিও $n$-নির্ভর) সংখ্যা দিয়ে গুণ করা হচ্ছে, তাই $T\{ax_1+bx_2\} = n(ax_1[n]+bx_2[n]) = a\cdot n\,x_1[n] + b\cdot n\,x_2[n] = aT\{x_1\}+bT\{x_2\}$ — সুপারপজিশন পাস করবে। কিন্তু উপরের ডেমো দেখিয়েছে এটি টাইম-ইনভ্যারিয়েন্ট নয় (শিফটের দুই পথ মেলেনি)। অর্থাৎ এটি লিনিয়ার-কিন্তু-টাইম-ভ্যারিয়েন্ট সিস্টেমের একটি সত্যিকারের উদাহরণ — LTI হতে হলে দুটো শর্তই একসাথে লাগবে।
অনুশীলন
-
চিন্তা করুন: উপরের প্রথম কোড সেলে
system_nonlinear-এর বদলে একটি নতুন সিস্টেমy[n] = 3*x[n] - 1(স্কেল করে ১ বিয়োগ) নিয়ে ভাবুন। এটি কি লিনিয়ার হবে? সূত্র $T\{ax_1+bx_2\}$ বনাম $aT\{x_1\}+bT\{x_2\}$ ব্যবহার করে $x=[0]$, $a=b=1$ দিয়ে হাতে যাচাই করুন।না, লিনিয়ার হবে না — এটি প্র ০১-এর মতোই একটি অ্যাফাইন সিস্টেম। $x_1=x_2=[0]$, $a=b=1$ দিয়ে: বাম পাশ $T\{0+0\}=T\{0\}=3(0)-1=-1$; ডান পাশ $T\{0\}+T\{0\}=(-1)+(-1)=-2$। $-1 \neq -2$, তাই সুপারপজিশন ফেল করবে — যেকোনো ধ্রুবক-অফসেট সিস্টেম (গুণাকার $x[n]$-এর সহগ যাই হোক না কেন) সাধারণত নন-লিনিয়ার।
-
পরীক্ষা করুন: প্রথম কোড সেলে
system_nonlinearফাংশনটির রিটার্ন লাইন[v**2 for v in x]-কে[3*v - 1 for v in x]-এ বদলে Run চেপে আপনার হিসেব যাচাই করুন —match2কি এখনওFalseদেখায়?হ্যাঁ, রান করলে
match2 = False-ই থাকবে (NOT LINEAR) — যদিও ভিন্ন সুনির্দিষ্ট সংখ্যায় (নতুনlhs2/rhs2মান আলাদা হবেx**2-এর চেয়ে), মূল সিদ্ধান্ত একই থাকে: যেকোনো সিস্টেম যা $x[n]=0$-এ জিরো-নয় আউটপুট দেয় (এখানে $-1$), তা কখনো সুপারপজিশন শর্ত পূরণ করতে পারে না।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ স্যাম্পলিং, কনভোলিউশন, Z-ট্রান্সফর্ম, DTFT/DFT, FFT, FIR/IIR ফিল্টার ডিজাইন, মাল্টিরেট প্রসেসিং, স্পেকট্রাল এস্টিমেশন, র্যান্ডম সিগন্যাল প্রসেসিং, বাস্তব প্রয়োগ ও ক্যাপস্টোন — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
- Numerical Methods কোর্স সহোদর কোর্স সাধারণ সংখ্যাগত অ্যালগরিদম ও হাতে-লেখা যাচাই-ভিত্তিক দর্শন — উপরের সুপারপজিশন/শিফট পরীক্ষার মতো "দাবি না করে গণনা করে দেখানো" পদ্ধতি সেই কোর্সেও ব্যবহৃত হয়েছে।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, Machine Learning, Deep Learning, System Design, Cybersecurity, Cloud Computing & DevOps, এবং আরও অনেক কোর্স — সব এক জায়গায়।