4.2

משוואות לינאריות ומטריצות הפוכות

פתרון באמצעות אלימינציה

Solving Linear Equations by Elimination

הופכים מערכת למשולשת באמצעות פעולות שורה, pivots והחלפות; אחר כך אורזים את החישוב בפירוק PA=LU.

יחידת לימוד עצמאיתשיעור 2 מתוך 5כ־65 דקות כולל תרגול4 מטרות למידה
  1. 1
    נקודת פתיחהמה כבר ידוע ומה השאלה?
  2. 2
    ניבוימה יקרה במקרה הפשוט?
  3. 3
    המחשהמה באמת משתנה בתמונה?
  4. 4
    ניסוח והצדקהשם, נוסחה ולמה היא נכונה
  5. 5
    בדיקהדוגמה, תרגול ומשוב
  6. 6
    העברהמקרה חדש והמשך המסלול

שאלה לפני נוסחה

מה אנחנו מנסים לראות?

לפתור מערכת באמצעות אלימינציה והצבה לאחור, לבחור pivot בטוח, ורק לאחר שהאלגוריתם מובן לתעד את פעולותיו במבנה PA=LU.

אלימינציה מסדרת את המידע כך שכל שורה חדשה עוסקת בפחות נעלמים. ה־pivots הם נקודות האחיזה, L זוכרת באילו כפולות השתמשנו כדי לבטל, ו־P זוכרת אילו שורות הוחלפו.

לפני ההמחשה: קראו רק את הכותרת “פעולת שורה אחת חושפת מערכת משולשת”. מה לדעתכם ישתנה, מה יישאר קבוע, ואיזה סימן בתמונה יוכל להפריך את הניבוי?

לראות לפני שמחשבים · המקרה הפשוט ביותר

פעולת שורה אחת חושפת מערכת משולשת

אלימינציה של מערכת שתי משוואות: בחירת pivot, ביטול והצבה לאחורמערכת מקורית2 3 │ 110 9 │ 11pivot=2 · ℓ₂₁=10/2=5R₂←R₂−5R₁מערכת משולשת2 3 │ 10 −6 │ 6ה־pivot השני חושף y=−1לאחורy=−1x=2אותו חישוב נשמר בפירוק — כאן לא נדרשה החלפת שורותA = L U = [1 0; 5 1] [2 3; 0 −6]פעולת שורה חוקית משנה את הייצוג, לא את זוג הפתרונות
עקבו מהצורה הראשונית אל התוצאה

ההמחשה מתחילה ב־[[2,3|1],[10,9|11]], מסמנת pivot=2 ומבצעת R₂←R₂−5R₁. אחר כך היא מציגה את השורה [0,−6|6], הצבה לאחור ואת A=LU.

מה כדאי לגלות: עקבו גם אחר אגף ימין: מן השורה החדשה מתקבל y=−1, ומהשורה הראשונה x=2. פעולת השורה שינתה את הייצוג אך לא את זוג הפתרונות.

אחרי שראינו

בסוף השיעור תוכלו

  • לבצע פעולות שורה חוקיות על מטריצה מורחבת ולהסביר מדוע הן שומרות את קבוצת הפתרונות.
  • להפוך מערכת למבנה משולש ולפתור אותו בהצבה לאחור.
  • לזהות pivot אפס או קטן, לבצע החלפת שורות ולתעד אותה במטריצת P.
  • לבנות את L ואת U מתוך מכפילי האלימינציה ולהשתמש בהן לפתרון אגפי ימין נוספים.

נותנים שמות למה שראינו

מושגים שנשתמש בהם

מטריצה מורחבת
הטבלה [A|b] שמצמידה את אגף ימין למקדמים כדי שכל פעולת שורה תפעל על המערכת כולה.
פעולת שורה חוקית
החלפת שורות, כפל שורה במספר לא־אפס או הוספת כפולה של שורה לשורה אחרת; כל אחת הפיכה ושומרת פתרונות.
pivot
האיבר המוביל שבו משתמשים כדי לאפס את שאר האיברים מתחתיו באותה עמודה.
מכפיל אלימינציה
היחס ℓᵢₖ=aᵢₖ/uₖₖ שמספר איזו כפולה של שורת ה־pivot יש לחסר משורה i.
מטריצה משולשת עליונה U
מטריצה שכל האיברים מתחת לאלכסון שלה אפס, ולכן אפשר לפתור ממנה מן השורה האחרונה כלפי מעלה.
הצבה לאחור
פתרון מערכת משולשת עליונה החל מן הנעלם האחרון והצבתו בשורות שמעליו.
scaled partial pivoting
בחירת שורה לפי היחס בין מועמד ה־pivot לבין האיבר הגדול באותה שורה. כך כפל משוואה שלמה במספר קטן אינו הופך אותה בטעות לסינגולרית.
פירוק PA=LU
תיעוד האלימינציה: P שומרת החלפות שורה, L שומרת מכפילים ו־U היא התוצאה המשולשת.

מהמילים אל הסימנים

כותבים את הפעולה שכבר ראינו

פתחו את הנוסחה רק אחרי שאתם יכולים לומר במילים מה כל פעולה אמורה לעשות. בשלב הבא נצדיק אותה צעד אחר צעד.

להצגת נוסחת המפתחקראו כל סימן כפעולה, לא כמשהו שצריך לשנןPA = LU (עם pivoting)

מרכיבים את הפעולות

מהתמונה אל הנוסחה — הגזירה, בלי לדלג על הצעדים

  1. מצמידים את אגף ימין למקדמים

    כותבים [A|b] כדי שכל שינוי במשוואה יופיע באותה שורה משני צדי הקו. כך לא מאבדים את הקשר בין המקדמים לבין התוצאה.

    Ax=b ⇒ [A|b]
  2. משתמשים רק בפעולות הפיכות

    מותר להחליף שתי שורות, לכפול שורה במספר לא־אפס או להוסיף לשורה כפולה של שורה אחרת. לכל פעולה יש פעולת ביטול, ולכן קבוצת הפתרונות אינה משתנה.

    Rᵢ←Rᵢ−ℓRₖ ⇔ Rᵢ←Rᵢ+ℓRₖ
  3. בוחרים pivot ומאפסים מתחתיו

    כדי לאפס את aᵢₖ מחשבים את המכפיל ℓᵢₖ=aᵢₖ/uₖₖ ומחסרים ℓᵢₖ פעמים את שורת ה־pivot. מבצעים בדיוק אותה פעולה גם על b.

    ℓᵢₖ=aᵢₖ/uₖₖ, Rᵢ←Rᵢ−ℓᵢₖRₖ
  4. חוזרים עד שמתקבלת מטריצה משולשת

    עוברים עמודה אחר עמודה ומשאירים אפסים מתחת לכל pivot. בסוף מתקבלת U, ובה השורה האחרונה כוללת בדרך כלל נעלם אחד בלבד.

    [A|b] → [U|c]
  5. פותרים מלמטה למעלה

    מוצאים את הנעלם האחרון מן השורה האחרונה, מציבים אותו בשורה שמעליה וממשיכים עד לנעלם הראשון. זהו שלב ההצבה לאחור.

    uₙₙxₙ=cₙ, xᵢ=(cᵢ−Σⱼ>ᵢuᵢⱼxⱼ)/uᵢᵢ
  6. pivot אפס דורש החלפת שורות

    אם עמדת ה־pivot היא אפס אך יש מתחתיה איבר לא־אפס, מחליפים שורות. בקוד משתמשים ב־scaled partial pivoting: משווים כל מועמד לגודל השורה שלו, כדי שההכרעה לא תשתנה אם כופלים משוואה שלמה במספר. P מתעדת את ההחלפות. אם אין מועמד יחסי בטוח, אין פתרון יחיד ויש לבדוק סתירה או משתנה חופשי.

    Rₖ↔Rᵣ, ובסוף PA=LU
  7. רק עכשיו אורזים את הצעדים ב־L וב־U

    L שומרת מתחת לאלכסון את מכפילי האלימינציה ו־U היא המטריצה המשולשת. לפתרון אגפי ימין נוספים פותרים Ly=Pb ואז Ux=y. האימות המלא של PA=LU משתמש בכפל מטריצות, שילמד בשיעור 4.3.

    PA=LU, Ly=Pb, Ux=y

עכשיו רואים את השיטה בפעולה

דוגמאות פתורות, צעד אחר צעד

דוגמה 1

אלימינציה והצבה לאחור ב־2×2

פתרו את 2x+y=7,‏ x−y=1 באמצעות אלימינציה.

  1. כותבים את המטריצה המורחבת [[2,1|7],[1,−1|1]].

  2. ה־pivot הראשון הוא 2 והמכפיל הוא ℓ₂₁=1/2. מבצעים R₂←R₂−(1/2)R₁.

  3. השורה השנייה נהפכת ל־[0,−3/2|−5/2], ולכן y=(−5/2)/(−3/2)=5/3.

  4. מציבים בשורה הראשונה: 2x+5/3=7, ולכן x=8/3.

  5. בדיקה במשוואה השנייה נותנת 8/3−5/3=1.

התוצאה ומה היא אומרת

האלימינציה לא שינתה את הפתרון; היא רק החליפה את המשוואה השנייה במשוואה שקולה ונוחה יותר.

(x,y)=(8/3,5/3)
דוגמה 2

כאשר ה־pivot הראשון הוא אפס

פתרו את 2y=4,‏ x+y=3 והסבירו מדוע חייבים להחליף שורות.

  1. המטריצה היא [[0,2|4],[1,1|3]]. אי אפשר להשתמש ב־0 כדי לאפס את האיבר שמתחתיו.

  2. מחליפים R₁↔R₂ ומקבלים [[1,1|3],[0,2|4]].

  3. מן השורה השנייה מתקבל y=2, ומן הראשונה x+2=3 ולכן x=1.

  4. מטריצת ההחלפה היא P=[[0,1],[1,0]]. כאן כבר PA משולשת, ולכן L=I ו־U=PA.

התוצאה ומה היא אומרת

החלפת השורות משנה את הסדר בלבד ושומרת את שתי המשוואות ואת פתרונן.

(x,y)=(1,2)

איפה זה פוגש את העולם

יישום

בניתוח מעגל או רשת אפשר לפרק את A פעם אחת ואז לפתור במהירות עבור אגפי ימין רבים. השלב היקר הוא הפירוק; ההצבות קדימה ואחורה זולות יותר וממחזרות את המבנה.

מלכודת נפוצה

מה כדאי לבדוק

לשנות את A בלי לשנות את b, או לחלק ב־pivot אפס או זעיר בלי להחליף שורות. בנוסף, L שומרת את הכפולות ℓ עצמן, אף שבפעולת השורה מחסרים אותן.

בודקים שהרעיון יושב

תרגול ומשוב

בדיקת הבנה

בחרו תשובה ורק אז בדקו את עצמכם

אם מבצעים R₂←R₂−3R₁ על [A|b], מה חייב לקרות לרכיב השני של אגף ימין?

בחרו אחת מהאפשרויות כדי להמשיך.

עכשיו אתם

אתגר קצר

עבור A=[[2,1,1],[4,−6,0],[−2,7,2]] ו־b=(5,−2,9), בצעו אלימינציה ללא החלפת שורות, בנו את L ואת U ופתרו את Ax=b.

רמז ראשון

השתמשו לפי הסדר במכפילים ℓ₂₁=2,‏ ℓ₃₁=−1 ו־ℓ₃₂=−1. זכרו: L שומרת את המכפילים עצמם, אף שבפעולות השורה מחסרים אותם.

הצגת דרך הפתרון
  1. אחרי R₂←R₂−2R₁ ו־R₃←R₃+R₁ מתקבלות השורות [0,−8,−2|−12] ו־[0,8,3|14].
  2. המכפיל הבא הוא ℓ₃₂=8/(−8)=−1, ולכן R₃←R₃+R₂ ומתקבלת [0,0,1|2].
  3. לכן U=[[2,1,1],[0,−8,−2],[0,0,1]] ו־L=[[1,0,0],[2,1,0],[−1,−1,1]]. אין החלפות, ולכן P=I.
  4. אפשר לקרוא את אגף ימין שעבר אלימינציה כ־y=(5,−12,2), כלומר כפתרון של Ly=b. לאחר מכן Ux=y נותנת בהצבה לאחור x₃=2,‏ x₂=1 ו־x₁=1.
  5. בשיעור 4.3 תוכלו לכפול ולוודא במפורש ש־LU=A; כרגע אפשר לאמת על ידי שחזור פעולות האלימינציה.

מימוש הנושא

קוד שאפשר לקחת לניסוי

הקוד מיישם את אותו רעיון מתמטי. ב־JavaScript אפשר להריץ אותו כאן; גרסת Python זמינה להשוואה ולהעתקה.

הקשר למתמטיקה

pluSolve מחשבת scale נפרד לכל שורה, בוחרת את יחס ה־pivot הבטוח ביותר, ומחליפה יחד את U,‏ b,‏ P,‏ L ו־rowScales. הכפל בסוף הקוד הוא תצוגה מקדימה לשיעור 4.3.

פלט צפוי

עבור הדוגמה יתקבל x קרוב ל־[1,1,2],‏ P=I ו־factorizationError קרוב לאפס. גם המערכת שבה השורה השנייה מוכפלת ב־10⁻¹³ תחזיר [1,2].

ניסוי המשך

נסו תחילה A=[[0,2],[1,1]],‏ b=[4,3] כדי לראות החלפה. אחר כך כִּפלו שורה אחת של A ושל b באותו מספר קטן וודאו שהפתרון אינו משתנה.

מהרעיון אל הקוד

מימוש חישובי

function pluSolve(matrix, rhs, relativeTolerance=1e-12) {
  const n = matrix.length;
  if (!n || rhs.length !== n || matrix.some((row) => row.length !== n)) {
    throw new Error("A must be square and match b");
  }

  const U = matrix.map((row) => row.map(Number));
  const rowScales = U.map((row) => Math.max(...row.map(Math.abs)));
  if (rowScales.some((scale) => scale === 0)) {
    throw new Error("no unique solution");
  }
  const b = rhs.map(Number);
  const L = Array.from({ length: n }, () => Array(n).fill(0));
  const P = Array.from(
    { length: n },
    (_, i) => Array.from({ length: n }, (_, j) => Number(i === j)),
  );

  for (let k = 0; k < n; k += 1) {
    let pivot = k;
    for (let i = k + 1; i < n; i += 1) {
      const candidateRatio = Math.abs(U[i][k]) / rowScales[i];
      const pivotRatio = Math.abs(U[pivot][k]) / rowScales[pivot];
      if (candidateRatio > pivotRatio) pivot = i;
    }
    if (U[pivot][k] === 0) throw new Error("no unique solution");
    if (Math.abs(U[pivot][k]) <= relativeTolerance*rowScales[pivot]) {
      throw new Error("nonzero pivot is numerically unsafe at this tolerance");
    }
    if (pivot !== k) {
      [U[k], U[pivot]] = [U[pivot], U[k]];
      [b[k], b[pivot]] = [b[pivot], b[k]];
      [P[k], P[pivot]] = [P[pivot], P[k]];
      [rowScales[k], rowScales[pivot]] = [rowScales[pivot], rowScales[k]];
      for (let j = 0; j < k; j += 1) {
        [L[k][j], L[pivot][j]] = [L[pivot][j], L[k][j]];
      }
    }

    L[k][k] = 1;
    for (let i = k + 1; i < n; i += 1) {
      const multiplier = U[i][k] / U[k][k];
      L[i][k] = multiplier;
      for (let j = k; j < n; j += 1) {
        U[i][j] -= multiplier * U[k][j];
      }
      b[i] -= multiplier * b[k];
    }
  }

  const x = Array(n).fill(0);
  for (let i = n - 1; i >= 0; i -= 1) {
    const known = U[i].slice(i + 1)
      .reduce((sum, value, j) => sum + value*x[i + 1 + j], 0);
    x[i] = (b[i] - known) / U[i][i];
  }
  return { x, P, L, U };
}

function multiplyMatrices(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, 1], [4, -6, 0], [-2, 7, 2]];
const result = pluSolve(A, [5, -2, 9]);
const PA = multiplyMatrices(result.P, A);
const LU = multiplyMatrices(result.L, result.U);
const factorizationError = Math.max(
  ...PA.flatMap((row, i) => row.map((value, j) => Math.abs(value - LU[i][j]))),
);
console.log({ ...result, factorizationError });
console.log(pluSolve([[1, 0], [0, 1e-13]], [1, 2e-13]).x);

לפני שממשיכים

מה לוקחים מהשיעור

  • פעולות שורה הפיכות משנות את צורת המערכת אך לא את קבוצת הפתרונות שלה.
  • כל פעולה על שורת A חייבת להתבצע גם על הרכיב המתאים של b.
  • אלימינציה יוצרת U והצבה לאחור פותרת ממנה את הנעלמים בסדר הפוך.
  • P מתעדת החלפות שורה ו־L מתעדת מכפילים; כך אפשר למחזר פירוק אחד עבור אגפי ימין רבים.

משימת מעבדה לשיעור הזה

תחנה 2 — אלימינציה צעד אחר צעד

בחרו pivot, חזו את המכפיל ואת השורה החדשה, ורק אז הפעילו את הצעד. עקבו אחר אגף ימין וודאו שהפתרון נשמר.

לפתיחת התחנה
מקורות להעמקה בלבד — השיעור עומד בפני עצמו

מדריך המרצים: עמ׳ 104–109

ספר הלימוד: עמ׳ 210–218