Разложение рациональной дроби на простейшие.
Федеральное агентство по образованию
Государственное общеобразовательное чреждение
высшего профессионального образования
Башкирский Государственный ниверситет
Нефтекамский филиал
Кафедра МиПОВМ
Курсовая работ
Тема: Разложение рациональной дроби на простейшие.
Выполнил студент
группы М-31
Остапов А. Б.
Принял:
Вильданов А. Н.
Нефтекамск 2006
Содержание.
Введение.
Часть 1. Теоретическая часть к курсовой работе.
Часть 2. Практическая часть к курсовой работе.
o з Реализация метода простых коэффициентов в MapleФ.
o з Реализация метода простых коэффициентов на DelphiФ.
Заключение.
Список литературы.
Введение./h1>
Этот вопрос же много раз изучен и рассмотрен. Казалось бы, что может быть проще для современного математика, чем разложить рациональную дробь на простейшие, разве что элементарные алгебраические операции. Однако, применение этого метода существенно облегчает жизнь - не будь метода - некоторые задачи было бы очень проблематично решить, некоторые вообще не решались.
Основные операции, в которых я применял этот метод, были:
) Разложение рациональной дроби на простейшие с целью дальнейшего интегрирования получившихся элементарных дробей (Матем. анализ);
б) Разложение рациональной дроби на простейшие для использования в процессе преобразования Лапласа, что иногда серьезно скоряет нахождение решения различных равнений и систем равнений в частных производных (Курс равнений мат. физики).
Разложение - это необходимость. Без нее нельзя обходиться, тем более на современном этапе развития математической мысли. Об этом и пойдет речь в моей курсовой работе.
Часть 1.
Теоретическая часть к курсовой работе.
Рациональной дробью назовем отношение двух алгебраических многочленов с вещественными коэффициентами:
Практическая часть к курсовой работе.
за Реализация метода простых коэффициентов в MapleФ.
Для определения конкретных значений сих коэффициентов следует привести равенство к общему знаменателю и сравнить коэффициенты при одинаковых степенях x в числителе. Т.е. по сути дела решить систему линейных равнений. Используется эта конструкция по большей части при вычислении интегралов, т.к. таким образом интеграл произвольной рациональной функции сводится, по сути дела, к сумме табличных интегралов. Этакая лекция по мат. анализу получилась.
Сразу скажу тем, кому вообще лень что-то делать по этому поводу. Maple делает все, что мы сейчас напишем, одной операцией:
> сonvert(rfun, parfrac, x);
И все. Спросите: зачем этот велосипед? Цель - не конечный результат, идея и методы ее реализации на Maple. Гораздо интереснее получается посмотреть на целую программу, реально работающий ниверсальный алгоритм, делающий конкретно нечто, чем просто читать обрывки help-ов под каждую команду языка на английском, не понимая в принципе, как это все связать воедино. Ясное дело, профессионалу, прочувствовавшему Maple, будет неинтересно читать подробные объяснения по поводу использованных функций языка, однако для изучающего систему не совсем новичка-математика это будет крайне полезно. Постараюсь в процессе показать читателю свое разумение философии пакета.
Как всегда первый вопрос: с чем работаем? Действительно, для отладки алгоритма необходимо создать хоть несколько рациональных дробей. Руками писать неудобно, поэтому даже этот этап сгрузим на машину.
> restart:
> readlib(randomize):
(а) > randomize():
(б) > d1:= rand(1..3):
> d2:= rand(2..7):
(в) > px:= randpoly(x, degree=21, coeffs=rand(-7..7), terms = 9):
(г) > for i from 1 to 3 do
> q[i]:= randpoly(x, degree=1, coeffs=rand(-7..7))^d1():
> q[i+3]:= (x^2 + x + d2())^d1():
> od:
(д) > rfun:= px/product(q[k], k=1..6);
Разберемся, что тут мы с вами наворотили. Итак, сначала подробно остановимся на генерации случайных целых чисел в системе Maple. (а) Ч здесь мы заставляем генератор случайных чисел привязаться к системному времени. Если этого не сделать, то генерируемая последовательность будет каждый раз одинаковой. Вызов просто функции rand() без аргументов возвратит двенадцатизначное случайное натуральное число. В большинстве случаев это ну совсем неудобно. Можно это дело исправить, передавая функции один аргумент: rand(n), что приведет к генерации числа из полуинтервала [0, n). Зачастую и этого недостаточно для решения поставленной задачи. Можно еще более сузить область значений - (б). Только в этом случае в d1 вернется отнюдь не число, а ссылка на процедуру, вызов которой приведет к генерации случайного числа из заданного отрезка. Произвольный полином максимальной степени 21 степени с коэффициентами из отрезка [-7,7] и девятью членами получим в (в). Дальше интереснее - нужно изготовить знаменатель. Сделаем его в виде произведения трех многочленов первой, и трех - второй степени. Причем по определению многочлены второй степени не должны иметь действительных корней. Реализующая эту задачу конструкция (г) очевидна и в пояснениях не нуждается. И наконец, собрав числитель и знаменатель в одно целое, в (д) получим нашу рациональную дробь. Выражение product(q[k], k=1..6); является формальным переводом на язык Maple записи:
з Реализация метода простых коэффициентов на DelphiФ.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Spin, StdCtrls, Grids, MatUtilits;
type
signs = -1..1;
polinom = array of real;
fpolinoms = array of polinom;
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Edit1: TEdit;
StringGrid2: TStringGrid;
Edit2: TEdit;
SpinEdit1: TSpinEdit;
SpinEdit2: TSpinEdit;
Button1: TButton;
Memo1: TMemo;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Edit4: TEdit;
procedure Button1Click(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
procedure SpinEdit2Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure Polinommul(a:polinom;n:byte;b:polinom;m:byte;var ab:polinom;var nm:byte);
procedure GetPolinom(r:fpolinoms;step:byte;flag:boolean;numdrob:byte;var res:polinom);
procedure Calculate(mass1:polinom;n:integer;var formula:string);
end;
const
n10 =10;
var
Form1: TForm1;
n1,n2,s1,s2:shortint;
roots1,roots2,znamen,matr:fpolinoms;
pol1,pol2,chislit:polinom;
matr1,koef:matdouble;
mass1:array of real;
elem:array[0..n10] of string[10];
equation,eq1,eq2,eq3:string;
implementation
{$R *.dfm}
Процедура перемножения объектов типа polinom, т. е. массивов с коэффициентами многочленов и получения результата их перемножения:
procedure TForm1.Polinommul(a:polinom;n:byte;b:polinom;m:byte;var ab:polinom;var nm:byte);
var
temp:real;
i,j,t:shortint;
p1:polinom;
begin
setlength(p1,m+n+1);
setlength(ab,m+n+1);
temp:=0;
for i:=0 to m+n doа p1[i]:=0;
for i:=0 to n do
for j:=0 to m do
begin
temp:=a[i]*b[j];
p1[i+j]:=p1[i+j]+temp;
end;
nm:=n+m;
ab:=p1;
{ t:=0;
for i:=0 to m+n do
if p1[i]=0 then
begin
t:=i+1;
continue;
end
else break;
setlength(ab,m+n-t);
for i:= 0 to m+n-t+1 do
ab[i]:=p1[i+t];
nm:=m+n-t+1;а }
end;
Процедура, которая из массива многочленов делает многочлен - или результат их перемножения - или произведение, но без i-го члена, в зависимости от flag.
procedure TForm1.GetPolinom(r:fpolinoms;step:byte;flag:boolean;numdrob:byte;var res:polinom);
var
buffer,buffer1,temp:polinom;
i,j,p,p1:byte;
flag1:boolean;
begin
if not(flag) then
begin
setlength(buffer,2);
setlength(buffer1,2);
setlength(temp,2);
buffer[0]:=r[0,0];
buffer[1]:=r[0,1];
p:=1;
p1:=1;
for i:=1 to step do
begin
setlength(temp,p1+1);
for j:=0 to 1 doа buffer1[j]:=r[i,j];
Form1.Polinommul(buffer,p,buffer1,1,temp,p1);
setlength(buffer,p1);
buffer:=temp;
p:=p1;
end;
end
else
begin
setlength(buffer,2);
setlength(buffer1,2);
setlength(temp,2);
buffer[0]:=0;
buffer[1]:=1.0;
p:=0;
p1:=0;
for i:=0 to step do
begin
if numdrob = i then
begin
buffer1[0]:=0;
buffer1[1]:=1.0;
end;
if numdrob<>i then inc(p);
if numdrob<>i then for j:=0 to 1 doа buffer1[j]:=r[i,j];
if numdrob=i then
begin
Form1.Polinommul(buffer,p,buffer1,1,temp,p1);
continue;
end;
Form1.Polinommul(buffer,p,buffer1,1,temp,p1);
if numdrob<>i then setlength(buffer,p1);
buffer:=temp;
end;
end;
setlength(res,p1);
res:=buffer;
end;
Основной текст программы, вбирающий в себя процедуры и реализовающий сам процесс разложения на простые множители. Его я повесил на кнопку: а
procedure TForm1.Button1Click(Sender: TObject);
var
i,j,k:byte;
temp:polinom;
st1,st2,st3,stt:string;
begin
Form1.Edit1.Text:='';
Form1.Edit2.Text:='';
Form1.Edit3.Text:='';
Form1.Edit4.Text:='';
n1:=strtoint(Form1.SpinEdit1.Text);
n2:=strtoint(Form1.SpinEdit2.Text)-1;
setlength(chislit,n1+1);
setlength(roots2,n2+1,2);
setlength(znamen,n2,n2);
for i:=0 to n1 do
begin
chislit[i]:=strtofloat(Form1.StringGrid1.Cells[i,0]);
end;
for i:=0 to n2 do
begin
roots2[i,0]:=1.0;
roots2[i,1]:=-strtofloat(Form1.StringGrid2.Cells[i,0]);
end;
form1.GetPolinom(roots2,n2,false,0,pol2);
setlength(temp,n2+1);
for i:=0 to n2 do
begin
for k:=0 to n2 do temp[k]:=0;
form1.GetPolinom(roots2,n2,true,i,temp);
for j:=0 to n2 do
Form1.Edit3.Text:= Form1.Edit3.Text+getfstring(temp[j+1],1)+' ';
for k:=0 to n2 do temp[k]:=0;
end;
form1.Calculate(chislit,n1+1,st1);
form1.Calculate(pol2,n2+2,st2);
Form1.Edit1.Text:=st1;
Form1.Edit2.Text:=st2;
{for i:=0 to n1 do
Form1.Edit1.Text:=Form1.Edit1.Text+getfstring(chislit[i],1)+' ';
for i:=0 to n2+1 do
Form1.Edit2.Text:=Form1.Edit2.Text+getfstring(pol2[i],1)+' ';}
Setlength(matr,n2+2,n2+1);
for i:=0 to n2 do
begin
form1.GetPolinom(roots2,n2,true,i,temp);
for j:=1 to n2+1 do matr[i,j-1]:=temp[j];
end;
i:=0;
for j:=0 to n2 do
matr[n2+1,j]:=0;
for j:=n2-n1 to n2 do
begin
matr[n2+1,j]:=chislit[i];
inc(i);
end;
setlength(matr1,n2+1,n2+2);
setlength(koef,n2+1,1);
for i:=0 to n2 do
for j:=0 to n2+1 do
matr1[i,j]:=matr[j,i];
korni(matr1,n2+1,n2+2,koef);
for i:=0 to n2 do
form1.Edit4.Text:=form1.Edit4.Text+getfstring(koef[i,0],3)+' ';
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
Form1.StringGrid1.ColCount:=strtoint(Form1.SpinEdit1.Text)+1;
end;
procedure TForm1.SpinEdit2Change(Sender: TObject);
begin
Form1.StringGrid2.ColCount:=strtoint(Form1.SpinEdit2.Text);
end;
procedure TForm1.FormCreate(Sender: TObject);
var i:shortint;
begin
Form1.StringGrid1.ColCount:=strtoint(Form1.SpinEdit1.Text)+1;
Form1.StringGrid2.ColCount:=strtoint(Form1.SpinEdit2.Text);
end;
Чтобы вид был более нагляден и информативен, я использовал процедуру преобразования массива коэффициентов:
procedure TForm1.Calculate(mass1:polinom;n:integer;var formula:string);
var
i,j,k1:byte;
sign:array of signs ;
first,flag:boolean;
odin:array of boolean;
s:integer;
begin
k1:=n-1;
for i:=0 to n-1 do
begin
elem[i]:='x^'+inttostr(k1);
dec(k1);
end;
first:=true;
setlength(odin,n);
setlength(sign,n);
setlength(mass1,n);
equation:='';
for i:=0 to n-1 do //calculating and building
begin
if abs(mass1[i])=1 then odin[i]:=true; //esli ediniza
if mass1[i]>0 then sign[i]:=1 //check sign
else
if mass1[i]=0 then sign[i]:=0
else sign[i]:=-1;
if odin[i] thenа //esli ediniza
begin
if i<n-1 then
case sign[i] of
1:
if first then
begin
equation:=equation+elem[i];
first:=false;
end
else
equation:=equation+' + '+elem[i];
0:
continue;
-1:
begin
if first then first:=false;
equation:=equation+' - '+elem[i];
end;
end
else
case sign[i] of
1:
if first then
begin
equation:=equation+'1';
first:=false;
end
else
equation:=equation+' + 1';
0:
continue;
-1:
begin
if first then first:=false;
equation:=equation+' - 1';
end;
end;
continue;
end;
if i = n-1 then
case sign[i] of
1:
if first then
begin
equation:=equation+getfstring(abs(mass1[i]),3);
first:=false;
end
else
equation:=equation+' + '+getfstring(abs(mass1[i]),3);
0:а continue;
-1:
begin
if first then first:=false;
equation:=equation+' - '+getfstring(abs(mass1[i]),3);
end;
end
else
case sign[i] of
1:
if first then
begin
equation:=equation+getfstring(abs(mass1[i]),3)+'*'+elem[i];
first:=false;
end
else
equation:=equation+' + '+getfstring(abs(mass1[i]),3)+'*'+elem[i];
0:
continue;
-1:
begin
equation:=equation+' - '+getfstring(abs(mass1[i]),3)+'*'+elem[i];
if first then first:=false;
end;
end;
end;
s:=0;
{ for i:=0 to n-1 do
s:=s+abs(mass1[i]);
if s=0 then equation:='0';а }
formula:=equation;
end;
end.
Пример:
Заключение.
В моей курсовой работе я рассмотрел подробно метод простых коэффициентов и реализовал программу на Delphi, которая вычисляет значения коэффициентов для случая простых действительных корней знаменателя. В Maple эта процедура тоже есть и вычисляет коэффициенты для любой дробно - рациональной функции. Нехватка времени не позволила мне довести мою программу до полной функциональности: вычисление коэффициентов для любого знаменателя, т. е. знаменателя с любыми корнями. В дальнейшем, может быть, я это осуществлю. Однако, даже в таком варианте она полезна для практического использования - быстрого вычисления коэффициентов.
Список литературы.
1.Бахвалов Н.С., Лапин А.В., Кобельков Г. М. Численные методы. - М.: Физматлит, 2001.
2.Волков Е.А. Численные методы. - Петербург, изд - во Лань, 2004.
3.Демидович Б.П., Марон И.А. Основы вычислительной математики. - М.: Наука, 1970.
4.Вержбицкий В.М. Численные методы. Линейная алгебра и нелинейные равнения. - М.: Высшая школа, 2.
5.Бахвалов Н.С., Лапин А.В. Численные методы в задачах и пражнениях. - М.: Высшая школа, 2.
6.Фаддеев Д.К., Фаддеева В.Н. Вычислительные методы линейной алгебры. - Петербург, изд Цво Лань, 2002.
7.Самарский А.А., Гулин А.В. Численные методы математической физики. - М.: Научный мир, 2003.
8.Деммель Дж. Вычислительная линейная алгебра. - М.: Мир, 2001.
9.Косарев В.И. 12 лекций по вычислительной математике. - М.: изд Цво МФТИ, 2.
10. Лобанов А.И., Мещеряков М.В., Чудов Л.А. Задачи для самостоятельного исследования в курсе вычислительной математики. - М.: изд Цво МФТИ, 2001