Hola para quienes quieran entender el programa comienza con una llamada Biseccion b=new Biseccion(0,1,0.01,20);
Donde los parámetros significan lo siguiente:
0 es el valor inferior inicial del intervalo de búsqueda (a)
1 es el valor superior inicial del intervalo de búsqueda (b)
0.01 es la tolerancia o desviación máxima admitida del resultado buscado (tol) (en este caso se da por bueno un resultado si está entre -0.01 y 0.01)
20 es el número de iteraciones permitidas (ni1)
A continuación se invoca double raiz=b.calcularRaiz();
En el método calcularRaiz se comienza calculando el punto medio del intervalo de búsqueda actual:
q=((b-a)/2);
Define un punto medio transitorio p = a+q
Si la imagen de p es 0 ó el intervalo q es menor que la tolerancia devuelve el valor del punto medio como resultado. Si el intervalo es menor que la tolerancia significa que tenemos el resultado dentro del intervalo, con una desviación del valor inferior a 0.01. Pero esta desviación no está referida al resultado de la función, sino al valor de x. Por tanto podría ocurrir que el valor de x estuviera muy próximo al valor que hace cero la función y sin embargo la función tener un valor superior a 0.01. Esto sería extraño porque en funciones continuas los límites izquierdo y derecho de la función cuando nos aproximamos al valor que hace cero la función son los valores inmediatos. No obstante podría no ocurrir así en determinados casos como funciones discontinuas o con asíntotas.
En resumen, aunque en este caso no te afecte al resultado creo que en vez de if(f(p,3)==0||q<tol) sería más correcto usar f(Math.abs(f(p,3))<tol){
Otro cambio que veo recomendable es modificar
int i=0;
while(i<ni){
Con estos cambios el código iría quedando así:
public class Biseccion {
double a,b,tol,p;
double matriz[][];
int k,j,ni;
public Biseccion(double a1, double b1, double tol1,int ni1){
a=a1;
b=b1;
tol=tol1;
ni=ni1;
this.matriz=new double[ni][5];
}
private double redondea(double n){
return Math.rint(n*1000000)/1000000;
}
private double f(double x,int opc){
double r;
switch(opc){
case 1:
r=Math.pow(x,3)+4*Math.pow(x,2)-10;
return r;
case 2:
r=Math.pow(x,3)-x-1;
return r;
case 3:
r=Math.pow(x,3)-7*Math.pow(x,2)+14*x-6;
return r;
default:
break;
}
return 0;
}
public double calcularRaiz(){
int i=0;
double p,q;
q=((b-a)/2);
p=(a+q);
while(i<ni){
matriz[i][0]= i;
matriz[i][1]=a;
matriz[i][2]=b;
matriz[i][3]=p;
matriz[i][4]=f(p,3);
//if(f(p,3)==0||q<tol){
if(Math.abs(f(p,3))<tol){
System.out.println("Proceso completado satisfactoriamente con "+f(p,3));
break;
}
else{
if(f(a,3)*f(p,3)>0)
a=p;
else
b=p;
q=redondea((b-a)/2);
p=redondea(a+q);
}
i++;
}
return p;
}
public double[][] getMatriz() {return matriz;}
}
Y el test:
//CLASE CON MÉTODO MAIN
public class PruebaBiseccion {
public static void main(String[] args) {
Biseccion b=new Biseccion(0,1,0.01,20);
double raiz=b.calcularRaiz();
System.out.println("La raíz es: "+raiz);
System.out.println("\n\n Matriz: \n");
for(double[] array : b.getMatriz()){
for(double numero:array)
System.out.print(numero+"\t");
System.out.println();
}
}
}
Ten en cuenta que los índices de i son 0, 1, 2, 3, ... y no 1, 2, 3, ...
Salu2