اكتشاف خطأ Round-off في برنامج Matlab [تحديث]

• أين صادفت الخطأ ؟
أثناء عملي على مشروع برنامج حساب مقلوب مصفوفة بلغة ++C ، قمت بتجريب عدد كبير من المصفوفات على المشروع في سبيل معالجته من الأخطاء، وكنت قد اتخذت برنامج Matlab مرجعاً لي في تمييز صحة نتائج المشروع من خطأها، فبرنامج Matlab يعد المرجع الأول للكثير من العمليات الرياضية.
في كل الحالات تمكن برنامج Matlab من إيجاد المقلوب الصحيح أو إظهار رسالة في حالة مصفوفة لايوجد لها مقلوب.
ظهرت المفاجئة عند مصفوفة واحدة فقط محددها مساوٍ إلى الصفر (Det = 0)، كما نعلم لايوجد لهذه المصفوفة أي مقلوب، وعند محاولة إدخالها إلى أي برنامج يجب أن يتوقف البرنامج مظهراً تعليلا بعدم إمكانية إيجاد مقلوب لتلك المصفوفة، وهذا ما أظهره البرنامج الذي عملنا على برمجته :

matrix-inverse(اضغط على الصورة لرؤيتها بالحجم الكامل)

عند إدخال نفس المصفوفة السابقة إلى برنامج Matlab ، حصلت على قيمة المحدد 6.6613e-15- بدلاً من الصفر، وذلك نتيجة لخطأ مشهور يسمى
Round-off error بسبب تقريب الأعداد الكسرية.

matlab-error

في هذه الحالة قام الـ Matlab بإظهار تنبيه يشمل قيمة RCOND ، ثم قام بإظهار نتيجة تقريبية لعملية المقلوب.
• ماهو سبب الخطأ ؟
يعتمد ذلك على العملية الداخلية التي يقوم بها البرنامج، فعلى سبيل المثال .. وجود هذه الأسطر في الكود المصدري لمشروعنا الذي تم ذكره في بداية المقالة مكننا من تجاوز هذا الخطأ وإظهار التعليل الصحيح لهذه الحالة :

for (i=0;i<n;i++) 
{
for (j=0;j<n;j++)
{
if ( ( X[i][j]==-0 ) || (( X[i][j]>-0.00000001 ) && ( X[i][j]<0.00000001 )) )
{
X[i][j]=0;
}
}
}

نلاحظ وجود الحلقات المتداخلة، حيث تمثل الحلقة الأولى السطر والحلقة الثانية العمود.
حيث :
( n ) رتبة المصفوفة
( i ) رقم السطر في المصفوفة
( j ) رقم العمود في المصفوفة

تقوم هذه الأسطر بإزالة الآثار المترتبة على عملية التقريب، وهي في حالة برنامجنا الذي صممناه 8 خانات بعد الفاصلة العشرية، عندها تفيد هذه الأسطر في الحالتين :
1- عند إدخال رقم لاينتمي إلى مجال التقريب الذي يعمل عليه البرنامج، عندها سيعتبره البرنامج مساوٍ إلى الصفر، فبرنامجنا يتعامل كحد أقصى مع رقم من رتبة 8 – ^ 10 ، أي يجب اعتبار كل رقم ينتمي إلى المجال ]0.000,000,01 + , 0.000,000,01 -[ مساوٍ إلى الصفر.

2- في الحالة الثانية :
(كمثال) : في حالة العملية (3*1/3) – 1 تجري على ثلاثة مراحل :
أولا : 0.333,333,33 = 1/3
ثانيا : 0.999,999,99 = 0.33,333,333 * 3
ثالثا : 0.000,000,001 = 0.999,999,99 – 1
نلاحظ أن ناتج العملية هو 0.000,000,001 ، بينما يجيب أن يكون مساوٍ إلى الصفر تماما، وتم الوقوع بهذا الخطأ نتيجة التقريب، نلاحظ وجود 9 خانات بعد الفاصلة العشرية، لذلك عند المرور على الكود السابق سوف يعتبره مساوٍ إلى الصفر ويتم إصلاح الخلل الناتج عن عملية التقريب.

يمكن رؤية التوضيح من الموقع الرسمي للـ Matlab من هنا
• مفتوح المصدر يفوز دوماً :
تحدثت في مقالة سابقة عن Octave، وهو نظير مجاني ومفتوح المصدر من الـ Matlab .
كانت المفارقة عندما جربت تلك المصفوفة على برنامج Octave ، فأعطى النتيجة بالشكل الصحيح بدون عمليات التقريب (Det=0)، كما نلاحظ في الصورة :

octave

لازلت أفضل Octave بسبب إظهاره للنتيجة بشكل واضح بدون عمليات التقريب، كان ذلك السبب الذي دفعني لجعل مشروعنا (مشروع برنامج حساب مقلوب مصفوفة بلغة ++C) مفتوح المصدر.

يمكن تحميل Octave لأنظمة ويندوز من هذا الرابط (150 ميغا بايت)، لرؤية آخر تحديثات البرنامج يمكن الذهاب إلى هذه الصفحة.
بعد فك الضغط عن الملف السابق، يجب الذهاب إلى المجلد bin وفتح الملف التنفيذي octave.exe لتشغيل البرنامج.

 

اترك تعليقًا

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *