পাঠ ০৮ · ৫৭-এর মধ্যে · মডিউল ২
Home / Courses / Numerical Methods / সেকেন্ট ও রেগুলা ফালসি

সেকেন্ট মেথড ও রেগুলা ফালসি

Secant method & regula falsi
৭ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

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

১ · সেকেন্ট মেথড — ডেরিভেটিভ ছাড়াই নিউটনের গতি

L07-এ আমরা দেখেছি নিউটন-রাফসনের গতি আসে ডেরিভেটিভ f'(x) ব্যবহার করে, কিন্তু বাস্তবে অনেক ফাংশনের ডেরিভেটিভ বিশ্লেষণাত্মকভাবে (analytically) বের করা কঠিন বা ব্যয়বহুল হতে পারে। সেকেন্ট মেথডSecant methodনিউটন-রাফসনের ডেরিভেটিভকে দুটি সাম্প্রতিক বিন্দুর মধ্য দিয়ে টানা একটি সিকান্ট লাইনের ঢাল দিয়ে আনুমানিক করে রুট খোঁজার মেথড — প্রতি ধাপে সর্বশেষ দুটি অনুমান ব্যবহার করে। এই সমস্যা সমাধান করে — ডেরিভেটিভের বদলে সর্বশেষ দুটি বিন্দু (x_{n-1}, f(x_{n-1})) ও (x_n, f(x_n))-এর মধ্য দিয়ে একটি সরলরেখা (সিকান্ট লাইন) টেনে, তার ঢালকে ডেরিভেটিভের আনুমানিক মান হিসেবে ব্যবহার করে:

$$x_{n+1} = x_n - f(x_n) \cdot \frac{x_n - x_{n-1}}{f(x_n) - f(x_{n-1})}$$

লক্ষ্য করুন এই সূত্রটি নিউটন-রাফসনের সূত্রের মতোই দেখতে, শুধু f'(x_n)-এর জায়গায় (f(x_n) - f(x_{n-1})) / (x_n - x_{n-1}) — যা ঠিক ডেরিভেটিভের সংজ্ঞার একটি আনুমানিক রূপ (ফাইনাইট ডিফারেন্স, M5-এ বিস্তারিত)। সেকেন্ট মেথড শুরু করতে দুটি প্রাথমিক অনুমান প্রয়োজন (নিউটনের একটির বদলে), এবং এটি বাইসেকশনের মতো ব্র্যাকেট বজায় রাখার প্রয়োজন নেই।

২ · সরাসরি তুলনা — নিউটন-রাফসন বনাম সেকেন্ট

একই সমীকরণ f(x) = x³ - x - 2-এ, একই টলারেন্স 10⁻⁸ পর্যন্ত, নিউটন-রাফসন (x₀ = 1.2 থেকে) ও সেকেন্ট মেথড (x₀ = 1.0, x₁ = 1.2 থেকে) একসাথে চালিয়ে দেখা যাক:

Python
def f(x):
    return x**3 - x - 2

def fprime(x):
    return 3 * x**2 - 1

TOL = 1e-8

print("=== নিউটন-রাফসন (x0=1.2) ===")
x = 1.2
nr_iters = None
for i in range(1, 20):
    fx = f(x)
    x_new = x - fx / fprime(x)
    if abs(x_new - x) < TOL:
        nr_iters = i
        x = x_new
        break
    x = x_new
print(f"নিউটন-রাফসন {TOL} টলারেন্সে পৌঁছাল {nr_iters} ইটারেশনে, x = {x:.10f}")

print()
print("=== সেকেন্ট মেথড (x0=1.0, x1=1.2) ===")
x0, x1 = 1.0, 1.2
sec_iters = None
for i in range(1, 20):
    f0, f1 = f(x0), f(x1)
    x2 = x1 - f1 * (x1 - x0) / (f1 - f0)
    if abs(x2 - x1) < TOL:
        sec_iters = i
        x1 = x2
        break
    x0, x1 = x1, x2
print(f"সেকেন্ট {TOL} টলারেন্সে পৌঁছাল {sec_iters} ইটারেশনে, x = {x1:.10f}")

print()
print(f"সারসংক্ষেপ: নিউটন-রাফসন = {nr_iters} ইটারেশন, সেকেন্ট = {sec_iters} ইটারেশন")
print(f"নিউটন-রাফসন প্রতি ধাপে ১টি ডেরিভেটিভ গণনা করে; সেকেন্ট একটিও করে না, শুধু f(x) গণনা করে")

    
নিউটন-রাফসন ৫ ইটারেশনে কনভার্জ করে, সেকেন্ট ৭ ইটারেশনে — সেকেন্ট একটু বেশি ইটারেশন নেয়, কারণ এর কনভারজেন্স অর্ডার (প্রায় ১.৬১৮, সোনালী অনুপাত) নিউটনের কোয়াড্রেটিক অর্ডার (২)-এর চেয়ে কম। কিন্তু বাস্তবে সেকেন্ট প্রায়ই দ্রুততর হতে পারে যখন f'(x) বিশ্লেষণাত্মকভাবে গণনা করা ব্যয়বহুল — প্রতি ধাপে একটি অতিরিক্ত ডেরিভেটিভ গণনার খরচের তুলনায় সেকেন্টের অতিরিক্ত ২টি ইটারেশনের খরচ প্রায়ই কম।

৩ · রেগুলা ফালসি — বাইসেকশনের নিরাপত্তা + সেকেন্টের ধারণা

রেগুলা ফালসিRegula Falsi / False Position methodবাইসেকশনের মতো একটি বৈধ ব্র্যাকেট (চিহ্ন-বিপরীত ইন্টারভাল) বজায় রেখে, কিন্তু মধ্যবিন্দুর বদলে সেকেন্ট লাইনের x-অক্ষ-ছেদ বিন্দু ব্যবহার করে পরবর্তী অনুমান বেছে নেওয়ার মেথড। বাইসেকশনের নিরাপত্তা রাখতে চায় (সবসময় একটি বৈধ, চিহ্ন-বিপরীত ব্র্যাকেট বজায় রাখে) কিন্তু মাঝবিন্দুর বদলে সেকেন্ট লাইনের x-অক্ষ-ছেদ বিন্দু ব্যবহার করে — ধারণাটি হলো, যদি ফাংশন একদিকে অন্যদিকের চেয়ে অনেক বেশি "খাড়া" হয়, মধ্যবিন্দু নেওয়ার চেয়ে সেই ঢাল ব্যবহার করা আরও ভালো অনুমান দিতে পারে।

Python
reference_root = 1.5213797068045678
TOL = 1e-8

def f(x):
    return x**3 - x - 2

a, b = 1.0, 2.0
fa, fb = f(a), f(b)
print(f"{'ইটার':>4} {'x':>16} {'f(x)':>14}")

x_prev = None
rf_iters = None
for i in range(1, 25):
    x = b - fb * (b - a) / (fb - fa)
    fx = f(x)
    print(f"{i:4d} {x:16.10f} {fx:+14.10f}")
    if x_prev is not None and abs(x - x_prev) < TOL:
        rf_iters = i
        break
    if fa * fx < 0:
        b, fb = x, fx
    else:
        a, fa = x, fx
    x_prev = x

print()
print(f"রেগুলা ফালসি {TOL} টলারেন্সে পৌঁছাল {rf_iters} ইটারেশনে, x = {x:.10f}")
print(f"রেফারেন্স মূলের বিপরীতে প্রকৃত এরর: {abs(x - reference_root):.2e}")

    
লক্ষণীয়ভাবে, রেগুলা ফালসির লাগে ১৬ ইটারেশন — সেকেন্টের ৭-এর চেয়ে অনেক বেশি, এমনকি বাইসেকশনের প্রত্যাশিত ~২০-এর কাছাকাছি! আউটপুট লক্ষ্য করলে দেখা যায় প্রান্ত b = 2.0 পুরো প্রক্রিয়া জুড়ে কখনো আপডেট হয়নি — f(x) সবসময় ঋণাত্মক থেকেছে, তাই a-ই বারবার সরেছে। এটাই রেগুলা ফালসির ক্লাসিক দুর্বলতা: যখন ফাংশন একদিকে উত্তল (convex) হয়, একটি প্রান্ত "আটকে" যায় এবং মেথডটি কার্যত এক-দিকের ধীর, লিনিয়ার কনভারজেন্সে পরিণত হয়।
মূল কথা · Key takeaway

সেকেন্ট মেথড ডেরিভেটিভ ছাড়াই নিউটন-রাফসনের প্রায়-কোয়াড্রেটিক গতি পায়, তবে ব্র্যাকেটের কোনো নিরাপত্তা-নিশ্চয়তা দেয় না (নিউটনের মতোই ভুল দিকে যেতে পারে)। রেগুলা ফালসি ব্র্যাকেটের নিরাপত্তা রাখে, কিন্তু ব্যবহারিক গতির দিক থেকে অনেক সময় হতাশাজনক হতে পারে — একটি প্রান্ত আটকে থাকার সমস্যার কারণে। L09-এ আমরা বাইসেকশন, ফিক্সড-পয়েন্ট, নিউটন-রাফসন ও সেকেন্ট — এই চারটি মেথডকে একই সমীকরণে, একই টলারেন্সে, একসাথে চালিয়ে সম্পূর্ণ ছবিটি দেখব।

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

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

প্র ০১ সেকেন্ট মেথডের ৭ ইটারেশনের প্রতিটিতে ১টি করে f(x) গণনা লাগে (আগের মানটি সংরক্ষিত থাকে), কিন্তু নিউটন-রাফসনের ৫ ইটারেশনের প্রতিটিতে ১টি f(x) এবং ১টি f'(x) গণনা লাগে। মোট ফাংশন-ইভ্যালুয়েশনের হিসেবে কোনটি "সস্তা"?

যদি f'(x) গণনার খরচ f(x) গণনার প্রায় সমান হয়, তাহলে নিউটন-রাফসনের মোট খরচ প্রায় ৫ × ২ = ১০ ইভ্যালুয়েশন, আর সেকেন্টের প্রায় ৭ + ২ = ৯ (শুরুর দুটি বিন্দুর জন্য অতিরিক্ত)। এই ক্ষেত্রে প্রায় কাছাকাছি, কিন্তু যদি f'(x) বিশ্লেষণাত্মকভাবে বের করা কঠিন বা ব্যয়বহুল ফাংশনে (যেমন একটি জটিল সিমুলেশনের আউটপুট), সেকেন্ট প্রায়ই স্পষ্টভাবে সস্তা।

প্র ০২ রেগুলা ফালসিতে প্রান্ত b = 2.0 "আটকে" গিয়েছিল কারণ f(x) সবসময় ঋণাত্মক থাকছিল। আপনার কী মনে হয়, এই সমস্যাটি ঠেকাতে কী পরিবর্তন করা যেতে পারে?

একটি সাধারণ সমাধান হলো "মডিফায়েড রেগুলা ফালসি" — যদি একই প্রান্ত পরপর কয়েকবার আটকে থাকে, তার f মান কৃত্রিমভাবে অর্ধেক করে দেওয়া, যাতে পরবর্তী সিকান্ট-বিন্দু সেই প্রান্তের দিকে কম টান খায় এবং বাইসেকশনের মতো আচরণের দিকে ফিরে আসে। এটি একটি ব্যবহারিক কৌশল যা রেগুলা ফালসিকে বাস্তবে অনেক বেশি প্রতিযোগিতামূলক করে তোলে।

প্র ০৩ সেকেন্ট মেথড শুরু করতে দুটি প্রাথমিক বিন্দু দরকার, কিন্তু বাইসেকশন বা রেগুলা ফালসির মতো সেগুলোর চিহ্ন বিপরীত হতে হয় না। এটি কি সুবিধা নাকি ঝুঁকি?

উভয়ই — সুবিধা কারণ ব্র্যাকেট খোঁজার প্রয়োজন নেই (কখনো কখনো একটি বৈধ ব্র্যাকেট খুঁজে পাওয়াই কঠিন), কিন্তু ঝুঁকিও বটে কারণ কোনো "নিরাপত্তা জাল" নেই — নিউটন-রাফসনের মতোই সেকেন্ট ভুল দিকে ডাইভার্জ করতে পারে বা এমন একটি বিন্দুতে যেতে পারে যেখানে f(x_n) - f(x_{n-1}) প্রায় শূন্য হয়ে যায় (হর শূন্যের কাছে, L07-এর ডেরিভেটিভ-শূন্য সমস্যার অনুরূপ)।

অনুশীলন

  1. চিন্তা করুন: রেগুলা ফালসি কোড সেলে যদি প্রাথমিক ব্র্যাকেট [1, 2]-এর বদলে ফাংশনের আকৃতি সম্পূর্ণ ভিন্ন এমন একটি ব্র্যাকেট ব্যবহার করা হতো যেখানে উভয় প্রান্ত থেকেই f(x) প্রতিসমভাবে পরিবর্তিত হয়, "আটকে থাকা প্রান্ত" সমস্যাটি কি এখনও হতো?

    সাধারণত না — "আটকে থাকা প্রান্ত" সমস্যা মূলত ঘটে যখন ফাংশন ব্র্যাকেটের এক অংশে অন্য অংশের চেয়ে অনেক বেশি উত্তল বা অবতল হয় (এখানে x³-এর কারণে)। যদি ফাংশন ব্র্যাকেটে প্রায় রৈখিক (linear) হয়, রেগুলা ফালসি খুব দ্রুত কনভার্জ করবে, প্রায় সেকেন্ট মেথডের মতোই।

  2. পরীক্ষা করুন: তুলনা কোড সেলে সেকেন্ট মেথডের প্রাথমিক বিন্দু x0, x1 = 1.0, 1.2 -কে x0, x1 = 1.4, 1.6-এ (রুটের আরও কাছে) বদলে Run চেপে দেখুন ইটারেশন সংখ্যা কমে কিনা।

    হ্যাঁ, রুটের কাছাকাছি প্রাথমিক বিন্দু শুরু করলে সাধারণত কম ইটারেশন লাগে (হয়তো ৪–৫ ইটারেশনে নেমে আসতে পারে), কারণ সিকান্ট লাইনটি শুরু থেকেই ফাংশনের প্রকৃত আকৃতির কাছাকাছি একটি ভালো আনুমানিক ঢাল দেয় — ঠিক যেমন নিউটন-রাফসনেও রুটের কাছে শুরু করলে কম ইটারেশন লাগে।

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

আগের পাঠ
নিউটন-রাফসন মেথড