روش وتری — به زبان ساده (+ دانلود فیلم آموزش گام به گام)

۲۸۸۳ بازدید
آخرین به‌روزرسانی: ۱۷ اردیبهشت ۱۴۰۲
زمان مطالعه: ۳۶ دقیقه
روش وتری — به زبان ساده (+ دانلود فیلم آموزش گام به گام)

روش وتری (Secant Method) بسیار شبیه به روش دو بخشی است، با این تفاوت که به جای تقسیم هر بازه با انتخاب نقطه میانی، هر بازه با وتر متصل کننده نقطه ابتدا و انتهای بازه تقسیم می‌شود. روش وتری همیشه به ریشه $$ f ( x) = 0 $$ همگرا می‌شود که $$ f (x) $$ در بازه $$ [a,b] $$ پیوسته بوده و $$ f(a)f(b)<0 $$.

محتوای این مطلب جهت یادگیری بهتر و سریع‌تر آن، در انتهای متن به صورت ویدیویی نیز ارائه شده است.

فرمول خط وتر

فرض کنید $$ f (x) $$ یک تابع پیوسته در بازه بسته $$ [a,b] $$ باشد، به گونه‌ای که $$ f(a)f(b) < 0 $$. یک جواب معادله $$ f ( x) = 0 $$ برای $$ x \in [a,b] $$ با قضیه مقدار میانی تضمین می‌شود. مشخصات ابتدا و انتهای بازه، یعنی $$ (a,f(a)) $$ و $$ (b,f(b)) $$ خط زیر را تشکیل می‌دهند:

$$ \large y = \frac { f ( b ) - f ( a ) } { b - a } ( x - a ) + f ( a ) $$

نقطه‌ای که خط وتر محور $$ x$$ را قطع می‌کند، در رابطه زیر صدق می‌کند:

$$ \large 0 = \frac { f ( b ) - f ( a ) } { b - a } ( x - a ) + f ( a ) $$

با حل این معادله، $$ x$$ به دست می‌آید:

$$ \large x = a - f ( a ) \frac { b - a } { f ( b ) - f ( a ) } $$

الگوریتم روش وتری

مراحل روش وتری اغلب شبیه روش دو بخشی است. تنها تفاوت در تقسیم هر زیربازه است.

  1. بازه شروع $$ [a_0,b_0] $$ را در نظر بگیرید، به گونه‌ای که $$ f(a_0)f(b_0) < 0 $$.
  2. مقدار $$ f(x_0) $$ را محاسبه کنید که $$ x _ 0$$ با خط وتر $$  x _ 0 = a _ 0 - f ( a _ 0 ) \frac { b _ 0 - a _ 0 } { f ( b _ 0 ) - f ( a _ 0 ) } $$ داده می‌شود.
  3. زیربازه بعدیِ $$ [a_1,b_1]$$ را تعیین کنید:
    1. اگر $$ f(a_0)f(x_0) < 0 $$، آنگاه $$ [a_1,b_1] $$ به عنوان بازه بعدی در نظر گرفته می‌شود که در آن، $$ a_1=a_0 $$ و $$ b_1=x_0 $$.
    2. اگر $$ f(b_0)f(x_0) < 0 $$، آنگاه $$ [a_1,b_1] $$ به عنوان بازه بعدی در نظر گرفته می‌شود که در آن، $$ a_1=x_0 $$ و $$ b_1=b_0 $$.
  4. مراحل ۲ و ۳ را تا زمانی که طول بازه $$ [a_N,b_N] $$ به یک مقدار از پیش تعیین شده برسد، تکرار کنید.
  5. مقدار $$ x _ N $$ را در $$N$$اُمین تکرار $$x$$ است محاسبه کنید.

طبق قضیه مقدار میانی، یک جواب برای معادله $$ f(x)=0 $$ در بازه $$ [a,b] $$ تضمین شده است که $$ f ( x)$$ در بازه $$ [a,b] $$ پیوسته بوده و $$ f(a)f(b) < 0 $$. به عبارت دیگر، علامت تابع در بازه مذکور تغییر کرده و در نتیجه، باید در نقطه (یا نقاطی) درون بازه برابر با صفر شود.

پیاده‌سازی در پایتون

تابعی می‌نویسیم و نام آن را "secant" قرار می‌دهیم. این تابع چهار ورودی "b" ،"a" ،"f" و "N" دارد و خروجی آن، حل معادله $$ f ( x ) =0 $$ با $$N$$ بار تکرار روش وتری است. اگر در هر نقطه از تکرار داشته باشیم: $$ f(a_n)f(b_n) \geq 0 $$ (به دلیل بازه اولیه نامناسب یا گرد کردن خطا در محاسبات)، آنگاه در خروجی برنامه، عبارت "Secant method fails." چاپ می‌شود و خروجی "None" خواهد بود.

1def secant(f,a,b,N):
2    '''Approximate solution of f(x)=0 on interval [a,b] by the secant method.
3
4    Parameters
5    ----------
6    f : function
7        The function for which we are trying to approximate a solution f(x)=0.
8    a,b : numbers
9        The interval in which to search for a solution. The function returns
10        None if f(a)*f(b) >= 0 since a solution is not guaranteed.
11    N : (positive) integer
12        The number of iterations to implement.
13
14    Returns
15    -------
16    m_N : number
17        The x intercept of the secant line on the the Nth interval
18            m_n = a_n - f(a_n)*(b_n - a_n)/(f(b_n) - f(a_n))
19        The initial interval [a_0,b_0] is given by [a,b]. If f(m_n) == 0
20        for some intercept m_n then the function returns this solution.
21        If all signs of values f(a_n), f(b_n) and f(m_n) are the same at any
22        iterations, the secant method fails and return None.
23
24    Examples
25    --------
26    >>> f = lambda x: x**2 - x - 1
27    >>> secant(f,1,2,5)
28    1.6180257510729614
29    '''
30    if f(a)*f(b) >= 0:
31        print("Secant method fails.")
32        return None
33    a_n = a
34    b_n = b
35    for n in range(1,N+1):
36        m_n = a_n - f(a_n)*(b_n - a_n)/(f(b_n) - f(a_n))
37        f_m_n = f(m_n)
38        if f(a_n)*f_m_n < 0:
39            a_n = a_n
40            b_n = m_n
41        elif f(b_n)*f_m_n < 0:
42            a_n = m_n
43            b_n = b_n
44        elif f_m_n == 0:
45            print("Found exact solution.")
46            return m_n
47        else:
48            print("Secant method fails.")
49            return None
50    return a_n - f(a_n)*(b_n - a_n)/(f(b_n) - f(a_n))

به عنوان مثال، تابع مورد نظر را با مقادیری که خروجی صحیح آن‌ها را می‌دانیم، بررسی می‌کنیم. می‌خواهیم نسبت فوق طلایی را تقریب بزنیم که تنها ریشه حقیقی چندجمله‌ای $$ p(x) = x^3 - x^2 - 1 $$ است.

1p = lambda x: x**3 - x**2 - 1
2print(p(1))
3print(p(2))
-1
3

از آنجایی که علامت چندجمله‌ای در بازه $$ [1,2] $$ تغییر می‌کند، می‌توانیم از روش وتری با شروع از بازه زیر استفاده کنیم:

1approx = secant(p,1,2,20)
2print(approx)
1.4655712311394433

مقدار دقیق نسبت فوق طلایی به صورت زیر است:

فرمول فوق طلایی

1supergolden = (1 + ((29 + 3*93**0.5)/2)**(1/3) + ((29 - 3*93**0.5)/2)**(1/3))/3
2print(supergolden)
1.4655712318767682

تقریب به دست آمده را با جواب دقیق آن مقایسه می‌کنیم:

1error = abs(supergolden - approx)
2print(error)
7.373248678277378e-10

پیاده‌سازی در متلب

روش وتری را می‌توان به سادگی در متلب نیز پیاده‌سازی کرد. برای مثال، کد متلب روش وتری برای یافتن ریشه همان چندجمله‌ای $$ p(x) = x^3 - x^2 - 1 $$ در متلب به صورت زیر است:

1clc;
2clear;
3close all;
4format long
5%% example 1
6% f = @(x) x^3-x^2-1;
7% xl = 1 ;
8% xu = 2 ;
9
10%%% example 2
11f = @(x) 3*exp(-2*x)+cos(x)-2;
12xl = 0 ;
13xu = 1 ;
14
15
16N = 20 ;
17for i = 1:N
18    xr = (xl*f(xu)-xu*f(xl))/(f(xu)-f(xl));
19    if f(xl)*f(xr) < 0
20        xu = xr ;
21    end
22    if f(xu)*f(xr) < 0
23        xl = xr ;
24    end
25    STR = ['n = ', num2str(i), ', x = ' ,num2str(xr), ', f(xr) = ' ,num2str(f(xr))];
26    disp(STR)
27end

خروجی حاصل از اجرای کد بالا به صورت زیر خواهد بود:

n = 1, x = 1.25, f(xr) = -0.60938
n = 2, x = 1.3766, f(xr) = -0.28626
n = 3, x = 1.4309, f(xr) = -0.11766
n = 4, x = 1.4524, f(xr) = -0.045671
n = 5, x = 1.4606, f(xr) = -0.017331
n = 6, x = 1.4637, f(xr) = -0.0065203
n = 7, x = 1.4649, f(xr) = -0.0024451
n = 8, x = 1.4653, f(xr) = -0.00091577
n = 9, x = 1.4655, f(xr) = -0.00034283
n = 10, x = 1.4655, f(xr) = -0.00012832
n = 11, x = 1.4656, f(xr) = -4.8029e-05
n = 12, x = 1.4656, f(xr) = -1.7976e-05
n = 13, x = 1.4656, f(xr) = -6.7276e-06
n = 14, x = 1.4656, f(xr) = -2.5179e-06
n = 15, x = 1.4656, f(xr) = -9.4236e-07
n = 16, x = 1.4656, f(xr) = -3.5269e-07
n = 17, x = 1.4656, f(xr) = -1.32e-07
n = 18, x = 1.4656, f(xr) = -4.9403e-08
n = 19, x = 1.4656, f(xr) = -1.849e-08
n = 20, x = 1.4656, f(xr) = -6.92e-09

اگر این مطلب برایتان مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

فیلم‌ های آموزش روش وتری — به زبان ساده (+ دانلود فیلم آموزش گام به گام)

فیلم آموزشی روش وتری

دانلود ویدیو

فیلم آموزشی حل مثال از روش وتری در متلب

دانلود ویدیو
بر اساس رای ۰ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
Mathematical Python
۱ دیدگاه برای «روش وتری — به زبان ساده (+ دانلود فیلم آموزش گام به گام)»

با سلام و احترام
در حالت کلی در روش سکانت، بازه اولیه لزوما شامل ریشه نیست. به همین دلیل در برخی مواقع این روش واگرا می شود که از ایرادات این روش است. بهتر است در ابتدای مطلب عنوان کنید که شما حالت خاصی از این روش را توضیح داده اید تا خواننده دید بهتری به مسئله داشته باشد.
با تشکر

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *