LU ডিকম্পোজিশন
এই পাঠে যা শিখবেন
- LU ডিকম্পোজিশনের সংজ্ঞা এবং কেন এটি গসিয়ান এলিমিনেশনেরই একটি পুনর্গঠিত রূপ
- Doolittle's method দিয়ে হাতে
LওUবের করার পদ্ধতি - Forward substitution (
Ly = b) ও back substitution (Ux = y) দিয়ে সিস্টেম সমাধান করা - একটি সত্যিকারের, চলমান Python ডেমো —
L*Uপুনর্গঠন যাচাই এবং একই ফ্যাক্টর দিয়ে সিস্টেম সমাধান
১ · কেন A-কে ভাঙা হয় L ও U-তে
L10-এ আমরা দেখেছি গসিয়ান এলিমিনেশন প্রতিটি সারি থেকে একটি factor গুণ বিয়োগ করে
A-কে upper-triangular U-তে রূপান্তর করে। মজার বিষয় হলো — সেই
factor-গুলো ফেলে না দিয়ে যদি একটি আলাদা lower-triangular ম্যাট্রিক্স L-এ সাজিয়ে
রাখি (ডায়াগোনালে ১ বসিয়ে), তাহলে:
এই ফ্যাক্টরাইজেশনের সুবিধা তখন বোঝা যায় যখন একই A-এর জন্য একাধিক ভিন্ন
b নিয়ে সমাধান করতে হয় (যেমন সিমুলেশনে বারবার ভিন্ন ইনপুট)। L ও
U একবার গণনা করে রাখলে, প্রতিটি নতুন b-এর জন্য শুধু দুটি সস্তা
O(n²) ধাপ (forward + back substitution) লাগে — সম্পূর্ণ O(n³) এলিমিনেশন
পুনরায় না করেই।
২ · Doolittle's method — হাতে L, U বের করা
Doolittle's method-এ U-এর প্রতিটি সারি এবং L-এর প্রতিটি কলাম একই সাথে ধাপে
ধাপে গণনা করা হয়:
এখানে k প্রতিটি ধাপে বাড়ে, এবং L-এর ডায়াগোনাল সবসময় ১ ধরা হয়
(এ কারণে একে "Doolittle" ফর্ম বলা হয় — বিকল্প হিসেবে "Crout's method"-এ U-এর ডায়াগোনাল
১ রাখা হয়)।
Ly = b সমাধান করে y বের করা — যেহেতু L lower-triangular, প্রথম সারি থেকে শুরু করে সরাসরি সমাধান হয়।Ux = y সমাধান করে চূড়ান্ত x বের করা — L10-এর মতোই, শেষ সারি থেকে উপরে।একই
L, U একাধিকবার ব্যবহার করা যায় — L39-এ ইনভার্স পাওয়ার মেথডে এই কৌশল পুনরায় কাজে লাগবে।৩ · একটি সত্যিকারের ডেমো — LU ফ্যাক্টরাইজেশন ও সিস্টেম সমাধান
নিচে একটি 3x3 ম্যাট্রিক্স A-কে L ও U-তে ভাঙা হয়েছে, তারপর
L*U গণনা করে সরাসরি মূল A-এর সাথে তুলনা করে দেখানো হয়েছে এটি হুবহু পুনর্গঠিত
হয়। এরপর Ly = b ও Ux = y সমাধান করে চূড়ান্ত x বের করা হয়েছে এবং
মূল সমীকরণে বসিয়ে যাচাই করা হয়েছে।
def lu_decompose(A):
n = len(A)
L = [[0.0] * n for _ in range(n)]
U = [[0.0] * n for _ in range(n)]
for i in range(n):
L[i][i] = 1.0
for k in range(n):
for j in range(k, n):
U[k][j] = A[k][j] - sum(L[k][m] * U[m][j] for m in range(k))
for i in range(k + 1, n):
L[i][k] = (A[i][k] - sum(L[i][m] * U[m][k] for m in range(k))) / U[k][k]
return L, U
def mat_mult(X, Y):
n = len(X)
p = len(Y[0])
m = len(Y)
return [[sum(X[i][t] * Y[t][j] for t in range(m)) for j in range(p)] for i in range(n)]
def forward_sub(L, b):
n = len(L)
y = [0.0] * n
for i in range(n):
y[i] = b[i] - sum(L[i][j] * y[j] for j in range(i))
return y
def back_sub(U, y):
n = len(U)
x = [0.0] * n
for i in range(n - 1, -1, -1):
x[i] = (y[i] - sum(U[i][j] * x[j] for j in range(i + 1, n))) / U[i][i]
return x
A = [
[4.0, 3.0, 2.0],
[2.0, -1.0, 1.0],
[6.0, 3.0, 5.0],
]
b = [21.0, 3.0, 26.0]
L, U = lu_decompose(A)
print("L =")
for row in L:
print(["%.6f" % v for v in row])
print("U =")
for row in U:
print(["%.6f" % v for v in row])
LU = mat_mult(L, U)
print()
print("যাচাই -- L*U পুনর্গঠন বনাম মূল A:")
max_diff = 0.0
for i in range(3):
for j in range(3):
diff = abs(LU[i][j] - A[i][j])
max_diff = max(max_diff, diff)
print(f"সর্বোচ্চ পার্থক্য = {max_diff:.2e}")
y = forward_sub(L, b)
x = back_sub(U, y)
print()
print("Ly = b থেকে y =", [round(v, 6) for v in y])
print("Ux = y থেকে x =", [round(v, 6) for v in x])
print()
print("যাচাই -- মূল Ax = b-তে বসিয়ে অবশিষ্টাংশ:")
for i in range(3):
lhs = sum(A[i][j] * x[j] for j in range(3))
print(f"সমীকরণ {i+1}: LHS = {lhs:.10f} b = {b[i]:.6f} residual = {lhs - b[i]:.2e}")
L = ['1.000000', '0.000000', '0.000000'] ['0.500000', '1.000000', '0.000000'] ['1.500000', '0.600000', '1.000000'] U = ['4.000000', '3.000000', '2.000000'] ['0.000000', '-2.500000', '0.000000'] ['0.000000', '0.000000', '2.000000'] যাচাই -- L*U পুনর্গঠন বনাম মূল A: সর্বোচ্চ পার্থক্য = 0.00e+00 Ly = b থেকে y = [21.0, -7.5, -1.0] Ux = y থেকে x = [3.25, 3.0, -0.5] যাচাই -- মূল Ax = b-তে বসিয়ে অবশিষ্টাংশ: সমীকরণ 1: LHS = 21.0000000000 b = 21.000000 residual = 0.00e+00 সমীকরণ 2: LHS = 3.0000000000 b = 3.000000 residual = 0.00e+00 সমীকরণ 3: LHS = 26.0000000000 b = 26.000000 residual = 0.00e+00
L*U মূল A-এর সাথে সর্বোচ্চ 0.00e+00 পার্থক্যে মিলে যায় — অর্থাৎ
ফ্যাক্টরাইজেশনটি হুবহু সঠিক। এরপর একই L, U ব্যবহার করে x = [3.25, 3.0,
-0.5] পাওয়া গেছে, এবং মূল সমীকরণে বসিয়ে সবগুলো residual শূন্য — সমাধানটি সত্যিই সঠিক।
LU ডিকম্পোজিশন গসিয়ান এলিমিনেশনের একই কাজ করে, কিন্তু মধ্যবর্তী তথ্য (factor-গুলো)
সংরক্ষণ করে পুনঃব্যবহারযোগ্য করে তোলে। L12-এ আমরা দেখব কখন এই সরল Doolittle পদ্ধতি ব্যর্থ হয়
(শূন্য পিভোট) এবং কীভাবে পিভোটিং দিয়ে PA = LU আকারে এটি সংশোধন করা হয়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১
L-এর ডায়াগোনালে সবসময় ১ কেন রাখা হয় — এটি কি স্বেচ্ছাচারী পছন্দ,
নাকি এর পেছনে কারণ আছে?
এটি একটি convention — A = LU সমীকরণে n×n মাত্রার A-এর জন্য
মোট n²টি সমীকরণ পাওয়া যায়, কিন্তু L ও U মিলিয়ে অজানা রাশি
আছে n² + nটি (উভয় ম্যাট্রিক্সের ডায়াগোনাল গুনলে)। তাই সিস্টেমটি সমাধানযোগ্য করতে
nটি অতিরিক্ত শর্ত দরকার — Doolittle পদ্ধতিতে L-এর ডায়াগোনাল ১
ধরে এই স্বাধীনতা ব্যবহার করা হয় (Crout's method বিকল্পভাবে U-এর ডায়াগোনাল ১
ধরে)।
প্র ০২
যদি একই A-এর জন্য দশটি ভিন্ন b ভেক্টর সমাধান করতে হয়, তাহলে LU
ডিকম্পোজিশন গসিয়ান এলিমিনেশনের চেয়ে কতটা সুবিধাজনক?
গসিয়ান এলিমিনেশন সরাসরি ব্যবহার করলে প্রতিটি b-এর জন্য পুরো O(n³)
এলিমিনেশন পুনরায় করতে হতো — দশবার। LU ডিকম্পোজিশনে L, U একবার
(O(n³)) গণনা করে রাখলে, প্রতিটি নতুন b-এর জন্য শুধু O(n²)
খরচের forward+back substitution লাগে — বড় n-এর জন্য এটি উল্লেখযোগ্য সাশ্রয়।
প্র ০৩
কোড সেলে U[k][k] শূন্য হলে L[i][k] গণনায় কী সমস্যা হবে?
L[i][k] = (...) / U[k][k] লাইনে ZeroDivisionError ঘটবে — ঠিক যেমন L10-এর
গসিয়ান এলিমিনেশনে শূন্য পিভোটের সমস্যা হয়েছিল, কারণ LU ডিকম্পোজিশন মূলত সেই একই এলিমিনেশন প্রক্রিয়া।
এই সমস্যার সমাধান একই — পিভোটিং, যা L12-এ বিস্তারিত আলোচনা করা হবে।
অনুশীলন
-
চিন্তা করুন: উপরের কোড সেলে
U-এর ডায়াগোনাল উপাদানগুলো (4, -2.5, 2) গুণ করলে কী পাওয়া যায় বলে আপনার মনে হয়, এবং এটিA-এর কোন বৈশিষ্ট্যের সাথে সম্পর্কিত হতে পারে?4 × (-2.5) × 2 = -20। এটি আসলেA-এর ডিটারমিন্যান্ট — যেহেতুdet(L) = 1(ত্রিভুজাকার ম্যাট্রিক্সের ডিটারমিন্যান্ট = ডায়াগোনালের গুণফল, আরL-এর ডায়াগোনাল সব১), তাইdet(A) = det(L) × det(U) = det(U)— অর্থাৎU-এর ডায়াগোনালের গুণফলইA-এর ডিটারমিন্যান্ট। -
পরীক্ষা করুন: কোড সেলে
print(U[0][0] * U[1][1] * U[2][2])যোগ করে Run চেপে আপনার অনুমান যাচাই করুন।এই কোড
-20.0প্রিন্ট করবে — ঠিক যেমন অনুমান করা হয়েছিল। এই সম্পর্কটি ব্যবহারিকভাবে গুরুত্বপূর্ণ:3×3বা তার বড় ম্যাট্রিক্সের ডিটারমিন্যান্ট সরাসরি cofactor expansion দিয়ে গণনা করা ব্যয়বহুল (O(n!)), কিন্তু LU ডিকম্পোজিশনের মাধ্যমে মাত্রO(n³)-এ পাওয়া যায়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ এরর অ্যানালাইসিস, রুট-ফাইন্ডিং, লিনিয়ার সিস্টেম, ইন্টারপোলেশন, নিউমেরিক্যাল ইন্টিগ্রেশন, ODE সলভিং, আইগেনভ্যালু মেথড, অপ্টিমাইজেশন ও ক্যাপস্টোন।
- Math for AI & ML কোর্স সহোদর কোর্স ম্যাট্রিক্স ও ডিটারমিন্যান্টের গাণিতিক ভিত্তি — এই কোর্স সেই ভিত্তির উপর কম্পিউটেশনাল দিকটি যোগ করে।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, Machine Learning, Deep Learning, System Design, Cybersecurity, Cloud Computing & DevOps, এবং আরও অনেক কোর্স।