משוואות לינאריות ומטריצות הפוכות
מטריצות הפוכות
Inverse Matrices
מגדירים מתי אפשר לבטל פעולה, בונים A⁻¹ באמצעות Gauss–Jordan ומקשרים הפיכות לפתרון יחיד לכל b.
- 1נקודת פתיחהמה כבר ידוע ומה השאלה?
- 2ניבוימה יקרה במקרה הפשוט?
- 3המחשהמה באמת משתנה בתמונה?
- 4ניסוח והצדקהשם, נוסחה ולמה היא נכונה
- 5בדיקהדוגמה, תרגול ומשוב
- 6העברהמקרה חדש והמשך המסלול
שאלה לפני נוסחה
מה אנחנו מנסים לראות?
להבין מה פירוש לבטל פעולה לינארית, להכריע אם מטריצה ריבועית הפיכה, ולבנות את ההפוכה באמצעות Gauss-Jordan בלי להסתמך על מושגי המרחבים של פרק 5.
מטריצה הפיכה היא העתקה שאפשר להריץ לאחור: היא אינה מועכת שני וקטורים שונים לאותה תוצאה ואינה מאבדת כיוון. עמודות A⁻¹ הן הוראות החזרה של וקטורי הבסיס.
לפני ההמחשה: קראו רק את הכותרת “A מעוותת, A⁻¹ משחזרת”. מה לדעתכם ישתנה, מה יישאר קבוע, ואיזה סימן בתמונה יוכל להפריך את הניבוי?
לראות לפני שמחשבים · המקרה הפשוט ביותר
A מעוותת, A⁻¹ משחזרת
שלושת השלבים מציגים ריבוע קלט, את המקבילית שמתקבלת תחת A=[[2,1],[0,1]], ואת הריבוע המשוחזר לאחר הפעלת A⁻¹.
מה כדאי לגלות: השוו כל קדקוד בשלב הראשון והאחרון. הפוכה אמיתית חייבת להחזיר את כל הצורה ואת כל הווקטורים, ולא רק נקודת בדיקה אחת.
אחרי שראינו
בסוף השיעור תוכלו
- לפרש את A⁻¹ כפעולת ביטול ולבדוק מועמד להפוכה משני צדי A.
- להסביר מדוע עמודות A⁻¹ מתקבלות מפתרון Axⱼ=eⱼ.
- לבצע Gauss-Jordan על [A|I] ולזהות מתי התהליך נכשל בגלל pivot חסר.
- להשתמש בהפוכה לשחזור x ולהסביר מדוע הופכים את סדר הגורמים ב־(AB)⁻¹.
נותנים שמות למה שראינו
מושגים שנשתמש בהם
- מטריצת היחידה I
- המטריצה שמקיימת Ix=x לכל וקטור מתאים; היא ממלאת בכפל את תפקיד המספר 1.
- מטריצה הפוכה
- עבור A ריבועית, מטריצה A⁻¹ שמקיימת גם A⁻¹A=I וגם AA⁻¹=I.
- הפיכה
- תכונה של מטריצה ריבועית שקיימת לה מטריצה הפוכה, ולכן כל פלט קובע קלט יחיד.
- סינגולרית
- מטריצה ריבועית שאינה הפיכה; לפחות כיוון לא־אפס אחד אובד או שלא ניתן להגיע לכל יעד.
- Gauss-Jordan
- אלימינציה שמאפסת איברים גם מתחת לכל pivot וגם מעליו, עד שהצד השמאלי נהפך ל־I.
- מטריצה מורחבת [A | I]
- הצמדה של A למטריצת היחידה כדי לבצע על שתיהן את אותן פעולות שורה ולבנות את A⁻¹.
- וקטור יחידה eⱼ
- וקטור שכל רכיביו 0 מלבד 1 במקום j; וקטורים אלה הם עמודות מטריצת היחידה.
- נוסחת ההפוכה ב־2×2
- עבור A=[[a,b],[c,d]], אם ad−bc≠0 אז A⁻¹=(1/(ad−bc))[[d,−b],[−c,a]].
- כמעט סינגולרית
- מטריצה הפיכה שקרובה, ביחס לגודל איבריה, למצב של pivot חסר; ההפוכה שלה עלולה להגדיל מאוד שגיאות קטנות.
מהמילים אל הסימנים
כותבים את הפעולה שכבר ראינו
פתחו את הנוסחה רק אחרי שאתם יכולים לומר במילים מה כל פעולה אמורה לעשות. בשלב הבא נצדיק אותה צעד אחר צעד.
להצגת נוסחת המפתח
קראו כל סימן כפעולה, לא כמשהו שצריך לשנןA⁻¹A = Iמרכיבים את הפעולות
מהתמונה אל הנוסחה — הגזירה, בלי לדלג על הצעדים
מגדירים פעולת ביטול מלאה
A⁻¹ חייבת לבטל את A בשני סדרי הכפל. התנאי הדו־צדדי חשוב מפני שכפל מטריצות אינו חילופי.
A⁻¹A=I וגם AA⁻¹=Iמשחזרים את הקלט
אם y=Ax וההפוכה קיימת, כופלים משמאל ב־A⁻¹. האסוציאטיביות מחברת את A⁻¹A ל־I ומשאירה את x.
A⁻¹y=A⁻¹(Ax)=(A⁻¹A)x=xכל עמודה מחזירה וקטור יחידה
אם כותבים A⁻¹ לפי עמודות, המכפלה AA⁻¹ מורכבת מן העמודות Axⱼ. כדי לקבל I, העמודה j חייבת לפתור Axⱼ=eⱼ.
A⁻¹=[x₁ ⋯ xₙ] ⇒ Axⱼ=eⱼפותרים את כל היעדים יחד
מצמידים ל־A את כל עמודות היחידה ומבצעים על [A | I] אותן פעולות שורה. אם מתקבל [I | E], שימור הפתרונות אומר שכל עמודה xⱼ של E מקיימת Axⱼ=eⱼ, ולכן AE=I. רצף פעולות השורה פועל משמאל באותה דרך על שני הצדדים; הוא שולח את I אל E ואת A אל I, ולכן גם EA=I. מכאן E=A⁻¹ בלי להניח מראש שההפוכה קיימת.
[A | I] → [I | A⁻¹]pivot חסר חושף אובדן מידע
אם אי אפשר לקבל pivot בכל עמודה, הצד השמאלי לא יוכל להפוך ל־I. האלימינציה משאירה חופש בקלט או יוצרת יעד שאי אפשר להגיע אליו, ולכן אין פעולה שמחזירה כל פלט לקלט יחיד.
pivot חסר ⇒ A⁻¹ אינה קיימתמבחן אחד, כמה משמעויות
עבור מטריצה ריבועית, קבלת pivot בכל עמודה פירושה ש־Gauss-Jordan מגיע ל־I, שכל יעד b מקבל פתרון יחיד וששום כיוון לא־אפס אינו נמחץ לאפס. השמות הפורמליים מרחב האפס, מרחב העמודות ובסיס יפותחו בפרק 5.
n pivots ⇔ לכל b יש x יחיד ⇔ Ax=0 רק עבור x=0מבטלים הרכבה בסדר הפוך
כדי לבטל AB מבטלים תחילה את A ואז את B. אפשר לבדוק ישירות שכפל B⁻¹A⁻¹ ב־AB, משמאל או מימין, נותן I. לפתרון מערכת גדולה עדיף בדרך כלל להשתמש באלימינציה או בפירוק משיעור 4.2 במקום לחשב את ההפוכה במפורש.
(AB)⁻¹=B⁻¹A⁻¹
עכשיו רואים את השיטה בפעולה
דוגמאות פתורות, צעד אחר צעד
בניית הפוכה ב־Gauss-Jordan
מצאו את ההפוכה של A=[[2,1],[1,1]] ואמתו אותה.
מתחילים מ־[[2,1|1,0],[1,1|0,1]].
מבצעים R₁←(1/2)R₁ ומקבלים [1,1/2|1/2,0].
מבצעים R₂←R₂−R₁, ואז R₂←2R₂, ומקבלים [0,1|−1,2].
מבצעים R₁←R₁−(1/2)R₂ ומקבלים [1,0|1,−1].
הצד השמאלי הוא I, ולכן הצד הימני הוא [[1,−1],[−1,2]]. כפל בשני הסדרים נותן I.
כל עמודה בהפוכה היא הקלט ש־A שולחת אל עמודת היחידה המתאימה.
A⁻¹=[[1,−1],[−1,2]]אלימינציה שנעצרת
בדקו אם A=[[1,2],[2,4]] הפיכה והסבירו את הכשל.
מתחילים מ־[[1,2|1,0],[2,4|0,1]] ומבצעים R₂←R₂−2R₁.
בצד השמאלי מתקבלת שורת אפסים, ולכן אין pivot שני ואי אפשר להגיע ל־I.
בנוסף A(2,−1)ᵀ=(0,0)ᵀ: הכיוון הלא־אפס (2,−1) אובד.
לכן הפלט 0 הגיע גם מן הקלט 0 וגם מן הקלט (2,−1), ושום הפוכה אינה יכולה לבחור ביניהם.
המטריצה סינגולרית; pivot חסר ואובדן כיוון הם שתי עדויות לאותו כשל.
A⁻¹ אינה קיימתאיפה זה פוגש את העולם
יישום
בכיול חיישן, A ממירה אות אמיתי למדידה ו־A⁻¹ משחזרת אותו. אם עמודות A כמעט תלויות, ההפוכה קיימת אך עלולה להעצים רעש מאוד; לכן עצם ההפיכות אינה מבטיחה חישוב יציב.
מלכודת נפוצה
מה כדאי לבדוק
לבצע פעולות שורה רק בצד A של [A | I], או להסיק הפיכות מפני שמערכת אחת Ax=b נפתרה. בחישוב מספרי נדרשות החלפות שורה וסף יחסי; סירוב בגלל pivot קטן הוא אזהרת אמינות, לא הוכחה שהמטריצה סינגולרית מתמטית.
בודקים שהרעיון יושב
תרגול ומשוב
בדיקת הבנה
בחרו תשובה ורק אז בדקו את עצמכם
בחרו אחת מהאפשרויות כדי להמשיך.
עכשיו אתם
אתגר קצר
עבור A(t)=[[1,t],[t,1]], מצאו את A(t)⁻¹, קבעו עבור אילו t היא אינה קיימת, ומצאו כיוון לא־אפס שנמחק כאשר t=1 וכאשר t=−1.
רמז ראשון
במטריצה 2×2 [[a,b],[c,d]] ההפוכה, אם היא קיימת, היא (1/(ad−bc))[[d,−b],[−c,a]]. כאן המכנה הוא 1−t².
הצגת דרך הפתרון
- הגורם הקובע הוא 1−t², ולכן עבור t≠±1 מתקבלת A(t)⁻¹=(1/(1−t²))[[1,−t],[−t,1]].
- כאשר t=1 שתי השורות זהות ו־A(1)(1,−1)ᵀ=0, ולכן הכיוון (1,−1) אובד.
- כאשר t=−1 השורה השנייה היא מינוס הראשונה ו־A(−1)(1,1)ᵀ=0, ולכן הכיוון (1,1) אובד.
- ככל ש־t מתקרב ל־±1 ביחס לסקלה של המטריצה, המכנה קטן וההפוכה מגדילה יותר שגיאות קטנות.
מימוש הנושא
קוד שאפשר לקחת לניסוי
הקוד מיישם את אותו רעיון מתמטי. ב־JavaScript אפשר להריץ אותו כאן; גרסת Python זמינה להשוואה ולהעתקה.
inverse מבצעת Gauss-Jordan עם scaled partial pivoting. pivot שהוא אפס מוכיח כשל; pivot שאינו אפס אך קטן מן הסף גורם לסירוב מספרי מפורש, בלי לטעון שההפוכה אינה קיימת מתמטית. multiply מאמתת תוצאה שהתקבלה.
למטריצה התלת־אלכסונית תתקבל ההפוכה (1/4)[[3,−2,1],[−2,4,−2],[1,−2,3]], שתי המכפלות יהיו קרובות ל־I, והמטריצה [[1,2],[2,4]] תחזיר null. עבור diag(1,10⁻¹³) תתקבל diag(1,10¹³).
נסו גם את 10⁻¹³I וגם את diag(1,10⁻¹³): שתיהן הפיכות אף שבשנייה רק שורה אחת קטנה. אחר כך נסו [[1,1],[1,1+10⁻¹⁴]]: אם האלגוריתם מסרב, פרשו זאת כאזהרת רגישות ולא כהוכחת סינגולריות.
מהרעיון אל הקוד
מימוש חישובי
function inverse(matrix, relativeTolerance=1e-12) {
const n = matrix.length;
if (!n || matrix.some((row) => row.length !== n)) {
throw new Error("A must be a nonempty square matrix");
}
const numericMatrix = matrix.map((row) => row.map(Number));
const rowScales = numericMatrix.map((row) => Math.max(...row.map(Math.abs)));
if (rowScales.some((scale) => scale === 0)) return null;
const augmented = numericMatrix.map((row, i) => [
...row,
...Array.from({ length: n }, (_, j) => Number(i === j)),
]);
for (let col = 0; col < n; col += 1) {
let pivot = col;
for (let row = col + 1; row < n; row += 1) {
const candidateRatio = Math.abs(augmented[row][col]) / rowScales[row];
const pivotRatio = Math.abs(augmented[pivot][col]) / rowScales[pivot];
if (candidateRatio > pivotRatio) {
pivot = row;
}
}
if (augmented[pivot][col] === 0) return null;
if (Math.abs(augmented[pivot][col]) <= relativeTolerance*rowScales[pivot]) {
throw new Error("nonzero pivot is numerically unsafe at this tolerance");
}
[augmented[col], augmented[pivot]] = [augmented[pivot], augmented[col]];
[rowScales[col], rowScales[pivot]] = [rowScales[pivot], rowScales[col]];
const scale = augmented[col][col];
augmented[col] = augmented[col].map((value) => value/scale);
for (let row = 0; row < n; row += 1) {
if (row === col) continue;
const factor = augmented[row][col];
augmented[row] = augmented[row].map(
(value, j) => value - factor*augmented[col][j],
);
}
}
return augmented.map((row) => row.slice(n));
}
function multiply(A, B) {
return A.map((row) =>
B[0].map((_, j) =>
row.reduce((sum, value, k) => sum + value*B[k][j], 0),
),
);
}
const A = [[2, 1, 0], [1, 2, 1], [0, 1, 2]];
const Ainv = inverse(A);
console.table(Ainv);
console.log({
A_times_Ainv: multiply(A, Ainv),
Ainv_times_A: multiply(Ainv, A),
});
console.log(inverse([[1, 2], [2, 4]]));
console.log(inverse([[1, 0], [0, 1e-13]]));def inverse(matrix, relative_tolerance=1e-12):
n = len(matrix)
if not n or any(len(row) != n for row in matrix):
raise ValueError("A must be a nonempty square matrix")
numeric_matrix = [[float(value) for value in row] for row in matrix]
row_scales = [max(abs(value) for value in row) for row in numeric_matrix]
if any(scale == 0 for scale in row_scales):
return None
augmented = [
row[:]
+ [float(i == j) for j in range(n)]
for i, row in enumerate(numeric_matrix)
]
for col in range(n):
pivot = max(
range(col, n),
key=lambda row: abs(augmented[row][col])/row_scales[row],
)
if augmented[pivot][col] == 0:
return None
if abs(augmented[pivot][col]) <= relative_tolerance*row_scales[pivot]:
raise ArithmeticError(
"nonzero pivot is numerically unsafe at this tolerance"
)
augmented[col], augmented[pivot] = augmented[pivot], augmented[col]
row_scales[col], row_scales[pivot] = row_scales[pivot], row_scales[col]
scale = augmented[col][col]
augmented[col] = [value/scale for value in augmented[col]]
for row in range(n):
if row == col:
continue
factor = augmented[row][col]
augmented[row] = [
value - factor*pivot_value
for value, pivot_value
in zip(augmented[row], augmented[col])
]
return [row[n:] for row in augmented]
def multiply(A, B):
return [
[
sum(a*b for a, b in zip(row, column))
for column in zip(*B)
]
for row in A
]
A = [[2, 1, 0], [1, 2, 1], [0, 1, 2]]
A_inv = inverse(A)
print(A_inv)
print({
"A_times_A_inv": multiply(A, A_inv),
"A_inv_times_A": multiply(A_inv, A),
})
print(inverse([[1, 2], [2, 4]]))
print(inverse([[1, 0], [0, 1e-13]]))לפני שממשיכים
מה לוקחים מהשיעור
- A⁻¹ היא פעולה שמבטלת את A משמאל ומימין ומאפשרת לשחזר קלט מפלט.
- Gauss-Jordan על [A|I] פותר בבת אחת את Axⱼ=eⱼ עבור כל עמודות היחידה.
- pivot חסר במטריצה ריבועית פירושו שאין הפוכה ושמידע כלשהו אובד.
- בהפיכת מכפלה הופכים גם כל גורם וגם את סדר הגורמים; לפתרון יחיד עדיף לרוב פירוק על חישוב A⁻¹.
משימת מעבדה לשיעור הזה
תחנה 3 — פעולה, הרכבה וביטול
עוותו רשת באמצעות A, נסו להחזיר אותה עם A⁻¹, ואז התקרבו למטריצה סינגולרית וצפו בהגדלת השגיאה.
מקורות להעמקה בלבד — השיעור עומד בפני עצמו
מדריך המרצים: עמ׳ 118–123
ספר הלימוד: עמ׳ 228–237