package com.ordobill.webapp.engine;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ordobill.webapp.beans.Modeling;
import com.ordobill.webapp.beans.Project;
import com.ordobill.webapp.beans.SampleBean;
import com.ordobill.webapp.beans.Sampleform;
import com.ordobill.webapp.beans.SimulationFields;
import com.ordobill.webapp.common.SqlMapClientManager;
import com.ordobill.webapp.economic.EconomicAnalysis;
public class SampleEngineImpl extends SimulationFields {
private Log log = LogFactory.getFactory().getInstance(this.getClass().getName());
private SqlMapClient sqlMap = SqlMapClientManager.getSqlMapClient();
private double sumF;
private ArrayList<SampleBean> saList;
private boolean modeCheck = false; // sa모드일경우 자동 수리 모드로 진입점
int saControl = 0;
int testNum = 0;
@SuppressWarnings("unused")
public Sampleform engineCore(Project project,ArrayList<SampleBean> figList,HashMap<String, SimulationFields[]> simulationArr) throws Exception {
long start = System.currentTimeMillis();
SampleBean samplebean = new SampleBean();
Sampleform sampleform = new Sampleform();
EconomicAnalysis _EconomicAnalysis = new EconomicAnalysis();
Modeling modeling = new Modeling();
sampleform.setLifeTime(project.getProLifeTime());
sampleform.setIteration(project.getProIterNum());
sampleform.setTd((float)project.getProTd());
sampleform.setLifeTime(project.getProLifeTime());
float[][] resultArr = null;
float[] totavaArr = null;
ArrayList<int[][]> breakList = new ArrayList<int[][]>();
float[] iterationArr = new float [sampleform.getIteration()];
String[][] stepAve = new String [2][figList.size()];
String[] stepFigName = new String [figList.size()];
sampleform.setIterationArr(new float [sampleform.getIteration()]);
sampleform.setYeartotRoof((int)sampleform.getTd()*24);
sampleform.setTotRoof((int)(sampleform.getYeartotRoof())*sampleform.getLifeTime());
boolean saTest = false;
saList = new ArrayList<SampleBean>();
sampleform.setFailState("flaring");
for (int k=0;k<sampleform.getIteration();k++) {
sumF = 0;
int[][] brakeArr = new int[3][figList.size()];
for (int i=0;i<brakeArr[0].length;i++) {
brakeArr[1][i] = figList.get(i).getFigUid();
}
resultArr = new float[figList.size()+1][(int)sampleform.getTotRoof()];
totavaArr = new float[sampleform.getLifeTime()];
sampleform.setYearAvailability(0f);
sampleform.setRepearState(true);
for (int i=0;i<figList.size();i++) {
saControl = 1;
sampleform.setStep(0f);
sampleform.setPresent(0f);
sampleform.setMaxMttf(figList.get(i).getFigMaxMttf()*8760f);
sampleform.setMinMttf(figList.get(i).getFigMinMttf()*8760f);
sampleform.setMostMttf(figList.get(i).getFigMostMttf()*8760f);
for (int s=0;s<sampleform.getTotRoof();s++){
//System.out.println(sampleform.getPresent());
if (sampleform.getPresent() <= s) {
this.computeHazardRate(sampleform,figList.get(i));
//System.out.println(sampleform.isGeneralState());
if (sampleform.isGeneralState()) { //정상
sampleform.setRepearState(true);
sampleform.setPresent(sampleform.getPresent()+24);
} else {//고장
brakeArr[0][i] = brakeArr[0][i] + 1;
if (figList.get(i).getFigMoType().equals("se")) {
//System.out.println(figList.get(i).getFigMoName());
sampleform.setRepearState(false);
//System.out.println("b:"+sampleform.getPresent());
sampleform.setPresent(sampleform.getPresent()+figList.get(i).getFigMttr());
//System.out.println("a:"+sampleform.getPresent());
} else if (sampleform.getFailState() == "flaring" && figList.get(i).getFigFlaring().floatValue() > 1) {
sampleform.setRepearState(true);
sampleform.setPresent(s+figList.get(i).getFigFlaring().floatValue());
sampleform.setFailState("mttr");
} else if (sampleform.getFailState() == "mttr" && figList.get(i).getFigFlaring().floatValue() > 1) {
sampleform.setRepearState(false);
sampleform.setImpRepair(figList.get(i).getFigMttr());
sampleform.setImpFailure(figList.get(i).getFigDelivery().floatValue());
sampleform.setPresent(sampleform.getPresent()+sampleform.getImpFailure()+sampleform.getImpRepair());
sampleform.setImpRepair(s+sampleform.getImpRepair());
sampleform.setFailState("flaring");
} else {
if (Integer.parseInt(figList.get(i).getFigFailureState()) == 1) { // 직렬일경우
sampleform.setRepearState(false);
sampleform.setImpRepair(figList.get(i).getFigMttr());
sampleform.setImpFailure(figList.get(i).getFigDelivery().floatValue());
sampleform.setPresent(sampleform.getPresent()+sampleform.getImpFailure()+sampleform.getImpRepair());
sampleform.setImpRepair(s+sampleform.getImpRepair());
} else if (Integer.parseInt(figList.get(i).getFigFailureState())> 1){ // 병렬일 경우
sampleform.setRepearState(true);
}
}
sampleform.setBreakpoint(sampleform.getPresent()); // 고장에서 정상으로 돌아올시점 기록
sumF = 0;
}
}
///////////////////////////////////////////////
if (sampleform.isRepearState()) {
sampleform.setAvailability(100f);
} else {
if (sampleform.getImpRepair()>s) { //delivery
sampleform.setAvailability(100f - (figList.get(i).getFigImpFailure().floatValue()*100f));
} else { //mttr
sampleform.setAvailability(100f - (figList.get(i).getFigImpRepair().floatValue()*100f));
}
}
resultArr[i][s] = sampleform.getAvailability();
sampleform.setStep(sampleform.getAvailability()+sampleform.getStep());
//log.debug(sampleform.getAvailability());
}
//stepFigName[i] = figList.get(i).getFigMoName();
stepAve[0][i] = figList.get(i).getFigMoName();
float val = (1-((sampleform.getTotRoof()-sampleform.getStep())/sampleform.getTotRoof()));
if (k == 0) {
stepAve[1][i] = Float.toString(val);
} else if(k == sampleform.getIteration()-1) {
stepAve[1][i] = Float.toString((val+Float.valueOf(stepAve[1][i]).floatValue())/sampleform.getIteration());
} else {
stepAve[1][i] = Float.toString(val+Float.valueOf(stepAve[1][i]).floatValue());
}
sampleform.setBreakpoint(0);
}
breakList.add(brakeArr);//장비별 고장횟수
//현재 다중 부품이 들어갈경우 하나라도 망가지면 시스템이 정지한다는 가정하에 가용성 계산(직렬)
for (int s=0;s<sampleform.getTotRoof();s++) {
for (int i=0;i<figList.size();i++) {
if (sampleform.getAvailability() > resultArr[i][s] || i == 0) {
sampleform.setAvailability(resultArr[i][s]);
}
}
resultArr[figList.size()][s] = sampleform.getAvailability();
sampleform.setYearAvailability(sampleform.getYearAvailability() + sampleform.getAvailability());
if (((s+1)%sampleform.getYeartotRoof()) == 0) {
int arrNum = (int) ((s+1)/sampleform.getYeartotRoof())-1;
sampleform.setYearAvailability(sampleform.getYearAvailability()/100f);
totavaArr[arrNum] = sampleform.getYearAvailability();
sampleform.setYearAvailability(0f);;
}
sampleform.setAvailability(0f);
}
//전체 가용율 계산
for (int i=0;i<totavaArr.length;i++) {
sampleform.setAvailability(sampleform.getAvailability() + totavaArr[i]);
}
float stdAva = (1-((sampleform.getTotRoof()-sampleform.getAvailability())/sampleform.getTotRoof()));
iterationArr[k] = stdAva;
sampleform.setAvailabilityAll(sampleform.getAvailabilityAll() + stdAva);
}
//sampleform.setStepFigName(stepFigName);
//장비별 망가진 횟수
/*for (int i=0;i<breakList.size();i++) {
//_EconomicAnalysis.
System.out.println(breakList.size());
for (int s=0;s<breakList.get(i)[0].length;s++) {
System.out.println(breakList.get(i)[0][s]);
}
}*/
sampleform.setStepAve(stepAve);
sampleform.setStepFigName(stepFigName);
sampleform.setBrakeArr(breakList);
sampleform.setResultArr(resultArr);//시간당 수치 or 마지막번지에는 eq 가용율
sampleform.setIterationArr(iterationArr);//iteration roof 당 가용율
sampleform.setYeartotRoof(sampleform.getYeartotRoof());//1년기준 총 루프 횟수
sampleform.setTotRoof((int)sampleform.getTotRoof());//Iteration 기준 총 루프 횟수
sampleform.setTotAvailability((sampleform.getAvailabilityAll()/sampleform.getIteration())*100);//총 총가용율
sampleform.setFmcont(figList.size()+1);
long end = System.currentTimeMillis();
log.debug( " testNum : " + testNum + "" );
log.debug( "실행 시간 : " + ( end - start )/1000.0 + "초" );
log.debug(sampleform.getTotRoof());
log.debug("총 총가용율:"+sampleform.getTotAvailability()+"%");
//request.setAttribute("resultparamater", sampleform.getTotavaArr());
//log.debug();
//log.debug();
return sampleform;
}
/*
* 수리분포 1:Exponential, 2:Normal, 3:Rectangular, 4:Triangular, 5:Webull, 6:Weibull Time Delay, 7:Conditional, 8:Constant Repair Time, 9:Multi-Shot Life
*/
public boolean computeHazardRate(Sampleform sampleform,SampleBean samplebean) {
/*for (int i=0;i<saList.size();i++) {
System.out.println(saList.get(i).getFigFreq()+" ::::: "+saList.get(i).getFigFreqStepResult()+","+sampleform.getPresent());
int saTime = 0;
if (saList.get(i).getFigFreqStepResult()>sampleform.getPresent()) {
modeCheck = true;
//System.out.println(saList.get(i).getFigFreqStepResult());
saList.get(i).setFigFreqStepResult((int)sampleform.getPresent()+(saList.get(i).getFigFreq()*8760));
//return false;
}
}*/
sampleform.setHazardRate(0f);
//System.out.println("->"+samplebean.);
if (samplebean.getFigDistribution() == 1) { //Exponential
sampleform.setHazardRate(1f/(samplebean.getFigExpMttf()*sampleform.getTd()));
//System.out.println(samplebean.getFigExpMttf() +",,,,,,,,,,,,,,,,"+ sampleform.getHazardRate());
} else if (samplebean.getFigDistribution() == 3) {//Rectangular
if (sampleform.getPresent() < sampleform.getMinMttf()) {
sampleform.setHazardRate(0f);
} else if (sampleform.getMinMttf() <= sampleform.getPresent() && sampleform.getPresent() <= sampleform.getMaxMttf()) {
sampleform.setHazardRate(1f/(((sampleform.getMaxMttf()-sampleform.getPresent())/8760f)*365f));
} else {
if (sampleform.getPresent() > sampleform.getMaxMttf()) {
sampleform.setMinMttf((samplebean.getFigMinMttf()*8760f)+sampleform.getPresent());
sampleform.setMaxMttf((samplebean.getFigMaxMttf()*8760f)+sampleform.getPresent());
}
}
} else if (samplebean.getFigDistribution() == 2){//Normal
double presentLife = 0;
if(sampleform.getBreakpoint() > 0f){
presentLife = sampleform.getPresent() - sampleform.getBreakpoint();
}else{
presentLife = sampleform.getPresent();
}
//double normalHazardRate = (this.norm((presentLife/8760d), samplebean.getFigNormExptMttf(), samplebean.getFigNormStdMttf()))/(this.normDist((presentLife/8760d), samplebean.getFigNormExptMttf(), samplebean.getFigNormStdMttf()));
//double z = ((presentLife/8760d)-samplebean.getFigNormExptMttf())/samplebean.getFigNormStdMttf();
double normalHazardRate = this.numericalCalculation((presentLife/8760d), samplebean.getFigNormExptMttf(), samplebean.getFigNormStdMttf());
//double normalHazardRate = this.timestepft((presentLife/8760d), samplebean.getFigNormExptMttf(), samplebean.getFigNormStdMttf());//엑셀2번째
//double normalHazardRate = ((1/samplebean.getFigNormExptMttf())*this.norm(z, 0, 1))/(1-this.NORMSDIST(z));//정규분포표 이용
normalHazardRate = normalHazardRate/sampleform.getTd();
//System.out.println(sampleform.getPresent()/sampleform.getTd()+"->"+normalHazardRate);
sampleform.setHazardRate(normalHazardRate);
} else if (samplebean.getFigDistribution() == 4) {//Triangular
if (sampleform.getPresent() < sampleform.getMinMttf()) {
sampleform.setHazardRate(0f);
} else if(sampleform.getMinMttf() <= sampleform.getPresent() && sampleform.getPresent() <= sampleform.getMostMttf()){
float val1 = 2f*(sampleform.getPresent() - sampleform.getMinMttf());
float val2 = sampleform.getMaxMttf() - sampleform.getMinMttf();
float val3 = sampleform.getMostMttf() - sampleform.getMinMttf();
float val4 = (float)Math.pow(sampleform.getPresent() - sampleform.getMinMttf(),2);
float val5 = (((val2*val3)-val4)/8760f)*365f;
sampleform.setHazardRate(val1/val5);
} else if (sampleform.getMostMttf() <= sampleform.getPresent() && sampleform.getPresent() <= sampleform.getMaxMttf()){
sampleform.setHazardRate(2f/(((sampleform.getMaxMttf()-sampleform.getPresent())/8760f)*365f));
} else {
if (sampleform.getPresent() > sampleform.getMaxMttf()) {
sampleform.setMinMttf((samplebean.getFigMinMttf()*8760f)+sampleform.getPresent());
sampleform.setMaxMttf((samplebean.getFigMaxMttf()*8760f)+sampleform.getPresent());
sampleform.setMostMttf((samplebean.getFigMostMttf()*8760f)+sampleform.getPresent());
}
}
} else if (samplebean.getFigDistribution() == 5) {//5:Weibull
double presentLife = 0;
if(sampleform.getBreakpoint() > 0f){
presentLife = sampleform.getPresent() - sampleform.getBreakpoint();
}else{
presentLife = sampleform.getPresent();
}
//System.out.println(presentLife+" "+sampleform.getBreakpoint());
double num1 = (samplebean.getFigWeiShapeMttf().doubleValue()/ samplebean.getFigWeiCharMttf().doubleValue());
double num2 = Math.pow(((presentLife/8760f)/ samplebean.getFigWeiCharMttf().doubleValue()), samplebean.getFigWeiShapeMttf().doubleValue() -1f);
sampleform.setHazardRate((num1*num2)/365f);
} else if (samplebean.getFigDistribution() == 6) {//6:Weibull Time Delay
float lifePresent = sampleform.getPresent()-sampleform.getBreakpoint();
sampleform.setTimeDelay(sampleform.getTimeDelay()+sampleform.getBreakpoint());
//if(sampleform.getPresent() > sampleform.getTimeDelay()){
if (true) {
double num1 = (samplebean.getFigWeiShapeMttf().doubleValue()/ samplebean.getFigWeiCharMttf().doubleValue());
double num2 = Math.pow(((lifePresent/8760f)/ samplebean.getFigWeiCharMttf().doubleValue()), samplebean.getFigWeiShapeMttf().doubleValue() -1f);
sampleform.setHazardRate((num1*num2)/365f);
} else {
sampleform.setHazardRate(0f);
}
//System.out.println(sampleform.getTimeDelay()/8760f);
} else { // SA 일경우
//System.out.println(sampleform.getPresent()+"::"+samplebean.getFigMoType());
//System.out.println(samplebean.getFigFreq()*8760);//saList.get(i).getFigFreq();
if ((samplebean.getFigFreq()*saControl)*8760<sampleform.getPresent()) {
saControl++;
sampleform.setGeneralState(false);
//System.out.println(testNum+":"+sampleform.getPresent());
testNum++;
return sampleform.isGeneralState();
} else {
sampleform.setGeneralState(true);
return sampleform.isGeneralState();
}
}
//Math.round(ran*10000000.0)/10000000.0
//if (Math.round(sampleform.getHazardRate()*10000000.0)/10000000.0 < Math.round(this.getRandomNumbers(0,samplebean.getFigDistribution())*10000000.0)/10000000.0) {
if (sampleform.getHazardRate() < this.getRandomNumbers(0,samplebean.getFigDistribution())) {
sampleform.setGeneralState(true);
} else {
sampleform.setGeneralState(false);
if (samplebean.getFigDistribution() == 2) {
//sampleform.setBreakpoint(sampleform.getPresent());
} else if (samplebean.getFigDistribution() == 3) {
sampleform.setMinMttf((samplebean.getFigMinMttf()*8760f)+sampleform.getPresent());
sampleform.setMaxMttf((samplebean.getFigMaxMttf()*8760f)+sampleform.getPresent());
} else if (samplebean.getFigDistribution() == 4) {
sampleform.setMinMttf((samplebean.getFigMinMttf()*8760f)+sampleform.getPresent());
sampleform.setMaxMttf((samplebean.getFigMaxMttf()*8760f)+sampleform.getPresent());
sampleform.setMostMttf((samplebean.getFigMostMttf()*8760f)+sampleform.getPresent());
} else if (samplebean.getFigDistribution() == 5 || samplebean.getFigDistribution() == 6) {
//sampleform.setBreakpoint(sampleform.getPresent());
}
}
//log.debug(sampleform.isGeneralState());
return sampleform.isGeneralState();
}
/*
* double X 현재시간
* double mean μ,
* double std_dv σ, hours 표준편차
*/
public double normDist(double X, double mean, double std_dv) {
// Berechnungsformel wurde von Hans Benz COMIT AG ermittelt
double res = 0;
double x = (X - mean) / std_dv;
if (x == 0) {
res = 0.5;
} else {
double oor2pi = 1 / (Math.sqrt(2 * 3.14159265358979323846));
double t = 1 / (1 + 0.231641900000 * Math.abs(x));
t *= oor2pi
* Math.exp(-0.5 * x * x)
* (0.319381530000 + t
* (-0.356563782000 + t
* (1.781477937000 + t
* (-1.821255978000 + t * 1.330274429000))));
if (x >= 0) {
res = 1 - t;
} else {
res = t;
}
}
//res = sumF+res;
//System.out.println(sumF);
//return 1-res;
return 1-res;
}
/*
* double X 현재시간
* double mean μ,
* double std_dv σ, hours 표준편차
*/
public double norm(double x, double mean, double std_dv){
//Math.sqrt = 제곱근 , Math.PI = π 값계산, Math.exp=자연대수e
//
//double x=1;
double sigma=std_dv;
double u=mean;
double val1 = ((1/Math.sqrt(2*Math.PI*sigma))*Math.exp(-0.5*( ((x-u)*(x-u))/(sigma*sigma) )));
double val2 = ((1/Math.sqrt(2*Math.PI))*Math.exp(-0.5*( ((x-u)*(x-u))/(sigma*sigma) )));
return val1;
}
//정해지지 않는 순수 난수 생성
public double getRandomNumbers(int n,int division){
double ran = (double)Math.random();
double ran2 = 0;
if(division== 2){
//ran2 = getRandomGaussian();
}
//System.out.println(ran+",,"+ran2);
/*Random randomObj = new Random();
double[] x = new double[n];
for(int i=0; i<n; i++){
x[i] = randomObj.nextDouble();
}
return x;*/
//System.out.println(ran+",,"+Math.round(ran*10000000.0)/10000000.0);
//return Math.round(ran*10000000.0)/10000000.0;
return ran;
}
public double getRandomGaussian(){
Random oRandom = new Random();
double ran = oRandom.nextGaussian();
/*double[] ran = new double[n];
for (int i=0;i<n;i++) {
ran[i] = oRandom.nextGaussian();
}*/
return ran;
}
public double timestepft(double x, double mean, double std_dv) {
//public void timestepft(){
double result = 0;
double valPDF = 0;
double valCDF = 0;
double sigma = std_dv;
double bigFt = 0;
double t = x;
double mu = mean;
//double checkScope = 10; //검토범위(푲준편차의 배수)
//double checkPoint = t-checkScope;//검토시작지점(t-검토범위)
int checkDivision = 100;//검토범위 분할 개수
double z = (t-mu)/sigma;
double d = Math.abs(Math.abs(z)/checkDivision);
//double val = this.getft(sigma, mu, t);
//double dt = (t-checkPoint)/checkDivision;
for (int i=1;i<=checkDivision;i++) {
//double abs_z = d*i;
double pdf_abs_val = d*((1/Math.sqrt(2*Math.PI)) * Math.exp(-0.5*Math.pow((d*i), 2)));
bigFt = bigFt + pdf_abs_val;
}
valPDF = (1/Math.sqrt(2*Math.PI)) * Math.exp(-0.5*Math.pow(Math.abs(z), 2));
if (z<=0) {
valCDF = 0.5-bigFt;
} else if (z>0) {
valCDF = 0.5+bigFt;
}
result = valPDF/sigma/(1-valCDF);
return result;
//System.out.println(result);
/*while(checkPoint<t){
double loopval = this.getft(sigma, mu, checkPoint);
System.out.println(loopval);
bigFt = bigFt + (loopval*dt);
checkPoint = checkPoint+dt;
}*/
//System.out.println("-->"+val/(1-bigFt));
}
public double getft(double sigma,double mu,double t){
double val = 0;
//val = ( 1 / (Math.sqrt(2*Math.PI) * sigma) )*Math.exp(- (Math.pow((t-mu),2)) / (2 * Math.pow(sigma,2)));
val = ( 1 / (Math.sqrt(2*Math.PI)) )*Math.exp(- (Math.pow((t-mu),2)) / (2 * Math.pow(sigma,2)));
return val;
}
//numerical calculation 의한 평가
//public double numericalCalculation() {
public double numericalCalculation(double x, double mean, double std_dv){
double result = 0;
double valPDF = 0;
double valCDF = 0;
double mu = mean; // 평균
double sigma = std_dv; // 표준편차
double t = x;
double c0 = 0.231641900000;
double c1 = 0.319381530000;
double c2 = -0.356563782000;
double c3 = 1.781477937000;
double c4 = -1.821255978000;
double c5 = 1.330274429000;
double z = (t-mu)/sigma; // (t-μ)/σ
double Iroot2pi = 1/Math.sqrt(2*Math.PI); // 1/root(2π)
double ta = 1/(1+c0*Math.abs(z)); // 1/(1+C0*ABS(z))
// Iroot2pi * exp(-0.5*z*z) * (C1*ta+C2*ta*ta+C3*ta*ta*ta+C4*ta*ta*ta*ta+C5*ta*ta*ta*ta*ta)
double TA = Iroot2pi * Math.exp(-0.5*z*z) * (c1*ta+c2*ta*ta+c3*ta*ta*ta+c4*ta*ta*ta*ta+c5*ta*ta*ta*ta*ta);
if (z>0) {
valCDF = 1-TA;
} else if (z<=0) {
valCDF = TA;
}
//.System.out.println(Math.pow(-0.5*z, 2));
valPDF = Iroot2pi/sigma * Math.exp(-0.5*Math.pow(z, 2)); //Iroot2pi/σ * EXP(-0.5*z^2) 0.125794409231
//valPDF = 0.125794409231;
if (z>0) {
result = valPDF/(1-valCDF);
} else if (z<=0) {
result = valPDF/(1-valCDF);
}
//System.out.println(result);
return result;
}
public double getArea(double[] u, double[] v){
int n = u.length;
double suc = 0;
for (int i = 0; i < n; i++) {
if (4.0 * Math.sqrt(1 - u[i]*u[i]) > 4.0*v[i]) {
suc++;
}
}
double est = 4.0*suc/n;
return est;
}
//누적표준정규분포표 구하기
public static double NORMSDIST(double z) {
double sign = 1;
if (z < 0) sign = -1;
return 0.5 * (1.0 + sign * erf(Math.abs(z)/Math.sqrt(2)));
}
private static double erf(double x) {
//A&S formula 7.1.26
double a1 = 0.254829592;
double a2 = -0.284496736;
double a3 = 1.421413741;
double a4 = -1.453152027;
double a5 = 1.061405429;
double p = 0.3275911;
x = Math.abs(x);
double t = 1 / (1 + p * x);
//Direct calculation using formula 7.1.26 is absolutely correct
//But calculation of nth order polynomial takes O(n^2) operations
//return 1 - (a1 * t + a2 * t * t + a3 * t * t * t + a4 * t * t * t * t + a5 * t * t * t * t * t) * Math.exp(-1 * x * x);
//Horner's method, takes O(n) operations for nth order polynomial
double result = (1 - ((((((a5 * t + a4) * t) + a3) * t + a2) * t) + a1) * t * Math.exp(-1 * x * x));
return result;
}
}