קוד ריד-סולומון

קוד ריד-סולומון (באנגלית: Reed–Solomon code) הוא קוד תיקון שגיאות ליניארי נפוץ ושימושי ביותר,
המבוסס על אינטרפולציה באמצעות פולינומים מעל שדות סופיים.
הקוד מיועד להעברה אמינה של מידע בערוץ תקשורת רועש (כדוגמת טלפון סלולרי), שבמידע המועבר בו עלולות להיווצר שגיאות, או לשמירת מידע במדיה שעלולה להיפגם (DVD, למשל), ולכן להכיל שגיאות.

מבוא

קוד ריד-סולומון פותחו על ידי צוות החוקרים אירווינג ריד וגוסטב סולומון ממעבדת לינקולן (MIT Lincoln Laboratory) - מעבדת המחקר של מחלקת ההגנה של ארצות הברית ב-MIT. 
במאמרם משנת 1960 הציגו ריד וסולומון שיטה יעילה ופשוטה לקידוד מידע, וניתחו את כמות השגיאות שניתן לתקן בעזרת קוד זה. מסתבר שהקוד הוצג לראשונה בשנת 1952, כחלק ממחקר בנושא ריבועים לטיניים, אך ריד וסולומון היו הראשונים להכיר בתכונותיו לתיקון שגיאות.
השימוש בקוד לתיקון שגיאות דורש הפעלת שני אלגוריתמים, לקידוד ולפענוח. תפקידו של אלגוריתם הקידוד לקחת מילה מסוימת (מילת המקור) ולקודד אותה למילה אחרת, ארוכה יותר, המכילה יתירות  (מילת הקוד).
אלגוריתם הפענוח מקבל כקלט את המילה הארוכה, ייתכן בתוספת שיבושים שונים שנוספו לה עקב השידור בערוץ הרועש. אלגוריתם הפענוח מנסה לשחזר את מילת המקור מתוך הקלט, כאשר היתירות שהוספה בתהליך הקידוד משמשת אותו להתמודדות עם השגיאות שקרו. תהליך הפענוח מורכב מאשר תהליך הקידוד. ריד וסולומון לא הציגו שיטת פענוח יעילה, וזו הומצאה בשנת 1967.
קוד ריד-סולומון המקוׂדֵד מחרוזת המכילה k אותיות (אות כנ"ל נקראת גם סימבול, ואורכה יכול להשתנות, ראו בהמשך) ל-n אותיות מסומן ב-RS(n,k)‎, ומסוגל לתקן עד  שגיאות (כלומר הוא קוד ליניארי בעל הפרמטרים ); הקוד מתקן שגיאות במידה המקסימלית האפשרית לקוד בעל הפרמטרים  ו-.

שימושים והרחבות

פיתוח שיטת קידוד יעילה וכן התפתחות תקשורת הנתונים הובילו לשימוש נרחב בקודי-תיקון שגיאות ובראשם בקודי ריד-סולומון. בימינו ניתן למצוא מערכות אלקטרוניות רבות אשר עושות שימוש בקודי ריד-סולומון, דוגמת מכשירי רדיו (הן קוויים, דוגמת ערוצי DSL, והן אלחוטיים דוגמת WiMAX), תקליטורים וDVD, ומקודדי-וידאו. שימושים נוספים של הקוד הם לשיפור מערכות פיזור ספקטרום של מערכות תקשורת אלחוטיות, וכן בהתמודדות עם שגיאות חד-כיווניות, מהסוג הנפוץ באפיקי נתונים מהירים של מחשבים.

שמירת מידע

קיים שימוש נרחב בקוד ריד-סולומון להתקנים שונים לשמירת מידע. במדיות רבות (בעיקר מדיות אופטיות) ההתקן עצמו גורם לשגיאות במידע השמור (למשל, עקב שריטות או פגמים אחרים) ובשל כך נדרשת יתירות במידע עצמו השמור על-גבי המדיה.
תכונות השגיאות במדיות אלו  הופכות את קוד ריד-סולומון לפתרון יעיל. לרוב השגיאות הנובעות מ"פגם" אינן מפוזרות אלא מקובצות יחדיו, ומתקבל רצף (burst) של שגיאות עמו הקוד מסוגל להתמודד היטב.
תקן שמירת המידע בתקליטורים (CD) מגדיר שימוש בשתי שכבות של קוד ריד-סולומון, שיטה המכונה CIRC. השכבה הראשונה היא בעלת הפרמטרים  RS(28,24)‎, לאחר מכן מתבצעת שזירה של המידע (פיזור הביטים כך שביטים עוקבים מורחקים אחד מהשני, interleaving), והפעלת קוד  RS(32,28)‎ על המידע השזור.
השכבה הראשונה מתמודדת עם פגמים בייצור התקליטור ובדרך שבה הוא נצרב (פגמי "מיקרו"). השכבה השנייה מיועדת להתמודד עם הפרעות כגון שריטות או טביעות אצבע, בעלות שטח הפרעה גדול יותר (פגמי "מאקרו").
שימוש נוסף לקוד ריד-סולומון עבור שמירת מידע ניתן למצוא בברקודים מודרניים (דו-ממדיים). קריאת ברקודים אלו מבוצעת על ידי צילום הברקוד וזיהוי פסים או ריבועים שחורים ולבנים. זווית הצילום, המרחק, כמות האור וכן תקינות מדבקת הברקוד עצמה הם גורמים בעלי השפעה רבה על איכות הזיהוי של המידע בברקוד. מתוך הנחה שחלק מהריבועים לא יזוהו נכון, מקודד המידע באמצעות קוד ריד-סולומון ומפעונח במהירות וביעילות בצד הקורא האופטי. תקני ברקוד הכוללים קידוד ריד-סולומון הם 
PDF-417 ,PostBar ,MaxiCode ,Datamatrix‏ ,קוד QR‏ ,Aztec Code, ועוד.

שידור מידע

אפליקציה משמעותית נוספת של הקוד היא עבור שידור מידע בתקשורת קווית או אלחוטית. אחת האפליקציות המפורסמות של קוד זה הייתה עבור המשדר של הגשושית וויאג'ר, בעת מסעה אל אורנוס ונפטון. גם במקרה זה הקוד בנוי משתי שכבות, כאשר השכבה הנוספת היא קוד קונבולוציה כגון קוד טורבו או קוד ויטרבי, אשר בעת שגיאה בתהליך הפענוח נוטים לייצר פרצי שגיאות, עמם קוד ריד-סולומון מתמודד בצורה טובה. בשיטה זו נעשה שימוש נרחב במשדרים לחלל העמוק, לרבות עבור גלילאו וגשושי משימות חקר מאדים, והפך לתקן המוסכם על ידי הוועדה המייעצת למערכות מידע בחלל (CCSDS).

קוד ריד-סולומון במובן הקלאסי

כאמור לעיל, המטרה היא לקחת  מספרים כלשהם, שיסומנו
,
להסתכל על הפולינום שמספרים אלו הם מקדמיו,
‬

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

כאל מספרים כלשהם, הרי ששידור "מספר כלשהו" מצריך שידור כמות לא חסומה של מידע. פתרון לבעיה זו מתקבל על ידי שימוש בקבוצה סופית של מספרים שמהווה שדה סופי בגודל n איברים, אשר יסומן .
איבר בשדה זה נקרא לרוב סימבול ומהווה את יחידת הבסיס של הקוד. על-מנת לשדר סימבול ניתן לקודד אותו לביטים או לעשות שימוש בשיטת אפנון מתקדמת שבה כל סימבול (של הקוד) מזוהה עם סימבול של האפנון. כיוון שקיימים 
סימבולים אפשריים בשדה הסופי, ניתן לקודד כל סימבול על ידי  ביטים.
באופן פורמלי:
קידוד ריד-סולומון מאורך 
ומממד 
מעל השדה הסופי

הוא המיפוי

כאשר ,
ו 
הם כלל אברי השדה הסופי (כלל הסימבולים אפשריים). קוד ריד-סולומון הוא אוסף כלל המילים אשר ממופות על ידי המיפוי לעיל, עבור כל מילות המקור האפשריות, .

‬קוד ריד-סולומון במובן מודרני

במקום לחשוב על המילה אותה אנו מקודדים, , בתור מקדמים של פולינום, אנחנו יכולים לחשוב עליה כעל ערכים של פולינום ב- מקומות ידועים. ערכים אלו מגדירים פולינום (ממעלה לכל היותר ) בצורה חד-חד ערכית בהתאם לאינטרפולציה. אם המקומות הידועים הם  האיברים הראשונים של , תחילית מילת הקוד תהא מילת המקור (כלומר, מתקבל קוד סיסטמטי).
הגדרה זו מראה כי קוד ריד-סולומון הוא מקרה פרטי של משפחת קודים רחבה יותר בשם קודי BCH. קוד BCH הוא קוד ציקלי עבורו קיים פולינום   בעל תכונות מסוימות הנקרא יוצר של הקוד, וכל מילת קוד היא מכפלה של הפולינום היוצר בפולינום המוגדר על ידי מילת המקור. 
בצורה זו, קוד ריד-סולומון מוגדר על ידי היוצר

כאשר  הוא שורש פרימיטיבי של השדה הסופי:  ולכל , . עבור מילת המקור  המגדירה את הפולינום  המילה המקודדת היא מקדמי הפולינום . משיקולי מעלות, הפולינום  הוא ממעלה 
 לכל היותר, ועל כן יש לשדר  סימבולים.
ניתן להראות כי הגדרה זו שקולה להגדרה המקורית של הקוד שהוצגה במאמרם של ריד וסולומון.

היסטוריה

בעוד קידוד מילה בשיטת ריד-סולומון הוא משימה פשוטה וקלה, פענוח הוא משימה מסובכת הצורכת משאבים רבים. פריצת הדרך בגילוי שיטה יעילה לפענוח התרחשה בשנת 1967, על ידי המתמטיקאי אלווין ברלקמפ (Berlekamp) שהציג אלגוריתם לפענוח קוד BCH מתוך ההבנה שקוד ריד-סולומון הוא מקרה פרטי של קוד BCH.
העקרונות המתמטיים של פענוח (עבור קוד BCH) הוצגו לראשונה בשנת 1960 במאמר של פטרסון (Peterson), אשר הציג שיטה לפענוח קוד BCH בסיבוכיות של . בשנת 1968 הציע ג'יימס מסי (Massey) דרך למימוש מפענח המבוסס על אוגרי הזזה בסיבוכיות של . בשנת 1975 הציגה קבוצה של מדענים מיפן שיטה לפענוח הקוד המבוססת על אלגוריתם אוקלידס בעלת סיבוכיות דומה.
בשנת 1995 הציגו הונג ווטרלי שיטה לביצוע הפענוח בסיבוכיות .

פענוח בשיטה נאיבית

הדרך הפשוטה (מבחינה רעיונית) לפענח מילת קוד, היא לבצע אינטרפולציה של כל הפולינומים המוגדרים על ידי  נקודות מתוך  הנקודות שמכילה מילת הקוד. כפי שמוצג בדוגמה לעיל בה שוחזר קו מתוך 4 נקודות בהן נפלה שגיאה יחידה, 3 אינטרפולציות הזדהו עם הקו הנכון, וכל אינטרפולציה אחרת הייתה שונה. באופן כללי ייתכן שמספר אינטרפולציות שגויות יתלכדו זו עם זו; עדיין, אם כל אינטרפולציה כזו תעניק "קול" אחד לטובת הפולינום שהיא מגדירה - הפולינום הנכון יזכה במרב הקולות, וכל שאר הפולינומים השגויים יזכו במספר קולות קטן (אבל ייתכן שגדול מ-1). הבעיה בשיטת פענוח זו, היא שיש לבצע אינטרפולציה עבור כל אחת מתוך  האפשרויות השונות, וזהו מספר גדול של חישובים שאינו נחשב יעיל. לדוגמה, בקוד RS(28,24)‎ אשר משמש תקליטורים, פענוח מילה יחידה (192 ביט של מידע) מצריך ביצוע כ-20 אלף אינטרפולציות (בעוד הזמן המוקצה לכך בתקליטור הוא כ-0.000136 שניות). באופן דומה, פענוח מילת קוד יחידה בקוד RS(208,192)‎ בו נעשה שימוש ב-DVD, מצריך ביצוע כ- אינטרפולציות - פעולה אשר תימשך מספר רב של ימים בטכנולוגיה בת ימינו.

פענוח לפי סינדרום (ברלקמפ-וולש)

השיטה המודרנית לפענוח קודי ריד סולומון מבוססת על הסתכלות על הקוד כמקרה פרטי של קודי BCH, לפי אלגוריתם שפותח על ידי ברלקמפ ושופר על ידי וולש (Welch)  וידוע בתור אלגוריתם ברלקמפ-וולש. להלן תיאור עקרוני של שיטת הפענוח.
נניח כי בעוד שנשלחה מילת הקוד  המתאימה לפולינום 
 המוגדר לעיל, בצד הקולט התקבלה המילה  אשר נפלו בה  שגיאות לכל היותר, כלומר, עבור  אינדקסים לכל היותר . כזכור, כלל הערכים הם איברים בשדה הסופי .
ניתן להגדיר פולינום שגיאה אשר יסומן . התכונות של פולינום השגיאה הן שבכל אינדקס  בו קרתה שגיאה, הפולינום יקבל את הערך 0, מעלתו תהיה , והוא נדרש להיות פולינום מתוקן. הצד המקבל לא יודע לבנות את פולינום השגיאה (כי אינו יודע את האינדקסים שבהן קרו שגיאות), אבל ידוע שפולינום כנ"ל קיים. 
עקרון המפתח הוא שקיים פולינום ממעלה  לכל היותר, שנסמנו  ומתקיים:

למשל, אם , אזי  הוא ממעלה   לכל היותר, והמשוואה לעיל מתקיימת לכל אינדקס . לכן אם ידועים הפולינומים  ניתן לפענח את המילה המקורית על ידי ביצוע חלוקה: . לא ייתכן שקיים פולינום אחר (ממעלה  לכל היותר) אשר שווה לתוצאת החלוקה, ולכן שיטה זו תשחזר את הפולינום הנכון.
ניתן למצוא את הפולינומים  בצורה יעילה: יהיו  המקדמים של הפולינום , ויהיו  המקדמים של . כזכור,  הוא פולינום מתוקן, ועל-כן . אם מציבים ב- את כל אחד מאברי השדה, מתקבלת מערכת של  משוואות ליניאריות עם  נעלמים (מקדמי ). מכיוון שכמות השגיאות מוגבלת ב-
מספר הנעלמים הוא , והמערכת ניתנת לפתרון.

פענוח בערוץ מחיקה

בערוצי תקשורת מסוימים הנקראים ערוצי מחיקה, השגיאה מתבטאת בכך שהצד הקולט לא מקבל כל מידע. בערוץ זה, כאשר כן נקלט מידע הוא תמיד נקלט נכון, אך לעיתים לא מגיע מידע (אירוע זה מכונה "מחיקה"). דוגמה לערוץ כזה הוא ערוץ תקשורת אופטי בו תדר מסוים מסמל "0" ותדר אחר מסמל "1": לעיתים הפוטונים הנשלחים "נבלעים", או נחסמים בתווך שבין המשדר למקלט; אך אם הפוטון הגיע לצד השני ניתן לזהות בצורה וודאית מה היה תדר הפוטון שנשלח, ומה הביט שהוא מסמל. 
שגיאות מסוג זה קלות מאוד לתיקון על ידי קוד ריד-סולומון. בהנחה שבקוד RS(n,k)‎ חלו  מחיקות לכל היותר, ניתן לעשות שימוש בשאר  הערכים שנקלטו ולבצע אינטרפולציה לפולינום שנשלח. מכיוון שנקודות אלו הגיעו ללא שגיאה, האינטרפולציה תצליח תמיד. מכאן שתיקון מחיקות  "קל" יותר מאשר תיקון שגיאות. שיטה לתיקון שגיאות היא רבת עוצמה יותר משיטה לתיקון מחיקות: ניתן להפוך מחיקה לשגיאה על ידי כך שנגריל ערך אקראי כלשהו במקום המחיקה. מן הסתם, ערך זה יהיה שגוי ויתפרש כ"שגיאה", אך כעת ניתן להפעיל את שיטת הפענוח להתמודדות עם שגיאות. מאידך, הקושי בהימצאותן של שגיאות (לעומת מחיקות) הוא שלא ידוע מיקומן של השגיאות, ואלגוריתם הפענוח נדרש להבדיל איזו נקודה היא השגויה ואיזו התקינה.

פענוח מחיקות ושגיאות בו זמנית

כאמור לעיל, קוד ריד-סולומון מסוגל להתמודד עם   מחיקות או עם   שגיאות כאשר . ניתן לשלב את שני אלו ולקבל כי קוד ריד-סולומון מסוגל להתמודד עם  מחיקות וגם  שגיאות, כל עוד .

יעילות הקוד במקרים פרטיים שונים

קוד RS(n,k)‎ מסוגל לתקן עד  סימבולים שגויים. במידה וכל סימבול מיוצג כרצף של ביטים באורך  הקוד יכול להתמודד עם לכל הפחות  ביטים שגויים (המפוזרים כל אחד בסימבול שונה), אך ייתכנו מצבים בהם הקוד מסוגל להתמודד עם עד 
 ביטים שגויים, המקובצים כולם ב- סימבולים שונים, לכל היותר. תכונה זו הופכת את הקוד לחזק במיוחד כאשר מדובר בערוץ בינארי בו פיזור השגיאות הוא ב"פרצים" צמודים. בנוסף, כאשר משתמשים במספר שכבות קוד תיקון-שגיאות (למשל, שתי שכבות קוד ריד-סולומון כפי שקיים בתקליטורים, או קוד קונבולוציה וקוד ריד-סולומון, כפי שמצוי בגשושית וויאג'ר), במידה והקוד הפנימי אינו מצליח לתקן את השגיאה, הוא מסמן זאת עבור הקוד החיצוני. כעת קוד ריד-סולומון בשכבה החיצונית יכול להתייחס לערך המסומן כאל "מחיקה" ולשפר את יכולת תיקון השגיאות.

הרחבות

קודי ריד-סולומון פתחו עידן רחב של מחקר בתחום תורת הקודים ויישומיה. לאורך השנים בוצעו מספר שיפורים והרחבות לקוד המקורי, על מנת לקבל קודי תיקון שגיאות המתאימים לאפליקציות שונות, לשפר את קצב הקוד ולהתקרב כמה שיותר אל קיבולת הערוץ (שהיא החסם על קצב הקוד המקסימלי, כפי שהוגדר  על ידי קלוד שאנון במשפט הידוע בתור משפט קידוד המקור של שנון).
יש וריאנטים של קודי ריד-סולומון המבוססים על מטריצות קושי מעל שדה מתאים.

קודי ריד-סולומון מוכללים

משפחה יותר רחבה של קודי ריד-סולומון, מתקבלת כאשר מילת הקוד מוכפלת בפולינום קבוע  שהוא פרמטר של הקוד. משפחה זו נקראת קודי ריד-סולומון מוכללים, ולכל    המוגדרים מעל השדה הסופי  בגודל  לכל הפחות, הקוד  מוגדר בתור אוסף המילים המתקבל על ידי הקידוד:

הפרמטר  מאפשר להקטין את אורך הקוד על ידי דגימת הפולינום בחלק מאברי השדה הסופי (המוגדרים על ידי ) ולא בכלל השדה. ניתן לראות כי קוד ריד-סולומון שהוגדר לעיל הוא מקרה פרטי של הקוד המוכלל, כאשר  הם כלל אברי השדה הסופי, ו-.

פענוח רשימה

עד כה, אלגוריתמי הפענוח ידעו להתמודד עם כמות שגיאות החסומה ב-. הערך  מסמל את מרחק המינג המינימלי בין שתי מילות קוד ונקרא גם מרחק הקוד. אם כמות השגיאות שקרו קטנה ממחצית מרחק הקוד - קיימת רק מילת קוד אחת שיכולה להיות זו שנשלחה ושיטות הפענוח שתוארו לעיל מצליחות לגלותהּ. נשאלת השאלה מה ניתן לעשות כאשר קרו יותר שגיאות?
במקרה זה, לא ניתן לדעת בוודאות מהי המילה שנשלחה, אבל ניתן לקבל רשימה של מילות מקור אפשריות. כל עוד מספר השגיאות שקרו קטן ממרחק הקוד - רשימה זו תהיה "קטנה": פולינומית באורך הקוד. מצד שני, אם מספר השגיאות גדול ממרחק הקוד - הרשימה תהיה ענקית: אקספוננציאלית באורך הקוד. בשנת 1997 הציע מדו סודן שיטה לבצע פענוח רשימה לקודי ריד-סולומון, בסיבוכיות פולינומית, תוצאה ששופרה בשנת 1999 וידועה בשם גורוסוואמי-סודן (Guruswami-Sudan) על שם ממציאיה. שיטה זו מאפשרת להתמודד עם  שגיאות. אם מסמנים את קצב הקוד  מתקבל כי השיטה מתמודדת עם אחוז שגיאות של  (כאשר החסם המקסימלי (מרחק הקוד) מהווה אחוז שגיאות של ).
בשנת 2004 הציגו פרברש וורדי (Parvaresh, Vardi) קוד המבוסס על ריד-סולומון, בו כל סימבול מהווה ערכים של שני פולינומים שונים. פענוח רשימה בשיטה הדומה לזו שהציגו גורוסוואמי-סודן מאפשר להתמודד עם אחוז שגיאות של . הרחבה של קוד פרברש-ורדי ל- פולינומים שונים מאפשר התמודדות עם  אשר עבור בחירת  גדול דיו מאפשרת אחוז שגיאות של . בעוד גורוסוואמי וסודן הראו איך לעשות שימוש בקוד ריד-סולומון עצמו, הרי שפרברש וורדי מגדירים קוד חדש (שמבוסס למעשה על שליחת מספר עותקים של מילת ריד-סולומון).
בשנת 2007 הציגו גורוסוואמי ורודרה (Guruswami, Rudra) כיצד להתקרב לחסם ולקבל קוד המתמודד עם יחס שגיאות של  לכל . הקוד של גורוסוואמי ורודרה, הידוע בשם קוד ריד-סולומון מקופל (Folded Reed-Solomon Code), מראה כיצד ניתן "לקפל" את ערכי הפולינומים השונים לתוך סימבול אחד, בשיטה דומה לקוד פרברש-ורדי אך בצורה יעילה יותר. הקיפול אפשרי לאור העובדה שקיים קשר בין הפולינומים השונים הנשלחים בקוד, וקשרים אלו יכולים לשמש לחסכון בשליחת מידע, ולהגדלת יעילות הקוד.