Как оценить кратность полинома root? - PullRequest
1 голос
/ 22 марта 2020

Я хочу оценить множественность полиномиальных корней.

Я нашел некоторую информацию об этом , выбрал тестовый пример и сделал c программу

Здесь должно быть 4 корня. Один простой root и один с кратностью 3.

#include <complex.h>
#include <math.h>
#include <stdio.h>

complex long double z0 = +1.5; // exact period = 1 stability = 3.000000000000000000 multiplicity = ?
complex long double z1 = -0.5; // exact period = 2 stability = 0.999999999999900080 multiplicity = ?
complex long double c  = -0.75; // parameter of the f function




/*
https://en.wikibooks.org/wiki/Fractals/Mathematics/Newton_method

*/
int GiveMultiplicity(const complex long double c, const complex long double z0 ,  const int pMax){

    complex long double z = z0;
    complex long double d = 1.0; /* d = first derivative with respect to z */

    complex long double e = 0.0; // second derivative with respect to z
    complex long double m;
    int multiplicity;

    int p;

    for (p=0; p < pMax; p++){

        d = 2*z*d; // f' = first derivative with respect to z */
        e = 2*(d*d +z*e); // f'' = second derivative with respect to z
        z = z*z +c ; // f = complex quadratic polynomial 
    }   

    m = (d*d)/(d*d -z*e);
    multiplicity = (int) round(cabs(m));


    return multiplicity;     
}






int main(){

    int m;


    m = GiveMultiplicity(c, z0, 1);
    printf("m = %d \n", m);

    m = GiveMultiplicity(c, z1,  1);
    printf("m = %d \n", m);

    m = GiveMultiplicity(c, z1, 2);
    printf("m = %d \n", m);




    return 0;
}

Результат:

m=1
m=1
m=1

Это хорошо? Может быть, я должен просто добавить результаты?

Хорошие результаты с использованием вычисления Symboli c являются корнями: [3/2, -1/2] и его кратности: [1,3]

Вот график функции f (z) = (z ^ 2-0,75) ^ 2-z-0,75 = z ^ 4-1,5 * z ^ 2-z-3/16 graph

Возможно ли вычислить аналогичные значения численно?

Ответы [ 4 ]

2 голосов
/ 15 апреля 2020

Сводка изменений:

  • оценка e до вычисления d внутри цикла;
  • при вычитании z0 из z после l oop вам также необходимо вычесть 1 из d для соответствия;
  • возмущает ввод небольшого количества из истинного root местоположения, чтобы избежать 0/0 = NaN результат: h должен быть достаточно маленьким, но не слишком маленький ...

Полная программа:

#include <complex.h>
#include <math.h>
#include <stdio.h>

complex long double h = 1.0e-6; // perturb a little; not too big, not too small
complex long double z0 = +1.5; // exact period = 1 stability = 3.000000000000000000 multiplicity = ?
complex long double z1 = -0.5; // exact period = 2 stability = 0.999999999999900080 multiplicity = ?
complex long double c  = -0.75; // parameter of the f function

/*
https://en.wikibooks.org/wiki/Fractals/Mathematics/Newton_method
*/
int GiveMultiplicity(const complex long double c, const complex long double z0, const int pMax){
    complex long double z = z0;
    complex long double d = 1.0; /* d = first derivative with respect to z */
    complex long double e = 0.0; // second derivative with respect to z
    complex long double m;
    int multiplicity;
    int p;
    for (p=0; p < pMax; p++){
        e = 2*(d*d +z*e); // f'' = second derivative with respect to z
        d = 2*z*d; // f' = first derivative with respect to z */
        z = z*z +c ; // f = complex quadratic polynomial
    }
    d = d - 1;
    z = z - z0;

    m = (d*d)/(d*d -z*e);
    multiplicity = (int) round(cabs(m));

    return multiplicity;
}

int main(){
    int m;

    m = GiveMultiplicity(c, z0 + h, 1);
    printf("m = %d\n", m);

    m = GiveMultiplicity(c, z1 + h, 1);
    printf("m = %d\n", m);

    m = GiveMultiplicity(c, z1 + h, 2);
    printf("m = %d\n", m);

    return 0;
}

Вывод:

m = 1
m = 1
m = 3
2 голосов
/ 22 марта 2020

Вы делаете это с интеграцией контура, см. здесь . Программное обеспечение доступно .

0 голосов
/ 30 марта 2020

Я обнаружил одну ошибку в моей исходной программе. Функция для нахождения периодов c точек должна быть

f^n(z) - z 

, поэтому

for (p=0; p < pMax; p++){

        d = 2*z*d; // f' = first derivative with respect to z */
        e = 2*(d*d +z*e); // f'' = second derivative with respect to z
        z = z*z +c ; // f = complex quadratic polynomial 
    }
z = z - z0; // new line 
0 голосов
/ 24 марта 2020

Я выбрал метод на основе геометрической записи root Он описан в Основная теорема алгебры: визуальный подход Даниэля Дж. Веллемана

Я считаю, сколько раз цветовые чаги вдоль круга вокруг root. Я использую функцию carg, которая возвращает фазовый угол z в интервале [−π; π]. Поэтому посчитайте изменение знака аргумента и разделите его на 2. Это оценивает кратность root. Это, вероятно, тот же метод, что и выше, но проще для понимания и реализации для меня.

Вот изображение динамической плоскости

до преобразования:

enter image description here

и после f (z):

enter image description here

и код:

А вот изображение аргумента z вокруг root (используется груз)

enter image description here
...