4 votos

Encontrar numéricamente las raíces de polinomios cúbicas donde coeficientes varían ampliamente en magnitud

Considere el siguiente polinomio:

$$ p(x) = x^3 + (C_b+K_a)x^2 - (C_aK_a + K_w)x - K_aK_w $$

Where:

  • $x, C_a, C_b$ are concentrations, positive real numbers typically within $[10^{-7};1]$. The unknown $x$ is the proton concentration and $C_a, C_b$ se supone que ser constante;
  • $K_a$ es ácido/base de la constante de disociación, normalmente dentro de $[10^{-12},10^{-2}]$;
  • $K_w$ es el agua iónica producto constante que se acerca $10^{-14}$.

Espero que este polinomio para tener al menos una solución real positiva debido a que la concentración de protones existen físicamente.

Mi objetivo es encontrar la verdadera solución positiva de la ecuación de $p(x)=0$ mediante el uso de algún método numérico (Newton, etc. o incluso fórmulas de Cardano), pero me enfrento a algunos de normalización problema debido a la diferencia de magnitudes entre las constantes o monomials.

Para una instalación típica:

$$K_a = 10^{-4.75},\quad C_a = 0.1,\quad C_b = 0.2$$

Polynomial coefficients widely varies in magnitude:

$$ a_3=1.0000,\quad a_2=0.2000,\quad a_1=-1.7792\cdot 10^{-11},\quad a_0=-1.7783\cdot 10^{-24} $$

The discriminant of this polynomial for this setup is about $\Delta = 5.6905\cdot 10^{-26}$, que es muy pequeño, puede ser cualquier cosa: cero, positivo o negativo, ¿quién sabe?

He utilizado tanto float y fixed decimal (con 40 decimales) aritmética para calcular estas cantidades. Ellos difieren ligeramente con la aritmética, sino de la ampliación problema sigue. Creo que mi problema es sobre numérico de la estabilidad y la normalización.

Wolfram parece ser capaz de resolverlo cuando yo uso simbólico de valores (la respuesta es correcta) en lugar de los coeficientes de desarrollo decimal (la respuesta es demasiado pequeño).

No estoy pidiendo una solución completa, en lugar de pistas o referencias a un método para encontrar raíces de este tipo de enfermos en escala de polinomios. Así que mis preguntas son:

  • ¿Cómo puedo resolver con precisión este tipo de polinomio con un método numérico?
  • ¿Qué tipo de normalización debe aplicar antes de resolverlo?
  • Hay un específico método numérico para esta clase de problema?

Nota

El polinomio $p(x)$ proviene de la definición del ácido/base de la constante de equilibrio:

$$ K_a = x\frac{b}{a}, \quad K_w = xy $$

Where matter amount and charge balances have been injected:

$$ C_a + C_b = a + b,\quad b + y = x + C_b $$

Actualización

He logrado encontrar una creíble root usando numpy.roots y decimal que cumple con Wolfram Alpha. El siguiente Python 3 código:

import numpy as np
import decimal

Ka = decimal.Decimal("10")**decimal.Decimal("-4.75")
Kw = decimal.Decimal("1e-14")
Ca = decimal.Decimal("0.1")
Cb = decimal.Decimal("0.2")
coefs = [decimal.Decimal(1), (Cb+Ka), -(Ca*Ka + Kw), -Ka*Kw]

r0 = np.roots(coefs)

Devuelve:

array([-2.00026673e-01,  8.89021156e-06, -9.99999983e-14])

Todavía estoy interesado en saber si hay otros cuidados a tomar para solucionar este tipo de problemas.

3voto

Claude Leibovici Puntos 54392

Si usted considerar el uso de método de Newton para encontrar el cero de $$f(x)=x^3+x^2 (\text{Cb}+\text{Ka})-x (\text{Ca} \,\text{Ka}+\text{Kw})-\text{Ka} \, \text{Kw}$$ $$f'(x)=3 x^2+2 x (\text{Cb}+\text{Ka})-(\text{Ca} \text{Ka}+\text{Kw})$$ $$f''(x)=6 x+2 (\text{Cb}+\text{Ka})$$ you must not start at $x=0$ desde $$f(0) \,f''(0)=-2\, \text{Ka} \,\text{Kw} \,(\text{Cb}+\text{Ka})<0$$ (think about Darboux-Fourier theorem). If you use $x_0=0$, entonces la primera iteración sería $$x_1=-\frac{\text{Ka} \, \text{Kw}}{\text{Ca} \,\text{Ka}+\text{Kw}} <0$$

La primera derivada cancela en $$x_*=\frac{1}{3} \left(\sqrt{(\text{Cb}+\text{Ka})^2+3 (\text{Ca}\, \text{Ka}+\text{Kw})}-(\text{Cb}+\text{Ka})\right) > 0$$ y la segunda derivada de la prueba de muestra que se trata de un mínimo.

Con el fin de generar el punto de partida $x_0$, realizan alrededor de $x=x_*$ ( $f'(x_*)=0$ ), la expansión de Taylor $$0=f(x_*)+\frac 12 f''(x_*)\,(x-x_*)^2+O((x-x_*)^3 ) \implies x_0=x_*+ \sqrt{-2\frac {f(x_*)}{f''(x_*)}}$$

Utilizando sus números, Newton recorre sería $$\left( \begin{array}{cc} n & x_n \\ 0 & \color{blue}{8.8902}609452502354578 \times 10^{-6}\\ 1 & \color{blue}{8.89021155}71665711819 \times 10^{-6}\\ 2 & \color{blue}{8.8902115568921917511} \times 10^{-6} \end{array} \right)$$ Esta es una muy fiable procedimiento.

Editar

Estoy casi seguro de que incluso podríamos omitir el procedimiento de Newton usando un $[1,2]$ Padé approximant construido alrededor de $x_1$. Esto daría $$x_1=x_0+\frac 12\frac{ f(x_0) \left(f(x_0)\, f''(x_0)-2\, f'(x_0)^2\right)}{f(x_0)^2 +f'(x_0)^3- f(x_0)\,f'(x_0)\, f''(x_0)}$$

Para el ejemplo práctico, esto daría $x_2=\color{blue}{8.890211556892191751}2 \times 10^{-6}$

2voto

Niall Connaughton Puntos 3786

De acuerdo a la computación en Wolfram Alpha vinculado en la pregunta, la tarea es encontrar las raíces de la ecuación cúbica

$x^{3} + (0.2 + 1 \times 10^{-4.75})x^{2}-(0.1 \times 10^{-4.75} + 1 \times 10^{-14})x - (1 \times 10^{-4.75} \times 1 \times 10^{-14})$

Si esto es representativo de las ecuaciones cúbicas que necesita ser resuelto, no parece haber ningún problema en la lucha contra este con el estándar IEEE-754 de doble precisión de cálculo y un estándar de solver, tales como Kahan s QBC de problemas:

William Kahan, "Para Resolver un Real Cúbicos Ecuación". Notas de la conferencia, la universidad de Berkeley, Nov. 1986 (en línea)

Estoy usando Kahan del código bastante literal, pero han mejorado en varios lugares por el uso de la FMA (fusionada multiplicar-agregar) operación, el cual es fácilmente accesible desde C++ como el estándar de función matemática fma(). Yo especifican los coeficientes de la siguiente manera:

double a3 =  1.0;
double a2 =  0.2 + exp10 (-4.75);
double a1 = -(0.1 * exp10 (-4.75) + exp10 (-14.0));
double a0 = -(exp10 (-4.75) * exp10 (-14.0));

Los resultados devueltos por la QBC problemas son:

-2.0002667300555729e-001
-9.9999998312876059e-014 + i *  0.0000000000000000e+000
 8.8902115568921925e-006 + i *  0.0000000000000000e+000

Estos coinciden con los resultados calculados por Wolfram Alpha: $-0.200027, -1.\times10^{-13}, 8.89021\times10^{-6}$

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X