internal static void subsm(int n,
int m, int nsub, int[] ind, int _ind_offset,
double[] l, int _l_offset, double[] u, int _u_offset,
int[] nbd, int _nbd_offset, double[] x, int _x_offset,
double[] d, int _d_offset, double[] xp, int _xp_offset,
double[] ws, int _ws_offset, double[] wy, int _wy_offset,
double theta, double[] xx, int _xx_offset, double[] gg, int _gg_offset,
int col, int head, ref int iword,
double[] wv, int _wv_offset, double[] wn, int _wn_offset, int iprint, ref int info)
{
int pointr = 0;
int m2 = 0;
int col2 = 0;
int ibd = 0;
int jy = 0;
int js = 0;
int i = 0;
int j = 0;
int k = 0;
double alpha = 0.0d;
double xk = 0.0d;
double dk = 0.0d;
double temp1 = 0.0d;
double temp2 = 0.0d;
double dd_p = 0.0d;
if ((nsub <= 0))
{
return;
}
if ((iprint >= 99))
{
// DISPLAY: "/,'----------------SUBSM entered-----------------'
}
//
// Compute wv = W'Zd.
//
pointr = head;
{
for (i = 1; i <= col; i++)
{
temp1 = 0.0;
temp2 = 0.0;
{
for (j = 1; j <= nsub; j++)
{
k = ind[(j - (1)) + _ind_offset];
temp1 = (temp1 + (wy[(k - (1)) + (pointr - (1))
* (n) + _wy_offset] * d[(j - (1)) + _d_offset]));
temp2 = (temp2 + (ws[(k - (1)) + (pointr - (1))
* (n) + _ws_offset] * d[(j - (1)) + _d_offset]));
}
}
wv[(i - (1)) + _wv_offset] = temp1;
wv[((col + i) - (1)) + _wv_offset] = (theta * temp2);
pointr = ((pointr) % (m) + 1);
}
}
//
// Compute wv:=K^(-1)wv.
//
m2 = (2 * m);
col2 = (2 * col);
dtrsl(wn, _wn_offset, m2, col2, wv, _wv_offset, 11, ref info);
if ((info != 0))
{
return;
}
{
for (i = 1; i <= col; i++)
{
wv[(i - (1)) + _wv_offset] = (-(wv[(i - (1)) + _wv_offset]));
}
}
dtrsl(wn, _wn_offset, m2, col2, wv, _wv_offset, 1, ref info);
if ((info != 0))
{
return;
}
//
// Compute d = (1/theta)d + (1/theta**2)Z'W wv.
//
pointr = head;
{
for (jy = 1; jy <= col; jy++)
{
js = (col + jy);
{
for (i = 1; i <= nsub; i++)
{
k = ind[(i - (1)) + _ind_offset];
d[(i - (1)) + _d_offset] = ((d[(i - (1)) + _d_offset]
+ ((wy[(k - (1)) + (pointr - (1)) * (n) + _wy_offset] * wv[(jy - (1))
+ _wv_offset]) / theta)) + (ws[(k - (1))
+ (pointr - (1)) * (n) + _ws_offset] * wv[(js - (1)) + _wv_offset]));
}
}
pointr = ((pointr) % (m) + 1);
}
}
dscal(nsub, (1.0 / theta), d, _d_offset, 1);
//
// ----------------------------------------------------
// Let us try the projection, d is the Newton direction
//
iword = 0;
dcopy(n, x, _x_offset, 1, xp, _xp_offset, 1);
// c
{
for (i = 1; i <= nsub; i++)
{
k = ind[(i - (1)) + _ind_offset];
dk = d[(i - (1)) + _d_offset];
xk = x[(k - (1)) + _x_offset];
if ((nbd[(k - (1)) + _nbd_offset] != 0))
{
if ((nbd[(k - (1)) + _nbd_offset] == 1))
{
x[(k - (1)) + _x_offset] = System.Math.Max(l[(k - (1)) + _l_offset], (xk + dk));
if ((x[(k - (1)) + _x_offset] == l[(k - (1)) + _l_offset]))
{
iword = 1;
}
}
else
{
if ((nbd[(k - (1)) + _nbd_offset] == 2))
{
xk = System.Math.Max(l[(k - (1)) + _l_offset], (xk + dk));
x[(k - (1)) + _x_offset] = System.Math.Min(u[(k - (1)) + _u_offset], xk);
if (((x[(k - (1)) + _x_offset] == l[(k - (1))
+ _l_offset]) || (x[(k - (1)) + _x_offset] == u[(k - (1)) + _u_offset])))
{
iword = 1;
}
}
else
{
if ((nbd[(k - (1)) + _nbd_offset] == 3))
{
x[(k - (1)) + _x_offset] = System.Math.Min(u[(k - (1)) + _u_offset], (xk + dk));
if ((x[(k - (1)) + _x_offset] == u[(k - (1)) + _u_offset]))
{
iword = 1;
}
}
}
}
}
else
{
x[(k - (1)) + _x_offset] = (xk + dk);
}
}
}
if ((iword == 0))
{
goto L911;
}
//
// check sign of the directional derivative
//
dd_p = 0.0;
{
for (i = 1; i <= n; i++)
{
dd_p = (dd_p + (((x[(i - (1)) + _x_offset]
- xx[(i - (1)) + _xx_offset])) * gg[(i - (1)) + _gg_offset]));
}
}
if ((dd_p > 0.0))
{
dcopy(n, xp, _xp_offset, 1, x, _x_offset, 1);
// DISPLAY: " Positive dir derivative in projection "
// DISPLAY: " Using the backtracking step "
}
else
{
goto L911;
}
//
// -----------------------------------------------------------------
//
alpha = 1.0;
temp1 = alpha;
ibd = 0;
{
for (i = 1; i <= nsub; i++)
{
k = ind[(i - (1)) + _ind_offset];
dk = d[(i - (1)) + _d_offset];
if ((nbd[(k - (1)) + _nbd_offset] != 0))
{
if (((dk < 0.0) && (nbd[(k - (1)) + _nbd_offset] <= 2)))
{
temp2 = (l[(k - (1)) + _l_offset] - x[(k - (1)) + _x_offset]);
if ((temp2 >= 0.0))
{
temp1 = 0.0;
}
else if (((dk * alpha) < temp2))
{
temp1 = (temp2 / dk);
}
}
else if (((dk > 0.0) && (nbd[(k - (1)) + _nbd_offset] >= 2)))
{
temp2 = (u[(k - (1)) + _u_offset] - x[(k - (1)) + _x_offset]);
if ((temp2 <= 0.0))
{
temp1 = 0.0;
}
else if (((dk * alpha) > temp2))
{
temp1 = (temp2 / dk);
}
}
if ((temp1 < alpha))
{
alpha = temp1;
ibd = i;
}
}
}
}
if ((alpha < 1.0))
{
dk = d[(ibd - (1)) + _d_offset];
k = ind[(ibd - (1)) + _ind_offset];
if ((dk > 0.0))
{
x[(k - (1)) + _x_offset] = u[(k - (1)) + _u_offset];
d[(ibd - (1)) + _d_offset] = 0.0;
}
else if ((dk < 0.0))
{
x[(k - (1)) + _x_offset] = l[(k - (1)) + _l_offset];
d[(ibd - (1)) + _d_offset] = 0.0;
}
}
{
for (i = 1; i <= nsub; i++)
{
k = ind[(i - (1)) + _ind_offset];
x[(k - (1)) + _x_offset] = (x[(k - (1)) + _x_offset] + (alpha * d[(i - (1)) + _d_offset]));
}
}
L911:
if ((iprint >= 99))
{
// DISPLAY: "----------------exit SUBSM --------------------"
}
return;
}