<!--Define JavaScript functions.-->

var NMAX = 50; //Global variable, maximum number of iterations.

/*The abscissae and weights are given for the interval (-1,1). Because of symmetry, only the positive abscissae and
  corresponding weights are given.
  xgk- abscissae of the 15-point Kronrod Rule.
  xgk[1], xgk[3], . . . abscissae of the 7-point Gauss Rule.
  xgk[0], xgk[2], . . . abscissae which are optimally added to the
  7-point Gauss Rule.
  wgk- weights of the 15-point Kronrod Rule.
  wg-  weights of the 7-point Gauss Rule.
*/

var WG = new Array(4);
WG = [0.12948496616886969327, 0.27970539148927666790, 0.38183005050511894495, 0.41795918367346938775];

var WGK = new Array(8);
WGK[0] = 0.02293532201052922496;
WGK[1] = 0.06309209262997855329;
WGK[2] = 0.10479001032225018383;
WGK[3] = 0.14065325971552591874;
WGK[4] = 0.16900472663926790282;
WGK[5] = 0.19035057806478540991;
WGK[6] = 0.20443294007529889241;
WGK[7] = 0.20948214108472782801;

var XGK = new Array(7);
XGK[0] = 0.99145537112081263920;
XGK[1] = 0.94910791234275852452;
XGK[2] = 0.86486442335976907278;
XGK[3] = 0.74153118559939443986;
XGK[4] = 0.58608723546769113029;
XGK[5] = 0.40584515137739716690;
XGK[6] = 0.20778495500789846760;

function f(tm, Per){
 var dummy = 2*Math.PI*tm/Per;
 return Math.sin(dummy);
}//End of function f

function isamax(Matrix, rep)
{/* Examines specified region of input column; returns row index of
    largest element. */

 var smax = Math.abs(Matrix[0][2]), xmag;
 var dum = 0;

 for (var i = 1; i <= rep; i++) {
  xmag = Math.abs(Matrix[i][2]);
  if (xmag > smax)  { dum = i;    smax = xmag;  }
 } //End for i
 return dum;}

function gl15t(a, b, xl, xr, iPar, per)
{var absc, fc, fsum, fval1, fval2, resg, resk, reskh, sl, sr;
 var j, jtw;
 var fv1 = new Array(7);
 var fv2 = new Array(7);

 /*centr- midpoint of the interval.
   hlgth- halflength of the interval.
   absc-  abscissa.
   fval - function value.
   resg- r of the 7-point Gauss Formula.
   resk- r of the 15-point Kronrod Formula.
   reskh- approximation to the mean value of f over (a, b). ie-
	  I/(b - a). */

 if (xl < xr) {  sl = xl;   sr = xr; }
 else {  sl = xr;   sr = xl; }

 var hlgth = (-a + b)/2, centr = a + hlgth, dhlgth = Math.abs(hlgth);

 var u = (-xr + centr)/(-xl + xr);   // Compute the 15-point Kronrod
 var phiu = (-xl + xr)*u*u*(2*u + 3);
 phiu = -phiu + xr;

 if ((phiu <= sl) || (phiu >= sr))  phiu = centr;

 iPar.fx = iPar.fm = f(phiu, per);
 fc = iPar.fm*(-6*u*(u + 1));
 resg = fc*WG[3];  resk = fc*WGK[7];  iPar.ra = Math.abs(resk);

 for (var j = 0; j < 3; j++) {
  jtw = j*2 + 1;
  absc = hlgth*XGK[jtw];

  u = -absc + centr;
  u = (-xr + u)/(-xl + xr);

  phiu = (-xl + xr)*u*u*(2*u + 3);
  phiu = -phiu + xr;

  if ((phiu <= sl) || (phiu >= sr))   phiu = centr;
  fval1 = f(phiu, per);
  iPar.fx = Math.max(iPar.fx, fval1);   iPar.fm = Math.min(iPar.fm, fval1);
  fval1 *= -6*u*(u + 1);
  fv1[jtw] = fval1;

  u = (-xr + centr + absc)/(-xl + xr);

  phiu = (-xl + xr)*u*u*(2*u + 3); 
  phiu = -phiu + xr;
  if ((phiu <= sl) || (phiu >= sr))   phiu = centr;
  fval2 = f(phiu, per);
  iPar.fx = Math.max(iPar.fx, fval2);   iPar.fm = Math.min(iPar.fm, fval2);
  fval2 *= -6*u*(u + 1);
  fv2[jtw] = fval2;

  fsum = fval1 + fval2;
  resg += WG[j]*fsum;   resk += WGK[jtw]*fsum;
  iPar.ra += WGK[jtw]*(Math.abs(fval1) + Math.abs(fval2)); 
 } // End for j.

 for (var j = 0; j < 7; j += 2){
  absc = hlgth*XGK[j];

  u = -absc + centr;
  u = (-xr + u)/(-xl + xr);

  phiu = (-xl + xr)*u*u*(2*u + 3);
  phiu = -phiu + xr;

  if ((phiu <= sl) || (phiu >= sr))   phiu = centr;
  fval1 = f(phiu, per);
  iPar.fx = Math.max(iPar.fx, fval1);   iPar.fm = Math.min(iPar.fm, fval1);
  fval1 *= -6*u*(u + 1);
  fv1[j] = fval1;

  u = (-xr + centr + absc)/(-xl + xr);

  phiu = (-xl + xr)*u*u*(2*u + 3);
  phiu = -phiu + xr;
  if ((phiu <= sl) || (phiu >= sr))   phiu = centr;
  fval2 = f(phiu, per);
  iPar.fx = Math.max(iPar.fx, fval2);   iPar.fm = Math.min(iPar.fm, fval2);
  fval2 *= -6*u*(u + 1);
  fv2[j] = fval2;

  fsum = fval1 + fval2;   resk += WGK[j]*fsum;
  iPar.ra += WGK[j]*(Math.abs(fval1) + Math.abs(fval2));
 } // End for j.

 reskh = resk/2;  iPar.rasc = WGK[7]*Math.abs(-reskh + fc);
 for (var j = 0; j < 7; j++)
  iPar.rasc += WGK[j]*(Math.abs(-reskh + fv1[j]) + Math.abs(-reskh + fv2[j]));
 iPar.q = resk*hlgth;  iPar.ra *= dhlgth;  iPar.rasc *= dhlgth;
 iPar.ae = Math.abs((-resg + resk)*hlgth);
 if ((iPar.rasc != 0) && (iPar.ae != 0))
  iPar.ae = (iPar.rasc)*Math.min(1, Math.pow((200*(iPar.ae)/(iPar.rasc)), 1.5));
 if (iPar.ra > Number.MIN_VALUE/(50.0*iPar.epsMch))
  iPar.ae = Math.max(iPar.ae, 50.0*iPar.epsMch*(iPar.ra));
 return;
}              // End gl15t.

function numInt1(dataForm){
var a = parseFloat(dataForm.b.value);
var b = parseFloat(dataForm.c.value);
var T = parseFloat(dataForm.Period.value);

if (a == b){
 dataForm.defInt.value = dataForm.funcEval.value = dataForm.erCode.value = dataForm.eVal.value = 0;
 return;
}

var c, iroff = 0, kf = 30, loc, nint = 1, mxtry = NMAX/2;
var e, eb, erReq = 1.0e-12, fmin, fmax, r, rabs, t, te, te1, te2, tr, tr1, tr2, xm;

var w = new Array(NMAX);
for (var i = 0; i < NMAX; i++) {
 w[i] = new Array(6);
 w[i][2] = 0.0;
} // End for i loop

eb = 1.0;
do {
  e = eb;
  eb /= 2.0;
  r = 1.0 + eb;
} while (r > 1.0);
// At this point, e should equal the machine epsilon

if (Math.abs((-a + b)%T) <= e){
 dataForm.defInt.value = dataForm.funcEval.value = dataForm.erCode.value = dataForm.eVal.value = 0;
 return;
}

var qPar = new Object();
qPar.fx = qPar.fm = qPar.rasc = qPar.ra = qPar.ae = qPar.q = 0.0;
qPar.epsMch = e;

w[1][4] = w[0][4] = w[0][0] = a;
w[1][5] = w[0][5] = w[1][1] = b;

// Select first subdivision randomly. 0.618 is golden section, so use it.
w[1][0] = w[0][1] = 0.382*a + 0.618*b;

gl15t(a, w[0][1], a, b, qPar, T);
r = w[0][3] = qPar.q;  e = w[0][2] = qPar.ae;
rabs = qPar.ra;  fmin = qPar.fm;  fmax = qPar.fx;

gl15t(w[1][0], b, a, b, qPar, T);
w[1][3] = qPar.q;
r += w[1][3];
w[1][2] = qPar.ae;
e += w[1][2];
rabs += qPar.ra;

fmax = Math.max(fmax, qPar.fx);
fmin = Math.min(fmin , qPar.fm);

t = 100.0*qPar.epsMch*rabs;

for (var i = 0; i < 2*NMAX; i++){

 if ((t >= Math.abs(r))  && (e < erReq)) break;

 eb = Math.abs(r)*Math.max(erReq, (50.0*qPar.epsMch));
 eb = Math.max(eb, 100.0*Number.MIN_VALUE);

 if (e <= eb) break;

 if (nint < (NMAX - 1))  c = ++nint;
 else  {
  c = -1;
  do{
   if ((mxtry <= 0) || (c == (NMAX - 1))) {
    dataForm.erCode.value = 5;
    dataForm.defInt.value = dataForm.eVal.value = "N/A";
    dataForm.funcEval.value = kf;
    return;
   }
   c++;
  } while (w[c][2] > 0.0);
//Found an interval to throw out.
  mxtry--;
 } // End else nint >= (NMAX - 1)

 loc = isamax(w, nint);

 xm = w[loc][0] + (-w[loc][0] + w[loc][1])/2;

 if (Math.max(Math.abs(w[loc][0]), Math.abs(w[loc][1])) > (1.0 + 100.0*qPar.epsMch)*(Math.abs(xm) + 1000.0*Number.MIN_VALUE)) {
  gl15t(w[loc][0], xm, w[loc][4], w[loc][5], qPar, T);
  tr1 = qPar.q; te1 = qPar.ae;
  fmin = Math.min(fmin, qPar.fm);
  fmax = Math.max(fmax, qPar.fx);

  if (te1 < eb*(-w[loc][0] + xm)/(-a + b))
   te1 = -te1;

  gl15t(xm, w[loc][1], w[loc][4], w[loc][5], qPar, T);
  tr2 = qPar.q; te2 = qPar.ae;
  kf += 30;

  fmin = Math.min(fmin, qPar.fm);
  fmax = Math.max(fmax, qPar.fx);

  if (te2 < eb*(-xm + w[loc][1])/(-a + b))
   te2 = -te2;

  te = Math.abs(w[loc][2]);
  tr = w[loc][3];
  w[c][2] = te2; w[c][3] = tr2; w[c][0] = xm;

  w[c][1] = w[loc][1]; w[c][4] = w[loc][4];
  w[c][5] = w[loc][5]; w[loc][2] = te1;
  w[loc][3] = tr1; w[loc][1] = xm;

  e += -te + Math.abs(te1) + Math.abs(te2);
  r += -tr + tr1 + tr2;

  if (Math.abs(-te + Math.abs(te1) + Math.abs(te2)) < 0.001*te) {
   iroff++;
   if (iroff >= 10) {
    dataForm.erCode.value = 4;
    dataForm.funcEval.value = kf;
    dataForm.defInt.value = dataForm.eVal.value = "N/A";
    return;
   } //End if (iroff >= 10)
  }//End if (Math.abs(Math.abs(te1) + Math.abs(te2) - te) < 0.001*te)
 } //End if max
 else {
  if (eb > w[loc][2]) 
   w[loc][2] = 0;
  else { 
   dataForm.erCode.value = 6;
   dataForm.funcEval.value = kf;
   dataForm.defInt.value = dataForm.eVal.value = "N/A";
   return;
  } //End else.
 }       // End else.

}//End for i loop

if (i >= 2*NMAX){
 dataForm.erCode.value = 7;
 dataForm.funcEval.value = kf;
 dataForm.defInt.value = dataForm.eVal.value = "N/A";
 return;
}

dataForm.funcEval.value = kf;
dataForm.erCode.value = 3;
dataForm.defInt.value = r;
dataForm.eVal.value = e;

t = erReq*Math.abs(r);
if ((e > erReq) && (e > t))    return;
dataForm.erCode.value = 2;
if ((e > erReq) && (e < t))    return;
dataForm.erCode.value = 1;
if ((e < erReq) && (e > t))    return;
dataForm.erCode.value = 0;

return;
}  //End of numInt1

// end of JavaScript function definitions -->