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

ইনভার্স পাওয়ার মেথড ও শিফটেড মেথড

Inverse power method & shifted methods
১৩ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

  • ইনভার্স পাওয়ার মেথডের ধারণা — কেন A⁻¹-এর উপর পাওয়ার মেথড সবচেয়ে ছোট আইগেনভ্যালু খুঁজে দেয়
  • কেন বাস্তবে ম্যাট্রিক্স ইনভার্স না বের করে প্রতি ইটারেশনে একটি লিনিয়ার সিস্টেম সমাধান করা হয়
  • শিফট প্যারামিটার কীভাবে যেকোনো নির্দিষ্ট আইগেনভ্যালুর কাছাকাছি কনভারজেন্স "টার্গেট" করতে দেয়
  • হাতে-কলমে বাস্তবায়ন এবং L38-এর একই ম্যাট্রিক্সে দুটি ভিন্ন আইগেনভ্যালুর জন্য প্রকৃত কনভারজেন্স টেবিল

১ · ইনভার্স পাওয়ার মেথডের ধারণা

L38-এ দেখা গেছে পাওয়ার মেথড A-এর ডমিন্যান্ট (সবচেয়ে বড় ম্যাগনিটিউডের) আইগেনভ্যালুর দিকে কনভার্জ করে। এখন লক্ষ্য করুন — যদি λ হয় A-এর একটি আইগেনভ্যালু (আইগেনভেক্টর v-এর সাথে), তাহলে A⁻¹-এর একই আইগেনভেক্টর v-এর সাথে যুক্ত আইগেনভ্যালু হলো ঠিক ১/λ। তাই A-এর সবচেয়ে ছোট আইগেনভ্যালু, A⁻¹-এর সবচেয়ে বড় (ডমিন্যান্ট) আইগেনভ্যালুতে পরিণত হয় — অর্থাৎ A⁻¹-এর উপর সরাসরি পাওয়ার মেথড চালালেই A-এর সবচেয়ে ছোট আইগেনভ্যালুর দিকে কনভার্জ করা যায়। এই কৌশলকে ইনভার্স পাওয়ার মেথড বলা হয়।

বাস্তবায়নের কৌশল — ইনভার্স না বের করে সিস্টেম সমাধান

ব্যবহারিকভাবে A⁻¹ সম্পূর্ণ গণনা করা ব্যয়বহুল এবং অপ্রয়োজনীয়। প্রতি ইটারেশনে দরকার শুধু A⁻¹v — আর w = A⁻¹v মানে ঠিক Aw = v। তাই প্রতি ইটারেশনে একটি লিনিয়ার সিস্টেম সমাধান করা হয় (M3/L10-এর গসিয়ান এলিমিনেশন দিয়ে) — ইনভার্স বের না করেই। এটি দ্রুততর এবং সংখ্যাগতভাবে বেশি স্থিতিশীল।

২ · শিফটেড ইনভার্স পাওয়ার মেথড — যেকোনো আইগেনভ্যালু "টার্গেট" করা

এই ধারণাকে আরও এক ধাপ এগিয়ে নেওয়া যায়। যদি λ হয় A-এর একটি আইগেনভ্যালু, তাহলে (A − s·I)-এর (যেকোনো শিফট s-এর জন্য) সংশ্লিষ্ট আইগেনভ্যালু হলো λ − s। সুতরাং (A − s·I)⁻¹-এর আইগেনভ্যালু হলো ১/(λ − s) — আর এই রাশিটি সবচেয়ে বড় হয় যখন λ শিফট s-এর সবচেয়ে কাছাকাছি। তাই (A − s·I)-এর উপর ইনভার্স পাওয়ার মেথড চালালে, ম্যাট্রিক্সটি এমন যেকোনো আইগেনভ্যালুর দিকে কনভার্জ করে যেটি s-এর সবচেয়ে কাছে — শিফট s বদলে বদলে ইচ্ছামতো যেকোনো আইগেনভ্যালু "টার্গেট" করা যায়।

$$(A - sI)^{-1}v_k = w \quad\Longleftrightarrow\quad (A - sI)\,w = v_k$$

৩ · হাতে-কলমে বাস্তবায়ন — দুটি ভিন্ন শিফটের সত্যিকারের কনভারজেন্স

L38-এর একই ম্যাট্রিক্স ব্যবহার করা হবে, যাতে ফলাফল সরাসরি তুলনীয় হয়:

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

নিচের কোড সেলে gauss_solve ফাংশনটি M3/L10-এর গসিয়ান এলিমিনেশন (পার্শিয়াল পিভোটিংসহ) হাতে-লেখা বাস্তবায়ন — প্রতি ইটারেশনে (A − shift·I)w = v সমাধান করে w বের করে, তারপর নরমালাইজ করে। প্রথমে শিফট ০ (সরল ইনভার্স পাওয়ার, সবচেয়ে ছোট আইগেনভ্যালু টার্গেট করে):

Python
import math

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

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 gauss_solve(M, b):
    # M3/L10-এর গসিয়ান এলিমিনেশন, পার্শিয়াল পিভোটিংসহ, হাতে-লেখা -- কোনো লাইব্রেরি নেই
    n = len(M)
    aug = [row[:] + [b[i]] for i, row in enumerate(M)]
    for col in range(n):
        piv = max(range(col, n), key=lambda r: abs(aug[r][col]))
        aug[col], aug[piv] = aug[piv], aug[col]
        pivot_val = aug[col][col]
        for row in range(col + 1, n):
            factor = aug[row][col] / pivot_val
            for k in range(col, n + 1):
                aug[row][k] -= factor * aug[col][k]
    x = [0.0] * n
    for row in range(n - 1, -1, -1):
        s = aug[row][n] - sum(aug[row][k] * x[k] for k in range(row + 1, n))
        x[row] = s / aug[row][row]
    return x

def shifted(M, s):
    n = len(M)
    return [[M[i][j] - (s if i == j else 0.0) for j in range(n)] for i in range(n)]

def inverse_power(M, shift, v0, iters):
    Ms = shifted(M, shift)
    v = v0[:]
    prev_eig = None
    print(f"{'ইটার':>4} | {'eigenvalue আনুমান':>20} | {'পরিবর্তন':>14}")
    for i in range(1, iters + 1):
        w = gauss_solve(Ms, v)          # (A - shift*I) w = v  সমাধান -- এটাই A^-1 v
        nrm = norm(w)
        v = [x / nrm for x in w]
        Av = matvec(M, v)
        eig_est = sum(v[k] * Av[k] for k in range(len(v)))   # Rayleigh quotient, মূল A-তে
        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
    return v, prev_eig

print("--- শিফট = ০ (সবচেয়ে ছোট আইগেনভ্যালু টার্গেট) ---")
v1, eig1 = inverse_power(A, 0.0, [1.0, 1.0, 1.0], 10)
print(f"চূড়ান্ত আইগেনভেক্টর: {[round(x, 6) for x in v1]}")

    
সত্যিকারের আউটপুট দেখায় শিফট ০-এ আইগেনভ্যালুর আনুমান ধীরে ধীরে কমতে কমতে ইটারেশন ১০-এ ১.৩২৪৮৭৫৭৬৬৫-এ পৌঁছায় (এখনও পুরোপুরি কনভার্জ করেনি — পরিবর্তনের পরিমাণ তখনও ০.০০০০১৬২৬) — এটিই A-এর সবচেয়ে ছোট আইগেনভ্যালু, প্রায় ১.৩২৪৮৬৯ (L40-এ QR অ্যালগরিদম দিয়ে নিশ্চিত করা হবে)। L38-এর ডমিন্যান্ট আইগেনভ্যালু ৫.২১৪৩২-এর তুলনায় এটি ভিন্ন, প্রত্যাশিতভাবেই — কারণ পাওয়ার মেথড ও ইনভার্স পাওয়ার মেথড দুটি ভিন্ন প্রান্তের আইগেনভ্যালু খোঁজে।

এবার শিফট ২.৫ ব্যবহার করলে — যা মধ্যম আইগেনভ্যালু ২.৪৬০৮১-এর কাছাকাছি — একই inverse_power ফাংশনটিই পুনর্ব্যবহার করা যায় (Pyodide-এর একই সেশনে আগের কোড সেল থেকে ফাংশনগুলো এখনও উপলব্ধ):

Python
print("--- শিফট = ২.৫ (মধ্যম আইগেনভ্যালুর কাছাকাছি টার্গেট) ---")
v2, eig2 = inverse_power(A, 2.5, [1.0, 1.0, 1.0], 10)
print(f"চূড়ান্ত আইগেনভেক্টর: {[round(x, 6) for x in v2]}")

    
লক্ষ্য করুন কনভারজেন্সের গতি — শিফট ২.৫ ব্যবহার করলে ইটারেশন ২-এ ইতিমধ্যে ২.৪৬০৮১৩, ইটারেশন ৩-এ ২.৪৬০৮১১১২৬৭ এবং ইটারেশন ৪-এ পরিবর্তনের পরিমাণ ০.০০০০০০০০০৫-এ নেমে আসে — প্রায় নিখুঁত কনভারজেন্স মাত্র ৪ ইটারেশনে! এটি শিফট ০-এর তুলনায় বহুগুণ দ্রুত, কারণ শিফট ২.৫ লক্ষ্য আইগেনভ্যালু ২.৪৬০৮১-এর অনেক কাছে, যেখানে বাকি দুটি আইগেনভ্যালু (৫.২১৪৩২ ও ১.৩২৪৮৭) তুলনামূলক অনেক দূরে — তাই কনভারজেন্স-নির্ধারক অনুপাত অত্যন্ত ছোট হয়ে যায়।
প্র্যাকটিক্যাল টিপ

বাস্তব প্রকৌশল সফটওয়্যারে শিফটেড ইনভার্স পাওয়ার মেথড প্রায়ই ব্যবহৃত হয় যখন আগে থেকেই একটি আইগেনভ্যালুর মোটামুটি আনুমান জানা থাকে (যেমন একটি স্ট্রাকচারের প্রায় জানা ন্যাচারাল ফ্রিকোয়েন্সি — L41-এ বিস্তারিত) এবং শুধু সেটিকে সূক্ষ্মভাবে নিখুঁত করতে হয়। প্রতি ইটারেশনে নতুন শিফট দিয়ে (Rayleigh quotient iteration নামের একটি সম্প্রসারণ) কনভারজেন্সকে আরও দ্রুততর — এমনকি cubic rate পর্যন্ত — করা সম্ভব, যদিও সেটি এই পাঠের সুযোগের বাইরে।

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

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

প্র ০১ কোড সেলে প্রতি ইটারেশনে A⁻¹ সরাসরি না বের করে gauss_solve দিয়ে একটি সিস্টেম সমাধান করা হয়েছে। এভাবে কেন সরাসরি ইনভার্স গণনা করার চেয়ে ভালো?

একটি n×n ম্যাট্রিক্সের সম্পূর্ণ ইনভার্স গণনা করতে সাধারণত nটি লিনিয়ার সিস্টেম সমাধান করার সমান কাজ লাগে (প্রতিটি স্ট্যান্ডার্ড বেসিস ভেক্টরের জন্য একটি), যেখানে একটি নির্দিষ্ট v-এর জন্য Aw = v সমাধান করতে মাত্র একটি সিস্টেম সমাধান লাগে — অনেক কম কাজ, এবং বড় স্পার্স ম্যাট্রিক্সের ক্ষেত্রে (M10/L48-এ বিস্তারিত) পার্থক্যটা বিশাল। এছাড়া সরাসরি ইনভার্স গণনা প্রায়ই সংখ্যাগতভাবে কম স্থিতিশীল।

প্র ০২ যদি শিফট s ঠিক একটি প্রকৃত আইগেনভ্যালুর সমান হয়ে যায় (যেমন s = ২.৪৬০৮১১১২৭২ ঠিক), তাহলে (A − s·I) ম্যাট্রিক্সটির কী হবে, আর gauss_solve-এ কী সমস্যা দেখা দিতে পারে?

যদি s ঠিক একটি আইগেনভ্যালুর সমান হয়, তাহলে (A − s·I) সিঙ্গুলার (নন-ইনভার্টিবল) হয়ে যায় — গসিয়ান এলিমিনেশনে একটি পিভট শূন্যের (বা কম্পিউটেশনাল রাউন্ড-অফের কারণে অত্যন্ত ক্ষুদ্র সংখ্যার) কাছাকাছি চলে আসবে, ফলে ZeroDivisionError বা একটি অবাস্তব বিশাল w তৈরি হতে পারে। বাস্তবে এটি সমস্যা নয় বরং সুবিধা — শিফটকে আইগেনভ্যালুর ঠিক কাছাকাছি কিন্তু সমান নয় রাখলে সিস্টেমটি প্রায়-সিঙ্গুলার হয়ে ওঠে এবং w-এর ম্যাগনিটিউড বিশাল হয়ে যায় — যা প্রকৃতপক্ষে সেই দিকের দিকে দ্রুত কনভারজেন্সকেই আরও জোরদার করে।

প্র ০৩ শিফট ০ ব্যবহার করলে ১০ ইটারেশনেও সম্পূর্ণ কনভার্জ করেনি (পরিবর্তন তখনও ০.০০০০১৬), কিন্তু শিফট ২.৫-এ মাত্র ৪ ইটারেশনেই প্রায় নিখুঁত। এই পার্থক্যের মূল কারণ কী?

কনভারজেন্স রেট নির্ভর করে শিফটেড সিস্টেমের দুটি সবচেয়ে কাছের আইগেনভ্যালুর অনুপাতের উপর। শিফট ০-এ, লক্ষ্য আইগেনভ্যালু (১.৩২৪৮৭) ও দ্বিতীয়-নিকটতম (২.৪৬০৮১)-এর অনুপাত মোটামুটি বড় (দূরত্ব কম, তাই ধীর)। শিফট ২.৫-এ, লক্ষ্য আইগেনভ্যালু (২.৪৬০৮১) শিফটের অত্যন্ত কাছে, তাই (A − 2.5I)-এর ইনভার্সে সেই দিকের আইগেনভ্যালু বাকিদের তুলনায় বিপুলভাবে বড় হয়ে যায় — L38-এর "যত বড় অনুপাত, তত দ্রুত কনভারজেন্স" নিয়মটাই এখানে প্রযোজ্য, শুধু শিফট করা ম্যাট্রিক্সে।

অনুশীলন

  1. চিন্তা করুন: L38-এর তিনটি প্রকৃত আইগেনভ্যালু আনুমানিক ৫.২১৪৩২, ২.৪৬০৮১, ও ১.৩২৪৮৭। শিফট ৪.০ ব্যবহার করলে ইনভার্স পাওয়ার মেথড কোন আইগেনভ্যালুর দিকে কনভার্জ করবে বলে আপনার ধারণা?

    ৫.২১৪৩২-এর দিকে — কারণ শিফট ৪.০-এর সবচেয়ে কাছের আইগেনভ্যালু হলো ৫.২১৪৩২ (দূরত্ব ১.২১৪৩২), যেখানে ২.৪৬০৮১-এর দূরত্ব ১.৫৩৯১৯ এবং ১.৩২৪৮৭-এর দূরত্ব ২.৬৭৫১৩ — উভয়ই বেশি।

  2. পরীক্ষা করুন: দ্বিতীয় কোড সেলে inverse_power(A, 2.5, [1.0, 1.0, 1.0], 10)-কে inverse_power(A, 4.0, [1.0, 1.0, 1.0], 10)-এ বদলে Run চাপুন এবং আপনার অনুমান যাচাই করুন।

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

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

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