Está en la página 1de 12

VALOR DE UNA FUNCION MATEMATICA EN JAVA

Para trabajos de programacin aplicada, como por ejemplo para clculos numricos, aveces hacemos uso de funciones matematicas, ya sean lineales, cuadrticas, cubicas, trigonomtricas etc. Y nos encontramos en la necesidad de poder analizar en valor de una funcin especifica, en el caso de ser una solo funcin no habra problemas, pero en el caso de ser cualquier funcin nos encontramos en la necesidad de quizs expresar la funcin de la forma mas conocida, como por ejemplo para funciones cuatraticas la podramos escribir del siguiente modo:
'

yf(x)=ax2+bx+c En un programa la escribiramos del siguiente modo Yf(x)=ax ^2+bx+c O bien para una funcin trigonomtrica Yf(x)=sen(ax ^2)+bx+tan c

Para escribirlas de ese modo necesitamos una clase o algo parecido, que nos pueda aceptar tal expresin y poder calcular el valor de la funcin segn el valor de x que le demos. En este post se describir una clase que hace tal tarea, osea podemos eviarle a la clase una expresin como la anterior, con un valor de x, y que la misma me realice el calculo. El cdigo a continuacin es el cdigo de la clase Funcion

package funciones; import import import import import import /** * java.util.ArrayList; java.util.regex.Matcher; java.util.regex.Pattern; javax.script.ScriptEngine; javax.script.ScriptEngineManager; javax.script.ScriptException;

* @author RAFAEL */ public class Funcion { private String operacion; private String resultadoConversion; private String resultadoOperacion; private int indiceIni; private int indiceFin; private String valor; public Funcion() { } public String evaluar( String operacion, String valor){ this.operacion=operacion; this.valor=valor; this.resultadoConversion=analizaCadena(this.operacion); this.resultadoConversion=reemplazaOperacionJS(this.resultadoConversion); return this.resultadoOperacion=calculo(this.resultadoConversion); } private String analizaCadena(String cadena){ cadena=cadena.replaceAll("x", this.valor); cadena=quitarEspacios(cadena); cadena="-"+cadena; char[] vectorCadena=cadena.toCharArray(); if(cadena.contains("^")){ cadena=reemplazaPotencia(vectorCadena, cadena); } vectorCadena=cadena.toCharArray(); if(cadena.contains("cos")){ cadena=reemplazaTrigonometrica(vectorCadena, cadena, ".co",'c'); } vectorCadena=cadena.toCharArray(); if(cadena.contains("sen")){ cadena=reemplazaTrigonometrica(vectorCadena, cadena, ".si",'s'); } vectorCadena=cadena.toCharArray(); if(cadena.contains("tan")){ cadena=reemplazaTrigonometrica(vectorCadena, cadena, ".ta",'t'); } return cadena; } private String reemplazaParIzq(char[] cadena,int indice){ ArrayList<Character> lista1=new ArrayList<Character>(); ArrayList<Character> lista2=new ArrayList<Character>(); String res=""; int i; for ( i = indice-1; i >=0; i--) { if(cadena[i]==')'){ lista1.add(cadena[i]); } else { if(cadena[i]=='('){ lista2.add(cadena[i]); } } res+=cadena[i]; if((lista1.size()==lista2.size())&&(i!=(indice-1))){ this.indiceIni=i; return invertir(res); }

} return null; } private String reemplazaParDer(char[] cadena,int indice ){ ArrayList<Character> lista1=new ArrayList<Character>(); ArrayList<Character> lista2=new ArrayList<Character>(); String res=""; int i; for ( i = indice+1; i <cadena.length ; i++) { if(cadena[i]=='('){ lista1.add(cadena[i]); } else { if(cadena[i]==')'){ lista2.add(cadena[i]); } } res+=cadena[i]; if((lista1.size()==lista2.size())&&(i!=(indice+1))){ this.indiceFin=i+1; return res; } } return null; } private String reemplazaNumIzq(char[] cadena,int indice){ Pattern exp= Pattern.compile("\\\\d|\\\\."); Matcher expReg; String resultadoBase =""; String res = ""; for (int i = indice-1; i >=0; i--) { res=""; res+=cadena[i]; expReg=exp.matcher(res); if (expReg.find()){ resultadoBase+=cadena[i]; this.indiceIni=i; } else { break; } } return invertir(resultadoBase); } private String reemplazaNumDer(char[] cadena,int indice){ Pattern exp= Pattern.compile("\\\\d|\\\\."); Matcher expReg; String resultadoBase =""; String res = ""; for (int i = indice+1; i<cadena.length; i++) { res=""; res+=cadena[i]; expReg=exp.matcher(res); if (expReg.find()){ resultadoBase+=cadena[i]; this.indiceFin=i+1; } else { break; }

} return resultadoBase; } private String invertir(String cadena){ char[] vector=cadena.toCharArray(); String res=""; for (int i = vector.length-1; i >=0; i--) { res+=vector[i]; } return res; } private String reemplazaPotencia(char[] vectorCadena,String cadena){ String resIzq="",resDer=""; for (int indice = 0; indice < vectorCadena.length; indice++) { if (vectorCadena[indice]=='^') { if (vectorCadena[indice - 1] == ')') { resIzq =reemplazaParIzq(vectorCadena, indice); } else{ resIzq =reemplazaNumIzq(vectorCadena, indice); } if (vectorCadena[indice + 1] == '(') { resDer =reemplazaParDer(vectorCadena, indice); } else{ resDer =reemplazaNumDer(vectorCadena, indice); } vectorCadena=(cadena.substring(0,this.indiceIni)+".po(" +resIzq+","+resDer+")"+(cadena.substring(this.indiceFin,cadena.length()))).toCha rArray(); cadena=(cadena.substring(0,this.indiceIni)+".po(" +resIzq+","+resDer+")"+(cadena.substring(this.indiceFin,cadena.length()))); indice=0; } } return cadena; } private String reemplazaTrigonometrica(char[] vectorCadena,Stringcadena,String op eracion,char caracter){ String resDer=""; for (int indice = 0; indice < vectorCadena.length; indice++) { if((vectorCadena[indice]==caracter)&&((vectorCadena)[indice1]!='.')&&(indice!=0)){ if (vectorCadena[indice + 3] == '(') { resDer =reemplazaParDer(vectorCadena, indice+2); } else{ resDer =reemplazaNumDer(vectorCadena, indice+2); } vectorCadena=(cadena.substring(0,indice)+operacion+"(" +resDer+")"+(cadena.substring(this.indiceFin,cadena.length()))).toCharArray(); cadena=(cadena.substring(0,indice)+operacion+"(" +resDer+")"+(cadena.substring(this.indiceFin,cadena.length())) ); indice=0; } }

return cadena; } public String getResultadoConversion() { return this.resultadoConversion; } public String getResultadoOperacion() { return resultadoOperacion; } private String quitarEspacios(String sTexto){ String sCadenaSinBlancos=""; for (int x=0; x < sTexto.length(); x++) { if (sTexto.charAt(x) != ' ') sCadenaSinBlancos += sTexto.charAt(x); } return sCadenaSinBlancos; } private String reemplazaOperacionJS(String operacion){ this.resultadoConversion=operacion.replaceAll(".po","Math.pow"); this.resultadoConversion=this.resultadoConversion.replaceAll(".co","Math.cos"); this.resultadoConversion=this.resultadoConversion.replaceAll(".si","Math.sin"); this.resultadoConversion=this.resultadoConversion.replaceAll(".ta","Math.tan"); return this.resultadoConversion.substring(1,this.resultadoConversion.length()); } private String calculo(String cadena) { ScriptEngineManager script = new ScriptEngineManager(); ScriptEngine js = script.getEngineByName("JavaScript"); try{ return js.eval(cadena).toString(); }catch(Exception e){ return e.toString(); } } }

Procederemos a explicar sencillamente y grandes rasgos lo que hace cada mtodo :

public String evaluar( String operacion, String valor)

Mtodo que evalua la cadena "operacion" que contiene la funcion a analizar con el valor "valor", este al igual que el metodo acceso de la propiedad resultado

"getResultado" nos devuelve el valor de la funcion matematica expresada en "operacion"

private String analizaCadena(String cadena)

Mtodo que me analiza la cadea recibida del constructor, en este se evalua el contenido de la misma, es decir si existe una potencia, o una funcin trigonomtrica.

private String reemplazaParIzq(char[] cadena,int indice)

Recibe un array conteniendo la operacin y a partir del ndice recibido de evalua hasta donde es el alcance de la operacin contenida dentro de los parentesis. Es decir si recibe una array conteniendo (sen (1)-2+3) ^8 devuelve (sen(1)2+3)

private String reemplazaParDer(char[] cadena,int indice )

Igual a la anterior pero evalua el alcance pero por la derecha, es decir en una potencia devuelve el exponente.

private String reemplazaNumIzq(char[] cadena,int indice)

En el caso de no haber parntesis, evalua el alcance pero de los nmeros que contiene la operacin, por ejemplo si la operacin es 233.4^8 devuelve 233.4

private String reemplazaNumDer(char[] cadena,int indice)

Igual a la anterior pero devuelve el alcance de la operacin por la derecha.

private String invertir(String cadena)

invierte una cadena.

private String reemplazaPotencia(char[] vectorCadena,String cadena)

Si existe una potencia, este mtodo es el indicado para realizar la conversin,es decir Si en la cadena existe 233.4^8 lo reemplaza por .po(233.4,8) para ser evaluada luego.

private String reemplazaTrigonometrica(char[] vectorCadena,String cadena,String operacion,char caracter)

Reemplaza las funciones trigonomtricas, es decir si en la operacin llega sen (3), la reemplaza por .si(3), para luego ser evaluada.

private String quitarEspacios(String sTexto)

Quita espacios en blanco.

private String reemplazaOperacionJS(String operacion)

para este caso Utilizamos la libreria de JavaScript incorporada en java, asi que reemplazamos para que este lenguaje la pueda analizar, como ser si viene en la cadena .si (3), lo reemplazamos por Math.sin(3)

private String calculo(String cadena)

una vez analizada toda la cadena, se procede con este metodo a realizar el calculo, para ello hacemos uso de javascript (ver este post para mas informacion). La sintaxis para utilizar esta clase es la siguiente

Ahora crearemos un proyecto Java en Netbeans,y en nuestro Main incluimos las siguientes lneas para probar las funciones escritas anteriormente. En todos los ejemplos observamos que instanciamos la clase Funcion, llamamos el metodo evaluar, y luego mostramos por la salida estndar la conversin que realiza la clase y el valor de la funcin. El constructor es inicializado, con la cadena que contiene la operacin, mas el valor que le vamos a dar al valor de x. Probamos la potencia
import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="3^x+32+4^(2+x)";// Funcion f=new Funcion(); f.evaluar(cadena, "2"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion());

} }

El resultado es

Probamos la raz

import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="x^(1/2)"; Funcion f=new Funcion(); f.evaluar(cadena, "144"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion()); System.out.println(Math.cos(1)); } }

La salida es

Probamos las trigonomtricas

import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="sen(34*2)+tan x"; Funcion f=new Funcion(); f.evaluar(cadena, "1"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion()); System.out.println(Math.cos(1)); } }

La salida es

Probamos una mezcla de las anteriores

import javax.script.ScriptException; public class Main { public static void main(String[] args) throws ScriptException { String cadena="sen (34*x)+tan 1+32+x^(2+4-cos 3)"; Funcion f=new Funcion(); f.evaluar(cadena, "1.5"); System.out.println(f.getResultadoConversion()); System.out.println(f.getResultadoOperacion()); System.out.println(Math.cos(1)); } }

El resultado obtenido

Bien con esto terminamos, vimos la clase Funcion que nos puede resolver problemas que nos pueden aparecer como mencionamos en los mtodos numricos hasta pronto

'