#include "lbfgsb.h"
static integer c__1 = 1;
int setulb(integer *n, integer *m, double *x,
double *l, double *u, integer *nbd, double *f, double
*g, double *factr, double *pgtol, double *wa, integer *
iwa, integer *task, integer *iprint, integer *csave, logical *lsave,
integer *isave, double *dsave)
{
integer i__1;
static integer ld, lr, lt, lz, lwa, lwn, lss, lxp, lws, lwt, lsy, lwy,
lsnd;
--iwa;
--g;
--nbd;
--u;
--l;
--x;
--wa;
--lsave;
--isave;
--dsave;
if ( *task == START ) {
isave[1] = *m * *n;
i__1 = *m;
isave[2] = i__1 * i__1;
i__1 = *m;
isave[3] = i__1 * i__1 << 2;
isave[4] = 1;
isave[5] = isave[4] + isave[1];
isave[6] = isave[5] + isave[1];
isave[7] = isave[6] + isave[2];
isave[8] = isave[7] + isave[2];
isave[9] = isave[8] + isave[2];
isave[10] = isave[9] + isave[3];
isave[11] = isave[10] + isave[3];
isave[12] = isave[11] + *n;
isave[13] = isave[12] + *n;
isave[14] = isave[13] + *n;
isave[15] = isave[14] + *n;
isave[16] = isave[15] + *n;
}
lws = isave[4];
lwy = isave[5];
lsy = isave[6];
lss = isave[7];
lwt = isave[8];
lwn = isave[9];
lsnd = isave[10];
lz = isave[11];
lr = isave[12];
ld = isave[13];
lt = isave[14];
lxp = isave[15];
lwa = isave[16];
mainlb(n, m, &x[1], &l[1], &u[1], &nbd[1], f, &g[1], factr, pgtol, &wa[
lws], &wa[lwy], &wa[lsy], &wa[lss], &wa[lwt], &wa[lwn], &wa[lsnd],
&wa[lz], &wa[lr], &wa[ld], &wa[lt], &wa[lxp], &wa[lwa], &iwa[1],
&iwa[*n + 1], &iwa[(*n << 1) + 1], task, iprint, csave, &lsave[1],
&isave[22], &dsave[1]);
return 0;
}
static double c_b7 = 0.;
int mainlb(integer *n, integer *m, double *x,
double *l, double *u, integer *nbd, double *f, double
*g, double *factr, double *pgtol, double *ws, double *
wy, double *sy, double *ss, double *wt, double *wn,
double *snd, double *z__, double *r__, double *d__,
double *t, double *xp, double *wa, integer *index,
integer *iwhere, integer *indx2, integer *task, integer *iprint,
integer *csave, logical *lsave, integer *isave, double *dsave)
{
integer ws_dim1, ws_offset, wy_dim1, wy_offset, sy_dim1, sy_offset,
ss_dim1, ss_offset, wt_dim1, wt_offset, wn_dim1, wn_offset,
snd_dim1, snd_offset, i__1=0;
double d__1, d__2;
fileType o__1=NULL;
static integer i__, k;
static double gd, dr, rr, dtd;
static integer col;
static double tol;
static logical wrk;
static double stp, cpu1, cpu2;
static integer head;
static double fold;
static integer nact;
static double ddum;
static integer info, nseg;
static double time;
static integer nfgv, ifun, iter;
static integer wordTemp;
static integer *word=&wordTemp;
static double time1, time2;
static integer iback;
static double gdold;
static integer nfree;
static logical boxed;
static integer itail;
static double theta;
static double dnorm;
static integer nskip, iword;
static double xstep, stpmx;
static integer ileave;
static double cachyt;
static integer itfile;
static double epsmch;
static logical updatd;
static double sbtime;
static logical prjctd;
static integer iupdat;
static double sbgnrm;
static logical cnstnd;
static integer nenter;
static double lnscht;
static integer nintol;
--indx2;
--iwhere;
--index;
--xp;
--t;
--d__;
--r__;
--z__;
--g;
--nbd;
--u;
--l;
--x;
--wa;
snd_dim1 = 2 * *m;
snd_offset = 1 + snd_dim1;
snd -= snd_offset;
wn_dim1 = 2 * *m;
wn_offset = 1 + wn_dim1;
wn -= wn_offset;
wt_dim1 = *m;
wt_offset = 1 + wt_dim1;
wt -= wt_offset;
ss_dim1 = *m;
ss_offset = 1 + ss_dim1;
ss -= ss_offset;
sy_dim1 = *m;
sy_offset = 1 + sy_dim1;
sy -= sy_offset;
wy_dim1 = *n;
wy_offset = 1 + wy_dim1;
wy -= wy_offset;
ws_dim1 = *n;
ws_offset = 1 + ws_dim1;
ws -= ws_offset;
--lsave;
--isave;
--dsave;
if ( *task == START ) {
epsmch = DBL_EPSILON;
timer(&time1);
col = 0;
head = 1;
theta = 1.;
iupdat = 0;
updatd = FALSE_;
iback = 0;
itail = 0;
iword = 0;
nact = 0;
ileave = 0;
nenter = 0;
fold = 0.;
dnorm = 0.;
cpu1 = 0.;
gd = 0.;
stpmx = 0.;
sbgnrm = 0.;
stp = 0.;
gdold = 0.;
dtd = 0.;
iter = 0;
nfgv = 0;
nseg = 0;
nintol = 0;
nskip = 0;
nfree = *n;
ifun = 0;
tol = *factr * epsmch;
cachyt = 0.;
sbtime = 0.;
lnscht = 0.;
*word = WORD_DEFAULT;
info = 0;
itfile = 8;
errclb(n, m, factr, &l[1], &u[1], &nbd[1], task, &info, &k, (ftnlen)
60);
if ( IS_ERROR(*task) ){
prn3lb(n, &x[1], f, task, iprint, &info, o__1, &iter, &nfgv, &
nintol, &nskip, &nact, &sbgnrm, &c_b7, &nseg, word, &
iback, &stp, &xstep, &k, &cachyt, &sbtime, &lnscht, (
ftnlen)60, (ftnlen)3);
return 0;
}
prn1lb(n, m, &l[1], &u[1], &x[1], iprint, o__1, &epsmch);
active(n, &l[1], &u[1], &nbd[1], &x[1], &iwhere[1], iprint, &prjctd,
&cnstnd, &boxed);
} else {
prjctd = lsave[1];
cnstnd = lsave[2];
boxed = lsave[3];
updatd = lsave[4];
nintol = isave[1];
itfile = isave[3];
iback = isave[4];
nskip = isave[5];
head = isave[6];
col = isave[7];
itail = isave[8];
iter = isave[9];
iupdat = isave[10];
nseg = isave[12];
nfgv = isave[13];
info = isave[14];
ifun = isave[15];
iword = isave[16];
nfree = isave[17];
nact = isave[18];
ileave = isave[19];
nenter = isave[20];
theta = dsave[1];
fold = dsave[2];
tol = dsave[3];
dnorm = dsave[4];
epsmch = dsave[5];
cpu1 = dsave[6];
cachyt = dsave[7];
sbtime = dsave[8];
lnscht = dsave[9];
time1 = dsave[10];
gd = dsave[11];
stpmx = dsave[12];
sbgnrm = dsave[13];
stp = dsave[14];
gdold = dsave[15];
dtd = dsave[16];
if ( *task == FG_LN ) {
goto L666;
}
if ( *task == NEW_X ) {
goto L777;
}
if ( *task == FG_ST ) {
goto L111;
}
if ( IS_STOP(*task) ) {
if ( *task == STOP_CPU ) {
dcopy(n, &t[1], &c__1, &x[1], &c__1);
dcopy(n, &r__[1], &c__1, &g[1], &c__1);
*f = fold;
}
goto L999;
}
}
*task = FG_START;
goto L1000;
L111:
nfgv = 1;
projgr(n, &l[1], &u[1], &nbd[1], &x[1], &g[1], &sbgnrm);
if (*iprint >= 1) {
printf("At iterate %5ld, f(x)= %5.2e, ||proj grad||_infty = %.2e\n",iter,*f,sbgnrm );
}
if (sbgnrm <= *pgtol) {
*task = CONV_GRAD;
goto L999;
}
L222:
if (*iprint >= 99) {
printf("ITERATION %5ld\n", i__1 );
}
iword = -1;
if (! cnstnd && col > 0) {
dcopy(n, &x[1], &c__1, &z__[1], &c__1);
wrk = updatd;
nseg = 0;
goto L333;
}
timer(&cpu1);
info = 0;
cauchy(n, &x[1], &l[1], &u[1], &nbd[1], &g[1], &indx2[1], &iwhere[1], &t[
1], &d__[1], &z__[1], m, &wy[wy_offset], &ws[ws_offset], &sy[
sy_offset], &wt[wt_offset], &theta, &col, &head, &wa[1], &wa[(*m
<< 1) + 1], &wa[(*m << 2) + 1], &wa[*m * 6 + 1], &nseg, iprint, &
sbgnrm, &info, &epsmch);
if (info != 0) {
info = 0;
col = 0;
head = 1;
theta = 1.;
iupdat = 0;
updatd = FALSE_;
timer(&cpu2);
cachyt = cachyt + cpu2 - cpu1;
goto L222;
}
timer(&cpu2);
cachyt = cachyt + cpu2 - cpu1;
nintol += nseg;
freev(n, &nfree, &index[1], &nenter, &ileave, &indx2[1], &iwhere[1], &
wrk, &updatd, &cnstnd, iprint, &iter);
nact = *n - nfree;
L333:
if (nfree == 0 || col == 0) {
goto L555;
}
timer(&cpu1);
if (wrk) {
formk(n, &nfree, &index[1], &nenter, &ileave, &indx2[1], &iupdat, &
updatd, &wn[wn_offset], &snd[snd_offset], m, &ws[ws_offset], &
wy[wy_offset], &sy[sy_offset], &theta, &col, &head, &info);
}
if (info != 0) {
if (*iprint >= 1) {
printf(" Nonpositive definiteness in Cholesky factorization in formk;\n");
printf(" refresh the lbfgs memory and restart the iteration.\n");
}
info = 0;
col = 0;
head = 1;
theta = 1.;
iupdat = 0;
updatd = FALSE_;
timer(&cpu2);
sbtime = sbtime + cpu2 - cpu1;
goto L222;
}
cmprlb(n, m, &x[1], &g[1], &ws[ws_offset], &wy[wy_offset], &sy[sy_offset]
, &wt[wt_offset], &z__[1], &r__[1], &wa[1], &index[1], &theta, &
col, &head, &nfree, &cnstnd, &info);
if (info != 0) {
goto L444;
}
subsm(n, m, &nfree, &index[1], &l[1], &u[1], &nbd[1], &z__[1], &r__[1], &
xp[1], &ws[ws_offset], &wy[wy_offset], &theta, &x[1], &g[1], &col,
&head, &iword, &wa[1], &wn[wn_offset], iprint, &info);
L444:
if (info != 0) {
if (*iprint >= 1) {
printf(" Singular triangular system detected;\n");
printf(" refresh the lbfgs memory and restart the iteration.\n");
}
info = 0;
col = 0;
head = 1;
theta = 1.;
iupdat = 0;
updatd = FALSE_;
timer(&cpu2);
sbtime = sbtime + cpu2 - cpu1;
goto L222;
}
timer(&cpu2);
sbtime = sbtime + cpu2 - cpu1;
L555:
i__1 = *n;
for (i__ = 1; i__ <= i__1; ++i__) {
d__[i__] = z__[i__] - x[i__];
}
timer(&cpu1);
L666:
lnsrlb(n, &l[1], &u[1], &nbd[1], &x[1], f, &fold, &gd, &gdold, &g[1], &
d__[1], &r__[1], &t[1], &z__[1], &stp, &dnorm, &dtd, &xstep, &
stpmx, &iter, &ifun, &iback, &nfgv, &info, task, &boxed, &cnstnd,
csave, &isave[22], iprint, &dsave[17]);
if (info != 0 || iback >= 20) {
dcopy(n, &t[1], &c__1, &x[1], &c__1);
dcopy(n, &r__[1], &c__1, &g[1], &c__1);
*f = fold;
if (col == 0) {
if (info == 0) {
info = -9;
--nfgv;
--ifun;
--iback;
}
*task = ABNORMAL;
++iter;
goto L999;
} else {
if (*iprint >= 1) {
printf(" Bad direction in the line search;\n");
printf(" refresh the lbfgs memory and restart the iteration.\n");
}
if (info == 0) {
--nfgv;
}
info = 0;
col = 0;
head = 1;
theta = 1.;
iupdat = 0;
updatd = FALSE_;
*task = RESTART;
timer(&cpu2);
lnscht = lnscht + cpu2 - cpu1;
goto L222;
}
} else if ( *task == FG_LN ) {
goto L1000;
} else {
timer(&cpu2);
lnscht = lnscht + cpu2 - cpu1;
++iter;
projgr(n, &l[1], &u[1], &nbd[1], &x[1], &g[1], &sbgnrm);
prn2lb(n, &x[1], f, &g[1], iprint, o__1, &iter, &nfgv, &nact, &
sbgnrm, &nseg, word, &iword, &iback, &stp, &xstep, (ftnlen)3);
goto L1000;
}
L777:
if (sbgnrm <= *pgtol) {
*task = CONV_GRAD;
goto L999;
}
d__1 = fabs(fold), d__2 = fabs(*f), d__1 = fmax(d__1,d__2);
ddum = fmax(d__1,1.);
if (fold - *f <= tol * ddum) {
*task = CONV_F;
if (iback >= 10) {
info = -5;
}
goto L999;
}
i__1 = *n;
for (i__ = 1; i__ <= i__1; ++i__) {
r__[i__] = g[i__] - r__[i__];
}
rr = ddot(n, &r__[1], &c__1, &r__[1], &c__1);
if (stp == 1.) {
dr = gd - gdold;
ddum = -gdold;
} else {
dr = (gd - gdold) * stp;
dscal(n, &stp, &d__[1], &c__1);
ddum = -gdold * stp;
}
if (dr <= epsmch * ddum) {
++nskip;
updatd = FALSE_;
if (*iprint >= 1) {
printf(" ys=%10.3e -gs=%10.3e BFGS update SKIPPED\n", dr, ddum );
}
goto L888;
}
updatd = TRUE_;
++iupdat;
matupd(n, m, &ws[ws_offset], &wy[wy_offset], &sy[sy_offset], &ss[
ss_offset], &d__[1], &r__[1], &itail, &iupdat, &col, &head, &
theta, &rr, &dr, &stp, &dtd);
formt(m, &wt[wt_offset], &sy[sy_offset], &ss[ss_offset], &col, &theta, &
info);
if (info != 0) {
if (*iprint >= 1) {
printf(" Nonpositive definiteness in Cholesky factorization in formt;\n");
printf(" refresh the lbfgs memory and restart the iteration.\n");
}
info = 0;
col = 0;
head = 1;
theta = 1.;
iupdat = 0;
updatd = FALSE_;
goto L222;
}
L888:
goto L222;
L999:
timer(&time2);
time = time2 - time1;
prn3lb(n, &x[1], f, task, iprint, &info, o__1, &iter, &nfgv, &nintol,
&nskip, &nact, &sbgnrm, &time, &nseg, word, &iback, &stp, &xstep,
&k, &cachyt, &sbtime, &lnscht, (ftnlen)60, (ftnlen)3);
L1000:
lsave[1] = prjctd;
lsave[2] = cnstnd;
lsave[3] = boxed;
lsave[4] = updatd;
isave[1] = nintol;
isave[3] = itfile;
isave[4] = iback;
isave[5] = nskip;
isave[6] = head;
isave[7] = col;
isave[8] = itail;
isave[9] = iter;
isave[10] = iupdat;
isave[12] = nseg;
isave[13] = nfgv;
isave[14] = info;
isave[15] = ifun;
isave[16] = iword;
isave[17] = nfree;
isave[18] = nact;
isave[19] = ileave;
isave[20] = nenter;
dsave[1] = theta;
dsave[2] = fold;
dsave[3] = tol;
dsave[4] = dnorm;
dsave[5] = epsmch;
dsave[6] = cpu1;
dsave[7] = cachyt;
dsave[8] = sbtime;
dsave[9] = lnscht;
dsave[10] = time1;
dsave[11] = gd;
dsave[12] = stpmx;
dsave[13] = sbgnrm;
dsave[14] = stp;
dsave[15] = gdold;
dsave[16] = dtd;
return 0;
}