পাঠ ০৪ · ৫৭-এর মধ্যে · মডিউল ১
Home / Courses / Numerical Methods / স্ট্যাবিলিটি ও কনভারজেন্স

অ্যালগরিদম স্ট্যাবিলিটি, কন্ডিশনিং ও কনভারজেন্স

Algorithm stability, conditioning & convergence
১১ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

  • কন্ডিশনিং ও স্ট্যাবিলিটির মধ্যে পার্থক্য — একটি সমস্যার ধর্ম বনাম একটি অ্যালগরিদমের ধর্ম
  • ভালো-কন্ডিশনড ও ইল-কন্ডিশনড সমস্যা কী, এবং কেন ইল-কন্ডিশনড সমস্যায় "সঠিক" অ্যালগরিদমও অনির্ভরযোগ্য ফলাফল দিতে পারে
  • একটি সত্যিকারের ২x২ রৈখিক সমীকরণ পার্টার্বেশন ডেমো — হাতে-লেখা Cramer's rule দিয়ে সমাধান করে সংবেদনশীলতা পরিমাপ করা
  • কনভারজেন্সের মৌলিক ধারণা এবং কেন এটি এই কোর্সের বাকি অংশের কেন্দ্রীয় থিম

১ · কন্ডিশনিং — সমস্যার একটি ধর্ম

কন্ডিশনিংকন্ডিশনিং (Conditioning)একটি গাণিতিক সমস্যার নিজস্ব সংবেদনশীলতা — ইনপুটের ছোট পরিবর্তনে আউটপুট কতটা বদলায় তার পরিমাপ। এটি সমস্যার ধর্ম, ব্যবহৃত অ্যালগরিদমের নয়। বোঝায় একটি সমস্যা তার ইনপুটের ছোট পরিবর্তনের প্রতি কতটা সংবেদনশীল। একটি ভালো-কন্ডিশনড (well-conditioned) সমস্যায়, ইনপুটে একটি ছোট পরিবর্তন আউটপুটেও একটি ছোট, প্রত্যাশিত পরিবর্তন ঘটায়। একটি ইল-কন্ডিশনড (ill-conditioned) সমস্যায়, ইনপুটে একটি ক্ষুদ্র পরিবর্তন আউটপুটে বিশাল, অসামঞ্জস্যপূর্ণ পরিবর্তন ঘটাতে পারে — এবং এটি ঘটে এমনকি একটি গাণিতিকভাবে সম্পূর্ণ সঠিক অ্যালগরিদম ব্যবহার করলেও, কারণ সমস্যাটাই স্বভাবতই অস্থির।

একটি ধ্রুপদী উদাহরণ হলো দুটি রেখার ছেদবিন্দু বের করা। যদি দুটি রেখা একে অপরের প্রায় সমান্তরাল হয়, তাদের ছেদবিন্দু বের করা ইল-কন্ডিশনড — কারণ একটি রেখার ঢালে সামান্য পরিবর্তনও ছেদবিন্দুকে অনেক দূরে সরিয়ে দিতে পারে। নিচের কোড সেলে ঠিক এই ঘটনাটি একটি ২x২ রৈখিক সমীকরণ সিস্টেমে হাতে-লেখা Cramer's rule দিয়ে সরাসরি দেখানো হয়েছে।

২ · সত্যিকারের ডেমো — ভালো-কন্ডিশনড বনাম ইল-কন্ডিশনড ২x২ সিস্টেম

দুটি অজানা $x, y$-এর একটি $2 \times 2$ সিস্টেম:

$$a_{11}x + a_{12}y = b_1 \qquad a_{21}x + a_{22}y = b_2$$

Cramer's rule দিয়ে হাতে সমাধান করা যায়:

$$\text{det} = a_{11}a_{22} - a_{12}a_{21}, \qquad x = \frac{b_1 a_{22} - a_{12} b_2}{\text{det}}, \qquad y = \frac{a_{11} b_2 - b_1 a_{21}}{\text{det}}$$

নিচের কোড সেলে দুটি সিস্টেম সমাধান করা হয়েছে — একটি ভালো-কন্ডিশনড (2x + y = 5, x - 3y = -1) এবং একটি ইল-কন্ডিশনড, প্রায়-সিঙ্গুলার (x + y = 2, x + 1.0001y = 2.0001 — দুটি রেখা প্রায় সমান্তরাল)। প্রতিটি সিস্টেমে a₂₂-কে ঠিক 0.001 বাড়িয়ে দেখা হয়েছে সমাধান কতটা বদলায়।

Python
def solve_2x2(a11, a12, a21, a22, b1, b2):
    det = a11 * a22 - a12 * a21
    x = (b1 * a22 - a12 * b2) / det
    y = (a11 * b2 - b1 * a21) / det
    return x, y, det

print("=== ভালো-কন্ডিশনড সিস্টেম ===")
print("2x + y = 5 ;  x - 3y = -1")
a11, a12, a21, a22, b1, b2 = 2.0, 1.0, 1.0, -3.0, 5.0, -1.0
x1, y1, det1 = solve_2x2(a11, a12, a21, a22, b1, b2)
print(f"মূল সমাধান: x = {x1:.6f}, y = {y1:.6f}   (det = {det1:.6f})")

x1p, y1p, det1p = solve_2x2(a11, a12, a21, a22 + 0.001, b1, b2)
print(f"a22 += 0.001 পর: x = {x1p:.6f}, y = {y1p:.6f}   (det = {det1p:.6f})")
dx1, dy1 = x1p - x1, y1p - y1
print(f"সমাধানের পরিবর্তন: dx = {dx1:.8f}, dy = {dy1:.8f}")
print()

print("=== ইল-কন্ডিশনড (প্রায়-সিঙ্গুলার) সিস্টেম ===")
print("x + y = 2 ;  x + 1.0001y = 2.0001   (দুই রেখা প্রায় সমান্তরাল)")
a11, a12, a21, a22, b1, b2 = 1.0, 1.0, 1.0, 1.0001, 2.0, 2.0001
x2, y2, det2 = solve_2x2(a11, a12, a21, a22, b1, b2)
print(f"মূল সমাধান: x = {x2:.6f}, y = {y2:.6f}   (det = {det2:.8f})")

x2p, y2p, det2p = solve_2x2(a11, a12, a21, a22 + 0.001, b1, b2)
print(f"a22 += 0.001 পর: x = {x2p:.6f}, y = {y2p:.6f}   (det = {det2p:.8f})")
dx2, dy2 = x2p - x2, y2p - y2
print(f"সমাধানের পরিবর্তন: dx = {dx2:.8f}, dy = {dy2:.8f}")
print()

shift1 = abs(dx1) + abs(dy1)
shift2 = abs(dx2) + abs(dy2)
print(f"ভালো-কন্ডিশনড মোট পরিবর্তন = {shift1:.8f}")
print(f"ইল-কন্ডিশনড মোট পরিবর্তন  = {shift2:.8f}")
print(f"সংবেদনশীলতার অনুপাত = {shift2 / shift1:.2f}x")

    
বাস্তব আউটপুট দেখায় ভালো-কন্ডিশনড সিস্টেমে মূল সমাধান x = 2.0, y = 1.0 (det = -7.0) — a22-তে 0.001 পরিবর্তনের পর সমাধান বদলে হয় x ≈ 1.999857, y ≈ 1.000286, অর্থাৎ মোট পরিবর্তন মাত্র ০.০০০৪২৮৭। কিন্তু ইল-কন্ডিশনড সিস্টেমে মূল সমাধান x ≈ 1.0, y ≈ 1.0 (det ≈ 0.0001 — শূন্যের অত্যন্ত কাছাকাছি, প্রায়-সিঙ্গুলার), আর একই 0.001 পরিবর্তনের পর সমাধান লাফিয়ে হয়ে যায় x ≈ 1.909, y ≈ 0.0909 — মোট পরিবর্তন ১.৮১৮! সংবেদনশীলতার অনুপাত দাঁড়ায় ~৪২৪১ গুণ — একই মাত্রার ইনপুট পরিবর্তন ইল-কন্ডিশনড সিস্টেমে হাজার গুণেরও বেশি বড় প্রভাব ফেলেছে, শুধু কারণ এর নির্ণায়ক (determinant) শূন্যের অত্যন্ত কাছাকাছি — অর্থাৎ দুই সমীকরণের রেখা দুটি প্রায় সমান্তরাল।
নির্ণায়ক (determinant) ও কন্ডিশনিংয়ের সংযোগ

একটি $2\times2$ সিস্টেমের নির্ণায়ক শূন্যের যত কাছাকাছি, সমাধান তত বেশি অস্থির — কারণ নির্ণায়ক শূন্য মানে সিস্টেমটি সিঙ্গুলার (কোনো নির্দিষ্ট সমাধান নেই, বা অসীম সমাধান)। M14-এ (ম্যাট্রিক্স নর্ম, কন্ডিশন নাম্বার ও এরর বাউন্ড) এই ধারণাকে একটি সুনির্দিষ্ট সংখ্যাগত পরিমাপ — কন্ডিশন নাম্বার — এ পরিণত করে বড় ম্যাট্রিক্সেও সাধারণীকরণ করা হবে।

৩ · স্ট্যাবিলিটি — অ্যালগরিদমের একটি ধর্ম

কন্ডিশনিং সমস্যার নিজস্ব ধর্ম হলেও, স্ট্যাবিলিটি নির্ভর করে আমরা সমস্যাটি কীভাবে সমাধান করছি তার উপর। একটি ভালো-কন্ডিশনড সমস্যাও একটি অস্থিতিশীল (numerically unstable) অ্যালগরিদম দিয়ে সমাধান করলে ভুল ফলাফল দিতে পারে — কারণ অ্যালগরিদমটি নিজেই গণনার মাঝপথে রাউন্ড-অফ এরর বাড়িয়ে তোলে (যেমন L03-এর catastrophic cancellation বারবার ঘটলে)। বিপরীতে, একটি স্থিতিশীল অ্যালগরিদম গণনার সময় এরর জমতে দেয় না বা নিয়ন্ত্রণে রাখে। M3-এ (গসিয়ান এলিমিনেশন) আমরা দেখব কীভাবে পিভোটিং নামের একটি সহজ কৌশল একই গাণিতিক সমস্যাকে অনেক বেশি স্থিতিশীলভাবে সমাধান করতে সাহায্য করে (বিস্তারিত M3/L12-এ)।

৪ · কনভারজেন্স — ইটারেটিভ মেথডের পরিমাপ

এই কোর্সের বেশিরভাগ মেথডই ইটারেটিভ — অর্থাৎ এরা একটি প্রাথমিক অনুমান থেকে শুরু করে ধাপে ধাপে সঠিক উত্তরের কাছাকাছি পৌঁছায় (L01-এর বাইসেকশন ডেমো এর একটি উদাহরণ)। কনভারজেন্সকনভারজেন্স (Convergence)একটি ইটারেটিভ মেথডের ধারাবাহিক অনুমানগুলো সত্যিকারের উত্তরের কতটা কাছাকাছি এবং কত দ্রুত পৌঁছায় তার বর্ণনা। বর্ণনা করে এই প্রক্রিয়াটি কত দ্রুত এবং কতটা নির্ভরযোগ্যভাবে ঘটে। L01-এর বাইসেকশন মেথড লিনিয়ার কনভারজেন্স দেখিয়েছিল (প্রতি ধাপে ইন্টারভাল অর্ধেক)। M2-তে আমরা দেখব নিউটন-রাফসন মেথড কোয়াড্রেটিক কনভারজেন্স দেখায় (প্রতি ধাপে এরর মোটামুটি বর্গ হয়ে যায়) — অনেক দ্রুত, কিন্তু কখনো কখনো সম্পূর্ণ ব্যর্থও হতে পারে। কনভারজেন্স, কন্ডিশনিং ও স্ট্যাবিলিটি — এই তিনটি ধারণা একসাথে ঠিক করে একটি নিউমেরিক্যাল সমাধান বাস্তবে কতটা নির্ভরযোগ্য, এবং Module 1-এর বাকি অংশ জুড়ে এই তিনটিই ফিরে ফিরে আসবে।

মূল কথা · Key takeaway

কন্ডিশনিং সমস্যার ধর্ম, স্ট্যাবিলিটি অ্যালগরিদমের ধর্ম, আর কনভারজেন্স বর্ণনা করে ইটারেটিভ প্রক্রিয়া কত দ্রুত সঠিক উত্তরে পৌঁছায় — তিনটি ভিন্ন কিন্তু গভীরভাবে সংযুক্ত ধারণা। এই পাঠের ডেমো সরাসরি দেখাল একই আকারের ইনপুট পরিবর্তন (0.001) দুটি ভিন্ন সমস্যায় সম্পূর্ণ ভিন্ন ফল দিতে পারে — শুধু সমস্যার গঠনের কারণে, অ্যালগরিদমের কোনো ভুলের কারণে নয়। M1 এখানেই শেষ — এখন থেকে আমরা এই ভিত্তির উপর দাঁড়িয়ে M2-তে সরাসরি রুট-ফাইন্ডিং মেথড (বাইসেকশন, ফিক্সড-পয়েন্ট, নিউটন-রাফসন, সেকেন্ট) নিয়ে গভীরে যাব।

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

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

প্র ০১ ইল-কন্ডিশনড সিস্টেমের det ≈ 0.0001 ছিল, যা শূন্যের অত্যন্ত কাছাকাছি। যদি det ঠিক 0 হতো, তাহলে solve_2x2 ফাংশনে কী ঘটত?

কোডে x = (...) / det লাইনে শূন্য দিয়ে ভাগ (ZeroDivisionError) হতো — Python সাথে সাথে প্রোগ্রাম থামিয়ে দিত। গাণিতিকভাবে এর মানে হলো সিস্টেমটি সম্পূর্ণ সিঙ্গুলার — হয় কোনো সমাধান নেই, নয়তো অসীম সমাধান আছে (দুটি রেখা হুবহু একই বা সম্পূর্ণ সমান্তরাল)। বাস্তব নিউমেরিক্যাল কোডে তাই det শূন্যের কতটা কাছাকাছি তা একটি টলারেন্সের সাথে যাচাই করে সতর্কবার্তা দেওয়া হয়, শুধু ভাগ করার আগে চুপচাপ চেষ্টা করা হয় না।

প্র ০২ যদি আমরা একই 0.001 পরিবর্তন a22-এর বদলে b2-তে করতাম, আপনার কী ধারণা — ইল-কন্ডিশনড সিস্টেমে প্রভাব কি একই রকম বড় হতো, নাকি ভিন্ন হতো?

প্রভাব একই ধরনের বড় হতো, কারণ সংবেদনশীলতার মূল উৎস হলো det শূন্যের কাছাকাছি হওয়া — Cramer's rule-এর সূত্রে det হর (denominator) হিসেবে থাকে, তাই যেকোনো ইনপুট (a11, a12, a21, a22, b1, b2-এর যেকোনোটি)-এর ছোট পরিবর্তনও det-এর কাছাকাছি-শূন্য মাত্রার কারণে অনুপাতিকভাবে বিবর্ধিত হয়ে সমাধানে প্রতিফলিত হয়। নির্দিষ্ট সংখ্যাটা ভিন্ন হবে (কারণ প্রতিটি প্যারামিটার সূত্রে আলাদাভাবে আসে), কিন্তু "ছোট ইনপুট বদল = বড় আউটপুট বদল" প্যাটার্নটি একই থাকবে।

প্র ০৩ বাস্তব জীবনে ইঞ্জিনিয়ারিং পরিমাপে সবসময় কিছুটা এরর থাকে (যেমন একটি সেন্সর ±0.001 নির্ভুলতায় মাপে)। এই পাঠের ডেমোর আলোকে, কেন একটি ইল-কন্ডিশনড মডেল ব্যবহার করে বাস্তব সেন্সর-ডেটা থেকে সিদ্ধান্ত নেওয়া বিপজ্জনক হতে পারে?

কারণ সেন্সরের স্বাভাবিক পরিমাপ-এরর (যা এড়ানো অসম্ভব) যদি একটি ইল-কন্ডিশনড মডেলের ইনপুট হয়, তাহলে সেই ছোট, স্বাভাবিক এররই মডেলের আউটপুটে একটি বিশাল, বিভ্রান্তিকর পরিবর্তন ঘটাতে পারে — ঠিক যেমন এই পাঠে 0.001 পরিবর্তনে সমাধান ৪২৪১ গুণ বেশি সংবেদনশীলভাবে বদলে গেছে। ব্যবহারিক ফল: মডেলটি হয়তো দুটি ভিন্ন পরিমাপ-রানে সম্পূর্ণ ভিন্ন উপসংহারে পৌঁছাবে, যদিও প্রকৃত অবস্থা প্রায় অপরিবর্তিত ছিল — তাই ইঞ্জিনিয়াররা প্রায়ই এমন সমস্যা সেটআপ (যেমন প্রায়-সমান্তরাল সীমাবদ্ধতা বা রিডানডেন্ট পরিমাপ) এড়িয়ে চলেন, অথবা M11-এর মতো সেনসিটিভিটি অ্যানালাইসিস কৌশল ব্যবহার করে ফলাফলের নির্ভরযোগ্যতা যাচাই করেন।

অনুশীলন

  1. চিন্তা করুন: ইল-কন্ডিশনড সিস্টেমে যদি দ্বিতীয় সমীকরণকে x + 1.00001y = 2.00001 (অর্থাৎ রেখা দুটি আগের চেয়েও বেশি কাছাকাছি সমান্তরাল) করা হয়, তাহলে একই 0.001 পরিবর্তনে সংবেদনশীলতার অনুপাত আগের ~৪২৪১-এর চেয়ে বাড়বে না কমবে বলে আপনার ধারণা?

    বাড়বে — সম্ভবত আরও অনেক বড় অনুপাতে। কারণ a22 = 1.00001 করলে det = a11*a22 - a12*a21 = 1.00001 - 1 = 0.00001, যা আগের det ≈ 0.0001-এর চেয়ে ১০ গুণ শূন্যের কাছাকাছি। যেহেতু সংবেদনশীলতা মোটামুটি det-এর ব্যস্তানুপাতিক (Cramer's rule-এর হর হিসেবে), সংবেদনশীলতার অনুপাত মোটামুটি আরও ১০ গুণ বাড়ার কথা।

  2. পরীক্ষা করুন: উপরের কোড সেলে ইল-কন্ডিশনড সিস্টেমের a22 = 1.0001-কে a22 = 1.00001-এ এবং b2 = 2.0001-কে b2 = 2.00001-এ পরিবর্তন করে Run চেপে আপনার অনুমান যাচাই করুন।

    এই পরিবর্তনে det ≈ 0.00001 হয় (আগের 0.0001-এর ১/১০), আর একই 0.001 পার্টার্বেশনে সমাধানের পরিবর্তন আরও বহুগুণ বেড়ে যায় — সংবেদনশীলতার অনুপাত দশ হাজারের ঘরে পৌঁছাতে পারে। এটি নিশ্চিত করে যে নির্ণায়ক শূন্যের যত কাছাকাছি যায়, কন্ডিশনিং তত দ্রুত (এবং প্রায় ব্যস্তানুপাতিকভাবে) খারাপ হতে থাকে — এটাই M14-এর কন্ডিশন নাম্বারের পেছনের মূল সংখ্যাগত সহজাত ধর্ম।

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

আগের পাঠ
এররের উৎস — রাউন্ড-অফ, ট্রাংকেশন ও প্রোপাগেশন