<!--Define JavaScript functions.-->

function sign(y){
 return ((y < 0) ? -1 : 1);
}  //End of function sign.

function f(par1, par2, par3, tm, Per){
 var dummy = 2*Math.PI*tm/Per;
 var cM = Math.cos(dummy), sM = Math.sin(dummy);
 dummy = (par1 + par2*cM)*cM*sM*sM + par3;
 return -dummy;
}//End of function f

function f1Max(dataForm){
var a = parseFloat(dataForm.b.value);
var b = parseFloat(dataForm.c.value);
var T = parseFloat(dataForm.Period.value);
var k1 = parseFloat(dataForm.a1.value);
var k2 = parseFloat(dataForm.a2.value);
var k3 = parseFloat(dataForm.a3.value);

if ((k1 == 0) && (k2 == 0) && (k3 != 0)){
 alert("The function is a constant straight line. No further action taken.");
 return;
}

//c is the squared inverse of the golden ratio
var c = (3.0 - Math.sqrt(5))/2;
var d, e = 0.0, fv, fw, fx, p, q, r, tol1, tol2, w, x, xm, v;
var MAXIT = 500; //Maximum number of iterations

if (b < a){//Ensure that a is the left endpoint and b the right
 d = b; b = a; a = d;
}

var tol1 = 1.0;
do {
 eps = tol1;
 tol1 /= 2;
 tol2 = 1.0 + tol1;
} while (tol2 > 1.0);
// At this point, eps should equal the machine precision, Machine Epsilon
eps = Math.sqrt(eps);
dataForm.sqepmch.value = eps;

//Initialization

w = x = v = a + c*(-a + b);
fv = fw = fx = f(k1, k2, k3, x, T);

//Start main loop

for (var i = 0; i < MAXIT; i++){
 xm = (a + b)/2;
 tol1 = eps*(Math.abs(x) + 1.0/3.0);
 tol2 = 2*tol1;

 if (Math.abs(-xm + x) <= (-(-a + b)/2 + tol2)) break; //Conditions met; leave main loop.

 //Is Golden Section necessary?
 if (Math.abs(e) <= tol1){  //Golden Section search
  if (x >= xm)
   e = -x + a;
  else
   e = -x + b;
  d = c*e;
 } //End if (Math.abs(e) <= tol1)
 else {//else Math.abs(e) > tol1
  r = (-w + x)*(-fv + fx);
  q = (-v + x)*(-fw + fx);
  p = -((-w + x)*r) + (-v + x)*q;
  q = 2*(-r + q);
  if (q > 0)
   p = -p;
  q = Math.abs(q);
  r = e;
  e = d;
  
  //Is a parabola acceptable?
  if ((Math.abs(p) >= Math.abs(q*r/2)) || (p <= (q*(-x + a))) || (p >= q*(-x + b))){
   if (x >= xm)
    e = -x + a;	//Golden-Section step
   else
    e = -x + b;
   d = c*e;
  }
  else {
   d = p/q;	//Parabolic interpolation step
   u = x + d;
   //f must not be evaluated too close to a or b
   if ((-a + u) < tol2)
    d = tol1*sign(-x + xm);	
   if ((-u + b) < tol2)
    d = tol1*sign(-x + xm);
  }//End else, compound OR statement, p >= q*r/2

 }//End else Math.abs(e) > tol1

 //f must not be evaluated too close to x
 if (Math.abs(d) >= tol1)
  u = x + d;
 else
  u = x + tol1*sign(d);
 fu = f(k1, k2, k3, u, T);
 //Update a, b, v, w, and x
 if (fu <= fx) {
  if (u >= x)
   a = x;
  else
   b = x;
  v = w; fv = fw; w = x; fw = fx; x = u; fx = fu;
  continue;
 }//End if fu <= fx
 if (u < x)
  a = u;
 else
  b = u;

 if ((fu <= fw) || (w == x)){
  v = w; fv = fw; w = u; fw = fu;
  continue;
 }

 if ((fu <= fv) || (v == x) ||(v == w)){
  v = u; fv = fu;
 }
 
}//End for i loop

dataForm.t.value = x;
dataForm.fmax.value = -f(k1, k2, k3, x, T);

return;
}  //End of f1Max

// end of JavaScript function definitions -->
