private static void mainlb(int n,
int m,
double[] x, int _x_offset,
double[] l, int _l_offset,
double[] u, int _u_offset,
int[] nbd, int _nbd_offset,
ref double f,
double[] g, int _g_offset,
double factr,
double pgtol,
double[] ws, int _ws_offset,
double[] wy, int _wy_offset,
double[] sy, int _sy_offset,
double[] ss, int _ss_offset,
double[] wt, int _wt_offset,
double[] wn, int _wn_offset,
double[] snd, int _snd_offset,
double[] z, int _z_offset,
double[] r, int _r_offset,
double[] d, int _d_offset,
double[] t, int _t_offset,
double[] xp, int _xp_offset,
double[] wa, int _wa_offset,
int[] index, int _index_offset,
int[] iwhere, int _iwhere_offset,
int[] indx2, int _indx2_offset,
ref string task,
int iprint,
ref string csave,
bool[] lsave, int _lsave_offset,
int[] isave, int _isave_offset,
double[] dsave, int _dsave_offset)
{
bool prjctd = false;
bool cnstnd = false;
bool boxed = false;
bool updatd = false;
bool wrk = false;
int i = 0;
int k = 0;
int nintol = 0;
int itfile = 0;
int iback = 0;
int nskip = 0;
int head = 0;
int col = 0;
int iter = 0;
int itail = 0;
int iupdat = 0;
int nseg = 0;
int nfgv = 0;
int info = 0;
int ifun = 0;
int iword = 0;
int nfree = 0;
int nact = 0;
int ileave = 0;
int nenter = 0;
double theta = 0.0d;
double fold = 0.0d;
double dr = 0.0d;
double rr = 0.0d;
double tol = 0.0d;
double xstep = 0.0d;
double sbgnrm = 0.0d;
double ddum = 0.0d;
double dnorm = 0.0d;
double dtd = 0.0d;
double epsmch = 0.0d;
double cpu1 = 0.0d;
double cpu2 = 0.0d;
double cachyt = 0.0d;
double sbtime = 0.0d;
double lnscht = 0.0d;
double time1 = 0.0d;
// double time2 = 0.0d;
double gd = 0.0d;
double gdold = 0.0d;
double stp = 0.0d;
double stpmx = 0.0d;
// double time = 0.0d;
// float epsilon = 0.0f;
if ((task.StartsWith("START", StringComparison.OrdinalIgnoreCase)))
{
//
// epsmch = (double)(Epsilon.epsilon(1.0));
epsmch = Constants.DoubleEpsilon;
//
//Timer.timer(time1);
//
// c Initialize counters and scalars when task='START'.
//
// c for the limited memory BFGS matrices:
col = 0;
head = 1;
theta = 1.0;
iupdat = 0;
updatd = false;
iback = 0;
itail = 0;
iword = 0;
nact = 0;
ileave = 0;
nenter = 0;
fold = 0.0;
dnorm = 0.0;
cpu1 = 0.0;
gd = 0.0;
stpmx = 0.0;
sbgnrm = 0.0;
stp = 0.0;
gdold = 0.0;
dtd = 0.0;
//
// c for operation counts:
iter = 0;
nfgv = 0;
nseg = 0;
nintol = 0;
nskip = 0;
nfree = n;
ifun = 0;
// c for stopping tolerance:
tol = (factr * epsmch);
//
// c for measuring running time:
cachyt = (double)(0);
sbtime = (double)(0);
lnscht = (double)(0);
//
// c 'info' records the termination information.
info = 0;
//
itfile = 8;
if ((iprint >= 1))
{
// c open a summary file 'iterate.dat'
; // WARNING: Unimplemented statement in Fortran source.
}
//
// c Check the input arguments for errors.
//
errclb(n, m, factr, l, _l_offset, u, _u_offset,
nbd, _nbd_offset, ref task, ref info, ref k);
if ((task.StartsWith("ERROR", StringComparison.OrdinalIgnoreCase)))
{
/*
Prn3lb.prn3lb(n, x, _x_offset, f, task, iprint,
info, itfile, iter, nfgv, nintol, nskip, nact, sbgnrm, 0.0, nseg, word,
iback, stp, xstep, k, cachyt, sbtime, lnscht);
*/
return;
}
//
// Prn1lb.prn1lb(n, m, l, _l_offset, u, _u_offset, x, _x_offset, iprint, itfile, epsmch);
//
// c Initialize iwhere & project x onto the feasible set.
//
active(n, l, _l_offset, u, _u_offset, nbd, _nbd_offset, x,
_x_offset, iwhere, _iwhere_offset, iprint, ref prjctd, ref cnstnd, ref boxed);
//
// c The end of the initialization.
//
}
else
{
// c restore local variables.
//
prjctd = lsave[(1 - (1)) + _lsave_offset];
cnstnd = lsave[(2 - (1)) + _lsave_offset];
boxed = lsave[(3 - (1)) + _lsave_offset];
updatd = lsave[(4 - (1)) + _lsave_offset];
//
nintol = isave[(1 - (1)) + _isave_offset];
itfile = isave[(3 - (1)) + _isave_offset];
iback = isave[(4 - (1)) + _isave_offset];
nskip = isave[(5 - (1)) + _isave_offset];
head = isave[(6 - (1)) + _isave_offset];
col = isave[(7 - (1)) + _isave_offset];
itail = isave[(8 - (1)) + _isave_offset];
iter = isave[(9 - (1)) + _isave_offset];
iupdat = isave[(10 - (1)) + _isave_offset];
nseg = isave[(12 - (1)) + _isave_offset];
nfgv = isave[(13 - (1)) + _isave_offset];
info = isave[(14 - (1)) + _isave_offset];
ifun = isave[(15 - (1)) + _isave_offset];
iword = isave[(16 - (1)) + _isave_offset];
nfree = isave[(17 - (1)) + _isave_offset];
nact = isave[(18 - (1)) + _isave_offset];
ileave = isave[(19 - (1)) + _isave_offset];
nenter = isave[(20 - (1)) + _isave_offset];
//
theta = dsave[(1 - (1)) + _dsave_offset];
fold = dsave[(2 - (1)) + _dsave_offset];
tol = dsave[(3 - (1)) + _dsave_offset];
dnorm = dsave[(4 - (1)) + _dsave_offset];
epsmch = dsave[(5 - (1)) + _dsave_offset];
cpu1 = dsave[(6 - (1)) + _dsave_offset];
cachyt = dsave[(7 - (1)) + _dsave_offset];
sbtime = dsave[(8 - (1)) + _dsave_offset];
lnscht = dsave[(9 - (1)) + _dsave_offset];
time1 = dsave[(10 - (1)) + _dsave_offset];
gd = dsave[(11 - (1)) + _dsave_offset];
stpmx = dsave[(12 - (1)) + _dsave_offset];
sbgnrm = dsave[(13 - (1)) + _dsave_offset];
stp = dsave[(14 - (1)) + _dsave_offset];
gdold = dsave[(15 - (1)) + _dsave_offset];
dtd = dsave[(16 - (1)) + _dsave_offset];
//
// c After returning from the driver go to the point where execution
// c is to resume.
//
if ((task.Substring((1) - 1, 5).StartsWith("FG_LN", StringComparison.OrdinalIgnoreCase)))
{
goto L666;
}
if ((task.Substring((1) - 1, 5).StartsWith("NEW_X", StringComparison.OrdinalIgnoreCase)))
{
goto L777;
}
if ((task.Substring((1) - 1, 5).StartsWith("FG_ST", StringComparison.OrdinalIgnoreCase)))
{
goto L111;
}
if ((task.Substring((1) - 1, 4).StartsWith("STOP", StringComparison.OrdinalIgnoreCase)))
{
if ((task.Substring((7) - 1, 9).StartsWith("CPU", StringComparison.OrdinalIgnoreCase)))
{
// c restore the previous iterate.
dcopy(n, t, _t_offset, 1, x, _x_offset, 1);
dcopy(n, r, _r_offset, 1, g, _g_offset, 1);
f = fold;
}
goto L999;
}
}
//
// c Compute f0 and g0.
//
task = "FG_START";
// c return to the driver to calculate f and g; reenter at 111.
goto L1000;
L111:
nfgv = 1;
//
// c Compute the infinity norm of the (-) projected gradient.
//
projgr(n, l, _l_offset, u, _u_offset, nbd, _nbd_offset,
x, _x_offset, g, _g_offset, ref sbgnrm);
if ((iprint >= 1))
{
// DISPLAY: iter, f, sbgnrm
// 'At iterate',i5,4x,'f= ',1p,d12.5,4X,'|proj g|= ',1P,D12.5"
// DISPLAY: iter, nfgv, sbgnrm, f
// "2(1x,i4),5x,'-',5x,'-',3x,'-',5x,'-',5x,'-',8x,'-',3x,1p,2(1x,d10.3)"
}
if ((sbgnrm <= pgtol))
{
// terminate the algorithm.
task = "CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL";
goto L999;
}
//
// c ----------------- the beginning of the loop --------------------------
//
L222:
if ((iprint >= 99))
{
// DISPLAY: (iter + 1))); ITERATION ',i5"
}
iword = -1;
if (((!cnstnd) && (col > 0)))
{
// skip the search for GCP.
dcopy(n, x, _x_offset, 1, z, _z_offset, 1);
wrk = updatd;
nseg = 0;
goto L333;
}
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
// c
// c Compute the Generalized Cauchy Point (GCP).
// c
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
//
cauchy(n, x, _x_offset, l, _l_offset, u, _u_offset, nbd, _nbd_offset,
g, _g_offset, indx2, _indx2_offset, iwhere, _iwhere_offset, t, _t_offset,
d, _d_offset, z, _z_offset, m, wy, _wy_offset, ws, _ws_offset, sy, _sy_offset,
wt, _wt_offset, theta, col, head, wa, (1 - (1)) + _wa_offset, wa,
(((2 * m) + 1) - (1)) + _wa_offset, wa, (((4 * m) + 1) - (1)) + _wa_offset, wa,
(((6 * m) + 1) - (1)) + _wa_offset, ref nseg, iprint, sbgnrm, ref info, epsmch);
if ((info != 0))
{
// c singular triangular system detected; refresh the lbfgs memory.
if ((iprint >= 1))
{
// DISPLAY: Singular triangular system detected;',/,
// refresh the lbfgs memory and restart the iteration.'"
}
info = 0;
col = 0;
head = 1;
theta = 1.0;
iupdat = 0;
updatd = false;
cachyt = ((cachyt + cpu2) - cpu1);
goto L222;
}
cachyt = ((cachyt + cpu2) - cpu1);
nintol = (nintol + nseg);
//
// Count the entering and leaving variables for iter > 0;
// find the index set of free and active variables at the GCP.
//
freev(n, ref nfree, index, _index_offset, ref nenter, ref ileave, indx2, _indx2_offset,
iwhere, _iwhere_offset, ref wrk, updatd, cnstnd, iprint, iter);
nact = (n - nfree);
//
L333:
//
// If there are no free variables or B=theta*I,
// then skip the subspace minimization.
//
if (((nfree == 0) || (col == 0)))
{
goto L555;
}
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
// c
// c Subspace minimization.
// c
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
//
// c Form the LEL^T factorization of the indefinite
// c matrix K = [-D -Y'ZZ'Y/theta L_a'-R_z' ]
// c [L_a -R_z theta*S'AA'S ]
// c where E = [-I 0]
// c [ 0 I]
//
if (wrk)
{
formk(n, nfree, index, _index_offset, nenter,
ileave, indx2, _indx2_offset, iupdat, updatd, wn, _wn_offset,
snd, _snd_offset, m, ws, _ws_offset, wy, _wy_offset, sy, _sy_offset,
theta, col, head, ref info);
}
if ((info != 0))
{
// nonpositive definiteness in Cholesky factorization;
// refresh the lbfgs memory and restart the iteration.
if ((iprint >= 1))
{
// DISPLAY: ' Nonpositive definiteness in Cholesky factorization in formk;'
// ' refresh the lbfgs memory and restart the iteration.'"
}
info = 0;
col = 0;
head = 1;
theta = 1.0;
iupdat = 0;
updatd = false;
sbtime = ((sbtime + cpu2) - cpu1);
goto L222;
}
//
// compute r=-Z'B(xcp-xk)-Z'g (using wa(2m+1)=W'(xcp-x) from 'cauchy')
//
cmprlb(n, m, x, _x_offset, g, _g_offset, ws, _ws_offset, wy, _wy_offset,
sy, _sy_offset, wt, _wt_offset, z, _z_offset, r, _r_offset, wa, _wa_offset,
index, _index_offset, theta, col, head, nfree, cnstnd, ref info);
if ((info != 0))
{
goto L444;
}
//
// c-jlm-jn call the direct method.
//
subsm(n, m, nfree, index, _index_offset, l, _l_offset, u, _u_offset,
nbd, _nbd_offset, z, _z_offset, r, _r_offset, xp, _xp_offset, ws, _ws_offset,
wy, _wy_offset, theta, x, _x_offset, g, _g_offset, col, head,
ref iword, wa, _wa_offset, wn, _wn_offset, iprint, ref info);
L444:
if ((info != 0))
{
// singular triangular system detected;
// refresh the lbfgs memory and restart the iteration.
if ((iprint >= 1))
{
// DISPLAY: ' Singular triangular system detected;',
// refresh the lbfgs memory and restart the iteration.'"
}
info = 0;
col = 0;
head = 1;
theta = 1.0;
iupdat = 0;
updatd = false;
goto L222;
}
L555:
//
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
// c
// c Line search and optimality tests.
// c
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
//
// c Generate the search direction d:=z-x.
//
{
for (i = 1; i <= n; i++)
{
d[(i - (1)) + _d_offset] = (z[(i - (1)) + _z_offset] - x[(i - (1)) + _x_offset]);
}
}
L666:
lnsrlb(n, l, _l_offset, u, _u_offset, nbd, _nbd_offset, x, _x_offset,
f, ref fold, ref gd, ref gdold, g, _g_offset, d, _d_offset, r, _r_offset, t, _t_offset,
z, _z_offset, ref stp, ref dnorm, ref dtd, ref xstep, ref stpmx, iter, ref ifun,
ref iback, ref nfgv, ref info, ref task, boxed, cnstnd, ref csave, isave,
(22 - (1)) + _isave_offset, dsave, (17 - (1)) + _dsave_offset);
if (((info != 0) || (iback >= 20)))
{
// restore the previous iterate.
dcopy(n, t, _t_offset, 1, x, _x_offset, 1);
dcopy(n, r, _r_offset, 1, g, _g_offset, 1);
f = fold;
if ((col == 0))
{
// abnormal termination.
if ((info == 0))
{
info = -9;
// restore the actual number of f and g evaluations etc.
nfgv = (nfgv - 1);
ifun = (ifun - 1);
iback = (iback - 1);
}
task = "ABNORMAL_TERMINATION_IN_LNSRCH";
iter = (iter + 1);
goto L999;
}
else
{
// refresh the lbfgs memory and restart the iteration.
if ((iprint >= 1))
{
// DISPLAY: Bad direction in the line search;'
// refresh the lbfgs memory and restart the iteration.
}
if ((info == 0))
{
nfgv = (nfgv - 1);
}
info = 0;
col = 0;
head = 1;
theta = 1.0;
iupdat = 0;
updatd = false;
task = "RESTART_FROM_LNSRCH";
goto L222;
}
}
else if ((task.StartsWith("FG_LN", StringComparison.OrdinalIgnoreCase)))
{
// return to the driver for calculating f and g; reenter at 666.
goto L1000;
}
else
{
// calculate and print out the quantities related to the new X.
iter = (iter + 1);
//
// Compute the infinity norm of the projected (-)gradient.
//
projgr(n, l, _l_offset, u, _u_offset, nbd, _nbd_offset,
x, _x_offset, g, _g_offset, ref sbgnrm);
//
// Print iteration information.
//
/* Prn2lb.prn2lb(n, x, _x_offset, f, g, _g_offset, iprint, itfile,
iter, nfgv, nact, sbgnrm, nseg, ref word,
iword, iback, stp, xstep); */
goto L1000;
}
L777:
//
// c Test for termination.
//
if ((sbgnrm <= pgtol))
{
// terminate the algorithm.
task = "CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL";
goto L999;
}
//
ddum = Accord.Math.Tools.Max(System.Math.Abs(fold), System.Math.Abs(f), 1.0);
if ((((fold - f)) <= (tol * ddum)))
{
// terminate the algorithm.
task = "CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH";
if ((iback >= 10))
{
info = -5;
}
// i.e., to issue a warning if iback>10 in the line search.
goto L999;
}
//
// Compute d=newx-oldx, r=newg-oldg, rr=y'y and dr=y's.
//
{
for (i = 1; i <= n; i++)
{
r[(i - (1)) + _r_offset] = (g[(i - (1)) + _g_offset] - r[(i - (1)) + _r_offset]);
}
}
rr = ddot(n, r, _r_offset, 1, r, _r_offset, 1);
if ((stp == 1.0))
{
dr = (gd - gdold);
ddum = (-(gdold));
}
else
{
dr = (((gd - gdold)) * stp);
dscal(n, stp, d, _d_offset, 1);
ddum = (-((gdold * stp)));
}
if ((dr <= (epsmch * ddum)))
{
// skip the L-BFGS update.
nskip = (nskip + 1);
updatd = false;
if ((iprint >= 1))
{
// DISPLAY: dr, ddum
// DISPLAY: ' ys=',1p,e10.3,' -gs=',1P,E10.3,' BFGS update SKIPPED'"
}
goto L888;
}
//
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
// c
// c Update the L-BFGS matrix.
// c
// cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
//
updatd = true;
iupdat = (iupdat + 1);
//
// c Update matrices WS and WY and form the middle matrix in B.
//
matupd(n, m, ws, _ws_offset, wy, _wy_offset, sy, _sy_offset,
ss, _ss_offset, d, _d_offset, r, _r_offset, ref itail, iupdat, ref col,
ref head, ref theta, rr, dr, stp, dtd);
//
// c Form the upper half of the pds T = theta*SS + L*D^(-1)*L';
// c Store T in the upper triangular of the array wt;
// c Cholesky factorize T to J*J' with
// c J' stored in the upper triangular of wt.
//
formt(m, wt, _wt_offset, sy, _sy_offset, ss,
_ss_offset, col, theta, ref info);
//
if ((info != 0))
{
// c nonpositive definiteness in Cholesky factorization;
// c refresh the lbfgs memory and restart the iteration.
if ((iprint >= 1))
{
// DISPLAY:"Nonpositive definiteness in Cholesky factorization in formt
// refresh the lbfgs memory and restart the iteration.'"
}
info = 0;
col = 0;
head = 1;
theta = 1.0;
iupdat = 0;
updatd = false;
goto L222;
}
//
// Now the inverse of the middle matrix in B is
//
// [ D^(1/2) O ] [ -D^(1/2) D^(-1/2)*L' ]
// [ -L*D^(-1/2) J ] [ 0 J' ]
//
L888:
//
// c -------------------- the end of the loop -----------------------------
//
goto L222;
L999:
//Timer.timer(time2);
//time = (time2 - time1);
/*Prn3lb.prn3lb(n, x, _x_offset, f, task, iprint, info, itfile,
iter, nfgv, nintol, nskip, nact, sbgnrm, time, nseg, word,
iback, stp, xstep, k, cachyt, sbtime, lnscht);*/
L1000:
//
// Save local variables.
//
lsave[(1 - (1)) + _lsave_offset] = prjctd;
lsave[(2 - (1)) + _lsave_offset] = cnstnd;
lsave[(3 - (1)) + _lsave_offset] = boxed;
lsave[(4 - (1)) + _lsave_offset] = updatd;
//
isave[(1 - (1)) + _isave_offset] = nintol;
isave[(3 - (1)) + _isave_offset] = itfile;
isave[(4 - (1)) + _isave_offset] = iback;
isave[(5 - (1)) + _isave_offset] = nskip;
isave[(6 - (1)) + _isave_offset] = head;
isave[(7 - (1)) + _isave_offset] = col;
isave[(8 - (1)) + _isave_offset] = itail;
isave[(9 - (1)) + _isave_offset] = iter;
isave[(10 - (1)) + _isave_offset] = iupdat;
isave[(12 - (1)) + _isave_offset] = nseg;
isave[(13 - (1)) + _isave_offset] = nfgv;
isave[(14 - (1)) + _isave_offset] = info;
isave[(15 - (1)) + _isave_offset] = ifun;
isave[(16 - (1)) + _isave_offset] = iword;
isave[(17 - (1)) + _isave_offset] = nfree;
isave[(18 - (1)) + _isave_offset] = nact;
isave[(19 - (1)) + _isave_offset] = ileave;
isave[(20 - (1)) + _isave_offset] = nenter;
//
dsave[(1 - (1)) + _dsave_offset] = theta;
dsave[(2 - (1)) + _dsave_offset] = fold;
dsave[(3 - (1)) + _dsave_offset] = tol;
dsave[(4 - (1)) + _dsave_offset] = dnorm;
dsave[(5 - (1)) + _dsave_offset] = epsmch;
dsave[(6 - (1)) + _dsave_offset] = cpu1;
dsave[(7 - (1)) + _dsave_offset] = cachyt;
dsave[(8 - (1)) + _dsave_offset] = sbtime;
dsave[(9 - (1)) + _dsave_offset] = lnscht;
dsave[(10 - (1)) + _dsave_offset] = time1;
dsave[(11 - (1)) + _dsave_offset] = gd;
dsave[(12 - (1)) + _dsave_offset] = stpmx;
dsave[(13 - (1)) + _dsave_offset] = sbgnrm;
dsave[(14 - (1)) + _dsave_offset] = stp;
dsave[(15 - (1)) + _dsave_offset] = gdold;
dsave[(16 - (1)) + _dsave_offset] = dtd;
return;
}