Разложение рациональной дроби на простейшие.

Реферат - Математика и статистика

Другие рефераты по предмету Математика и статистика

˜ вместо шести множителей получилось только пять. Ну и что? Просто два “произвольных” многочлена полностью совпали (и по степеням тоже). На что только ни способен генератор случайных чисел в Maple! Результат раскрытия можно посмотреть на рисунке там он выглядит куда меньше.

Второй этап работы заключается в определении характера правильности дроби и выделении целой части (если нужно), т.е. представлению ее в виде:

 

где Z(x) целая часть, а R(x) не делится на Q(x) . Сделаем это следующим образом:

 

 

> fracpart:= rem(numer(rfun), denom(rfun), x, zpart);

 

 

Заведем переменную fracpart и zpart соответственно для дробной и для целой части рациональной дроби. Процедура-функция rem возвращает остаток от деления многочленов как основной результат. Третий (необязательный) параметр имя переменной, “в которую будет вычислена” целая часть. Совершенно аналогично действует функция quo , где основным результатом является целая часть от деления. Здесь функции numer и denom соответственно дают доступ к числителю и знаменателю дроби.

Сейчас начинается интересное, а именно: попытка записать, собственно, само разложение с неопределенными коэффициентами. Для начала нужно проанализировать структуру знаменателя. Разложим его на множители:

> denomx:= factor(denom(rfun));

Разделим текущую подзадачу на два этапа: “изготовление” списка знаменателей будущих простейших дробей и запись самого разложения. Для реализации первого этапа нам понадобится написать процедуру-функцию, которая бы занималась преобразованием выражения вида A n в упорядоченный список вида [A, A 2 , A 3 , ..., A n ].

(а) > transpol:= proc (p: polynom) local j;

(б) > if degree(p, x) <= 1 then

> p;

> else

(в) > if not type(op(2, p), numeric) then

> p;

> else

(г) > seq(op(1, p)^p, j=1.. op(2, p));

> fi;

> fi;

> end:

 

 

В (а) объявим имя функции, тип и количество передаваемых параметров, а также локальные переменные в поле local . Результатом работы функции будет результат последней выполненной операции. Теперь опишем сам алгоритм. Если была передана константа либо многочлен первой степени, то вернется он же (б) . Дальше получим и проанализируем тип объекта op(2, p) . Здесь я обращаюсь к многочлену p как к списку. Maple позволяет работать почти с любым из своих объектов как со списком. После проверки (б) у нас останется лишь три варианта для p : (x 2 +bx+c), (x 2 +bx+c) n , (ax+b) n . Их op(2, p) будет соответственно равен x 2 , n, n . В первом случае (наш “op” не число) придется возвратить параметр в первозданном виде это просто квадратный неприводимый трехчлен, а в остальных осуществляем разложение (г) формируем нужную последовательность. Далее приготовим список знаменателей будущих простейших дробей, используя только что написанное:

 

> ds:= [seq(transpol(op(k, denomx)), k=1.. nops(denomx))];

 

В нашем конкретном случае результат с точностью до расположения элементов списка будет выглядеть следующим образом:

 

ds:= [2, 2x+3, 5x-4, 4x-1, (4x-1) 2 , (4x-1) 3 , x 2 +x+2, x 2 +x+4, (x 2 +x+4) 2 , ...,(x 2 +x+4) 6 ]

 

Записать разложение с неопределенными коэффициентами, имея такую прелесть, ничего не стоит:

 

> rxn:= 0:

> lastvar:= 1:

> for i from 1 to nops(ds) do

(а) > if degree(op(1, op(i, ds)), x) = 1 then

(б) > rxn:= rxn + (A[lastvar])/op(i, ds);

> else

(в) > rxn:= rxn + (A[lastvar]*x+A[lastvar + 1])/op(i, ds);

> lastvar:= lastvar + 1;

> fi;

> lastvar:= lastvar + 1;

> od:

Теперь все сначала и по порядку. Заведем переменную rxn , в которую после запишем разложение. Счетчик lastvar уже использованных индексов коэффициентов установим в значение 1 (следующий, не использованный индекс). Далее, пробегая по списку ds знаменателей будущих простейших дробей, анализируем их степень. Собственно сама реализация такого анализа (а) может показаться довольно странной. Со встроенной функцией degree все понятно она возвратит степень многочлена относительно переменной, переданной в качестве второго параметра. Что же значит запись op(1, op(i, ds))? Так как вариантов здесь только два, то их и рассмотрим. Если op(i, ds) выражение вида (x 2 +bx+c) n либо (x+d) n , то op(1, op(i, ds)) вернет то, что находится в скобках. В другом случае x 2 +bx+c либо x+d (скобок нет) такая композиция возвратит высший член многочлена (он записан в лексикографическом виде). Таким образом реализуется определение степени знаменателя без учета кратности . А дальше, в зависимости от этого формируется числитель степени на единицу меньшей. За что люблю Maple, так это за (б) и (в) . Ну где вы видели, чтоб вот так “на ходу” можно было “собрать” переменную? А здесь возможно и такое. Естественно, использовав очередной индекс, необходимо увеличить значение счетчика.

Итак, нечто весьма похожее на разложение, приведенное в теореме, мы получили. Теперь дело за малым нужно вычислить эти самые A k -ые. Сделаем это так: приведем полученное разложение к общему знаменателю, разберемся с подобными и соберем коэффициенты перед x i , где i = 0 ... 21 (в нашем случае) в числителе:

 

 

> f:= collect(numer(rxn), x):

> for i from 0 to degree(f, x) do

> cundef[i]:= coeff(f, x, i):

> od:

 

 

Функция numer , вернув числитель, “по дороге” приведет rxn к общему знаменателю, collect как раз и повыносит за скобки x i . В переменные (не массив!) cundef i выделим с помощью функции coeff (третий параметр степень переменной, остальные два очевидны) эти самые коэффициенты. Их количество будет равно степени f плюс один (нулевая). Зачем это надо? А что у нас во fracpart? Именно то же самое, но коэффициенты определенные. Что делаем? Составляем систему линейных уравнений и решаем относительно наших A k -ых. Единственность решения такой системы доказана до нас, посему спокойн