حل معادله در متلب
به نام خدا و سلام.
به جلسه بیست و نهم از سری جلسات آموزش متلب خوش آمدید. آموزش نرم افزار متلب از وبسایت متلبپلاس به صورت رایگان ارائه میشود. در این جلسه به آموزش حل معادله در متلب میپردازیم. بدلیل کاربرد زیاد معادله جبری، حل معادله جبری با استفاده از متلب مبحث مهمی است. نحوه حل معادله جبری با solve، ریشه یابی با roots، vpasolve و fzero… از مباحث این جلسه هستند.
با متلب پلاس همراه باشید.
این مقاله درباره حل معادله جبری ساده (یک معادله، یک مجهول) در متلب است. آموزش حل دستگاه معادلات جبری نیز در وبسایت متلبپلاس ارائه شده است. برای مشاهده این مقاله روی 👈 حل دستگاه معادلات در متلب 👉 کلیک نمائید.
حل معادله با دستور solve در متلب
معروفترین دستور برای حل معادله جبری در متلب، دستور solve است. دستور solve(eqn,var) معادله eqn را برحسب متغیر var حل میکند. دقت کنید که معادله eqn بایستی حتما به صورت نمادین (symbolic) باشد. مثلا اگر معادلهای برحسب x است، ابتدای کار syms x را در متلب وارد کنیم. با استفاده از دستور solve هم میتوان معادله را به صورت پارامتری حل کرد و هم عددی. قدرت اصلی solve در حل معادلات پارامتری است. اما برای معادلات ساده نیز پاسخ عددی مناسبی ارائه میکند.
حل معادله در متلب را با یک مثال شروع میکنیم. لطفا همین الان نرم افزار متلب را باز کرده و همراه ما کدهای زیر را بنویسید.
برای مثال اول، یک معادله خطی ساده درنظر میگیریم.
syms x a b
eqn = a*x + b == 0;
solve(eqn,x)
پس از اجرای این کد، پاسخ به صورت زیر خواهد بود.
ans =
-b/a
برای حل همین معادله برحسب متغیر b داریم:
syms x a b
eqn = a*x + b == 0;
solve(eqn,b)
پس از اجرا
ans =
-a*x
حال یک مثال از حل معادله مثلثاتی در متلب درنظر میگیریم. میخواهیم نقطه یا نقاطی که تابع سینوس و کسینوس باهم برابرند را بیابیم. کد حل این معادله در متلب به صورت زیر است.
syms x
solve(cos(x) == sin(x), x)
که پس از اجرای آن، داریم:
ans =
pi/4
اما میدانیم که این معادله مثلثاتی بیش از یک پاسخ دارد. برای محاسبه کردن حل کامل این معادله مثلثاتی، در دستور solve عبارت ‘ReturnConditions’, true را اضافه میکنیم. با افزودن این عبارت، متلب پاسخ پارامتری معادله را به ما میدهد. این دستور دارای 3 خروجی خواهد بود. خروجی اول پاسخ معادله، خروجی دوم پارامترهای پاسخ و خروجی سوم شرایط پارامترها میباشد. بنابراین داریم:
syms x
[solx, param, cond] = solve(cos(x) == sin(x), x, 'ReturnConditions', true)
که پس از اجرای آن، داریم:
solx =
pi/4 + pi*k
param =
k
cond =
in(k, 'integer')
در این پاسخ، متلب از پارامتر k استفاده کردهاست. پارامتر k طبق شرایط، یک عدد صحیح (integer) است.
در برخی موارد ممکن است پس از اجرای دستور solve با پیغامEmpty sym: مواجه شویم. اگر این پیغام به صورت عادی باشد، معادله پاسخ ندارد. اما اگر این پیغام به صورت هشدار (Warning) نارنجی رنگ ارائه شد، دستور solve نمیتواند معادله را حل کند. مثلا معادله زیر پاسخ ندارد. به آن توجه کنید.
syms x
eqn = 3*x + 2 == 3*x + 3;
solve(eqn, x)
پس از اجرا، متلب پیغام خالی بودن پاسخ میدهد.
ans =
Empty sym: 0-by-1
اما در مواردی ممکن است دستور solve قادر به حل معادله نباشد. این اتفاق در معادلات غیرخطی بیشتر رخ میدهد. برای مثال، معادله غیرخطی زیر را با استفاده از solve نمیتوان حل کرد.
syms x
eqn = 2^(x) + sin(x+6) == 0;
solve(eqn, x)
Warning: Unable to solve symbolically. Returning a numeric solution using vpasolve.
In solve (line 304)
ans =
-0.50130743300391239342096633648703
در نسخههای جدید متلب، چنانچه solve نتواند معادله را حل کند، متلب آن را به روش عددی محاسبه میکند. در ادامهی این آموزش، دستور حل معادله غیرخطی به روش عددی ارائه میشود.
افزودن شرط با assume
در برخی موارد نیز معادله دارای چندین پاسخ است اما پاسخ مدنظر ما دارای شرط است. مثلا پاسخ مثبت، منفی و… هر شرط دیگر. در این حالت بهترین راه، استفاده از دستور assume است. دستور assume فرضیات ما را به متلب اعلام میکند. مثلا معادله x3+4x2-x را درنظر بگیرید. این معادله 3 ریشه دارد. یک ریشه صفر، یک ریشه مثبت و یک ریشه منفی. برای محاسبه ریشهی مثبت یک معادله از دستور assume(x > 0) استفاده میکنیم. معنی این عبارت، این است که فرض کن x مثبت است. برای درک بهتر به مثال زیر دقت کنید.
syms x
eqn = x*(x^2 + 4*x - 1);
assume(x > 0)
solve(eqn)
ans =
5^(1/2) - 2
syms x
eqn = x*(x^2 + 4*x - 1);
solve(eqn)
ans =
0
- 5^(1/2) - 2
5^(1/2) - 2
به همین ترتیب هر شرط دیگر روی x قابل اعمال است. برخی از شرایط مهم دستور assume در شکل زیر نشان داده شده.
محاسبه ریشههای چند جملهای با دستور roots در متلب
اگر معادله به صورت چند جملهای باشد، بهترین روش حل آن، دستور roots است. دستور roots(p) ریشههای چند جملهای p را محاسبه میکند. برای استفاده از دستور roots چند جملهای را به صورت یک بردار مینویسیم. به این صورت که ضرایب چند جملهای از بزرگ به کوچک را در یک بردار قرار میدهیم. دقت کنید که هر چند جملهای از مرتبه n دارای n+1 جمله (ضریب) است. برای حل، معادله 3x2-5x+1 را درنظر میگیریم.
roots([3 -5 1])
که پس از اجرا داریم:
ans =
1.4343
0.2324
حال یک چند جملهای از مرتبه 4 به صورت x4-5x2+4=0 درنظر میگیریم. اگرچه ضرایب مرتبه 3 و یک این چند جمله وجود ندارد، اما باید بجای آنها صفر قرار دهیم. برای محاسبه ریشههای این چند جملهای در متلب، به صورت زیر عمل میکنیم.
roots([1 0 -5 0 4])
ans =
-2.0000
2.0000
-1.0000
1.0000
اگر بخواهیم یک چند جملهای با ریشههای دلخواه ایجاد کنیم، از دستور poly استفاده میکنیم. کافیست ریشههای موردنظر را درون یک بردار نوشته و در دستور poly قرار دهیم. بالافاصله ضرایب جملات چند جملهای برای ما محاسبه میشود. ریشههای بدست آمده از مثال قبل را درون دستور poly وارد میکنیم.
poly([1 -1 2 -2])
ans =
1 0 -5 0 4
حل معادله جبری غیرخطی با دستور vpasolve در متلب
دیدیم که دستور solve برای حل معادلات غیرخطی مناسب نیست. دستوری که برای حل معادلات جبری پیچیده در متلب وجود دارد، دستور vpasolve است. طرز استفاده و نوشتار دستور vpasolve کاملا مشابه با solve است. معادله بایستی به صورت نمادین (symbolic) در متلب تعریف شده باشد. vpasolve(eqn,var) معادله eqn را برحسب متغیر var به صورت عددی حل میکند.
برای اولین مثال از حل معادله با vpasolve در متلب، یک چند جملهای درنظر میگیریم.
syms x
vpasolve(2*x^4 - 5*x^3 + 3*x^2 - x + 98 == 0, x)
پس از اجرا داریم:
ans =
- 1.2997207538112349855025278574397 + 1.8324210875394525528525398452798i
- 1.2997207538112349855025278574397 - 1.8324210875394525528525398452798i
2.5497207538112349855025278574397 + 1.7909726179492826718588472233013i
2.5497207538112349855025278574397 - 1.7909726179492826718588472233013i
دقت کنید که پاسخ معادله با دستور solve و vpasolve به صورت متغیر نمادین (symbolic) است. به همین دلیل تا چندین رقم پس از اعشار نمایش داده شده.
اما حل معادله چند جملهای هدف ما نیست. میخواهیم یک معادله جبری پیچیده را با vpasolve حل کنیم. برای این کار معادله 100sin(x)=x3-5 را درنظر میگیریم.
syms x
eqn = 100*sin(x) == x^3 - 5;
vpasolve(eqn, x)
پس از اجرا داریم:
ans =
-0.050022110032308573131994710969971
اما اگر به معادله دقت کنید، از مرتبه 3 است. پس حداقل 3 پاسخ داریم. اما دستور vpasolve معادله را به صورت عددی حل کرده و اولین پاسخی که بیابد را به ما میدهد. برای این که بتوانیم پاسخهای دیگر را محاسبه کنیم، باید محدوده آن پاسخ را بدانیم. vpasolve(eqn,var,init_guess) معادله eqn را برحسب متغیر var در محدوده init_guess حل میکند. در واقع، در اطراف مقدار حدس، بدنبال حل میگردد. مقدار حدس را میتوانیم شانسی قرار دهیم. اما بهتر است ابتدا نمودار معادله را رسم کنیم تا محل پاسخ را ببینیم. برای رسم از رسم آسان نمودار در متلب استفاده میکنیم. نحوه رسم سریع و آسان نمودار در جلسه آموزش رسم نمودار در متلب ارائه شدهاست.
syms x
eqnLeft = 100*sin(x);
eqnRight = x^3 - 5;
fplot([eqnLeft eqnRight],'linewidth',1.5)
grid on
title('100*sin(x) = x^3 - 5')
براساس نمودار مشاهده میشود که این دو خط در سه نقطه باهم برخورد کردهاند. پس این معادله دارای 3 پاسخ است. از طرفی، دیدیم که دستور vpasolve پاسخ نزدیک به صفر (-0.05) را محاسبه کرد. برای محاسبه سایر پاسخها با دستور vpasolve، کافیست محدوده آنها را در این دستور وارد کنیم. مثلا طبق شکل بالا، واضح است که در نزدیکی 3 یک پاسخ داریم. همین نقطه را امتحان میکنیم.
syms x
eqn = 100*sin(x) == x^3 - 5;
vpasolve(eqn, x, 3)
پس از اجرا داریم:
ans =
2.9368575134743980596766530293978
بنابراین برای یافتن سایر ریشههای یک معادله با vpasolve، میتوان از حدس اولیه استفاده کرد.
تعیین بازه حل در دستور vpasolve
یکی دیگر از ویژگیهای دستور vpasolve، تعیین محدوده برای پاسخ است. مثلا پیدا کردن پاسخهای مثبت یک معادله، یا پاسخهای مختلط آن. شرط محدودهی پاسخ در انتهای دستور vpasolve قرار داده میشود. مثلا معادله x6+4x3-1=0 دارای 6 پاسخ است. یک پاسخ منفی، یک پاسخ مثبت و 4 پاسخ مختلط. اگر این معادله را بدون بازه حل یا حدس اولیه در متلب بنویسیم، همهی 6 پاسخ ارائه میشود. اما مثلا برای پیدا کردن جواب منفی این معادله به صورت زیر عمل میکنیم.
syms x
eqn = x^6 + 4*x^3 - 1;
vpasolve(eqn, x,[-inf 0])
در واقع بازه حل از منفی بینهایت تا صفر تعیین شده. پس از اجرا داریم:
ans =
-1.6180339887498948482045868343656
به این نکته دقت کنید که فرض assume روی حل عددی کاربرد ندارد. برای یافتن پاسخ مثبت این معادله نیز به صورت زیر عمل میکنیم.
syms x
eqn = x^6 + 4*x^3 - 1;
vpasolve(eqn, x,[0 inf])
در واقع بازه حل از صفر تا بینهایت تعیین شدهاست. پس از اجرا داریم:
ans =
0.61803398874989484820458683436564
حل معادله جبری غیرخطی با دستور fzero در متلب
برای حل معادله با دستور fzero در متلب، نیاز به ایجاد تابع داریم. این تابع میتواند یا به صورت تابع ساده باشد و یا به صورت فانکشن هندل (Function Handle) که نوعی تابع ناشناس است. برای یادگیری تعریف تابع، جزئیات و انواع آن بر روی تعریف تابع در متلب 👉 کلیک کنید. fzero(fun,x0) معادله fun را با حدس اولیه x0 حل میکند. وارد کردن حدس اولیه در دستور fzero اجباری است. اولین مثال از حل معادله با fzero معادله x4+3x-5=0 است. ابتدا یک تابع به صورت زیر تعریف کرده و سپس با نام fun ذخیره میکنیم.
function y = fun(x)
y = x^4 + 3*x - 5;
پس از اینکه این تابع را در دایرکتوری حاضر ذخیره کردیم، در پنجره فرمان فراخوانی میکنیم. فراخوانی توابع درون دستور fzero با @ انجام میشود. برای حل این معادله با حدس اولیه 2، داریم:
fzero(@fun, 2)
ans =
1.1277
همانطور که مشاهده میکنید، fzero یک ریشه این معادله را در نزدیکی 2 محاسبه کرد. اگر حدس اولیه از مقدار پاسخ نهایی دور باشد، fzero خطا میدهد.
اما روش دیگر استفاده از fzero برای حل معادله، استفاده از فانکشن هندل است. این روش نسبت به تعریف تابع معمولی، سریعتر و راحتتر است. مثلا برای حل معادله قبل به صورت زیر عمل میکنیم. هر دو نوشتار زیر معادل هستند.
fzero(@(x) x^4 + 3*x - 5, 2)
ans =
1.1277
f = @(x) x^4 + 3*x - 5;
fzero(f, 2)
ans =
1.1277
این نوشتار، به صورت تابع ناشناس یا فانکشن هندل است. واضح است که استفاده از این روش نسبت به نوشتن تابع و ذخیره و فراخوانی آن، راحتتر است.
در حل معادله با fzero، این امکان وجود دارد که یک بازه برای حل وارد کنیم. این بازه حتما باید دارای پاسخ باشد. به عبارت دیگر باید علامت تابع در ابتدا و انتهای بازه متفاوت باشد. یعنی اگر a ابتدای بازه و b انتهای آن است، f(a) و f(b) دارای علامت مخالف باشند. بازه حل بجای حدس اولیه وارد میشود. اگر x_interval بازه باشد، fzero(fun,x_interval) پاسخ fun را در این بازه بدست میآورد. اگر بازه وارد شده شرط وجود پاسخ را نداشته باشد (یا مقدار تابع مخالف العلامه نباشد) متلب خطا میدهد.
تنظیمات دستور fzero با استفاده از تابع optimset
دستور fzero قابلیتهای جذاب دیگری نیز دارد که در این بخش به یکی از آنها میپردازیم. این ویژگی، قابلیت نمایش مراحل حل معادله است. برای اینکه روند حل معادله در متلب با دستور fzero بررسی شود، از optimset استفاده میکنیم. اگر optimset(‘Display’,’iter’) را در دستور fzero وارد کنیم، مراحل حل ارائه میشود. در حقیقت، fzero به صورت عددی پاسخ معادلات را محاسبه میکند. با فعال کردن نمایش مراحل حل، تمام روند حل معادله ارائه میشود. برای درک بهتر به مثال زیر دقت کنید.
میخواهیم معادله x4+3x-5=0 را حل کنیم و مراحل حل را نیز ببینیم. برای این کار عبارت optimset(‘Display’,’iter’) را به fzero اضافه میکنیم.
fzero(@(x) x^4 + 3*x - 5, 2,optimset('Display','iter'))
پس از اجرا داریم:
Search for an interval around 2 containing a sign change:
Func-count a f(a) b f(b) Procedure
1 2 17 2 17 initial interval
3 1.94343 15.0955 2.05657 19.0582 search
5 1.92 14.3495 2.08 19.9577 search
7 1.88686 13.336 2.11314 21.2787 search
9 1.84 11.9823 2.16 23.2478 search
11 1.77373 10.2191 2.22627 26.2437 search
13 1.68 8.00594 2.32 30.9302 search
15 1.54745 5.3765 2.45255 38.5378 search
17 1.36 2.50102 2.64 51.4953 search
18 1.0949 -0.278137 2.64 51.4953 search
Search for a zero in the interval [1.0949, 2.64]:
Func-count x f(x) Procedure
18 1.0949 -0.278137 initial
19 1.1032 -0.209156 interpolation
20 1.12827 0.0053238 interpolation
21 1.12765 -0.000114413 interpolation
22 1.12766 -6.08552e-08 interpolation
23 1.12766 0 interpolation
Zero found in the interval [1.0949, 2.64]
ans =
1.1277
در خروجی متلب اطلاعات مفیدی ارائه شدهاست. متلب یک مقدار a و یک مقدار b را با توجه به حدس اولیه درنظر گرفته. سپس f(a) و f(b) را محاسبه میکند. اگر f(a) با f(b) هم علامت نباشد، آنگاه در این بازه پاسخ داریم. با تغییر مقادیر a و b متلب پس از چند مرحله تکرار، این شرایط را پیدا کردهاست. متلب با تکرار، بازه [1.0949 2.64] را محاسبه نموده است. بنابراین به دنبال پاسخ در این بازه میگردد. سپس با مقداردهی به x و محاسبه f(x)، مقداری که به ازای آن f(x) صفر شده را محاسبه میکند.
حل معادله با استفاده از رسم نمودار
یکی دیگر از راههای حل معادله جبری، رسم نمودار است. در این روش، تابع معادله را رسم کرده و محل تلاقی آن با محور صفر (y=0) را پیدا میکنیم. پس از اینکه محدوده تلاقی پیدا شد، دو روش داریم. روش اول پیدا کردن نقطه دقیق با استفاده از نمودار و روش دوم حل عددی با vpasolve. شاید این سوال پیش بیاید که چرا از ابتدا با vpasolve معادله را حل نکنیم. باید گفت که در برخی مسائل به دنبال یک ریشه خاص (در محدوده خاص) از یک معادله هستیم. بنابراین بهترین روش، رسم معادله و سپس یافتن پاسخ است. مثلا معادله (x3 + 10)sin(2x) را درنظر بگیرید. پاسخ صفر، پاسخ بدیهی این معادله است. اگر این معادله را با vpasolve حل کنیم، پاسخ صفر را میدهد.
syms x
eq = (x^3+10)*sin(2*x);
vpasolve(eq,x)
ans =
0
بنابراین ابتدا آن را در بازه منفی 5 تا 5 رسم میکنیم. توجه کنید که یک خط در y=0 نیز روی این نمودار رسم میشود.
x = -5:0.1:5;
y1 = (x.^3+10).*sin(2*x);
plot(x,y1,'linewidth',1.5)
hold on
plot(x,zeros(1,length(x)),'linewidth',1.5)
grid on
حال باتوجه به شکل بالا، میتوانیم محدوده موردنظر برای یافتن پاسخ را حدس بزنیم. مثلا واضح است که در نزدیکی 3، یک پاسخ داریم. چرا که خط آبی و قرمز باهم برخورد کردهاند.
syms x
eq = (x^3+10)*sin(2*x);
vpasolve(eq,x,3)
پس از اجرا داریم:
ans =
3.1415926535897932384626433832795
همچنین در نزدیکی منفی 5 یک تلاقی دیگر مشاهده میشود. این پاسخ را نیز به صورت زیر محاسبه میکنیم.
syms x
eq = (x^3+10)*sin(2*x);
vpasolve(eq,x,-5)
ans =
-4.7123889803846898576939650749193
به این ترتیب، رسم نمودار میتواند کمک بزرگی به حل معادله در متلب بکند. آموزش کامل رسم نمودار در متلب، در جلسه بیست و یکم ارائه شده. از منوی سمت راست، دسترسی به جلسه رسم نمودار و سایر جلسات فراهم است.
تمرینات این جلسه
در انتهای این جلسه 3 تمرین متلب مربوط به مباحث این جلسه ارائه شده است. لطفا این تمرینها را حل کرده و با پاسخ آن مقایسه کنید. پاسخ تمرینات متلب این جلسه در کانال تلگرام متلب پلاس منتشر میشود. از آیکونهای سمت راست صفحه میتوانید در این کانال عضو شوید.
تمرین اول) معادله جبری پارامتری ax2+bx+c=0 را با دستور solve حل کنید.
تمرین دوم) معادله غیرخطی 1+x2=tan(x) را با دستور vpasolve حل کرده و 2 ریشه مختلف را در بازه منفی 2 تا 2 بیابید. در صورت نیاز، از رسم نمودار برای یافتن محدوده پاسخ استفاده کنید.
تمرین سوم) معادله x2-sin(x)/x را با دستور fzero متلب حل کنید.
جمعبندی
جلسه بیست و نهم از سری جلسات آموزش متلب به پایان رسید. این جلسه به طور کامل درباره حل معادله در متلب صحبت کردیم. حل معادله جبری خطی، غیرخطی و معادلات پیچیده اهمیت زیادی در محاسبات مهندسی دارد. روش حل معادله با دستور solve، vpasolve، fzero و رسم نمودار ارائه شد. در انتها چند تمرین برای یادگیری بیشتر به شما واگذار کردیم که پاسخ آنها در کانال تلگرامی متلب پلاس وجود دارد. بی صبرانه منتظر نظرات، سوال و ابهامات شما عزیزان هستیم. سعی میکنیم تا هرگونه سوال یا ابهامی که در این باره دارید را پاسخ دهیم.
توصیه میشود که حتما تمرینات این جلسه را انجام بدید و اگر سوال و ابهامی دارید در بخش نظرات (پایین همین صفحه) به ما بگید. از فهرست سمت راست هم میتونید به بقیه جلسات دسترسی داشته باشید.
دیدگاهتان را بنویسید