PDA

View Full Version : سوال: مشکل در محاسبه ی دترمینان



kavehmj
سه شنبه 17 آذر 1394, 19:22 عصر
سلام.

دوستان من به یک مشکل بسیار عجیبی برخورد کردم.
من تابعی برای محاسبه ی دترمینان ماتریس نوشته بودم. تابع رو هم با انواع و اقسام ماتریس ها چک کردم و هر دفعه به جواب های درستی می رسیدم.


مشکلم این هست که در کد من، در یک جایی به یک ماتریس 6x6 می رسم. وقتی می خواهم دترمینان آن را حساب کنم، به یک عددی می رسم که غلط است.
اما همین ماتریس 6x6 رو وقتی در محیط کامپایلر وارد می کنم، برنامه مقدار دترمینان را به درستی حساب می کند. (مقدار درست رو با برنامه متلب چک کردم.)

کد من به شرح زیر است:

137336137336





طی فرآیند برنامه، ماتریس Kbound که در این مثال یه ماتریس 6x6 هست ساخته می شه.
همین ماتریس رو من به صورت دستی در خط 1910 با نام Kbound2 وارد کردم.

وقتی که برنامه یک بار در خط 1903 دترمینان Kbound رو حساب می کند و سپس در خط 1930 دترمینان Kbound2 رو حساب می کند (که این دو ماتریس با هم برابر هستند) به دو جواب کاملا متفاوت می رسم.
دترمینان رو به روش گاوس این تابع حساب می کنه. نام تابع هم Determinant2 هست.
توابعی رو هم در تابع Determinant2 تعریف کردم که در هر مرحله خروجی بگیره که بفهمم مشکلش چیه.


چیزایی که تا الان فهمیدم اینه:
هر دو ماتریس با مقادیر کاملا یکسان وارد تابع می شوند.
اما در طول فرآیند محاسبه که در هر مرحله ماتریس از سطر و ستون یک واحد کوچک تر می شود، برخی از درایه هاشون با یکدیگر متفاوت می شود. به همین دلیل در انتها جواب دترمینان دو جواب متفاوت خواهد بود.

کامپایلرم هم Microsoft Visual Studio 2013 هست. حتی با DEV هم امتان کردم. باز هم جواب ماتریسی که در طول برنامه تشکیل می شه دترمینان غلطی می ده و مقدارش هم با کامپایلر MVS13 متفاوته.


ممنون می شوم اگر راهنمایی ام کنید که مشکل از کجاست.

kavehmj
سه شنبه 17 آذر 1394, 19:26 عصر
توضیح: دوستان به علت محدودیت ارسال کاراکتر در پست، مجبور شدم بسیاری از توابع برنامه رو که در تشکیل ماتریس Kbound نقش داشتند رو حذف کنم. به همین خاطر اگر کد کامل رو برای کامپایل نیاز دارید، بفرمایید تا براتون با ایمیلی یا اگر راه دیگری می شناسید، بفرستم.

rahnema1
سه شنبه 17 آذر 1394, 23:03 عصر
سلام
خب می تونید فایلها را زیپ کنید
وقتی پست را ارسال می کنید یک دکمه به نام ضمیمه وجود داره که کلیک کنید و فایل را ارسال کنید
ضمن تقدیر از زحمتی که کشیدید و این برنامه را آماده کردید
در هر صورت چند نکته به ذهنم می رسه
اگر به جای شما بودم به جای آرایه دوبعدی یک کلاس ماتریس تعریف می کردم و داخل اون عملگر هایی مثل + یا * یا مثلا معکوس ماتریس تعریف می کردم
یا مثلا از vector استفاده می کردم که هر دفعه نخوام سایز آرایه را مشخص کنم
به جای استفاده از *char و تابعهایی مثل strcpy و strcmp از string استفاده می کردم که کار باهش خیلی راحت و بی دردسره و احتمال خطا داخلش کمتره

kavehmj
چهارشنبه 18 آذر 1394, 00:21 صبح
سلام
خب می تونید فایلها را زیپ کنید
وقتی پست را ارسال می کنید یک دکمه به نام ضمیمه وجود داره که کلیک کنید و فایل را ارسال کنید
ضمن تقدیر از زحمتی که کشیدید و این برنامه را آماده کردید
در هر صورت چند نکته به ذهنم می رسه
اگر به جای شما بودم به جای آرایه دوبعدی یک کلاس ماتریس تعریف می کردم و داخل اون عملگر هایی مثل + یا * یا مثلا معکوس ماتریس تعریف می کردم
یا مثلا از vector استفاده می کردم که هر دفعه نخوام سایز آرایه را مشخص کنم
به جای استفاده از *char و تابعهایی مثل strcpy و strcmp از string استفاده می کردم که کار باهش خیلی راحت و بی دردسره و احتمال خطا داخلش کمتره


با تشکر از پیشنهادادتون.
راستش من با کلاس و vector کار نکردم و آشنایی ندارم. واسه همین بالاجبار از توابع استفاده کردم.

کل کد برنامه رو تو ی فایل text ذخیره کردم و می فرستم.
فقط تو این تابع determinant2 یک سری کد برای خخروجی گرفتن اضافه کردم که ببینم مشکل از کجاست. مشکل ظاهرا تو دقت اعداد هست. مثلا در متغیر ZeroerF در مرحله ی اول که i=n و در سطر آخر که k=5، در ماترسی اول (که از طریق برنامه محاسبه شده) مقدار 0.631579 ولی در ماتریس دوم که مستقیم با عدد به کامپایلر دادم، مقدار 0.63158 حساب شده. همین تفاوت در مراحل بعدی بیشتر و بیشتر می شه که در نهایت باعث می شه دترمینان اشتباهی برای ماتریس اول بهم تحویل بده.


با تشکر



137336137336

rahnema1
چهارشنبه 18 آذر 1394, 18:34 عصر
من چند تا اشکال بود که برطرف کردم
مثلا برای مقایسه رشته ها از == نمی شه استفاده کرد که تبدیل به strcmp کردم
این یه مشکل که همین طور که قبلا گفتم بهتر بود به جای *char از string استفاده کنید
لازمه تابع به تابع تست کنید ببینید درست کار می کنه یا نه
حالا این همه زحمت کشیدید اگه شاید یه هفته یا کمتر وقت می گذاشتید و نحوه کار با کتابخانه ای مثل Armadillo (http://arma.sourceforge.net) که تحت ++c هست یاد می گرفتید کارتون خیلی خیلی راحت می شد چون واسه محاسبات ماتریسی هست و دترمینان و خیلی چیزهای دیگه هم داره و کدی که ایجاد می کردید خیلی خوانا تر و حجم خیلی کمتر می شد و نحوه استفاده از اون هم خیلی مشابهت با دستورات متلب داره
این هم کد اصلاح شده
http://www.sharefile.ir/uploads/1449675252.zip