Массивы
Понижение степени полинома
Если для полинома \[ P(x) \] n-й степени найден корень \[ x_1 \] , то можно понизить степень полинома, построив полином \[ P1(x) \] степени \[ n-1 \] , у которого все корни совпадают с корнями полинома \[ P(x) \] за исключением того, что у него нет корня \[ x_1 \] .
Запишем соотношение, связывающее полиномы:
\[ P(x)=P1(x)(x-x1)\\ a_n x^n+a_{n-1}x^{n-1}+\ldots+a_1 x+a_0=(b_{n-1}x^{n-1}+b_{n-2}x^{n-2}+\ldots+b_1 x+b_0)(x-x1) \]Учитывая соотношение 6.3 о равенстве двух полиномов одной степени, можно выписать \[ n+1 \] соотношение, связывающее коэффициенты этих полиномов. Эти соотношения нетрудно разрешить относительно неизвестных коэффициентов \[ b_k \] . В результате получим:
\[ b_{n-1}=a_n;\\ b_{n-2}=a_{n-1}+b_{n-1}x_1;\\ \ldots\\ b_0=a_1+b_1 x_1; \]Заметьте, неизвестных всего \[ n \] , а уравнений можно построить - \[ n+1 \] . Но последнее уравнение \[ (a0 + b_0 x1 = 0) \] является следствием предыдущих и используется для контроля вычислений.
К новому полиному можно применить тот же процесс - найти его корень и понизить затем степень полинома. Реально понижение степени не намного упрощает задачу отыскания корней, так что чаще всего проще искать корни исходного полинома, изменяя начальные приближения в итерационном процессе или отыскивая различные интервалы, на которых полином меняет свой знак.
Нахождение коэффициентов полинома по его корням
До сих пор рассматривалась задача отыскания корней полинома с заданными коэффициентами. Иногда приходится решать обратную задачу - найти коэффициенты полинома, если известны его корни - \[ x_1, x_2, … x_n \] . Полиномов с одинаковыми корнями существует бесчисленное множество. Однако среди них существует единственный полином с коэффициентом \[ a_n \] , равным единице. Этот полином называется приведенным, его-то и будем строить. Все остальные полиномы получаются из приведенного полинома умножением всех коэффициентов на произвольное число \[ a_n \] , от которого требуется лишь, чтобы оно не было равно нулю. Поэтому для однозначного решения задачи требуется задать n корней и коэффициент при старшем члене полинома. Тогда можно записать следующее равенство:
\[ P_n(x)=a_n(x-x_n)(x-x_{n-1})\ldots(x-x_1) \]Для нахождения коэффициентов полинома \[ P_n(x) \] воспользуемся, как обычно, соотношением 6.3. Но применить его напрямую сложно. Поэтому воспользуемся процессом, обратным к процессу понижения степени. Построим вначале \[ P_1(x) \] - полином первой степени, у которого \[ x_1 \] является единственным корнем. Затем повысим степень и построим полином второй степени - \[ P_2(x) \] , у которого появляется еще один корень - \[ x_2 \] . Продолжая этот процесс, дойдем до искомого полинома \[ P_n(x) \] . При вычислении коэффициентов нового полинома будем использовать коэффициенты уже посчитанного полинома на единицу меньшей степени. Получающиеся в результате соотношения близки к тем, что приведены для случая понижения степени полинома.
Коэффициенты полинома первой степени \[ P_1(x) \] выписываются явно:
\[ a_1=1;\quad a_0=-x_1; \]Коэффициенты полинома k-й степени вычисляются через коэффициенты полинома степени k-1:
\[ P_k(x)=P_{k-1}(x)(x-x_k) \]Переходя к коэффициентам, получим следующие уравнения:
\[ a_k=a'_{k-1};\\ a_{k-i}=a'_{k-i-1}-a'_{k-i}x_k;\quad \forall i\quad i=1,\dots k-1;\\ a_0=-a'_0 x_k; \]В соотношении 6.5 через \[ a' \] обозначены коэффициенты полинома степени \[ k-1 \] . На самом деле схема безопасна и позволяет считать коэффициенты на том же месте, не требуя дополнительной памяти. Приведу алгоритм вычисления коэффициентов полинома по его корням в виде схемы, приближенной к языку C#.
Дано:
- \[ an \] - коэффициент при старшем члене полинома \[ P_n(x) \] ;
- \[ n \] - степень полинома;
- \[ x \] - массив корней полинома \[ (x[0], x[1], …x[n]) \] ;
Вычислить:
- массив \[ a \] - массив коэффициентов полинома \[ (a[0], a[1], …a[n]) \] .
//Вычисляем коэффициенты полинома первой степени a[1]= 1; a[0] = -x[0]; //цикл по числу полиномов for(int k=2;k<=n; k++) { //Вычисляем коэффициенты полинома степени k //Вначале старший коэффициент a[k]= a[k-1]; //затем остальные коэффициенты, кроме последнего for(int i=k-1;i>0; i--) { a[i] = a[i-1]- a[i]*x[k-1]; } //теперь младший коэффициент a[0]= -a[0]*x[k-1]; } //Последний этап - умножение коэффициентов на an for(int i=0; i<=n; i++) a[i] = a[i]*an;
Полином Лагранжа
Пусть на плоскости заданы \[ n+1 \] точка: \[ R_0(x_0, y_0), R_1(x_1, y_1), R_2(x_2, y_2),\ldots, R_n(x_n, y_n) \] . Полиномом Лагранжа \[ P_L(x) \] называется полином n-й степени, проходящий через все точки \[ R_k \] . Если точки \[ R_k \] не образуют возвратов, то такой полином существует и является единственным. Под возвратом понимается ситуация, когда существуют две точки \[ R_i \] и \[ R_j \] такие, что \[ x_i = x_j \] .
Как построить такой полином? Лагранж предложил следующий алгоритм. Полином \[ P_L(x) \] строится как сумма \[ n+1 \] полиномов n-й степени:
\[ P_L(x)=\sum\limits_{k=1}^{n+1}P_k(x) \]Каждый из полиномов \[ P_k(x) \] , входящих в сумму, строится следующим образом. Корнями полинома \[ P_k(x) \] являются все точки \[ R_i \] за исключением точки \[ R_k \] . Единственность \[ P_k(x) \] обеспечивается за счет того, что коэффициент при старшем члене an подбирается так, чтобы полином проходил через точку \[ R_k \] . В записи Лагранжа полином \[ P_k(x) \] выглядит следующим образом:
\[ P_k(x)=y_k\frac{(x-x_o)(x-x_1)\ldots(x-x_{k-1})(x-x_{k+1})\ldots(x-x_n)}{(x_k-x_0)(x_k-x_1)\ldots(x_k-x_{k-1})(x_k-x_{k+1})\ldots(x_k-x_n)} \]В записи 6.6 в числителе находится приведенный полином, построенный по корням, а \[ y_k \] , деленное на знаменатель в формуле 6.6, задает \[ an \] - старший коэффициент полинома.
Условия, накладываемые на полиномы \[ P_k(x) \] , обеспечивают выполнение требований к полиному Лагранжа - сумма полиномов \[ P_k(x) \] будет полиномом, проходящим через все заданные точки.
Поскольку алгоритм построения приведенного полинома по его корням уже разобран, то схема построения полинома Лагранжа может выглядеть так:
//Полином Лагранжа определяется как сумма из n+1 //полиномов Pk, для которых известны корни. for(int k=0; k<=n; k++) { //Задание корней для полинома Pk for(int i =0; i<k; i++) roots[i] = X[i]; for(int i =k+1; i<=n; i++) roots[i-1] = X[i]; //Вычисление коэффициентов приведенного полинома по его корням coefk = CalcCoefFromRoots(roots); //вычисление An - старшего коэффициента полинома. An = Y[k] / HornerP(coefk,X[k]); //Добавление очередного полинома Pk к PL - сумме полиномов for(int i =0; i<=n; i++) { coefL[i]= coefL[i]+An*coefk[i]; } }
В этой схеме:
- X и Y - массивы, задающие декартовы координаты точек, через которые проходит полином Лагранжа,
- n - степень полинома,
- roots - массив корней приведенного полинома \[ P_k \] ,
- coefk - массив его коэффициентов,
- An - старший коэффициент полинома, вычисляемый из условия прохождения полинома \[ P_k \] через точку с координатами X[k], Y[k],
- coefL - массив коэффициентов полинома Лагранжа,
- HornerP - метод, вычисляющий по схеме Горнера значение полинома по его коэффициентам и значению координаты x,
- CalcCoefFromRoots - метод, вычисляющий массив коэффициентов приведенного полинома по его корням.