Métodos de Neville y Aitken
Una de las dificultades de la interpolación de Lagrange, es que el error es difícil (o imposible) de calcular. La forma habitual de trabajar es ir incrementando el orden de los polinomios, hasta que se obtiene un valor deseado. Sin embargo, cada cálculo es independiente del previo, perdiéndose contacto entre uno y otro. Los polinomios de Legendre también se pueden generar aprovechando los cálculos previos, en forma iterativa.
Calcularemos, usando los valores dados en table.dat, los polinomios de Lagrange de distinto orden y con distinta combinaciones de puntos adyacentes, para x=1.5. Llamaremos Pi,j,k(x) al polinomio de Lagrange de orden 2, que pasa por los puntos adyacentes x=xi, x=xj y x=xk. Se puede demostrar que el polinomio de Lagrange que pasa por los puntos adyacentes x=xi, x=xj, x=xk y x=xl se obtiene haciendo:
(x-xi)Pjkl - (x-xl)Pijk
P(x) = Pijkl(x) = ---------------------------
(xl-xk)
Por ejemplo:
(r-x1)P2 - (r-x2)P1
P12® = -----------------------------
( x2 - x1 )
en el caso de r=1.5 :
(1.5 - 1.0)0.6200860 - (1.5 - 1.3)0.7651977
P12(1.5) = ---------------------------------------------- = 0.5233449
( 1.3 - 1.0 )
o
(1.5 - 1.3)0.4554022 - (1.5 - 1.6)0.6200860
P23(1.5) = ---------------------------------------------- = 0.5102968
( 1.6 - 1.3 )
y en orden mas elevado:
(1.5 - 1.0)0.5102968 - (1.5 - 1.6)0.5233449
P123(1.5) = ---------------------------------------------- = 0.5124715
( 1.6 - 1.0 )
Escribiendo los polinomios Pijkl en una matriz A x1 A11 x2 A21 A22 x3 A31 A32 A33 x4 A41 A42 A43 A44 x5 A51 A52 A53 A54 A55
el algoritmo de Neville se puede simplificar en el siguiente esquema: Interpolación de la función f(x) dada en n puntos x1, x2, … ,xn
INPUT: xi en el array X(i) y f(xi) en la matriz A(i,1) • Paso 1: For i=2,…,n • for j=2,…,i • (x-xi-j+1)Ai,j-1 - (x-xi)Ai-1,j-1 • Ai,j = ------------------------------------ • xi - xi-j+1 • • Paso 2: Output A•
PROGRAMA DE AIKTEN DE JAVA
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.math.Big Decimal?; public class Aitken extends J Frame? { //GUI private J Label? tituloLabel, x0Label, datoTolLabel, aLabel, bLabel; private J Text Field? x0Campo, datoTolCampo, aCampo, bCampo; private J Button? comenzarBoton, limpiarBoton, ayudaBoton; private J Text Area? salidaArea; private J Scroll Pane? desplazador; //DATOS private Big Decimal x0; private Big Decimal pn; private Big Decimal pnMas1; private Big Decimal pnMas2; private Big Decimal qn; private Big Decimal A; private Big Decimal B; private Big Decimal tolerancia; public Aitken() { super(“Programa que utiliza el metodo de Aitken.”); Container contenedor = getContentPane(); contenedor.setLayout( new Flow Layout?() ); x0Label = new J Label(“X0″); contenedor.add( x0Label ); x0Campo = new J Text Field( 10 ); contenedor.add( x0Campo ); datoTolLabel = new J Label(“TOLERANCIA: .5 X 10″); contenedor.add( datoTolLabel ); datoTolCampo = new J Text Field( 10 ); contenedor.add( datoTolCampo ); aLabel = new J Label(“A”); contenedor.add( aLabel ); aCampo = new J Text Field( 10 ); contenedor.add( aCampo ); bLabel = new J Label(“B”); contenedor.add( bLabel ); bCampo = new J Text Field( 10 ); contenedor.add( bCampo ); salidaArea = new J Text Area( 20,60 ); salidaArea.setFont( new Font( “Monospaced”, Font.PLAIN, 12) ); salidaArea.setEditable( false ); desplazador = new J Scroll Pane( salidaArea ); contenedor.add( desplazador ); comenzarBoton = new J Button(“Comenzar”); comenzarBoton.addActionListener( new Action Listener?()//Clase interna anonima { public void actionPerformed( Action Event? evento ) { //Valida entrada, si resive false algo en la entrada esta mal else continua. if( validaEntrada() == false ) System.out.println(“Error en la entrada” ); else { //Construir X0,A,B x0 = new Big Decimal( x0Campo.getText() ); A = new Big Decimal( aCampo.getText() ); B = new Big Decimal( bCampo.getText() ); int n = 1; //Iteraciones String salida = “n\t Xn\t g(Xn)\t |Xn-g(Xn)|\n”; salida += “----------------------------------------------------\n”; //Asignamos 10 cifras significativas x0 = x0.setScale( 10,x0.ROUND_HALF_DOWN ); A = A.setScale( 10,A.ROUND_HALF_DOWN ); B = B.setScale( 10,B.ROUND_HALF_DOWN ); tolerancia = calculaTolerancia( Integer.parseInt( datoTolCampo.getText() )); tolerancia = tolerancia.setScale( 10,tolerancia.ROUND_HALF_DOWN ); //Calcular 3 Pn pn = PN( x0 ); pnMas1 = PN( pn ); pnMas2 = PN( pnMas1 ); pn = pn.setScale( 10,pn.ROUND_HALF_DOWN ); pnMas1 = pnMas1.setScale( 10,pnMas1.ROUND_HALF_DOWN ); pnMas2 = pnMas2.setScale( 10,pnMas2.ROUND_HALF_DOWN ); qn = QN(); qn = qn.setScale( 10,qn.ROUND_HALF_DOWN ); } } } ); contenedor.add( comenzarBoton ); limpiarBoton = new J Button(“Limpiar”); limpiarBoton.setEnabled( false ); limpiarBoton.addActionListener( new Action Listener()//Clase interna anonima { public void actionPerformed( Action Event evento ) { } } ); contenedor.add( limpiarBoton ); ayudaBoton = new J Button(“Ayuda”); ayudaBoton.addActionListener( new Action Listener()//Clase interna anonima { public void actionPerformed( Action Event evento ) { String salida = “APLICACION PARA OBTENER LA RAIZ CUADRADA\n\n\n” ; salida += “1) Recive un valor para X y un valor para Q\n\n”; salida+= “2) X puede tener como maximo la siguiente forma: 9999999999.999999\n”; salida += “tambien puede ser asi 9999999999 \n\n”; salida += “3) Q puede tener como la maximo la siguiente forma: 9999999999.999999\n”; salida += “tambien puede ser asi 9999999999.\n\n”; salida += “4) Esta aplicacion tiene 6 cifras significativas, por lo tanto los resultados son con 6 digitos como decimales\n\n”; salida += “5) El programa puede recibir digitos con 6 digitos como decimales, si tiene mas marcara una esepcion.\n”; J Option Pane.showMessageDialog( null, salida, “Ayuda”, J Option Pane.INFORMATION_MESSAGE ); } } ); contenedor.add( ayudaBoton ); //Configuracion ventana setSize( 520,510 ); setVisible( true ); setResizable( false ); }//Fin contructor //Funcion que evalua Pn( x ) // pn( xn ) = A/B * E ala -x private Big Decimal PN( Big Decimal x ) { Big Decimal xTmp; Big Decimal division; Big Decimal resultado; Big Decimal eAlaX; double x2; division = new Big Decimal( 0 ); division = division.setScale( 10,division.ROUND_HALF_DOWN ); division = A.divide( B, division.ROUND_HALF_DOWN ); xTmp = x.negate( ); xTmp = xTmp.setScale( 10,xTmp.ROUND_HALF_DOWN ); x2 = xTmp.doubleValue(); eAlaX = new Big Decimal( Math.exp( x2 ) ); eAlaX = eAlaX.setScale( 10,eAlaX.ROUND_HALF_DOWN ); resultado = division.multiply( eAlaX ); resultado = resultado.setScale( 10,resultado.ROUND_HALF_DOWN ); resultado = resultado.negate(); return resultado; }//fin PN() // pn -( ( pn+1 - pn )ALA2) / (pn+2 - pn+1 + pn ) ) private Big Decimal QN() { Big Decimal resultado = new Big Decimal( 0 ); //Parte 1 Big Decimal resta = pnMas1.subtract( pn ) ; resta = resta.pow( 2 ); //Parte 2 Big Decimal suma = pnMas2.subtract( pnMas1 ); suma = suma.add( pn ); //Division Big Decimal division = new Big Decimal( 0 ); division = resta.divide( suma, division.ROUND_HALF_DOWN ); resultado = pn.subtract( division ); return resultado; } //Funcion ke calcla la tolerancia. .5 X 10 a la -n private Big Decimal calculaTolerancia( final int n ) { double valor = .5 * Math.pow( 10,−1 * n ); Big Decimal t = new Big Decimal( valor ); return t; }//Fin funcion calcularTolerancia() //Funcion que permite validar la entrada, devueve un false en caso de un error private boolean validaEntrada( ) { boolean validos = true; //Leer datos de las campos de la ventana. String x0Cadena, datoTolCadena, aCadena, bCadena; x0Cadena = x0Campo.getText(); datoTolCadena = datoTolCampo.getText(); aCadena = aCampo.getText(); bCadena = bCampo.getText(); //VALIDAR ENTRADA DE DATOS if( setX0( x0Cadena ) == false ) { validos = false; J Option Pane.showMessageDialog( null, “X0 contiene dato invalido!!”, “ERROR”, J Option Pane.ERROR_MESSAGE ); } if( setDatoTol( datoTolCadena ) == false ) { validos = false; J Option Pane.showMessageDialog( null, “Tolerancia contiene dato invalido!!”, “ERROR”, J Option Pane.ERROR_MESSAGE ); } if( setA( aCadena ) == false ) { validos = false; J Option Pane.showMessageDialog( null, “A contiene dato invalido!!”, “ERROR”, J Option Pane.ERROR_MESSAGE ); } if( setB( bCadena ) == false ) { validos = false; J Option Pane.showMessageDialog( null, “B contiene dato invalido!!”, “ERROR”, J Option Pane.ERROR_MESSAGE ); } return validos; }//Fin de funcion validaEntrada() //Funcion que valida el X0. EJEMPLO: 99, .99 99 99 99 99 private boolean setX0( String dato ) { boolean valido = true; //Validar x0 //valida ke sea un expresion de punto flotante 9999999999.999999 if( !( dato.matches( “\\d{1,1}[.]\\d{1,10}”) ) ) //Valida ke sean puros digitos. 9999999999 if( !( dato.matches( “\\d{1,1}”) ) ) valido = false; return valido; }//Fin funcion setX0() //Funcion que valida el exponente de la .5 X 10 a la n sea valido. EJEMPLO: 1 a 5 private boolean setDatoTol( String dato ) { boolean valido = true; //Validar x0 //Valida ke sean puros digitos. 9 if( !( dato.matches( “\\d{1,1}”) ) ) valido = false; return valido; }//setDatoTol() //Funcion que valida el a. EJEMPLO: 999, −999, 999.99 99 99 99 99, −999.99 99 99 99 99 private boolean setA( String dato ) { boolean valido = false; //Validar x0 //Valida +999 if( dato.matches( “\\[+]d{1,3}”) ) valido = true; else //Valida −999 if( dato.matches( “\\[-]d{1,3}”) ) valido = true; else //Valida ke sean puros digitos. 999 if( dato.matches( “\\d{1,3}”) ) valido = true; else //Valida +999.99 99 99 99 99 if( dato.matches( “\\[+]d{1,3}[.]//d{1,10}”) ) valido = true; else //Valida −999.99 99 99 99 99 if( dato.matches( “\\[-]d{1,3}[.]//d{1,10}”) ) valido = true; else //valida ke sea un expresion de punto flotante 999.99 99 99 99 99 if( dato.matches( “\\d{1,3}[.]\\d{1,10}”)) valido = true; return valido; }//Fin funcion setA() private boolean setB( String dato ) { boolean valido = false; //Validar x0 //Valida +999 if( dato.matches( “\\[+]d{1,3}”) ) valido = true; else //Valida −999 if( dato.matches( “\\[-]d{1,3}”) ) valido = true; else //Valida ke sean puros digitos. 999 if( dato.matches( “\\d{1,3}”) ) valido = true; else //Valida +999.99 99 99 99 99 if( dato.matches( “\\[+]d{1,3}[.]//d{1,10}”) ) valido = true; else //Valida −999.99 99 99 99 99 if( dato.matches( “\\[-]d{1,3}[.]//d{1,10}”) ) valido = true; else //valida ke sea un expresion de punto flotante 999.99 99 99 99 99 if( dato.matches( “\\d{1,3}[.]\\d{1,10}”)) valido = true; //Validar que sea diferente de 0 if( valido == true ) { double datoTmp = Double.parseDouble( dato ); if( datoTmp == 0 ) { System.out.println( “B es zero “ ); valido = false; } } return valido; }//Fin funcion setB() public static void main( String args[] ) { Aitken aplicacion = new Aitken(); aplicacion.setDefaultCloseOperation( J Frame.EXIT_ON_CLOSE ); } }//Fin de la clase