some image

Tag Matematicas

Raíz cuadrada Newton – Raphson en Java con Bigdecimal

Etiquetas: , Blog, Programación No comments

Este Post esta dedicado a Phicar y Voodoo, quienes fueron los que implantaron el origen de la duda la cual me ha llevado a pensar en esta posible implementación del método :).

1) ¿Qué es el método de Newton – Raphson?

Según la wiki : En análisis numérico, el método de Newton (conocido también como el método de Newton-Raphson o el método de Newton-Fourier) es un algoritmo eficiente para encontrar aproximaciones de los ceros o raíces de una función real. También puede ser usado para encontrar el máximo o mínimo de una función, encontrando los ceros de su primera derivada.

En este enlace, podrán encontrar una demostración bastante buena sobre las deficiencias y ventajas del método, así como su implementación matemática.

2) ¿Porqué utilizar el método de Newton – Raphson para obtener la raiz cuadrada?

a) Para realizar la demostración de método numérico planteado.
b) Porqué para operar con BigDecimal no existe un método implementado para obtener raíz cuadrada (sqrt).
c) Porqué puede ser muy útil en las maratones de programación.
d) Para jugar un rato con la programación y las matemáticas.

3) Código

/**
 * Esta clase muestra un ejemplo del como obtener una raiz cuadrada, basandose
 * en el metodo de NewtonRaphson. La implementacion de este numero  
 * @author codesandtags
 * 
 *         Explicacion del metodo NewtonRaphson Referencias :
 *         http://es.scribd.com/doc/15638680/Metodo-de-NewtonRaphson
 * 
 */
public class NewtonRaphsonBigDecimal {

	public static void main(String[] args) throws IOException {

		// Objeto para lectura por teclado
		BufferedReader input = new BufferedReader(new InputStreamReader(
				System.in));
		// Variables
		double numero = 0.0;
		String numeroBig = null;
		int precision = 0;

		// Instancia a la clase
		NewtonRaphsonBigDecimal resultado = new NewtonRaphsonBigDecimal();

		System.out.println(" ------ Calculando raices double -------");
		// Numero a calcular
		System.out.print("\nIngrese numero : ");
		numero = Double.parseDouble(input.readLine());
		// Precision de la raiz
		System.out.print("Ingrese precision : ");
		precision = Integer.parseInt(input.readLine());

		// Se obtiene la raiz
		System.out.println("Raiz : " + resultado.getRaiz(numero, precision));

		// Haciendo magia con 5 numeros aleatorios
		for (int i = 0; i < 5; i++) {
			numero = Math.floor(Math.random() * 500);
			precision = (int) Math.floor(Math.random() * 15 + 1);
			System.out
					.println("Raiz : " + resultado.getRaiz(numero, precision));
		}

		System.out
				.println("\n ------ Calculando raices double BigDecimal -------");
		// Numero a calcular
		System.out.print("\nIngrese numero gigante : ");
		numeroBig = input.readLine();
		// Precision de la raiz
		System.out.print("Ingrese precision : ");
		precision = Integer.parseInt(input.readLine());

		// Se obtiene la raiz
		System.out.println("Raiz : "
				+ resultado.getRaizBigDecimal(numeroBig, precision));

	}

	/**
	 * Obtiene una raiz con el metodo de Newton - Raphson, teniendo en cuenta la
	 * precision de la raiz a obtener
	 * 
	 * Formula = raiz - (raiz^2 - numero) / (2 * raiz)
	 * 
	 * @param numero
	 * @param precision
	 * @return
	 */
	public double getRaiz(double numero, int precision) {
		System.out.println("\nObteniendo raiz cuadrada para el numero [" + numero
				+ "] y precision + [" + precision + "]");
		if (numero <= 0) {
			System.err.println("ERROR : No se puede obtener raices negativas");
			return 0;
		}

		double raiz = 1;
		for (int i = 0; i < precision; i++) {
			raiz = raiz - (Math.pow(raiz, 2) - numero) / (2 * raiz);
		}

		return raiz;
	}

	/**
	 * Obtiene una raiz con el metodo de Newton - Raphson para numberos
	 * BigDecimal, teniendo en cuenta la precision de la raiz a obtener
	 * 
	 * Formula = raiz - (raiz^2 - numero) / (2 * raiz)
	 * 
	 * @param numero
	 * @param precision
	 * @return
	 */
	public String getRaizBigDecimal(String numero, int precision) {
		System.out.println("\nObteniendo raiz cuadrada Bigdecimal para el numero ["
				+ numero + "] y precision + [" + precision + "]");

		BigDecimal bigNumero = new BigDecimal(numero);
		BigDecimal raiz = BigDecimal.ONE;
		BigDecimal raizTemp = null;

		if (bigNumero.compareTo(BigDecimal.ZERO) < 1) {
			System.err.println("ERROR : No se puede obtener raices negativas");
			return "0";
		}

		for (int i = 0; i < precision; i++) {
			// Se guarda el valor temporal de la raiz para operar mas adelante
			raizTemp = raiz;

			// Factor a = (raiz^2 - 2)
			raiz = raiz.pow(2).subtract(bigNumero);
			// Factor b = Factor a / (2 * raiz)
			// Aqui se utiliza RoundingMode.HALF_UP, para evitar valores
			// infinitos y la excepcion generada en tiempo de ejecucion
			// "Non-terminating decimal expansion no exact representable
			// decimal result" y 10 decimales
			raiz = raiz.divide(raizTemp.multiply(BigDecimal.valueOf(2)), 10,
					RoundingMode.HALF_UP);
			// raiz - Factor b
			raiz = raizTemp.subtract(raiz);
		}

		return raiz.toString();
	}

}

4) Salida

 ------ Calculando raices double -------

Ingrese numero : 85296325874125896325874125896465
Ingrese precision : 100

Obteniendo raiz cuadrada para el numero [8.52963258741259E31] y precision + [100]
Raiz : 9.235601002323882E15

Obteniendo raiz cuadrada para el numero [427.0] y precision + [6]
Raiz : 20.748088791061598

Obteniendo raiz cuadrada para el numero [181.0] y precision + [12]
Raiz : 13.45362404707371

Obteniendo raiz cuadrada para el numero [138.0] y precision + [7]
Raiz : 11.747340132123018

Obteniendo raiz cuadrada para el numero [177.0] y precision + [15]
Raiz : 13.30413469565007

Obteniendo raiz cuadrada para el numero [194.0] y precision + [12]
Raiz : 13.92838827718412

 ------ Calculando raices double BigDecimal -------

Ingrese numero gigante : 852963258741258963258741258964658529632587412589632587412589646565465456465464
Ingrese precision : 250

Obteniendo raiz cuadrada Bigdecimal para el numero [852963258741258963258741258964658529632587412589632587412589646565465456465464] y precision + [250]
Raiz : 923560100232388213395499100296508317192.4280825418

Solucionando Método de Bisección en Java

Etiquetas: , Blog, Programación No comments

Bueno, estos días he estado estudiando algo de análisis numéricos / Métodos numéricos y me dio por investigar un poco más sobre el método de bisección y llevarlo a un lenguaje de programación (En este caso Java). Luego de investigar y ver varios videos para compender mejor la secuencia de pasos llegue a este codigo :).

Video : Explicacion Metodo Bisección

Codigo : 

Lo único que se debería cambiar en el método para utilizarlo, sería la implementación de la función. En este caso para aplicar los conceptos de programación, decidí utilizar una interface la cuál sera la encargada de obligar a nuestra clase a implementar la función.
Interface :

public interface Funcion {
	public double funcion(double x);
}

Clase :

public class MetodoBiseccion implements Funcion {

	private double a;
	private double b;
	private int iteraciones;
	private double error;

	public static void main(String[] args) {

		// Instanciacion y configuracion de nuestro ejercicio
		MetodoBiseccion biseccion = new MetodoBiseccion();
		biseccion.setIntervalo(0, 1);
		biseccion.setIteraciones(6);
		biseccion.setError(10e-4);
		biseccion.solucion();

	}

	@Override
	public double funcion(double x) {
		double resultado = Math.pow((Math.E), x) - (3 * x);
		return resultado;
	}

	/**
	 * Solucion del Metodo de Biseccion
	 */
	public void solucion() {
		System.out.println("Intervalo : [" + a + ", " + b + "]");
		System.out.println("Error : " + error);
		System.out.println("Iteraciones : " + iteraciones);
		System.out
				.println("------------------------------------------------ \n");

		double c = 0;
		double fa = 0;
		double fb = 0;
		double fc = 0;
		int iteracion = 1;

		do {
			// Aqui esta la magia
			c = (a + b) / 2;

			System.out.println("Iteracion (" + iteracion + ") : " + c);
			fa = funcion(a);
			fb = funcion(b);
			fc = funcion(c);

			if (fc * fa < 0) {
				b = c;
				fa = funcion(a);
				fb = funcion(b);
				c = (a + b) / 2;
				fc = funcion(c);
			} else {
				a = c;
				fa = funcion(a);
				fb = funcion(b);
				c = (a + b) / 2;
				fc = funcion(c);
			}
			iteracion++;
			// Itera mientras se cumpla la cantidad de iteraciones establecidas
			// y la funcion se mantenga dentro del margen de error
		} while (iteracion <= iteraciones && Math.abs(fc) >= error);

	}

	/**
	 * Definicion del intervalo
	 * 
	 * @param a
	 * @param b
	 */
	public void setIntervalo(double a, double b) {
		this.a = a;
		this.b = b;
	}

	/**
	 * Definicion de las iteraciones
	 * 
	 * @param iteraciones
	 */
	public void setIteraciones(int iteraciones) {
		this.iteraciones = iteraciones;
	}

	/**
	 * Definicion del margen de error
	 * 
	 * @param error
	 */
	public void setError(double error) {
		this.error = error;
	}

}

 

Pruebas  : 

Intervalo : [0.0, 1.0]
Error : 0.0010
Iteraciones : 6
------------------------------------------------ 

Iteracion (1) : 0.5
Iteracion (2) : 0.75
Iteracion (3) : 0.625
Iteracion (4) : 0.5625
Iteracion (5) : 0.59375
Iteracion (6) : 0.609375

Hallar Raíz Cuadrada de un número y validarlo

Etiquetas: , Blog, Programación No comments

Este sencillo ejemplo muestra la forma de obtener la raíz cuadrada de un numero dado, validando que el numero ingresado no sea negativo ya que corresponde a una raíz imaginaria. El ingreso de los datos es través de teclado.

Código

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Leer un numero y si es positivo hallar su raíz cuadrada, de lo contrario
 * escribir raíz imaginaria.
 *
 * @author codesandtags
 */
public class RaizCuadrada {

	public static void main(String[] args) throws IOException {

		// Objeto para lectura de datos por teclado
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// Instanciacion de la clase
		RaizCuadrada raiz = new RaizCuadrada();
		int numero = 1;

		System.out
				.println("Nota : Para terminar la ejecucion del programa pulse el numero 0. \n\n");
		// Llamado al metodo que halla la raiz
		while (numero != 0) {
			System.out.print("Ingrese numero : ");
			numero = Integer.parseInt(br.readLine());
			System.out.println("Raiz : " + raiz.hallarRaizCuadrada(numero));
		}

	}

	/**
	 * Obtiene la raiz cuadrada de un numero especificado, en caso de que el
	 * numero sea negativo mostrar la palabra ERROR ya que las raices cuadradas
	 * negativas son imaginarias
	 *
	 * @param numero
	 * @return
	 */
	public double hallarRaizCuadrada(int numero) {
		double respuesta = 0;
		if (numero < 0) {
			System.err.println("ERROR : Raiz Imaginaria");
			return 0;
		} else {
			respuesta = Math.sqrt(numero);
		}
		return respuesta;
	}
}

Salida

Nota : Para terminar la ejecucion del programa pulse el numero 0. 

Ingrese numero : 20
Raiz : 4.47213595499958
Ingrese numero : -27
Raiz : 0.0
Ingrese numero : ERROR : Raiz Imaginaria
27
Raiz : 5.196152422706632
Ingrese numero : 9
Raiz : 3.0
Ingrese numero : 0
Raiz : 0.0

Implementación del método Newton Raphson para hallar raices

Obtener numero primo ordinal (th) con Java y BigInteger

Etiquetas: , Blog, Programación No comments

Este codigo muestra un ejemplo de como obtener un numero primero ordinal (th), utilizando el metodo nextProbablePrime de la clase BigInteger.

package org.codesandtags.rosecode;

import java.math.BigInteger;

/***
 * un número primo es un número natural mayor que 1 que tiene únicamente dos
 * divisores distintos: él mismo y el 1. Los números primos se contraponen así a
 * los compuestos, que son aquellos que tienen algún divisor natural aparte de
 * sí mismos y del 1. El número 1, por convenio, no se considera ni primo ni
 * compuesto. (Wikipedia).
 * 
 * Aunque existe diferentes formas de hallar los numeros primos en este codigo
 * muestra un ejemplo de como obtener los probables numeros primos utilizando
 * BigInteger. La implementacion es muy facil y por lo general es util para las
 * maratones de programacion y retos varios
 * 
 * @author Codes and Tags
 * 
 */
public class Problem1 {
	public static void main(String args[]) {
		// Instancia al objeto
		Problem1 solve = new Problem1();
		// Se obtienen varios numeros primos con el tiempo para el ejemplo
		solve.getNumberPrime(1);
		solve.getNumberPrime(2);
		solve.getNumberPrime(10000);
	}

	/***
	 * Obtiene el un numero primo ordinal dado. Por ejemplo el primer numero
	 * primo ordinal es el 2, el segundo es el 3, el 10000 es el 104729
	 * Adicionalmente muestra el tiempo consumido para encontrar el numero
	 * primo.
	 * 
	 * @return numero
	 */
	public void getNumberPrime(int numberth) {
		// Tiempo inicial del sistema en milisegundos
		long startTime = System.currentTimeMillis();
		// BigInteger para utilizar el metodo nextProbablePrime
		BigInteger number = BigInteger.ONE;
		// Se obtiene el numero th
		for (int i = 0; i < numberth; i++) {
			number = number.nextProbablePrime();
		}
		// Tiempo final del sistema en milisegundos
		long endTime = System.currentTimeMillis();
		// Se nuestra el resultado
		System.out.println(numberth + "th : " + number);
		System.out.println("Tiempo ms : " + (endTime - startTime));
	}
}

&nsbsp;
La salida obtenida por el programa seria como esta :
&nsbsp;

1th : 2
Tiempo ms : 3
2th : 3
Tiempo ms : 0
10000th : 104729
Tiempo ms : 4673