Cómo calcular al menos una raíz real del polinomio [matemáticas] f (x): = x ^ {47} + x ^ {35} -1 [/ matemáticas]

SOLO hay una raíz real de este polinomio. Su derivada es [matemática] f ‘(x) = 47x ^ {46} + 35x ^ {34} [/ matemática]. Observe que cada término en la derivada es positivo para todos [matemática] x \ ne 0 [/ matemática], por lo que la derivada solo es igual a cero en [matemática] x = 0 [/ matemática] y en todas partes es positiva. Eso significa que la función está aumentando estrictamente, por lo que puede haber como máximo una raíz real . También está bastante claro que la función es continua y [math] \ lim_ {x \ to – \ infty} = – \ infty [/ math] y [math] \ lim_ {x \ to \ infty} = \ infty [/ math ] Entonces debe haber al menos una raíz real . Juntas, las dos declaraciones subrayadas implican que hay exactamente una raíz real.

No conozco ninguna forma de encontrar su valor exacto (de forma rápida o no). Sin embargo, puede encontrar su valor aproximado utilizando cualquier número de algoritmos numéricos.

Hay una manera MUY rápida de obtener una muy buena aproximación de la respuesta correcta. Con solo pensarlo un poco, debe quedar claro que la respuesta correcta se encuentra en el intervalo [matemáticas] \ left (\ sqrt [35] {\ frac 1 2}, \ sqrt [47] {\ frac 1 2} \ right) \ aprox (0.98039, 0.98536) [/ matemáticas].

¿Por qué debe ser esto cierto? Porque si llevamos el punto final izquierdo a la potencia 47, es un poco menos de 1/2 y si lo llevamos a la potencia 35 es exactamente la mitad. Sumarlos juntos da un resultado que es un poco menor que uno, por lo que el polinomio es ligeramente negativo en el punto final izquierdo del intervalo.

Del mismo modo, si llevamos el punto final derecho a la potencia 47 es exactamente 1/2 y si lo llevamos a la potencia 35, es un poco más grande que 1/2, por lo que la suma de estos términos es un poco más grande que uno y el polinomio es ligeramente positivo en el punto final derecho del intervalo. La continuidad de la función asegura que la raíz esté en algún lugar de este intervalo (ya muy pequeño).

Podría hacer mucho peor que simplemente aproximar la raíz como el punto medio del intervalo (que es 0.9829). ¡Resulta que el error relativo en esta aproximación es un poco menos de una cuadragésima parte del uno por ciento (.00025)!

Puede obtener una mejor respuesta muy rápidamente usando Matlab / Octave con los siguientes comandos:

f = ceros (1,48); % crea un vector de 48 ceros que
% representa los coeficientes del polinomio

f ([1 13 48]) = [1 1 -1]; % hace el primero y 13 el valor 1 y el 48 valor -1
% todos los demás valores permanecen en cero

r = raíces (f); % calcula las 47 raíces del polinomio de 47 ° grado
% todas menos una de estas raíces serán complejas

x = real (r (abs (imag (r)) == min (abs (imag (r))))); % make x igual al real
% parte de la raíz que tiene la magnitud más pequeña
%parte imaginaria. Esta parte imaginaria debería ser
% idénticamente cero, pero debido a la precisión de la máquina,
% podría ser ligeramente distinto de cero. Por eso nosotros
% no debería simplemente buscar la raíz con un imaginario
% parte que es EXACTAMENTE cero.

formato largo% Esto nos permitirá ver TODOS los dígitos

disp (x)% muestra el valor de la raíz real

El resultado, para la precisión de la máquina, es 0.983111062986726.

Esta es (aproximadamente) la raíz real única.

Me gustaría agregar que la raíz real única de ese polinomio es irracional. Usando el teorema de la raíz racional para polinomios con coeficientes enteros, podemos decir que las raíces racionales (si existen) son [matemáticas] 1 [/ matemáticas] o [matemáticas] -1 [/ matemáticas]. Otras fórmulas para calcular esta raíz en forma numérica se dieron en otras respuestas.

[matemáticas] f (0) = – 1 [/ matemáticas]
[matemáticas] f (1) = 1 [/ matemáticas]

Como [math] f (x) [/ math] es continuo, cruza el eje x en algún lugar entre [math] 0 [/ math] y [math] 1 [/ math].

Cualquiera de los siguientes puede usarse para aproximar la raíz

  • Método de bisección
  • Método de Newton
  • Método secante

Aquí hay un código que encuentra la raíz entre [matemática] 0 [/ matemática] y [matemática] 1 [/ matemática] utilizando el método de bisección (búsqueda binaria).

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

#include
#include
#define EPSILON 1e-9 using namespace std; double function(double x);
double root(); int main()
{
cout<<"Root = "< return 0;
} double function(double x)
{
return pow(x, 47)+pow(x, 35)-1;
} double root()
{
int iteration=0;
double low=0;
double high=1;
double mid;
double current=0, past=0; do
{
past=current;
mid=(low+high)/2;
current=function(mid); if(current>0)
high=mid;
else
low=mid;
}while(fabs(current-past)>EPSILON); return mid;
}

Salida:
Raíz = [matemáticas] 0.983111 [/ matemáticas]

Una respuesta que requiere otra respuesta

f (x) = x ^ n + x ^ m – 1 = 0
(n & m) son enteros positivos impares (n> m)
x = [1- (1 / n) + (2m-n + 1) / (2! n ^ 2) – (3m-2n + 1) (3m-n + 1) / (3! n ^ 3)
+ (4m-3n + 1) (4m-2n + 1) (4m-n + 1) / (4! N ^ 4)
– (5m-n + 1) (5m-2n + 1) (5m-3n + 1) (5m-4n + 1) / (5! N ^ 5) +…],

aquí tienes (n = 47 & m = 35)
esta fórmula de solución exacta simplemente puede ser programada, y creo que daría un resultado mucho más rápido y una mejor aproximación a cualquier grado de precisión deseado, ¿crees que sí?

GRACIAS POR VERIFICAR

Como la derivada [math] f ‘(x) = 47x ^ {46} + 35x ^ {34} = x ^ {34} (47 x ^ {12} +35) [/ math] tiene solo una raíz real en [ matemáticas] x = 0 [/ matemáticas] y [matemáticas] \ lim_ {x \ to – \ infty} f ‘(x) = \ lim_ {x \ to \ infty} f’ (x) [/ matemáticas] sigue, que [matemáticas] f (x) [/ matemáticas] es monótono, es decir, tiene como polinomio continuo de grado impar solo una raíz real. El exponente [matemática] 47 [/ matemática] es relativamente alto, por lo que [matemática] f (1) = 1 \ aproximadamente 0 [/ matemática], es decir, esta raíz debe estar cerca de [matemática] x = 1 [/ matemática ] Entonces [math] x = 1 [/ math] es un buen punto de partida para una iteración de Newton-Raphson. La raíz aproximada calculada por el siguiente código es [matemática] 0.9831110629867269 [/ matemática] con el valor absoluto de la función en este punto menor que [matemática] 10 ^ {- 15} [/ matemática].

El siguiente código de q & d Haskell implementa el método Newton-Raphson. Por supuesto que podría ser refinado.

Tipo Coeficiente = Doble
tipo Exponente = Int
tipo Polynomial = [(Coeficiente, Exponente)]

valor :: Doble -> Polinomio -> Doble
valor _ [] = 0
valor xp = (fst mon) * x ^ (snd mon) + valor x (cola p)
donde mon = cabeza p

derivada :: Doble -> Polinomio -> Doble
derivada _ [] = 0
derivada xp = valor xq
donde q = map (\ y-> (fst y * fromIntegral (snd y), snd y -1)) $ filter (\ x -> snd x / = 0) p

newton :: Doble -> Polinomio -> Doble -> Doble
newton s [] _ ​​= s
newton sp prc | abs v El | de lo contrario = newton nxt p prc
dónde
v = valor sp
nxt = s – v / derivada sp

La función newton debería llamarse como

newton 1 [(1,47), (1,35), (- 1,0)] 1e-15

donde el 1 es el punto de partida de la iteración, la lista representa el polinomio y el número [mathr] 1 \ mathrm e \! – \! \! 15 [/ math] es la incertidumbre del valor calculado.