کلیدستان

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

کد:
delr=(-b(n)*c(n-1)+b(n+1)*c(n-2))/denom;
dels=(-b(n+1)*c(n-1)+b(n)*c(n))/denom;
e=abs((delr)+(dels));
r=r+delr;
s=s+dels;


الان این برنامه من فقط میتونه اعداد حقیقی رو به جواب برسونه منتها برای اعداد مختلط مشکل داره .. میشه یه راهنمایی کنید ممنون میشم .... 
سلام.
برخی پارامترها داده نشده. لطفا نحوه محاسبه آنها را هم بنویسید تا بتونیم کدها رو بررسی کنیم.
یک جوری کدها رو بدید که بشه در متلب اجرا کرد و خطا را مشاهده نمود.
(۱۳۹۲/۰۲/۲۶, ۱۲:۱۳ ق.ظ)'admin' نوشته: [ -> ]سلام.
برخی پارامترها داده نشده. لطفا نحوه محاسبه آنها را هم بنویسید تا بتونیم کدها رو بررسی کنیم.
یک جوری کدها رو بدید که بشه در متلب اجرا کرد و خطا را مشاهده نمود.  


باید کل کد رو بنویسم پس ..... خطا نمیده بلکه در جواب ریشه ها وقتیکه دلتا منفی میشه ریشه ها رو بصورت Nan و بعضی وقتا به شکل Inf میده ، اما زمانیکه دلتا مثبت هستش مشکلی نیست... 

استادم بهم گفت که باید برای دلتاهای منفی هم تعریف کنی که به شکل ریشه مختلط بهت جواب بده ...لطفا فایل پیوست رو ببینید . Smile

[attachment=105]
برنامه، تعدادی ورودی از کاربر میگیره، لطفا بگید دقیقا چه مقادیری رو در برنامه وارد کردید که چنین نتایجی داد. (حتما همه رو ذکر کنید)
پس از دانستن مقادیر، میشه مرحله به مرحله، برنامه رو چک کرد.
 
(۱۳۹۲/۰۲/۲۶, ۱۰:۴۳ ب.ظ)'admin' نوشته: [ -> ]برنامه، تعدادی ورودی از کاربر میگیره، لطفا بگید دقیقا چه مقادیری رو در برنامه وارد کردید که چنین نتایجی داد. (حتما همه رو ذکر کنید)
پس از دانستن مقادیر، میشه مرحله به مرحله، برنامه رو چک کرد.ا 



 


به طور کلی فرقی نمیکنه اما هروقت که دلتا منفی بشه اینطور میشه 
ولی به طور مثال برای اعداد زیر :


کد:
Polynominal Equation: a1.X^(n)+ a2.X^(n-1)+ ….+an.X^(0)
Quadratic factor: x^2-rx-s
Polynominal degree, n=5
a1=1
a2=2
a3=3.25
a4=0.01
a5=-0.36
a6=1
 Please insert value of r=-1
 Please insert value of s=-1
Tolerance for error=0.002


برنامه جواب زیر را میدهد :

کد:
Quadratic factor at 1 =x^2-NaNx-NaN
The result is
x1=NaN
x2=NaN
Quadratic factor at 2 =x^2-NaNx-NaN
The result is
x3=NaN
x4=NaN
x5=NaN
Actual tolerance for error= NaN
Iteration number= 9
قسمتی از کدها رو اشتباه نوشتید، من برنامه خودتون رو با مرتب کردن و تصحیح فواصل مربوط به حلقه ها در اینجا میارم (حالا میگم اشتباه در کجاست) :



کد:
disp('Polynominal Equation: a1.X^(n)+ a2.X^(n-1)+ ….+an.X^(0)');
disp('Quadratic factor: x^2-rx-s');
n=input('Polynominal degree, n=');
for i=1:n+1
    a(i)=input(['a',num2str(i),'=']);
end
r=input(' Please insert value of r=');
s=input(' Please insert value of s=');
tol=input('Tolerance for error=');
k=1;
z=1;
ite=0;
while n>=3;
    e=1;
    while e>tol;
        ite=ite+1;
        for i=1:n+1;
            if i==1;
                b(i)=a(i);
                c(i)=b(i);
            else if i==2;
                b(i)=a(i)+r*b(i-1);
                c(i)=b(i)-r*c(i-1);
            else
                b(i)=a(i)+r*b(i-1)+s*b(i-2);
                c(i)=a(i)-r*c(i-1)-s*c(i-2);
            end
        end
    end
    denom=c(n-1)^2-c(n)*c(n-2);
    if denom==0;
        r=r+1;
        s=s-1;
        E=1;
    else
        delr=(-b(n)*c(n-1)+b(n+1)*c(n-2))/denom;
        dels=(-b(n+1)*c(n-1)+b(n)*c(n))/denom;
        e=abs((delr)+(dels));
        r=r+delr;
        s=s+dels;
    end
end
disp(['Quadratic factor at ',num2str(z),' =x^2-',num2str(r),'x-',num2str(s)]);
x1=(r+(r^2+4*s)^(1/2))/2;
x2=(r-(r^2+4*s)^(1/2))/2;
disp('The result is');
disp(['x',num2str(k),'=',num2str(x1)]);
disp(['x',num2str(k+1),'=',num2str(x2)]);
z=z+1;
k=k+2;
n=n-2;
v=[1 -r -s];
m=deconv(a,v);
a=m;
end
if mod(n,2)==1;
    x3=-a(2)/a(1);
    disp(['x',num2str(k),'=',num2str(x3)]);
else
    x4=(-a(2)+(a(2)^2-4*a(3))^(1/2))/2;
    x5=(-a(2)-(a(2)^2-4*a(3))^(1/2))/2;
    disp(['x',num2str(k),'=',num2str(x4)]);
    disp(['x',num2str(k+1),'=',num2str(x5)]);
end
disp(['Actual tolerance for error= ', num2str(e)]);
disp(['Iteration number= ', num2str(ite)]);


اگر به حلقه while n>=3 دقت کنید، متوجه می شوید که دو end برای آن نوشته اید (دو end در پایان حلقه). بنابراین شما باید دوباره کل فرمول ها و روند برنامه نویسی رو چک کنید.

در ضمن، میشه مقادیری که گفتید رو به صورت دستی در برنامه نوشت که مرتب مجبور به وارد کردن آنها نباشید، من این کار رو کردم و همچنین مقداری کدها رو تغییر دادم تا متوجه بشید در حلقه while چه اتفاقی میفته (این کد تصحیح شده نیست و تنها مقادیر را به صورت دستی در برنامه نوشته ایم) :


کد:
clear all
close all
clc

disp('Polynominal Equation: a1.X^(n)+ a2.X^(n-1)+ ….+an.X^(0)');
disp('Quadratic factor: x^2-rx-s');
n=5; % input('Polynominal degree, n=');
a=[1 2 3.25 0.01 -0.36 1];
r=-1; % input(' Please insert value of r=');
s=-1; % input(' Please insert value of s=');
tol=0.002; % input('Tolerance for error=');
k=1;
z=1;
ite=0;
disp('-------------------------')
while n>=3;    
    disp('in while loop')
    e=1;
    while e>tol;
        ite=ite+1;
        for i=1:n+1;
            if i==1;
                b(i)=a(i);
                c(i)=b(i);
            else if i==2;
                b(i)=a(i)+r*b(i-1);
                c(i)=b(i)-r*c(i-1);
            else
                b(i)=a(i)+r*b(i-1)+s*b(i-2);
                c(i)=a(i)-r*c(i-1)-s*c(i-2);
            end
        end
    end
    disp('-------------------------')
    denom=c(n-1)^2-c(n)*c(n-2)
    if denom==0;
        r=r+1;
        s=s-1;
        E=1;
    else
        
        delr=(-b(n)*c(n-1)+b(n+1)*c(n-2))/denom
        dels=(-b(n+1)*c(n-1)+b(n)*c(n))/denom
        e=abs((delr)+(dels));
        r=r+delr;
        s=s+dels;
    end
end
r
s
disp('-------------------------')
disp(['Quadratic factor at ',num2str(z),' =x^2-',num2str(r),'x-',num2str(s)]);
x1=(r+(r^2+4*s)^(1/2))/2;
x2=(r-(r^2+4*s)^(1/2))/2;
disp('The result is');
disp(['x',num2str(k),'=',num2str(x1)]);
disp(['x',num2str(k+1),'=',num2str(x2)]);
z=z+1;
k=k+2;
n=n-2;
v=[1 -r -s];
m=deconv(a,v);
a=m;
end
if mod(n,2)==1;
    x3=-a(2)/a(1);
    disp(['x',num2str(k),'=',num2str(x3)]);
else
    x4=(-a(2)+(a(2)^2-4*a(3))^(1/2))/2;
    x5=(-a(2)-(a(2)^2-4*a(3))^(1/2))/2;
    disp(['x',num2str(k),'=',num2str(x4)]);
    disp(['x',num2str(k+1),'=',num2str(x5)]);
end
disp(['Actual tolerance for error= ', num2str(e)]);
disp(['Iteration number= ', num2str(ite)]);
(۱۳۹۲/۰۲/۲۷, ۱۲:۴۵ ق.ظ)'admin' نوشته: [ -> ]قسمتی از کدها رو اشتباه نوشتید، من برنامه خودتون رو با مرتب کردن و تصحیح فواصل مربوط به حلقه ها در اینجا میارم (حالا میگم اشتباه در کجاست) :





کد:
disp('Polynominal Equation: a1.X^(n)+ a2.X^(n-1)+ ….+an.X^(0)');
disp('Quadratic factor: x^2-rx-s');
n=input('Polynominal degree, n=');
for i=1:n+1
    a(i)=input(['a',num2str(i),'=']);
end
r=input(' Please insert value of r=');
s=input(' Please insert value of s=');
tol=input('Tolerance for error=');
k=1;
z=1;
ite=0;
while n>=3;
    e=1;
    while e>tol;
        ite=ite+1;
        for i=1:n+1;
            if i==1;
                b(i)=a(i);
                c(i)=b(i);
            else if i==2;
                b(i)=a(i)+r*b(i-1);
                c(i)=b(i)-r*c(i-1);
            else
                b(i)=a(i)+r*b(i-1)+s*b(i-2);
                c(i)=a(i)-r*c(i-1)-s*c(i-2);
            end
        end
    end
    denom=c(n-1)^2-c(n)*c(n-2);
    if denom==0;
        r=r+1;
        s=s-1;
        E=1;
    else
        delr=(-b(n)*c(n-1)+b(n+1)*c(n-2))/denom;
        dels=(-b(n+1)*c(n-1)+b(n)*c(n))/denom;
        e=abs((delr)+(dels));
        r=r+delr;
        s=s+dels;
    end
end
disp(['Quadratic factor at ',num2str(z),' =x^2-',num2str(r),'x-',num2str(s)]);
x1=(r+(r^2+4*s)^(1/2))/2;
x2=(r-(r^2+4*s)^(1/2))/2;
disp('The result is');
disp(['x',num2str(k),'=',num2str(x1)]);
disp(['x',num2str(k+1),'=',num2str(x2)]);
z=z+1;
k=k+2;
n=n-2;
v=[1 -r -s];
m=deconv(a,v);
a=m;
end
if mod(n,2)==1;
    x3=-a(2)/a(1);
    disp(['x',num2str(k),'=',num2str(x3)]);
else
    x4=(-a(2)+(a(2)^2-4*a(3))^(1/2))/2;
    x5=(-a(2)-(a(2)^2-4*a(3))^(1/2))/2;
    disp(['x',num2str(k),'=',num2str(x4)]);
    disp(['x',num2str(k+1),'=',num2str(x5)]);
end
disp(['Actual tolerance for error= ', num2str(e)]);
disp(['Iteration number= ', num2str(ite)]);


اگر به حلقه while n>=3 دقت کنید، متوجه می شوید که دو end برای آن نوشته اید (دو end در پایان حلقه). بنابراین شما باید دوباره کل فرمول ها و روند برنامه نویسی رو چک کنید.

در ضمن، میشه مقادیری که گفتید رو به صورت دستی در برنامه نوشت که مرتب مجبور به وارد کردن آنها نباشید، من این کار رو کردم و همچنین مقداری کدها رو تغییر دادم تا متوجه بشید در حلقه while چه اتفاقی میفته (این کد تصحیح شده نیست و تنها مقادیر را به صورت دستی در برنامه نوشته ایم) :




کد:
clear all
close all
clc

disp('Polynominal Equation: a1.X^(n)+ a2.X^(n-1)+ ….+an.X^(0)');
disp('Quadratic factor: x^2-rx-s');
n=5; % input('Polynominal degree, n=');
a=[1 2 3.25 0.01 -0.36 1];
r=-1; % input(' Please insert value of r=');
s=-1; % input(' Please insert value of s=');
tol=0.002; % input('Tolerance for error=');
k=1;
z=1;
ite=0;
disp('-------------------------')
while n>=3;    
    disp('in while loop')
    e=1;
    while e>tol;
        ite=ite+1;
        for i=1:n+1;
            if i==1;
                b(i)=a(i);
                c(i)=b(i);
            else if i==2;
                b(i)=a(i)+r*b(i-1);
                c(i)=b(i)-r*c(i-1);
            else
                b(i)=a(i)+r*b(i-1)+s*b(i-2);
                c(i)=a(i)-r*c(i-1)-s*c(i-2);
            end
        end
    end
    disp('-------------------------')
    denom=c(n-1)^2-c(n)*c(n-2)
    if denom==0;
        r=r+1;
        s=s-1;
        E=1;
    else
        
        delr=(-b(n)*c(n-1)+b(n+1)*c(n-2))/denom
        dels=(-b(n+1)*c(n-1)+b(n)*c(n))/denom
        e=abs((delr)+(dels));
        r=r+delr;
        s=s+dels;
    end
end
r
s
disp('-------------------------')
disp(['Quadratic factor at ',num2str(z),' =x^2-',num2str(r),'x-',num2str(s)]);
x1=(r+(r^2+4*s)^(1/2))/2;
x2=(r-(r^2+4*s)^(1/2))/2;
disp('The result is');
disp(['x',num2str(k),'=',num2str(x1)]);
disp(['x',num2str(k+1),'=',num2str(x2)]);
z=z+1;
k=k+2;
n=n-2;
v=[1 -r -s];
m=deconv(a,v);
a=m;
end
if mod(n,2)==1;
    x3=-a(2)/a(1);
    disp(['x',num2str(k),'=',num2str(x3)]);
else
    x4=(-a(2)+(a(2)^2-4*a(3))^(1/2))/2;
    x5=(-a(2)-(a(2)^2-4*a(3))^(1/2))/2;
    disp(['x',num2str(k),'=',num2str(x4)]);
    disp(['x',num2str(k+1),'=',num2str(x5)]);
end
disp(['Actual tolerance for error= ', num2str(e)]);
disp(['Iteration number= ', num2str(ite)]);

 


متشکرم از لطفت ، هنوز امتحان نکردم ... راستش من خودم مطلب رو یاد گرفتم و متاسفانه این ریزه کاریهارو بلد نیستم. تنها هنرم اینه که از خود ایرادهای مطلب شاید یچی حالیم بشه
دانشجوی ارشد مکانیک هستم و خب تو دوره لیسانس خودم یاد گرفتم البته با کمک یه کتاب بسیار عالی و نایاب. بخاطر همین اینطور اشتباهات برام بوجود میاد و بدبختانه من الگوریتم بلد نیستم . اگه میشه یکم این ریزه کاریها رو هم بهم یاد بدی که چک کردن برنامه رو هم یاد بگیرم ممنونت میشم ..... 
(۱۳۹۲/۰۲/۲۷, ۰۸:۲۳ ب.ظ)'babak84' نوشته: [ -> ]متشکرم از لطفت ، هنوز امتحان نکردم ... راستش من خودم مطلب رو یاد گرفتم و متاسفانه این ریزه کاریهارو بلد نیستم. تنها هنرم اینه که از خود ایرادهای مطلب شاید یچی حالیم بشه
دانشجوی ارشد مکانیک هستم و خب تو دوره لیسانس خودم یاد گرفتم البته با کمک یه کتاب بسیار عالی و نایاب. بخاطر همین اینطور اشتباهات برام بوجود میاد و بدبختانه من الگوریتم بلد نیستم . اگه میشه یکم این ریزه کاریها رو هم بهم یاد بدی که چک کردن برنامه رو هم یاد بگیرم ممنونت میشم ..... 
 

من هم مثل شما با یک کتاب شروع کردم و دو سه فصل اول کتاب رو خوندم و بعد پروژه های استادا بودن که باعث شدن برم دنبال یادگیری دستورات جدید .
برای یادگیری متلب، هیچ چیزی بهتر از انجام پروژه نیست چون حسابی درگیر یادگیری نرم افزار متلب میشید.
فقط مهمترین نکته که من بارها به دوستان گفتم اینه که گاهی میدیدم که دوستی مثلا 30 خط کد مینویسه و بعد تازه کدها رو اجرا میکنه تا ببینه خطا داره یا نه . این روش به شدت غلطه . من هر دو سه خط جدیدی که کد در برنامه می نویسم، برنامه رو اجرا می کنم و مقادیر متغیرها رو هم در خروجی نگاه می کنم که مبادا خطایی پیش بیاد یا مقادیر غلطی در برنامه تولید بشه.
این طوری شما کاملا به برنامه تسلط دارید و نیازی نیست بعدا درگیر قسمت های مختلف برنامه بشید که ببینید مشکل از کدوم قسمته.
بنابراین برنامه را مرحله به مرحله بنویسید و مقادیر متغیرها را هم در خروجی چک کنید.
نکته مهم دیگر اینکه ابتدا متغیرهای برنامه را به صورت دستی در برنامه بنویسید تا مجبور نباشید برای هر بار اجرا، مقادیر رو تایپ کنید، سپس وقتی کل برنامه نوشته شد و همه چیز درست بود، از دستور input استفاده کنید تا برنامه، متغیرها را از کاربر بگیرد.
(۱۳۹۲/۰۲/۲۷, ۰۸:۵۴ ب.ظ)'admin' نوشته: [ -> ]
(۱۳۹۲/۰۲/۲۷, ۰۸:۲۳ ب.ظ)'babak84' نوشته: [ -> ]متشکرم از لطفت ، هنوز امتحان نکردم ... راستش من خودم مطلب رو یاد گرفتم و متاسفانه این ریزه کاریهارو بلد نیستم. تنها هنرم اینه که از خود ایرادهای مطلب شاید یچی حالیم بشه
دانشجوی ارشد مکانیک هستم و خب تو دوره لیسانس خودم یاد گرفتم البته با کمک یه کتاب بسیار عالی و نایاب. بخاطر همین اینطور اشتباهات برام بوجود میاد و بدبختانه من الگوریتم بلد نیستم . اگه میشه یکم این ریزه کاریها رو هم بهم یاد بدی که چک کردن برنامه رو هم یاد بگیرم ممنونت میشم ..... 

 

من هم مثل شما با یک کتاب شروع کردم و دو سه فصل اول کتاب رو خوندم و بعد پروژه های استادا بودن که باعث شدن برم دنبال یادگیری دستورات جدید .
برای یادگیری متلب، هیچ چیزی بهتر از انجام پروژه نیست چون حسابی درگیر یادگیری نرم افزار متلب میشید.
فقط مهمترین نکته که من بارها به دوستان گفتم اینه که گاهی میدیدم که دوستی مثلا 30 خط کد مینویسه و بعد تازه کدها رو اجرا میکنه تا ببینه خطا داره یا نه . این روش به شدت غلطه . من هر دو سه خط جدیدی که کد در برنامه می نویسم، برنامه رو اجرا می کنم و مقادیر متغیرها رو هم در خروجی نگاه می کنم که مبادا خطایی پیش بیاد یا مقادیر غلطی در برنامه تولید بشه.
این طوری شما کاملا به برنامه تسلط دارید و نیازی نیست بعدا درگیر قسمت های مختلف برنامه بشید که ببینید مشکل از کدوم قسمته.
بنابراین برنامه را مرحله به مرحله بنویسید و مقادیر متغیرها را هم در خروجی چک کنید.
نکته مهم دیگر اینکه ابتدا متغیرهای برنامه را به صورت دستی در برنامه بنویسید تا مجبور نباشید برای هر بار اجرا، مقادیر رو تایپ کنید، سپس وقتی کل برنامه نوشته شد و همه چیز درست بود، از دستور input استفاده کنید تا برنامه، متغیرها را از کاربر بگیرد.

 

مرسی از لطفت بابت نکته هایی که گفتی . اما هنوز برنامه ایراد داره . متاسفانه این برنامه برای دلتاهای منفی جوابی نداره ... حتی همین برنامه که به صورت عددی نوشتی هم این مشکل رو داره . من میخوام که برای دلتاهای منفی به شکل اعداد مختلط هم جواب بده . میشه یکم راهنمایی کنی . باتشکر از وقتیکه میذاری 
سلام.
من نگفتم که برنامه رو تصحیح کردم و فقط گفتم که مشکل از کجاست.
کدهای اول که دقیقا کدهای خودتون هست. کدهای دوم هم، همون مقادیری که از ورودی میگرفت رو به صورت دستی بهش دادیم (تا بهتر بتونید برنامه رو تست کنید نه اینکه برنامه تصحیح شده باشه). هر دو کد، برای حلقه while، دو تا end داره (هر دو غلطه).
حالا که مشکل رو متوجه شدید، این شما هستید که باید برنامه رو تصحیح کنید چون فقط شما می دونید چی میخواید بنویسید.