পাঠ ৩৮ · ৫৭-এর মধ্যে · মডিউল ৮
Home / Courses / Numerical Methods / আইগেনভ্যালু ও পাওয়ার মেথড

আইগেনভ্যালু সমস্যা ও পাওয়ার মেথড

The eigenvalue problem & power method
১২ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

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

১ · আইগেনভ্যালু ও আইগেনভেক্টর — সংক্ষিপ্ত রিমাইন্ডার

একটি আইগেনভেক্টরএকটি নন-জিরো ভেক্টর v যাকে ম্যাট্রিক্স A দিয়ে গুণ করলে দিক অপরিবর্তিত থাকে — শুধু দৈর্ঘ্য একটি স্কেলার λ (আইগেনভ্যালু) দিয়ে গুণ হয়। হলো এমন একটি নন-জিরো ভেক্টর v, যাকে n×n ম্যাট্রিক্স A দিয়ে গুণ করলে সরাসরি সেই একই ভেক্টরের একটি স্কেলড সংস্করণ পাওয়া যায়:

$$Av = \lambda v$$

এখানে λ (ল্যাম্বডা) হলো সেই আইগেনভেক্টরের সাথে যুক্ত আইগেনভ্যালু। জ্যামিতিকভাবে, বেশিরভাগ ভেক্টরকে A দিয়ে গুণ করলে তার দিক ও দৈর্ঘ্য দুটোই বদলে যায় — কিন্তু আইগেনভেক্টরগুলো হলো সেই বিশেষ দিকগুলো যেখানে A-এর প্রভাব শুধু একটি সরল স্কেলিং। একটি n×n ম্যাট্রিক্সের (সাধারণভাবে) nটি আইগেনভ্যালু থাকতে পারে। এই বস্তুগুলো কী এবং এগুলোর বীজগাণিতিক বৈশিষ্ট্য (characteristic polynomial দিয়ে হাতে বের করা ইত্যাদি) নিয়ে বিস্তারিত Math for AI & ML কোর্সে আছে — এই পাঠ ধরে নেয় সেই ভিত্তি আছে, এবং প্রশ্ন করে: বড় ম্যাট্রিক্সে এগুলো কম্পিউটারে বাস্তবে কীভাবে গণনা করা হয়? কারণ characteristic polynomial-এর মূল বের করা (যেমন L05-L09-এর রুট-ফাইন্ডিং মেথড দিয়ে) ৪×৪ বা তার চেয়ে বড় ম্যাট্রিক্সের জন্য ব্যবহারিকভাবে অসম্ভব হয়ে যায় — তাই M8-এর বাকি পাঠগুলো সম্পূর্ণ ভিন্ন, ইটারেটিভ পথ নেয়।

দিক অপরিবর্তিত
Av সবসময় v-এর সমান্তরাল — A শুধু দৈর্ঘ্য λ গুণ বদলায়, দিক ঘোরায় না।
একাধিক আইগেনভ্যালু
n×n ম্যাট্রিক্সের সাধারণত nটি আইগেনভ্যালু থাকে, ম্যাগনিটিউড অনুযায়ী সাজানো — সবচেয়ে বড়টিকে ডমিন্যান্ট বলা হয়।
কেন গুরুত্বপূর্ণ
ভাইব্রেশন, স্ট্যাবিলিটি, PCA — প্রায় সব ক্ষেত্রেই ডমিন্যান্ট আইগেনভ্যালু/ভেক্টর একাই সবচেয়ে বেশি তথ্য বহন করে (বিস্তারিত L41-এ)।

২ · পাওয়ার মেথডের ধারণা

পাওয়ার মেথড-এর মূল স্বজ্ঞা সহজ: যেকোনো শুরুর ভেক্টর v₀-কে, তাত্ত্বিকভাবে, ম্যাট্রিক্সের সব আইগেনভেক্টরের একটি মিশ্রণ (লিনিয়ার কম্বিনেশন) হিসেবে লেখা যায়। যখন এই ভেক্টরকে বার বার A দিয়ে গুণ করা হয়, প্রতিটি আইগেন-দিকের অবদান তার নিজস্ব আইগেনভ্যালুর ঘাত (power) অনুযায়ী বাড়ে বা কমে — আর যেহেতু ডমিন্যান্ট আইগেনভ্যালু λ₁ সবচেয়ে বড়, k বার গুণ করার পর সেই দিকটাই বাকিদের তুলনায় দ্রুততম বাড়ে এবং ধীরে ধীরে পুরো ভেক্টরে প্রাধান্য বিস্তার করে — এই থেকেই মেথডের নাম "পাওয়ার" (ঘাত) মেথড।

প্রতি ধাপে Av দ্রুত বিশাল বা ক্ষুদ্র হয়ে যেতে পারে (যদি |λ₁| > 1 বা < 1) — তাই প্রতি ইটারেশনের পর ভেক্টরকে তার নিজের নর্ম দিয়ে ভাগ করে নরমালাইজ করা হয়, যাতে দৈর্ঘ্য সবসময় ১ থাকে এবং দিকটাই একমাত্র যা পর্যবেক্ষণ করা হয়। আইগেনভ্যালুর আনুমান বের করতে প্রতি ইটারেশনে Rayleigh quotient ব্যবহার করা হয়:

$$\lambda_{\text{est}} = v^{\top} (A v)$$

যেখানে v ইতিমধ্যে নরমালাইজড (দৈর্ঘ্য ১)। এটি একটি সিমেট্রিক ম্যাট্রিক্সের জন্য বিশেষভাবে ভালো কাজ করে — নিচের ডেমোর ম্যাট্রিক্সটিও সিমেট্রিক।

৩ · হাতে-কলমে বাস্তবায়ন — একটি সত্যিকারের কনভারজেন্স ডেমো

নিচের ম্যাট্রিক্স A সিমেট্রিক এবং পজিটিভ-ডেফিনিট (M3/M14-এর কন্ডিশনিং আলোচনার মতো একটি সুন্দরভাবে-আচরণকারী ম্যাট্রিক্স):

$$A = \begin{bmatrix} 4 & 1 & 1 \\ 1 & 3 & 1 \\ 1 & 1 & 2 \end{bmatrix}$$

নিচের কোড সেলে matvec (ম্যাট্রিক্স-ভেক্টর গুণ), norm ও normalize সম্পূর্ণ হাতে লেখা — কোনো NumPy নেই। শুরুর ভেক্টর v₀ = [1, 1, 1], এবং প্রতি ইটারেশনে Rayleigh quotient দিয়ে আইগেনভ্যালুর আনুমান ও আগের ইটারেশনের তুলনায় পরিবর্তনের পরিমাণ প্রিন্ট করা হয়েছে।

Python
import math

A = [
    [4.0, 1.0, 1.0],
    [1.0, 3.0, 1.0],
    [1.0, 1.0, 2.0],
]

def matvec(M, v):
    return [sum(M[i][j] * v[j] for j in range(len(v))) for i in range(len(M))]

def norm(v):
    return math.sqrt(sum(x * x for x in v))

def normalize(v):
    n = norm(v)
    return [x / n for x in v]

v = [1.0, 1.0, 1.0]     # শুরুর ভেক্টর -- যেকোনো নন-জিরো ভেক্টর দিয়ে শুরু করা যায়
prev_eig = None

print(f"{'ইটার':>4} | {'eigenvalue আনুমান':>20} | {'পরিবর্তন':>14}")
for i in range(1, 13):
    w = matvec(A, v)          # ধাপ ১: A দিয়ে গুণ
    v = normalize(w)          # ধাপ ২: নরমালাইজ (দৈর্ঘ্য ১ রাখা)
    Av = matvec(A, v)
    eig_est = sum(v[k] * Av[k] for k in range(len(v)))   # Rayleigh quotient
    if prev_eig is None:
        print(f"{i:4d} | {eig_est:20.10f} | {'--':>14}")
    else:
        print(f"{i:4d} | {eig_est:20.10f} | {abs(eig_est - prev_eig):14.10f}")
    prev_eig = eig_est

print()
print(f"চূড়ান্ত আইগেনভেক্টর: {[round(x, 6) for x in v]}")
print(f"চূড়ান্ত আইগেনভ্যালু আনুমান: {prev_eig:.10f}")

    
সত্যিকারের আউটপুট দেখায় আইগেনভ্যালুর আনুমান ইটারেশন ১-এ ৫.১৮১৮১৮ থেকে শুরু করে দ্রুত স্থির হচ্ছে: ইটারেশন ৬-এ ৫.২১৪৩০৫৮, আর ইটারেশন ১২-এ ৫.২১৪৩১৯৭৪১৭ — যেখানে পরিবর্তনের পরিমাণ ইতিমধ্যে 0.0000000059-এ নেমে এসেছে। সংশ্লিষ্ট আইগেনভেক্টর [0.755774, 0.520676, 0.397118]-এ কনভার্জ করেছে (নরমালাইজড, দৈর্ঘ্য ১)। এই ডমিন্যান্ট আইগেনভ্যালু/ভেক্টরই L39, L40-এ যাচাই করা হবে ভিন্ন মেথড দিয়ে — সংখ্যাগুলো মিলবে, কারণ এটি একই ম্যাট্রিক্সের একই প্রকৃত আইগেনভ্যালু, শুধু ভিন্ন অ্যালগরিদম দিয়ে বের করা।

৪ · কনভারজেন্স রেট ও সীমাবদ্ধতা

পাওয়ার মেথডের কনভারজেন্স রেট নির্ভর করে দুটি সবচেয়ে বড় আইগেনভ্যালুর অনুপাতের উপর — যত ছোট |λ₂/λ₁|, তত দ্রুত কনভারজেন্স। উপরের ম্যাট্রিক্সের প্রকৃত আইগেনভ্যালুগুলো (পরের পাঠগুলোতে ভিন্ন মেথড দিয়ে নিশ্চিত হবে) প্রায় ৫.২১৪৩২, ২.৪৬০৮১, ও ১.৩২৪৮৭ — তাই |λ₂/λ₁| ≈ ২.৪৬০৮১/৫.২১৪৩২ ≈ ০.৪৭২। Rayleigh quotient ব্যবহার করলে (সিমেট্রিক ম্যাট্রিক্সের জন্য) এই অনুপাতের বর্গ অনুযায়ী এরর কমে (≈ ০.৪৭২² ≈ ০.২২৩) — উপরের আউটপুটে প্রতি ধাপে পরিবর্তনের অনুপাত পর্যবেক্ষণ করলে (যেমন ০.০০০৪৮৭/০.০০২২০০ ≈ ০.২২) এই তাত্ত্বিক হারের সাথে বাস্তব সংখ্যাগুলো সত্যিই মিলে যায়।

সীমাবদ্ধতা

পাওয়ার মেথড শুধু ডমিন্যান্ট আইগেনভ্যালু/ভেক্টর বের করে — বাকিগুলো নয়। যদি দুটি আইগেনভ্যালুর ম্যাগনিটিউড সমান বা কাছাকাছি হয় (|λ₂/λ₁| ≈ ১), কনভারজেন্স অত্যন্ত ধীর হয়ে যায় বা একদমই হয় না। শুরুর ভেক্টর যদি (দুর্ভাগ্যক্রমে) ডমিন্যান্ট আইগেনভেক্টরের সাথে ঠিক লম্ব (orthogonal) হয়, তত্ত্বগতভাবে মেথড কখনোই সেই দিকে ঘুরবে না — বাস্তবে ফ্লোটিং-পয়েন্ট রাউন্ড-অফ এরর (M1/L03) সাধারণত একটি ক্ষুদ্র অংশ সেই দিকে ঢুকিয়ে দেয়, তাই এটি খুব কমই বাস্তব সমস্যা হয়। বাকি আইগেনভ্যালুগুলো বের করতে দরকার ভিন্ন কৌশল — L39-এ ইনভার্স ও শিফটেড পাওয়ার মেথড, এবং L40-এ QR অ্যালগরিদম।

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

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

প্র ০১ প্রতি ইটারেশনে ভেক্টরকে নরমালাইজ করার কী প্রয়োজন — যদি এটা বাদ দেওয়া হয় তাহলে কী সমস্যা হবে?

নরমালাইজেশন ছাড়া, যদি ডমিন্যান্ট আইগেনভ্যালু |λ₁| > 1 হয়, ভেক্টরের এন্ট্রিগুলো প্রতি ইটারেশনে দ্রুত বাড়তে বাড়তে ফ্লোটিং-পয়েন্ট ওভারফ্লো-তে পৌঁছাতে পারে (আবার |λ₁| < 1 হলে দ্রুত আন্ডারফ্লো হয়ে শূন্যে পরিণত হতে পারে)। নরমালাইজেশন শুধু দিকটা রাখে, ম্যাগনিটিউড নিয়ন্ত্রণে রাখে — ফলে গণনাটি সংখ্যাগতভাবে স্থিতিশীল থাকে, উত্তরের উপর কোনো প্রভাব না ফেলেই (আইগেনভেক্টর দিক-নির্দিষ্ট, দৈর্ঘ্য নয়)।

প্র ০২ শুরুর ভেক্টর v₀ = [1, 1, 1]-এর বদলে v₀ = [1, 0, 0] বা এমনকি v₀ = [-3, 7, 2] ব্যবহার করলে কি ফলাফল বদলাবে?

চূড়ান্ত ফলাফল (ডমিন্যান্ট আইগেনভ্যালু ও তার দিক) প্রায় সবসময় একই থাকবে — শুধু কনভার্জ করতে কম-বেশি ইটারেশন লাগতে পারে, শুরুর ভেক্টরে ডমিন্যান্ট আইগেন-দিকের "অংশ" কতটা বেশি বা কম আছে তার উপর নির্ভর করে। শুধু একটি বিরল ক্ষেত্রে ফলাফল বদলাবে না বরং কনভার্জই করবে না: যদি শুরুর ভেক্টর ঠিক ডমিন্যান্ট আইগেনভেক্টরের সাথে লম্ব হয় (তত্ত্বগতভাবে) — বাস্তবে এটি রাউন্ড-অফ এরর দিয়ে প্রায় সবসময় এড়িয়ে যায়।

প্র ০৩ উপরের ম্যাট্রিক্সে |λ₂/λ₁| ≈ ০.৪৭২ — তুলনামূলক দ্রুত কনভারজেন্স দেখিয়েছে। যদি একটি ম্যাট্রিক্সে |λ₂/λ₁| = ০.৯৯ হতো, তাহলে কী হতো এবং তখন কী করা যেতে পারে?

|λ₂/λ₁| = ০.৯৯ মানে প্রতি ইটারেশনে এরর মাত্র ~১% কমে (Rayleigh quotient ব্যবহার করলে ~২%) — কনভার্জ করতে কয়েক হাজার ইটারেশন লাগতে পারে, যা ব্যবহারিকভাবে অসহনীয়। এই পরিস্থিতিতেই L39-এর শিফটেড ইনভার্স পাওয়ার মেথড কাজে আসে — একটি সঠিকভাবে বেছে নেওয়া শিফট দিয়ে কনভারজেন্সের অনুপাতকে কৃত্রিমভাবে অনেক ছোট করে তোলা যায়, যতই দুই আইগেনভ্যালু কাছাকাছি থাকুক না কেন।

অনুশীলন

  1. চিন্তা করুন: উপরের আউটপুট টেবিলে ইটারেশন ৫-এ পরিবর্তনের পরিমাণ ০.০০০২২০০৪২২। ধারা অনুযায়ী (প্রতি ধাপে প্রায় ০.২২ গুণ) ইটারেশন ৬-এ পরিবর্তনের পরিমাণ মোটামুটি কত হবে বলে আপনার ধারণা?

    ০.০০০২২০০৪২২ × ০.২২ ≈ ০.০০০০৪৮৪ — আর কোড সেলের প্রকৃত আউটপুটে ইটারেশন ৬-এর পরিবর্তন হলো ০.০০০০৪৮৭১৬০, যা এই আনুমানের সাথে খুব কাছাকাছি। এটি নিশ্চিত করে যে কনভারজেন্স সত্যিই প্রায়-স্থির একটি অনুপাতে (geometric rate-এ) ঘটছে, যা আগের বিভাগে আলোচিত (λ₂/λ₁)² তত্ত্বের সাথে সামঞ্জস্যপূর্ণ।

  2. পরীক্ষা করুন: কোড সেলে শুরুর ভেক্টর v = [1.0, 1.0, 1.0]-কে v = [1.0, -2.0, 0.5]-এ বদলে Run চাপুন। চূড়ান্ত আইগেনভ্যালুর আনুমান কি একই থাকে?

    হ্যাঁ — চূড়ান্ত আইগেনভ্যালুর আনুমান একই ৫.২১৪৩...-এ কনভার্জ করে (হয়তো কনভার্জ করতে এক-দুই ইটারেশন বেশি বা কম লাগতে পারে), কারণ ডমিন্যান্ট আইগেনভ্যালু ম্যাট্রিক্সের নিজস্ব বৈশিষ্ট্য — শুরুর ভেক্টরের উপর নির্ভর করে না (যতক্ষণ না সেটি ডমিন্যান্ট আইগেনভেক্টরের সাথে ঠিক লম্ব হয়)।

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

আগের পাঠ
ওয়েভ ইকুয়েশনের জন্য ফাইনাইট ডিফারেন্স