পলিনোমিয়াল ইন্টারপোলেশন — লাগ্রাঞ্জ ফর্ম
এই পাঠে যা শিখবেন
- ইন্টারপোলেশন সমস্যাটি ঠিক কী, এবং কেন এটি রুট-ফাইন্ডিং বা লিনিয়ার সিস্টেম সমাধানের থেকে আলাদা একটি সমস্যা
- লাগ্রাঞ্জ বেসিস পলিনোমিয়াল
Lᵢ(x)কীভাবে গঠিত হয় এবং কেন এটি ঠিক ডেটা পয়েন্টের মধ্য দিয়ে যায় - Python-এ হাতে-লেখা লাগ্রাঞ্জ ইন্টারপোলেশন বাস্তবায়ন করা, কোনো বহিরাগত লাইব্রেরি ছাড়াই
- ইন্টারপোলেটেড মান বনাম প্রকৃত ফাংশন মানের মধ্যে সত্যিকারের এরর পরিমাপ করা
১ · ইন্টারপোলেশন সমস্যা
ধরুন আমাদের কাছে n+1টি ডেটা পয়েন্ট আছে: (x₀,y₀), (x₁,y₁), ..., (xₙ,yₙ) — যেমন
কোনো পরীক্ষার মাপা রিডিং, অথবা একটি জটিল ফাংশনের কয়েকটি নমুনা মান। ইন্টারপোলেশনInterpolationজানা ডেটা পয়েন্টগুলোর মধ্য দিয়ে ঠিক যাওয়া এমন একটি ফাংশন (সাধারণত পলিনোমিয়াল) তৈরি করা, যা দিয়ে ডেটা পয়েন্টগুলোর মধ্যবর্তী বা কাছাকাছি যেকোনো বিন্দুতে মান আনুমানিক করা যায়। সমস্যাটি হলো — এমন একটি ফাংশন P(x) খুঁজে বের করা যা
প্রতিটি xᵢ-তে ঠিক yᵢ মান দেয় (P(xᵢ) = yᵢ), এবং তারপর সেই P(x)
দিয়ে নতুন কোনো x-এ মান আনুমানিক করা।
এটি M2-এর রুট-ফাইন্ডিং (যেখানে f(x) = 0 সমাধান করা হয়) বা M3-এর লিনিয়ার সিস্টেম সমাধান
(যেখানে অজানা ভেরিয়েবল বের করা হয়) থেকে আলাদা একটি সমস্যা — এখানে আমরা একটি নতুন ফাংশন তৈরি
করছি যা জানা ডেটার সাথে মিলে যায়। একটি মূল উপপাদ্য বলে — n+1টি ভিন্ন x-মানের
ডেটা পয়েন্টের মধ্য দিয়ে ঠিক একটি ডিগ্রি-n (বা তার কম) পলিনোমিয়াল যায়।
লাগ্রাঞ্জ ফর্ম এবং নিউটনের ডিভাইডেড-ডিফারেন্স ফর্ম (L17) — দুটোই এই একই পলিনোমিয়াল লেখার
দুটি ভিন্ন উপায় মাত্র।
২ · লাগ্রাঞ্জ বেসিস পলিনোমিয়াল
লাগ্রাঞ্জ ফর্মের মূল কৌশল হলো — প্রতিটি ডেটা পয়েন্ট i-এর জন্য একটি বিশেষ "বেসিস পলিনোমিয়াল"
Lᵢ(x) তৈরি করা যা xᵢ-তে ঠিক ১ এবং বাকি সব xⱼ (j≠i)-তে
ঠিক ০ মান দেয়:
তারপর পুরো ইন্টারপোলেটিং পলিনোমিয়াল হলো এই বেসিসগুলোর একটি ওয়েটেড যোগফল, যেখানে ওয়েট হলো yᵢ:
লক্ষ্য করুন — যখন x = xₖ বসানো হয়, তখন Lₖ(xₖ) = 1 কিন্তু বাকি সব
Lᵢ(xₖ) = 0 (i≠k), তাই P(xₖ) = yₖ — ঠিক যা আমরা চাই। এই ধর্মটাই
নিশ্চিত করে পলিনোমিয়ালটি প্রতিটি ডেটা পয়েন্টের মধ্য দিয়ে ঠিক যায়।
ফর্মুলাটি সরাসরি বোঝা যায় এবং কোড করা সহজ — কোনো লিনিয়ার সিস্টেম সমাধান করার দরকার নেই।
একটি নতুন ডেটা পয়েন্ট যোগ করলে সব বেসিস পলিনোমিয়াল আবার গণনা করতে হয় — L17-এর নিউটন ফর্মে এই সমস্যা নেই।
অনেক বেশি ডেটা পয়েন্ট মানে অনেক উঁচু ডিগ্রির পলিনোমিয়াল — L18-এ দেখানো হবে এটি কীভাবে মারাত্মক ভুল (রুঙ্গের ফেনোমেনন) তৈরি করতে পারে।
৩ · একটি সত্যিকারের ডেমো — sin(x) ইন্টারপোলেট করা
নিচের কোড সেলে math.sin(x)-কে x = 0.0, 0.5, 1.0, 1.5, 2.0 — এই ৫টি বিন্দুতে
স্যাম্পল করে একটি ডিগ্রি-৪ লাগ্রাঞ্জ পলিনোমিয়াল তৈরি করা হয়েছে। তারপর এই পলিনোমিয়াল দিয়ে
x = 1.2 (যা স্যাম্পল পয়েন্টগুলোর মাঝেই আছে, কিন্তু নিজে কোনো স্যাম্পল পয়েন্ট নয়) বিন্দুতে
মান আনুমানিক করে প্রকৃত math.sin(1.2)-এর সাথে তুলনা করা হয়েছে।
import math
xs = [0.0, 0.5, 1.0, 1.5, 2.0]
ys = [math.sin(x) for x in xs]
def lagrange_interpolate(xs, ys, x):
total = 0.0
n = len(xs)
for i in range(n):
term = ys[i]
for j in range(n):
if j != i:
term *= (x - xs[j]) / (xs[i] - xs[j])
total += term
return total
print("স্যাম্পল পয়েন্ট:")
for x, y in zip(xs, ys):
print(f" x={x} sin(x)={y:.6f}")
x_new = 1.2
p_val = lagrange_interpolate(xs, ys, x_new)
true_val = math.sin(x_new)
err = abs(p_val - true_val)
print()
print(f"x_new = {x_new}")
print(f"লাগ্রাঞ্জ ইন্টারপোলেটেড P({x_new}) = {p_val:.8f}")
print(f"প্রকৃত math.sin({x_new}) = {true_val:.8f}")
print(f"পরম এরর = {err:.8f}")
x_new2 = 1.9
p_val2 = lagrange_interpolate(xs, ys, x_new2)
true_val2 = math.sin(x_new2)
err2 = abs(p_val2 - true_val2)
print()
print(f"x_new2 = {x_new2}")
print(f"লাগ্রাঞ্জ ইন্টারপোলেটেড P({x_new2}) = {p_val2:.8f}")
print(f"প্রকৃত math.sin({x_new2}) = {true_val2:.8f}")
print(f"পরম এরর = {err2:.8f}")
x = 1.2-তে লাগ্রাঞ্জ পলিনোমিয়াল দেয় ০.৯৩১৮৭২২৫, আর প্রকৃত
math.sin(1.2) হলো ০.৯৩২০৩৯০৯ — পরম এরর মাত্র ০.০০০১৬৬৮৪।
আরেকটি বিন্দু x = 1.9-এ (যা স্যাম্পল রেঞ্জের একেবারে কিনারার কাছে) এরর একটু বেশি —
০.০০০৩১৩৩৬ — মাত্র ৫টি স্যাম্পল পয়েন্ট দিয়েও যথেষ্ট নির্ভুল আনুমানিক মান, কিন্তু কিনারার
কাছে এরর বাড়ার এই প্রবণতাই L18-এ রুঙ্গের ফেনোমেননের কেন্দ্রীয় বিষয়।
লাগ্রাঞ্জ ফর্ম হলো ইন্টারপোলেটিং পলিনোমিয়াল লেখার সবচেয়ে স্বজ্ঞাত (intuitive) উপায় — প্রতিটি ডেটা
পয়েন্টের জন্য একটি বেসিস পলিনোমিয়াল, তাদের ওয়েটেড যোগফল। এটি সঠিক উত্তর দেয়, কিন্তু কম্পিউটেশনালি
কিছুটা অদক্ষ (প্রতিটি নতুন x-এর জন্য O(n²) কাজ, আর নতুন ডেটা পয়েন্ট যোগ করলে
সব আবার গণনা করতে হয়)। L17-এ আমরা দেখব নিউটনের ডিভাইডেড-ডিফারেন্স ফর্ম একই পলিনোমিয়াল
তৈরি করে, কিন্তু বাড়ানো-যায়-এমন (incremental) কাঠামোয়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ উপরের ডেমোতে ৫টি ডেটা পয়েন্ট দিয়ে ডিগ্রি-৪ পলিনোমিয়াল তৈরি হয়েছে। যদি আরও ৫টি পয়েন্ট যোগ করে মোট ১০টি পয়েন্ট ব্যবহার করা হয়, লাগ্রাঞ্জ ফর্মের কম্পিউটেশনাল খরচ কীভাবে বদলাবে?
প্রতিটি বেসিস পলিনোমিয়াল Lᵢ(x) গণনা করতে nটি গুণ লাগে, আর n+1টি
বেসিস আছে — তাই একটি বিন্দুতে মান বের করতে মোট কাজ O(n²)। পয়েন্ট সংখ্যা দ্বিগুণ (৫ থেকে
১০) করলে কাজ প্রায় চারগুণ বেড়ে যায়। এছাড়া, সবগুলো বেসিস পলিনোমিয়াল xᵢ-নির্ভর, তাই নতুন
পয়েন্ট যোগ করলে আগের সব হিসাব বাতিল হয়ে যায় — পুরোটা আবার গণনা করতে হয়।
প্র ০২
x = 1.2-তে এরর ছিল 0.00016684, কিন্তু কিনারার কাছাকাছি
x = 1.9-তে এরর প্রায় দ্বিগুণ (0.00031336)। কেন কিনারার কাছে এরর সাধারণত বেশি
হয়?
ইন্টারপোলেশন এরর সরাসরি নির্ভর করে ডেটা পয়েন্টগুলো থেকে টার্গেট বিন্দুর দূরত্বের গুণফলের উপর
((x-x₀)(x-x₁)...(x-xₙ) এই পদটি এরর সূত্রে থাকে)। x = 1.2 স্যাম্পল রেঞ্জের
(0 থেকে 2) মাঝামাঝি, যেখানে দুই পাশেই কাছাকাছি ডেটা পয়েন্ট আছে — কিন্তু
x = 1.9 রেঞ্জের কিনারার খুব কাছে, তাই একদিকে কম পয়েন্ট দিয়ে "সাপোর্ট" পাওয়া যায়। এটাই
সাধারণ প্যাটার্ন যা L18-এ রুঙ্গের ফেনোমেননে আরও চরম আকারে দেখা যাবে।
প্র ০৩
লাগ্রাঞ্জ ফর্মের ফর্মুলায় প্রতিটি বেসিস পলিনোমিয়ালের হরে (denominator) (xᵢ - xⱼ)
আছে। যদি দুটো ডেটা পয়েন্টের x-মান একই হয় (যেমন দুইবার ভুল করে একই x দিয়ে
দুটো ভিন্ন y রেকর্ড করা হয়), তাহলে কী সমস্যা হবে?
xᵢ = xⱼ হলে হর (xᵢ - xⱼ) = 0 হয়ে যাবে, যা ZeroDivisionError
তৈরি করবে। এটি গাণিতিকভাবেও অর্থবহ — একই x-এ দুটো ভিন্ন y থাকলে সেটি আর একটি
ফাংশনই না (একটি x-এর একটিই মান থাকা উচিত), তাই ইন্টারপোলেটিং পলিনোমিয়াল তৈরি করাই অসম্ভব —
কোডে এই ধরনের ইনপুট যাচাই করে আগেই এরর দেখানো ভালো অভ্যাস।
অনুশীলন
-
চিন্তা করুন: উপরের কোড সেলে যদি
x_new = 1.0বসানো হয় (যা নিজেই একটি স্যাম্পল পয়েন্ট), তাহলে পরম এরর কত হবে বলে আপনার ধারণা?এরর প্রায়
০(শুধু ফ্লোটিং-পয়েন্ট রাউন্ড-অফের কারণে অতি ক্ষুদ্র একটি সংখ্যা, যেমন10⁻¹⁶মাত্রার) — কারণ লাগ্রাঞ্জ পলিনোমিয়াল সংজ্ঞা অনুযায়ী প্রতিটি স্যাম্পল পয়েন্টে ঠিক সেইyমান-ই ফেরত দেয়, এটাই এর মূল ধর্ম। -
পরীক্ষা করুন: উপরের কোড সেলে
x_new = 1.0যোগ করে Run চেপে আপনার অনুমান যাচাই করুন, তারপরxs-এ আরও দুটো পয়েন্ট (যেমন2.5ও3.0, তাদেরsinমানসহ) যোগ করে দেখুনx = 1.9-এর এরর বদলায় কিনা।x_new = 1.0-এ এরর সত্যিই প্রায়0(মেশিন প্রিসিশনের সীমায়)। আরও পয়েন্ট যোগ করলেx = 1.9এখন রেঞ্জের মাঝামাঝি হয়ে যায় (কিনারায় থাকে না), তাই সাধারণত এরর কমে যায় — যদিও উঁচু ডিগ্রির পলিনোমিয়াল সবসময় ভালো ফল দেয় না, যা L18-এ বিস্তারিত দেখানো হবে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- L17 · নিউটনের ডিভাইডেড ডিফারেন্স পরবর্তী পাঠ একই পলিনোমিয়াল, কিন্তু একটি বাড়ানো-যায়-এমন (incremental) ফর্মে — এবং একটি সত্যিকারের ক্রস-চেক দেখাবে দুটো ফর্ম একই উত্তর দেয়।
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ এরর অ্যানালাইসিস, রুট-ফাইন্ডিং, লিনিয়ার সিস্টেম, ইন্টারপোলেশন, নিউমেরিক্যাল ইন্টিগ্রেশন, ODE সলভিং, আইগেনভ্যালু মেথড, অপ্টিমাইজেশন ও ক্যাপস্টোন।
- Math for AI & ML কোর্স সহোদর কোর্স পলিনোমিয়াল ও ফাংশনের মৌলিক গাণিতিক ভিত্তি — এই কোর্স সেই ভিত্তির উপর কম্পিউটেশনাল দিকটি যোগ করে।