package gov.nasa.ial.mde.solver; import java.util.ArrayList; import gov.nasa.ial.mde.math.IntervalXY; import gov.nasa.ial.mde.solver.classifier.TrigClassifier; import gov.nasa.ial.mde.solver.features.individual.AsymptoteFeature; import gov.nasa.ial.mde.solver.features.individual.FrequencyFeature; import gov.nasa.ial.mde.solver.features.individual.OffsetFeature; import gov.nasa.ial.mde.solver.features.individual.PeriodFeature; import gov.nasa.ial.mde.solver.symbolic.AnalyzedEquation; import gov.nasa.ial.mde.util.MathUtil; @SuppressWarnings("all") public class SolvedTangentFunction extends SolvedTrigFunction implements PeriodFeature, OffsetFeature, AsymptoteFeature{ protected String[] newFeatures = {"frequency", "phase", "offset", "shift", "period", "orientation", "asymptotes", "rate"}; protected TrigClassifier TC; public SolvedTangentFunction(AnalyzedEquation analyzedEquation) { super(analyzedEquation, "tangent function"); double A = 1; double B = Double.NaN; double C = Double.NaN; double D = 0; double phase = Double.NaN; double offset = Double.NaN; String baseAsymptote = ""; String period = ""; String frequency = ""; double amplitude = Double.NaN; String orientation = "WARRRGL!"; String interval= ""; String domain = ""; // domain IntervalXY range = null; // Range // TODO improve the spliting String getCoeff = "y=(-?\\d*[\\./]?\\d*)\\*tan\\([^)\\n]*\\)([\\+-]\\d*[\\./]?\\d*)?"; String insideTAN = "tan\\(([^)\\n]*)\\)"; String getOffset = "tan\\([^)\\n]*\\)([\\+\\-]\\d*[\\./]?\\d*)"; TC = (TrigClassifier) analyzedEquation.getClassifier(); String equat = analyzedEquation.getInputEquation(); //System.out.println(equat); equat = equat.trim(); equat = equat.replaceAll("-tan", "-1*tan"); //System.out.println(equat); String innerEquat = equat.replaceAll(insideTAN, "____$1____"); //System.out.println(" Tan: " + innerEquat); innerEquat = "y= " + innerEquat.split("____")[1]; //System.out.println(" Tan: " + innerEquat); Solver solver = new Solver(); solver.add(innerEquat); solver.solve(); Solution solution = solver.get(0); SolvedGraph features = solution.getFeatures(); if(features instanceof SolvedLine) { String coeff = equat.replaceAll(getCoeff, "____$1____"); //System.out.println(" Coeff: " + coeff); if(coeff.contains("____")){ coeff= coeff.split("____")[1]; if(coeff.contains("/")){ String[] fraction= coeff.split("/"); A = Double.valueOf(fraction[0])/Double.valueOf(fraction[1]); }else{ A = Double.valueOf(coeff); } } //B affects the period //B = 1 creates asymptotes at -pi/2 and pi/2 //B = pi creates asymptotes at -.5 and .5 B = ((SolvedLine) features).getSlope(); C = ((SolvedLine) features).getYIntercept(); String offsetString = equat.replaceAll(getOffset, "____$1____"); //System.out.println(" Offset: " + offsetString); if(offsetString.contains("____")){ offsetString = offsetString.split("____")[1]; if(offsetString.contains("/")){ String[] fraction= offsetString.split("/"); D = Double.valueOf(fraction[0])/Double.valueOf(fraction[1]); }else{ D = Double.valueOf(offsetString); } } /* System.out.println(" A: " + A); System.out.println(" B: " + B); System.out.println(" C: " + C); System.out.println(" D: " + D); */ //System.out.println(" Offset: " + offsetString); if(Math.signum(A*B)==1){ orientation = "ascending"; } else if(Math.signum(A*B)==-1){ orientation = "decending"; } else{ orientation = "0"; } offset = D; //pi/B //TODO: need some better formatting for PI in B period = calculatePeriod(B); //period = (Math.round((Math.abs(1.0/B)*100))/100.0) + "pi"; //frequency = (Math.round((Math.abs((B)*100)))/100.0) +"/pi"; //String asmptoteEquation= Math.PI*B; baseAsymptote = MathUtil.trimDouble(((2*B) - C/B), -1) +""; domain = "x for all real numbers except for where we encounter vertical asymptotes"; range = new IntervalXY(analyzedEq.getActualVariables()[1], Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); putNewFeatures(newFeatures); putFeature("offset", offset + ""); putFeature("orientation", orientation); putFeature("period", period); putFeature("asymptotes", baseAsymptote); putFeature("rate",A+""); putFeature("domain", domain); putFeature("range", range); } } private String calculatePeriod(double coeff) { if(this.isMultipleOfPi(coeff)){ double ret = coeff/3.142; //TODO formating if(ret==1.0){ return "1"; } MathUtil.trimDouble(ret, -1); return "1/"+ret; }else{ if(coeff==1.0){ return "pi"; } return "pi/"+ coeff; } } public String getPeriod() { Object value = this.getValue(PeriodFeature.PATH, PeriodFeature.KEY); String periodString = (String)value; System.out.println("Getting period.\nPeriod is : " + periodString); return periodString; } public double getOffset() { Object value = this.getValue(OffsetFeature.PATH, OffsetFeature.KEY); Double doubleValue = new Double((String)value); System.out.println("Getting Offset.\nOffset is : " + doubleValue); return doubleValue; } public String[] getAsymptotes() { Object values = this.getValues(AsymptoteFeature.PATH, AsymptoteFeature.KEY); ArrayList list = (ArrayList)values; System.out.println("The size of the returned array is"+list.size()); String[] asymptotes = new String[list.size()]; for(int i=0;i<list.size();i++) { System.out.println(list.get(i)); asymptotes[i]=(String) list.get(i); } return asymptotes; } }