מרחבים ותתי־מרחבים
מרחב האפס
The Nullspace of A: Solving Av=0
פותרים Ax=0 בעזרת pivot ומשתנים חופשיים, בונים פתרונות מיוחדים ומקבלים בסיס לכל הכיוונים שהמטריצה מוחקת.
- 1נקודת פתיחהמה כבר ידוע ומה השאלה?
- 2ניבוימה יקרה במקרה הפשוט?
- 3המחשהמה באמת משתנה בתמונה?
- 4ניסוח והצדקהשם, נוסחה ולמה היא נכונה
- 5בדיקהדוגמה, תרגול ומשוב
- 6העברהמקרה חדש והמשך המסלול
שאלה לפני נוסחה
מה אנחנו מנסים לראות?
למצוא את כל הכיוונים שמטריצה מוחקת: לפתור Ax=0, להפוך משתנים חופשיים לפרמטרים ולבנות מהם פתרונות מיוחדים של מרחב האפס.
מרחב האפס אוסף את כל הכיוונים שהמטריצה אינה רואה. תנועה בכיוון כזה משנה את הקלט אך משאירה את הפלט בדיוק באפס; כל משתנה חופשי מוסיף כיוון בלתי תלוי אחד של חוסר־נראות.
לפני ההמחשה: קראו רק את הכותרת “משתנים חופשיים הופכים לכיוונים שהמטריצה מוחקת”. מה לדעתכם ישתנה, מה יישאר קבוע, ואיזה סימן בתמונה יוכל להפריך את הניבוי?
לראות לפני שמחשבים · המקרה הפשוט ביותר
משתנים חופשיים הופכים לכיוונים שהמטריצה מוחקת
התרשים עובר בשלושה שלבים: מן הפרמטרים (s,t), אל הצירוף s n₁+t n₂ במרחב הקלט, ומשם דרך A אל וקטור האפס.
מה כדאי לגלות: השוו את שתי משבצות ה־free בתחתית לשני הווקטורים n₁,n₂. כל משתנה חופשי מוסיף כיוון בסיס אחד, אך כל צירוף שלהם עדיין נשלח לאותו פלט 0.
אחרי שראינו
בסוף השיעור תוכלו
- להוכיח ש־N(A) הוא תת־מרחב של מרחב הקלט ℝⁿ.
- להבחין ב־RREF בין משתני pivot למשתנים חופשיים.
- לכתוב את הפתרון ההומוגני בצורה פרמטרית ולחלץ פתרון מיוחד לכל פרמטר.
- לאמת כל כיוון שמתקבל באמצעות הכפלה ב־A ולהסביר את משמעות האפסיות n−rank(A).
נותנים שמות למה שראינו
מושגים שנשתמש בהם
- מערכת הומוגנית
- מערכת מן הצורה Ax=0; היא תמיד עקבית כי x=0 הוא פתרון.
- מרחב האפס N(A)
- אוסף כל הקלטים x∈ℝⁿ שמקיימים Ax=0.
- משתנה pivot
- משתנה שהעמודה שלו מכילה pivot ב־RREF ולכן ערכו נקבע באמצעות המשתנים החופשיים.
- משתנה חופשי
- משתנה בעמודה ללא pivot; מותר לבחור את ערכו באופן עצמאי.
- פרמטר
- סמל כמו s או t המייצג כל מספר ממשי ומקודד דרגת חופש אחת.
- פתרון מיוחד
- פתרון שמתקבל כאשר פרמטר חופשי אחד שווה 1 וכל היתר 0.
- אפסיות nullity
- ממד מרחב האפס; מספר הכיוונים החופשיים שהמטריצה מוחקת.
- משפט הדרגה־והאפסיות
- עבור A בעלת n עמודות: rank(A)+dim N(A)=n.
מהמילים אל הסימנים
כותבים את הפעולה שכבר ראינו
פתחו את הנוסחה רק אחרי שאתם יכולים לומר במילים מה כל פעולה אמורה לעשות. בשלב הבא נצדיק אותה צעד אחר צעד.
להצגת נוסחת המפתח
קראו כל סימן כפעולה, לא כמשהו שצריך לשנןN(A)={x∈ℝⁿ:Ax=0}, dim N(A)=n−rמרכיבים את הפעולות
מהתמונה אל הנוסחה — הגזירה, בלי לדלג על הצעדים
מגדירים את הכיוונים הבלתי נראים
N(A) חי במרחב הקלט, ולכן מספר הרכיבים בכל וקטור בו שווה למספר עמודות A. הוא כולל תמיד את x=0, אך עשוי לכלול כיוונים נוספים.
N(A)={x∈ℝⁿ:Ax=0}עוצרים לחשוב: אל תחפשו וקטורים באורך m; Ax חי ב־ℝᵐ אבל x עצמו חי ב־ℝⁿ.
מוכיחים שזה תת־מרחב
אם Au=0 ו־Av=0, לינאריות הכפל במטריצה מבטיחה שכל צירוף של u ו־v נשלח גם הוא לאפס.
A(αu+βv)=αAu+βAv=0מחליפים את A בצורה נוחה
פעולות שורה שקולות לכפל במטריצה הפיכה E. לכן R=EA מקיימת Rx=0 אם ורק אם Ax=0, ו־RREF שומרת בדיוק על מרחב האפס.
R=EA, Ax=0 ⇔ Rx=0מזהים מי תלוי ומי חופשי
עמודת pivot מובילה משוואה ולכן המשתנה שלה נקבע. עמודה בלי pivot אינה מובילה משוואה חדשה, ולכן המשתנה שלה הופך לפרמטר חופשי.
pivot variables = dependent; nonpivot variables = freeכותבים פתרון פרמטרי
מעבירים את המשתנים החופשיים לאגף ימין, נותנים להם שמות s,t,… ומבטאים באמצעותם את משתני ה־pivot.
x=x(s,t,…)עוצרים לחשוב: אל תעצור ברשימת משוואות: אסוף את מקדמי כל פרמטר לווקטור משלו.
מחלצים פתרונות מיוחדים
עבור כל פרמטר מציבים בו 1 וביתר הפרמטרים 0. כך מתקבלת רשימת כיוונים שכל צירוף שלהם נותן את כל N(A).
x=s₁n₁+⋯+sₖnₖסופרים דרגות חופש ומאמתים
אם יש n עמודות ו־r pivots, נשארים n−r משתנים חופשיים. כל וקטור מיוחד חייב לעבור בדיקה ישירה Anᵢ=0; במחשב ההשוואה לאפס נעשית עד סף מספרי.
dim N(A)=n−rank(A)עוצרים לחשוב: באלגברה מדויקת הדרגה חד־משמעית; בנתוני floating point מדווחים rank ביחס ל־tolerance.
עכשיו רואים את השיטה בפעולה
דוגמאות פתורות, צעד אחר צעד
שני פרמטרים, שני כיוונים
מצאו את N(A) עבור A=[[1,2,3],[2,4,6]].
השורה השנייה היא פי 2 מהראשונה, ולכן RREF היא [[1,2,3],[0,0,0]].
x₁ הוא משתנה pivot; x₂=s ו־x₃=t חופשיים.
מן המשוואה x₁+2x₂+3x₃=0 מתקבל x₁=−2s−3t.
לכן x=s(−2,1,0)+t(−3,0,1).
בדיקה: A(−2,1,0)=0 וגם A(−3,0,1)=0.
מרחב האפס הוא מישור דרך הראשית ב־ℝ³, ובו שתי דרגות חופש.
N(A)=span{(−2,1,0),(−3,0,1)}כיוון שאינו משנה את הפלט
מה מוחקת המטריצה B=[[1,−1],[2,−2]]?
Bx=0 נותן x₁−x₂=0; המשוואה השנייה היא כפולה ואינה מוסיפה אילוץ.
נסמן x₂=t, ואז x₁=t.
כל פתרון הוא t(1,1), ולכן תנועה שווה בשני רכיבי הקלט אינה נראית במוצא.
למשל B(7,7)=(0,0), וגם B(−3,−3)=(0,0).
N(B) הוא הישר בכיוון (1,1).
N(B)=span{(1,1)}איפה זה פוגש את העולם
יישום
במערכת מדידה, כיוון במרחב האפס הוא שינוי במצב שאף חיישן אינו מזהה. בבקרת רובוט או בשחזור תמונה, זיהוי הכיוונים האלה מגלה אילו דרגות חופש אינן ניתנות לקביעה מן הנתונים.
מלכודת נפוצה
מה כדאי לבדוק
להשתמש בשורות האפס כווקטורי בסיס, או לשכוח לבנות פתרון נפרד לכל משתנה חופשי. הבסיס חי במרחב הקלט ℝⁿ, ומספר וקטורי הבסיס חייב להיות n−r.
בודקים שהרעיון יושב
תרגול ומשוב
בדיקת הבנה
בחרו תשובה ורק אז בדקו את עצמכם
בחרו אחת מהאפשרויות כדי להמשיך.
עכשיו אתם
אתגר קצר
המשיכו עם מטריצת העוגן A=[[2,4,6,4],[2,5,7,6],[2,3,5,2]]. מן RREF(A)=[[1,0,1,−2],[0,1,1,2],[0,0,0,0]] מצאו את כל N(A), את האפסיות ואת הפתרונות המיוחדים.
רמז ראשון
עמודות 3 ו־4 חופשיות. בחרו x₃=s,x₄=t ופתרו את שתי השורות עבור x₁,x₂.
הצגת דרך הפתרון
- עמודות 1 ו־2 הן עמודות pivot, ולכן x₃=s ו־x₄=t חופשיים.
- השורות נותנות x₁+x₃−2x₄=0 ו־x₂+x₃+2x₄=0, כלומר x₁=−s+2t ו־x₂=−s−2t.
- לכן x=s(−1,−1,1,0)+t(2,−2,0,1). אלה שני הפתרונות המיוחדים.
- כפל ישיר בשתי עמודות מראה שהן נשלחות לאפס. הדרגה 2 והאפסיות 4−2=2, כמצופה.
מימוש הנושא
קוד שאפשר לקחת לניסוי
הקוד מיישם את אותו רעיון מתמטי. ב־JavaScript אפשר להריץ אותו כאן; גרסת Python זמינה להשוואה ולהעתקה.
nullspaceBasis מוצאת את ה־pivots, מסמנת את יתר העמודות כחופשיות ובונה עבור כל אחת וקטור מיוחד. matVec מבצעת את בדיקת Anᵢ.
באתגר יוחזרו pivots בעמודות 1 ו־2, free בעמודות 3 ו־4, שני וקטורי בסיס [−1,−1,1,0] ו־[2,−2,0,1], ושני וקטורי אפס באימות.
כִּפלו את כל A ב־10⁻¹². לאחר מכן הוסיפו רעש 10⁻¹⁴ לשורה התלויה ושנו את tolerance כדי להבחין בין מרחב אפס מדויק למרחב אפס מספרי.
מהרעיון אל הקוד
מימוש חישובי
function rref(input, relativeTolerance=1e-12) {
const matrix = input.map((row) => row.map(Number));
const rows = matrix.length;
const columns = matrix[0].length;
const rowScales = matrix.map((row) => Math.max(...row.map(Math.abs)));
const pivots = [];
let pivotRow = 0;
for (let column = 0; column < columns && pivotRow < rows; column += 1) {
let best = -1;
let bestRatio = 0;
for (let row = pivotRow; row < rows; row += 1) {
const ratio = rowScales[row] === 0
? 0
: Math.abs(matrix[row][column])/rowScales[row];
if (ratio > bestRatio) {
bestRatio = ratio;
best = row;
}
}
if (best === -1 || bestRatio <= relativeTolerance) continue;
[matrix[pivotRow], matrix[best]] = [matrix[best], matrix[pivotRow]];
[rowScales[pivotRow], rowScales[best]] = [rowScales[best], rowScales[pivotRow]];
const scale = matrix[pivotRow][column];
matrix[pivotRow] = matrix[pivotRow].map((value) => value/scale);
for (let row = 0; row < rows; row += 1) {
if (row === pivotRow) continue;
const factor = matrix[row][column];
matrix[row] = matrix[row].map(
(value, j) => value - factor*matrix[pivotRow][j],
);
}
pivots.push(column);
pivotRow += 1;
}
return { matrix, pivots };
}
function nullspaceBasis(A) {
const { matrix, pivots } = rref(A);
const columns = A[0].length;
const free = Array.from(
{ length: columns },
(_, index) => index,
).filter((index) => !pivots.includes(index));
const basis = free.map((freeColumn) => {
const vector = Array(columns).fill(0);
vector[freeColumn] = 1;
pivots.forEach((pivotColumn, row) => {
vector[pivotColumn] = -matrix[row][freeColumn];
});
return vector;
});
return { pivots, free, basis };
}
function matVec(A, v) {
return A.map((row) =>
row.reduce((sum, value, j) => sum + value*v[j], 0),
);
}
const A = [
[2, 4, 6, 4],
[2, 5, 7, 6],
[2, 3, 5, 2],
];
const result = nullspaceBasis(A);
console.log({
pivotVariables: result.pivots.map((i) => i + 1),
freeVariables: result.free.map((i) => i + 1),
basis: result.basis,
verification: result.basis.map((vector) => matVec(A, vector)),
});def rref(source, relative_tolerance=1e-12):
matrix = [[float(value) for value in row] for row in source]
rows, columns = len(matrix), len(matrix[0])
row_scales = [max(abs(value) for value in row) for row in matrix]
pivots = []
pivot_row = 0
for column in range(columns):
if pivot_row == rows:
break
best = max(
range(pivot_row, rows),
key=lambda row: (
abs(matrix[row][column])/row_scales[row]
if row_scales[row] else 0.0
),
)
best_ratio = (
abs(matrix[best][column])/row_scales[best]
if row_scales[best] else 0.0
)
if best_ratio <= relative_tolerance:
continue
matrix[pivot_row], matrix[best] = matrix[best], matrix[pivot_row]
row_scales[pivot_row], row_scales[best] = (
row_scales[best], row_scales[pivot_row]
)
scale = matrix[pivot_row][column]
matrix[pivot_row] = [value/scale for value in matrix[pivot_row]]
for row in range(rows):
if row == pivot_row:
continue
factor = matrix[row][column]
matrix[row] = [
value - factor*pivot_value
for value, pivot_value
in zip(matrix[row], matrix[pivot_row])
]
pivots.append(column)
pivot_row += 1
return matrix, pivots
def nullspace_basis(A):
matrix, pivots = rref(A)
columns = len(A[0])
free = [index for index in range(columns) if index not in pivots]
basis = []
for free_column in free:
vector = [0.0]*columns
vector[free_column] = 1.0
for row, pivot_column in enumerate(pivots):
vector[pivot_column] = -matrix[row][free_column]
basis.append(vector)
return {"pivots": pivots, "free": free, "basis": basis}
def mat_vec(A, vector):
return [
sum(value*vector[j] for j, value in enumerate(row))
for row in A
]
A = [
[2, 4, 6, 4],
[2, 5, 7, 6],
[2, 3, 5, 2],
]
result = nullspace_basis(A)
print({
"pivot_variables": [i+1 for i in result["pivots"]],
"free_variables": [i+1 for i in result["free"]],
"basis": result["basis"],
"verification": [mat_vec(A, vector) for vector in result["basis"]],
})לפני שממשיכים
מה לוקחים מהשיעור
- N(A) מכיל את כל הקלטים שהמטריצה שולחת לאפס וחי ב־ℝⁿ.
- פעולות שורה שומרות את N(A), ולכן RREF היא הכלי הנוח לחישובו.
- כל משתנה חופשי יוצר פרמטר ופתרון מיוחד אחד.
- rank(A)+dim N(A)=n, ויש לאמת כל כיוון באמצעות Anᵢ=0.
משימת מעבדה לשיעור הזה
תחנה 2 — הכיוון שהמטריצה מוחקת
חזו תחילה איזה כיוון יישלח ל־0. לאחר מכן הזיזו קלט לאורך הכיוון ובדקו שהפלט נשאר קבוע, וקשרו כל דרגת חופש לעמודה ללא pivot.
מקורות להעמקה בלבד — השיעור עומד בפני עצמו
מדריך המרצים: עמ׳ 135–140
ספר הלימוד: עמ׳ 261–272