private static void cauchy(int n, double[] x, int _x_offset, double[] l, int _l_offset,
double[] u, int _u_offset, int[] nbd, int _nbd_offset, double[] g, int _g_offset,
int[] iorder, int _iorder_offset, int[] iwhere, int _iwhere_offset, double[] t, int _t_offset,
double[] d, int _d_offset, double[] xcp, int _xcp_offset, int m,
double[] wy, int _wy_offset, double[] ws, int _ws_offset, double[] sy, int _sy_offset,
double[] wt, int _wt_offset, double theta, int col,
int head, double[] p, int _p_offset, double[] c, int _c_offset,
double[] wbp, int _wbp_offset, double[] v, int _v_offset, ref int nseg,
int iprint, double sbgnrm, ref int info, double epsmch)
{
bool xlower = false;
bool xupper = false;
bool bnded = false;
int i = 0;
int j = 0;
int col2 = 0;
int nfree = 0;
int nbreak = 0;
int pointr = 0;
int ibp = 0;
int nleft = 0;
int ibkmin = 0;
int iter = 0;
double f1 = 0.0d;
double f2 = 0.0d;
double dt = 0.0d;
double dtm = 0.0d;
double tsum = 0.0d;
double dibp = 0.0d;
double zibp = 0.0d;
double dibp2 = 0.0d;
double bkmin = 0.0d;
double tu = 0.0d;
double tl = 0.0d;
double wmc = 0.0d;
double wmp = 0.0d;
double wmw = 0.0d;
double tj = 0.0d;
double tj0 = 0.0d;
double neggi = 0.0d;
double f2_org = 0.0d;
if ((sbgnrm <= 0.0))
{
if ((iprint >= 0))
{
// DISPLAY: Subgnorm = 0. GCP = X.
}
dcopy(n, x, _x_offset, 1, xcp, _xcp_offset, 1);
return;
}
bnded = true;
nfree = (n + 1);
nbreak = 0;
ibkmin = 0;
bkmin = 0.0;
col2 = (2 * col);
f1 = 0.0;
if ((iprint >= 99))
{
// DISPLAY: '---------------- CAUCHY entered-------------------'
}
//
// c We set p to zero and build it up as we determine d.
//
{
for (i = 1; i <= col2; i++)
{
p[(i - (1)) + _p_offset] = 0.0;
}
}
//
// c In the following loop we determine for each variable its bound
// c status and its breakpoint, and update p accordingly.
// c Smallest breakpoint is identified.
//
{
for (i = 1; i <= n; i++)
{
neggi = (-(g[(i - (1)) + _g_offset]));
if (((iwhere[(i - (1)) + _iwhere_offset] != 3)
&& (iwhere[(i - (1)) + _iwhere_offset] != -1)))
{
// c if x(i) is not a constant and has bounds,
// c compute the difference between x(i) and its bounds.
if ((nbd[(i - (1)) + _nbd_offset] <= 2))
{
tl = (x[(i - (1)) + _x_offset] - l[(i - (1)) + _l_offset]);
}
if ((nbd[(i - (1)) + _nbd_offset] >= 2))
{
tu = (u[(i - (1)) + _u_offset] - x[(i - (1)) + _x_offset]);
}
//
// c If a variable is close enough to a bound
// c we treat it as at bound.
xlower = ((nbd[(i - (1)) + _nbd_offset] <= 2) && (tl <= 0.0));
xupper = ((nbd[(i - (1)) + _nbd_offset] >= 2) && (tu <= 0.0));
//
// c reset iwhere(i).
iwhere[(i - (1)) + _iwhere_offset] = 0;
if (xlower)
{
if ((neggi <= 0.0))
{
iwhere[(i - (1)) + _iwhere_offset] = 1;
}
}
else if (xupper)
{
if ((neggi >= 0.0))
{
iwhere[(i - (1)) + _iwhere_offset] = 2;
}
}
else
{
if ((System.Math.Abs(neggi) <= 0.0))
{
iwhere[(i - (1)) + _iwhere_offset] = -3;
}
}
}
pointr = head;
if (((iwhere[(i - (1)) + _iwhere_offset] != 0) && (iwhere[(i - (1)) + _iwhere_offset] != -1)))
{
d[(i - (1)) + _d_offset] = 0.0;
}
else
{
d[(i - (1)) + _d_offset] = neggi;
f1 = (f1 - (neggi * neggi));
// calculate p := p - W'e_i* (g_i).
{
for (j = 1; j <= col; j++)
{
p[(j - (1)) + _p_offset] = (p[(j - (1))
+ _p_offset] + (wy[(i - (1)) + (pointr - (1)) * (n) + _wy_offset] * neggi));
p[((col + j) - (1)) + _p_offset] = (p[((col + j) - (1))
+ _p_offset] + (ws[(i - (1)) + (pointr - (1)) * (n) + _ws_offset] * neggi));
pointr = ((pointr) % (m) + 1);
}
}
if ((((nbd[(i - (1)) + _nbd_offset] <= 2)
&& (nbd[(i - (1)) + _nbd_offset] != 0)) && (neggi < 0.0)))
{
// x(i) + d(i) is bounded; compute t(i).
nbreak = (nbreak + 1);
iorder[(nbreak - (1)) + _iorder_offset] = i;
t[(nbreak - (1)) + _t_offset] = (tl / ((-(neggi))));
if (((nbreak == 1) || (t[(nbreak - (1)) + _t_offset] < bkmin)))
{
bkmin = t[(nbreak - (1)) + _t_offset];
ibkmin = nbreak;
}
}
else if (((nbd[(i - (1)) + _nbd_offset] >= 2) && (neggi > 0.0)))
{
// x(i) + d(i) is bounded; compute t(i).
nbreak = (nbreak + 1);
iorder[(nbreak - (1)) + _iorder_offset] = i;
t[(nbreak - (1)) + _t_offset] = (tu / neggi);
if (((nbreak == 1) || (t[(nbreak - (1)) + _t_offset] < bkmin)))
{
bkmin = t[(nbreak - (1)) + _t_offset];
ibkmin = nbreak;
}
}
else
{
// x(i) + d(i) is not bounded.
nfree = (nfree - 1);
iorder[(nfree - (1)) + _iorder_offset] = i;
if ((System.Math.Abs(neggi) > 0.0))
{
bnded = false;
}
}
}
}
}
//
// The indices of the nonzero components of d are now stored
// in iorder(1),...,iorder(nbreak) and iorder(nfree),...,iorder(n).
// The smallest of the nbreak breakpoints is in t(ibkmin)=bkmin.
//
if ((theta != 1.0))
{
// complete the initialization of p for theta not= one.
dscal(col, theta, p, ((col + 1) - (1)) + _p_offset, 1);
}
//
// c Initialize GCP xcp = x.
//
dcopy(n, x, _x_offset, 1, xcp, _xcp_offset, 1);
if (((nbreak == 0) && (nfree == (n + 1))))
{
// is a zero vector, return with the initial xcp as GCP.
return;
}
//
// c Initialize c = W'(xcp - x) = 0.
//
{
for (j = 1; j <= col2; j++)
{
c[(j - (1)) + _c_offset] = 0.0;
}
}
//
// c Initialize derivative f2.
//
f2 = (-((theta * f1)));
f2_org = f2;
if ((col > 0))
{
bmv(m, sy, _sy_offset, wt, _wt_offset,
col, p, _p_offset, v, _v_offset, ref info);
if ((info != 0))
{
return;
}
f2 = (f2 - BoundedBroydenFletcherGoldfarbShanno.ddot(col2, v, _v_offset, 1, p, _p_offset, 1));
}
dtm = (-((f1 / f2)));
tsum = 0.0;
nseg = 1;
if ((iprint >= 99))
{
// DISPLAY: "There are " + nbreak + " breakpoints "
}
//
// c If there are no breakpoints, locate the GCP and return.
//
if ((nbreak == 0))
goto L888;
nleft = nbreak;
iter = 1;
tj = 0.0;
//
// c------------------- the beginning of the loop -------------------------
//
L777:
//
// Find the next smallest breakpoint;
// compute dt = t(nleft) - t(nleft + 1).
//
tj0 = tj;
if ((iter == 1))
{
// Since we already have the smallest breakpoint we need not do
// heapsort yet. Often only one breakpoint is used and the
// cost of heapsort is avoided.
tj = bkmin;
ibp = iorder[(ibkmin - (1)) + _iorder_offset];
}
else
{
if ((iter == 2))
{
// Replace the already used smallest breakpoint with the
// breakpoint numbered nbreak > nlast, before heapsort call.
if ((ibkmin != nbreak))
{
t[(ibkmin - (1)) + _t_offset] = t[(nbreak - (1)) + _t_offset];
iorder[(ibkmin - (1)) + _iorder_offset] = iorder[(nbreak - (1)) + _iorder_offset];
}
// Update heap structure of breakpoints
// (if iter=2, initialize heap).
}
hpsolb(nleft, t, _t_offset, iorder, _iorder_offset, (iter - 2));
tj = t[(nleft - (1)) + _t_offset];
ibp = iorder[(nleft - (1)) + _iorder_offset];
}
//
dt = (tj - tj0);
//
if (((dt != 0.0) && (iprint >= 100)))
{
// DISPLAY: nseg, f1, f2
// "/,'Piece ',i3,' --f1, f2 at start point ',1p,2(1x,d11.4)"
//
// DISPLAY: dt,
// "'Distance to the next break point = ',1p,d11.4"
//
// DISPLAY: dtm,
// "'Distance to the stationary point = ',1p,d11.4"
}
//
// If a minimizer is within this interval, locate the GCP and return.
//
if ((dtm < dt))
goto L888;
//
// Otherwise fix one variable and
// reset the corresponding component of d to zero.
//
tsum = (tsum + dt);
nleft = (nleft - 1);
iter = (iter + 1);
dibp = d[(ibp - (1)) + _d_offset];
d[(ibp - (1)) + _d_offset] = 0.0;
if ((dibp > 0.0))
{
zibp = (u[(ibp - (1)) + _u_offset] - x[(ibp - (1)) + _x_offset]);
xcp[(ibp - (1)) + _xcp_offset] = u[(ibp - (1)) + _u_offset];
iwhere[(ibp - (1)) + _iwhere_offset] = 2;
}
else
{
zibp = (l[(ibp - (1)) + _l_offset] - x[(ibp - (1)) + _x_offset]);
xcp[(ibp - (1)) + _xcp_offset] = l[(ibp - (1)) + _l_offset];
iwhere[(ibp - (1)) + _iwhere_offset] = 1;
}
if ((iprint >= 100))
{
// DISPLAY: "Variable " + ibp + " is fixed."
}
if (((nleft == 0) && (nbreak == n)))
{
// all n variables are fixed,
// return with xcp as GCP.
dtm = dt;
goto L999;
}
//
// Update the derivative information.
//
nseg = (nseg + 1);
dibp2 = (System.Math.Pow(dibp, 2));
//
// Update f1 and f2.
//
// temporarily set f1 and f2 for col=0.
//
f1 = (((f1 + (dt * f2)) + dibp2) - ((theta * dibp) * zibp));
f2 = (f2 - (theta * dibp2));
//
if ((col > 0))
{
// update c = c + dt*p.
daxpy(col2, dt, p, _p_offset, 1, c, _c_offset, 1);
// choose wbp,
// the row of W corresponding to the breakpoint encountered.
pointr = head;
{
for (j = 1; j <= col; j++)
{
wbp[(j - (1)) + _wbp_offset] = wy[(ibp - (1))
+ (pointr - (1)) * (n) + _wy_offset];
wbp[((col + j) - (1)) + _wbp_offset] = (theta * ws[(ibp
- (1)) + (pointr - (1)) * (n) + _ws_offset]);
pointr = ((pointr) % (m) + 1);
}
}
// compute (wbp)Mc, (wbp)Mp, and (wbp)M(wbp)'.
bmv(m, sy, _sy_offset, wt, _wt_offset, col, wbp,
_wbp_offset, v, _v_offset, ref info);
if ((info != 0))
{
return;
}
wmc = ddot(col2, c, _c_offset, 1, v, _v_offset, 1);
wmp = ddot(col2, p, _p_offset, 1, v, _v_offset, 1);
wmw = ddot(col2, wbp, _wbp_offset, 1, v, _v_offset, 1);
// update p = p - dibp*wbp.
daxpy(col2, (-(dibp)), wbp, _wbp_offset, 1, p, _p_offset, 1);
// complete updating f1 and f2 while col > 0.
f1 = (f1 + (dibp * wmc));
f2 = ((f2 + ((2.0e0 * dibp) * wmp)) - (dibp2 * wmw));
}
f2 = System.Math.Max((epsmch * f2_org), f2);
if ((nleft > 0))
{
dtm = (-((f1 / f2)));
goto L777;
// to repeat the loop for unsearched intervals.
}
else if (bnded)
{
f1 = 0.0;
f2 = 0.0;
dtm = 0.0;
}
else
{
dtm = (-((f1 / f2)));
}
//
// c------------------- the end of the loop -------------------------------
//
L888:
if ((iprint >= 99))
{
// DISPLAY: "GCP found in this segment",
//
// DISPLAY: nseg, f1, f2
// 'Piece ',i3,' --f1, f2 at start point ',1p,2(1x,d11.4)"
// dtm
// "'Distance to the stationary point = ',1p,d11.4"
}
if ((dtm <= 0.0))
{
dtm = 0.0;
}
tsum = (tsum + dtm);
//
// Move free variables (i.e., the ones w/o breakpoints) and
// the variables whose breakpoints haven't been reached.
//
daxpy(n, tsum, d, _d_offset, 1, xcp, _xcp_offset, 1);
//
L999:
//
// Update c = c + dtm*p = W'(x^c - x)
// which will be used in computing r = Z'(B(x^c - x) + g).
//
if ((col > 0))
{
daxpy(col2, dtm, p, _p_offset, 1, c, _c_offset, 1);
}
if ((iprint > 100))
{
for (i = 1; i <= n; i++)
{
// DISPLAY: xcp[(i - (1)) + _xcp_offset];
}
// DISPLAY: "'Cauchy X = ',/,(4x,1p,6(1x,d11.4))"
}
if ((iprint >= 99))
{
// DISPLAY: '---------------- exit CAUCHY----------------------'
}
}