#include <assert.h>
#include <iostream>
#include "soplex/spxdefines.h"
#include "soplex/spxsolver.h"
#include "soplex/spxout.h"
namespace soplex
{
template <class R>
void SPxSolverBase<R>::shiftFvec()
{
R minrandom = 10.0 * entertol();
R maxrandom = 100.0 * entertol();
R allow = entertol() - epsilon();
assert(type() == ENTER);
assert(allow > 0);
for(int i = dim() - 1; i >= 0; --i)
{
if(theUBbound[i] + allow < (*theFvec)[i])
{
MSG_DEBUG(std::cout << "DSHIFT08 theUBbound[" << i << "] violated by " <<
(*theFvec)[i] - theUBbound[i] - allow << std::endl);
if(theUBbound[i] != theLBbound[i])
{
shiftUBbound(i, (*theFvec)[i] + random.next((double)minrandom, (double)maxrandom));
}
else
{
shiftUBbound(i, (*theFvec)[i]);
theLBbound[i] = theUBbound[i];
}
}
else if((*theFvec)[i] < theLBbound[i] - allow)
{
MSG_DEBUG(std::cout << "DSHIFT08 theLBbound[" << i << "] violated by " << theLBbound[i] -
(*theFvec)[i] - allow << std::endl);
if(theUBbound[i] != theLBbound[i])
shiftLBbound(i, (*theFvec)[i] - random.next((double)minrandom, (double)maxrandom));
else
{
shiftLBbound(i, (*theFvec)[i]);
theUBbound[i] = theLBbound[i];
}
}
}
#ifndef NDEBUG
testBounds();
MSG_DEBUG(std::cout << "DSHIFT01 shiftFvec: OK" << std::endl;)
#endif
}
template <class R>
void SPxSolverBase<R>::shiftPvec()
{
R minrandom = 10.0 * leavetol();
R maxrandom = 100.0 * leavetol();
R allow = leavetol() - epsilon();
bool tmp;
int i;
assert(type() == LEAVE);
assert(allow > 0.0);
for(i = dim() - 1; i >= 0; --i)
{
tmp = !isBasic(coId(i));
if((*theCoUbound)[i] + allow <= (*theCoPvec)[i] && tmp)
{
if((*theCoUbound)[i] != (*theCoLbound)[i])
shiftUCbound(i, (*theCoPvec)[i] + random.next((double)minrandom, (double)maxrandom));
else
{
shiftUCbound(i, (*theCoPvec)[i]);
(*theCoLbound)[i] = (*theCoUbound)[i];
}
}
else if((*theCoLbound)[i] - allow >= (*theCoPvec)[i] && tmp)
{
if((*theCoUbound)[i] != (*theCoLbound)[i])
shiftLCbound(i, (*theCoPvec)[i] - random.next((double)minrandom, (double)maxrandom));
else
{
shiftLCbound(i, (*theCoPvec)[i]);
(*theCoUbound)[i] = (*theCoLbound)[i];
}
}
}
for(i = coDim() - 1; i >= 0; --i)
{
tmp = !isBasic(id(i));
if((*theUbound)[i] + allow <= (*thePvec)[i] && tmp)
{
if((*theUbound)[i] != (*theLbound)[i])
shiftUPbound(i, (*thePvec)[i] + random.next((double)minrandom, (double)maxrandom));
else
{
shiftUPbound(i, (*thePvec)[i]);
(*theLbound)[i] = (*theUbound)[i];
}
}
else if((*theLbound)[i] - allow >= (*thePvec)[i] && tmp)
{
if((*theUbound)[i] != (*theLbound)[i])
shiftLPbound(i, (*thePvec)[i] - random.next((double)minrandom, (double)maxrandom));
else
{
shiftLPbound(i, (*thePvec)[i]);
(*theUbound)[i] = (*theLbound)[i];
}
}
}
#ifndef NDEBUG
testBounds();
MSG_DEBUG(std::cout << "DSHIFT02 shiftPvec: OK" << std::endl;)
#endif
}
template <class R>
void SPxSolverBase<R>::perturbMin(
const UpdateVector<R>& uvec,
VectorBase<R>& p_low,
VectorBase<R>& p_up,
R eps,
R p_delta,
int start,
int incr)
{
assert(uvec.dim() == p_low.dim());
assert(uvec.dim() == p_up.dim());
const R* vec = uvec.get_const_ptr();
R minrandom = 10.0 * p_delta;
R maxrandom = 100.0 * p_delta;
R x, l, u;
int i;
if(fullPerturbation)
{
eps = p_delta;
for(i = uvec.dim() - start - 1; i >= 0; i -= incr)
{
u = p_up[i];
l = p_low[i];
x = vec[i];
if(LT(u, R(infinity)) && NE(l, u) && u <= x + eps)
{
p_up[i] = x + random.next((double) minrandom, (double)maxrandom);
theShift += p_up[i] - u;
}
if(GT(l, R(-infinity)) && NE(l, u) && l >= x - eps)
{
p_low[i] = x - random.next((double)minrandom, (double)maxrandom);
theShift -= p_low[i] - l;
}
}
}
else
{
const R* upd = uvec.delta().values();
const IdxSet& idx = uvec.delta().indices();
for(int j = uvec.delta().size() - start - 1; j >= 0; j -= incr)
{
i = idx.index(j);
x = upd[i];
u = p_up[i];
l = p_low[i];
if(this->dualStatus(this->baseId(i)) == SPxBasisBase<R>::Desc::D_ON_BOTH)
{
continue;
}
if(x < -eps)
{
if(LT(u, R(infinity)) && NE(l, u) && vec[i] >= u - eps)
{
p_up[i] = vec[i] + random.next((double)minrandom, (double)maxrandom);
theShift += p_up[i] - u;
}
}
else if(x > eps)
{
if(GT(l, R(-infinity)) && NE(l, u) && vec[i] <= l + eps)
{
p_low[i] = vec[i] - random.next((double)minrandom, (double)maxrandom);
theShift -= p_low[i] - l;
}
}
}
}
}
template <class R>
void SPxSolverBase<R>::perturbMax(
const UpdateVector<R>& uvec,
VectorBase<R>& p_low,
VectorBase<R>& p_up,
R eps,
R p_delta,
int start,
int incr)
{
assert(uvec.dim() == p_low.dim());
assert(uvec.dim() == p_up.dim());
const R* vec = uvec.get_const_ptr();
R minrandom = 10.0 * p_delta;
R maxrandom = 100.0 * p_delta;
R x, l, u;
int i;
if(fullPerturbation)
{
eps = p_delta;
for(i = uvec.dim() - start - 1; i >= 0; i -= incr)
{
u = p_up[i];
l = p_low[i];
x = vec[i];
if(LT(u, R(infinity)) && NE(l, u) && u <= x + eps)
{
p_up[i] = x + random.next((double)minrandom, (double)maxrandom);
theShift += p_up[i] - u;
}
if(GT(l, R(-infinity)) && NE(l, u) && l >= x - eps)
{
p_low[i] = x - random.next((double)minrandom, (double)maxrandom);
theShift -= p_low[i] - l;
}
}
}
else
{
const R* upd = uvec.delta().values();
const IdxSet& idx = uvec.delta().indices();
for(int j = uvec.delta().size() - start - 1; j >= 0; j -= incr)
{
i = idx.index(j);
x = upd[i];
u = p_up[i];
l = p_low[i];
if(this->dualStatus(this->baseId(i)) == SPxBasisBase<R>::Desc::D_ON_BOTH)
{
continue;
}
if(x > eps)
{
if(LT(u, R(infinity)) && NE(l, u) && vec[i] >= u - eps)
{
p_up[i] = vec[i] + random.next((double)minrandom, (double)maxrandom);
theShift += p_up[i] - u;
}
}
else if(x < -eps)
{
if(GT(l, R(-infinity)) && NE(l, u) && vec[i] <= l + eps)
{
p_low[i] = vec[i] - random.next((double)minrandom, (double)maxrandom);
theShift -= p_low[i] - l;
}
}
}
}
}
template <class R>
void SPxSolverBase<R>::perturbMinEnter(void)
{
MSG_DEBUG(std::cout << "DSHIFT03 iteration= " << this->iteration() << ": perturbing " << shift();)
fVec().delta().setup();
perturbMin(fVec(), lbBound(), ubBound(), epsilon(), entertol());
MSG_DEBUG(std::cout << "\t->" << shift() << std::endl;)
}
template <class R>
void SPxSolverBase<R>::perturbMaxEnter(void)
{
MSG_DEBUG(std::cout << "DSHIFT04 iteration= " << this->iteration() << ": perturbing " << shift();)
fVec().delta().setup();
perturbMax(fVec(), lbBound(), ubBound(), epsilon(), entertol());
MSG_DEBUG(std::cout << "\t->" << shift() << std::endl;)
}
template <class R>
R SPxSolverBase<R>::perturbMin(
const UpdateVector<R>& uvec,
VectorBase<R>& p_low,
VectorBase<R>& p_up,
R eps,
R p_delta,
const typename SPxBasisBase<R>::Desc::Status* stat,
int start,
int incr)
{
assert(uvec.dim() == p_low.dim());
assert(uvec.dim() == p_up.dim());
const R* vec = uvec.get_const_ptr();
R minrandom = 10.0 * p_delta;
R maxrandom = 100.0 * p_delta;
R x, l, u;
int i;
R l_theShift = 0;
if(fullPerturbation)
{
eps = p_delta;
for(i = uvec.dim() - start - 1; i >= 0; i -= incr)
{
u = p_up[i];
l = p_low[i];
x = vec[i];
if(LT(u, R(infinity)) && NE(l, u) && u <= x + eps && rep() * stat[i] < 0)
{
p_up[i] = vec[i] + random.next((double)minrandom, (double)maxrandom);
l_theShift += p_up[i] - u;
}
if(GT(l, R(-infinity)) && NE(l, u) && l >= x - eps && rep() * stat[i] < 0)
{
p_low[i] = vec[i] - random.next((double)minrandom, (double)maxrandom);
l_theShift -= p_low[i] - l;
}
}
}
else
{
const R* upd = uvec.delta().values();
const IdxSet& idx = uvec.delta().indices();
for(int j = uvec.delta().size() - start - 1; j >= 0; j -= incr)
{
i = idx.index(j);
x = upd[i];
u = p_up[i];
l = p_low[i];
if(x < -eps)
{
if(LT(u, R(infinity)) && NE(l, u) && vec[i] >= u - eps && rep() * stat[i] < 0)
{
p_up[i] = vec[i] + random.next((double)minrandom, (double)maxrandom);
l_theShift += p_up[i] - u;
}
}
else if(x > eps)
{
if(GT(l, R(-infinity)) && NE(l, u) && vec[i] <= l + eps && rep() * stat[i] < 0)
{
p_low[i] = vec[i] - random.next((double)minrandom, (double)maxrandom);
l_theShift -= p_low[i] - l;
}
}
}
}
return l_theShift;
}
template <class R>
R SPxSolverBase<R>::perturbMax(
const UpdateVector<R>& uvec,
VectorBase<R>& p_low,
VectorBase<R>& p_up,
R eps,
R p_delta,
const typename SPxBasisBase<R>::Desc::Status* stat,
int start,
int incr)
{
assert(uvec.dim() == p_low.dim());
assert(uvec.dim() == p_up.dim());
const R* vec = uvec.get_const_ptr();
R minrandom = 10.0 * p_delta;
R maxrandom = 100.0 * p_delta;
R x, l, u;
int i;
R l_theShift = 0;
if(fullPerturbation)
{
eps = p_delta;
for(i = uvec.dim() - start - 1; i >= 0; i -= incr)
{
u = p_up[i];
l = p_low[i];
x = vec[i];
if(LT(u, R(infinity)) && NE(l, u) && u <= x + eps && rep() * stat[i] < 0)
{
p_up[i] = vec[i] + random.next((double)minrandom, (double)maxrandom);
l_theShift += p_up[i] - u;
}
if(GT(l, R(-infinity)) && NE(l, u) && l >= x - eps && rep() * stat[i] < 0)
{
p_low[i] = vec[i] - random.next((double)minrandom, (double)maxrandom);
l_theShift -= p_low[i] - l;
}
}
}
else
{
const R* upd = uvec.delta().values();
const IdxSet& idx = uvec.delta().indices();
for(int j = uvec.delta().size() - start - 1; j >= 0; j -= incr)
{
i = idx.index(j);
x = upd[i];
u = p_up[i];
l = p_low[i];
if(x > eps)
{
if(LT(u, R(infinity)) && NE(l, u) && vec[i] >= u - eps && rep() * stat[i] < 0)
{
p_up[i] = vec[i] + random.next((double)minrandom, (double)maxrandom);
l_theShift += p_up[i] - u;
}
}
else if(x < -eps)
{
if(GT(l, R(-infinity)) && NE(l, u) && vec[i] <= l + eps && rep() * stat[i] < 0)
{
p_low[i] = vec[i] - random.next((double)minrandom, (double)maxrandom);
l_theShift -= p_low[i] - l;
}
}
}
}
return l_theShift;
}
template <class R>
void SPxSolverBase<R>::perturbMinLeave(void)
{
MSG_DEBUG(std::cout << "DSHIFT05 iteration= " << this->iteration() << ": perturbing " << shift();)
pVec().delta().setup();
coPvec().delta().setup();
theShift += perturbMin(pVec(), lpBound(), upBound(), epsilon(), leavetol(),
this->desc().status(), 0, 1);
theShift += perturbMin(coPvec(), lcBound(), ucBound(), epsilon(), leavetol(),
this->desc().coStatus(), 0, 1);
MSG_DEBUG(std::cout << "\t->" << shift() << std::endl;)
}
template <class R>
void SPxSolverBase<R>::perturbMaxLeave(void)
{
MSG_DEBUG(std::cout << "DSHIFT06 iteration= " << this->iteration() << ": perturbing " << shift();)
pVec().delta().setup();
coPvec().delta().setup();
theShift += perturbMax(pVec(), lpBound(), upBound(), epsilon(), leavetol(),
this->desc().status(), 0, 1);
theShift += perturbMax(coPvec(), lcBound(), ucBound(), epsilon(), leavetol(),
this->desc().coStatus(), 0, 1);
MSG_DEBUG(std::cout << "\t->" << shift() << std::endl;)
}
template <class R>
void SPxSolverBase<R>::unShift(void)
{
MSG_INFO3((*this->spxout), (*this->spxout) << "DSHIFT07 = " << "unshifting ..." << std::endl;);
if(isInitialized())
{
int i;
R t_up, t_low;
const typename SPxBasisBase<R>::Desc& ds = this->desc();
theShift = 0;
if(type() == ENTER)
{
R eps = entertol();
if(rep() == COLUMN)
{
for(i = dim(); i-- > 0;)
{
SPxId l_id = this->baseId(i);
int l_num = this->number(l_id);
if(l_id.type() == SPxId::ROW_ID)
{
t_up = -this->lhs(l_num);
t_low = -this->rhs(l_num);
}
else
{
assert(l_id.type() == SPxId::COL_ID);
t_up = this->upper(l_num);
t_low = this->lower(l_num);
}
if(t_up != t_low)
{
if((*theFvec)[i] < t_up + eps) theUBbound[i] = t_up; else if((*theFvec)[i] > t_up) theShift += theUBbound[i] - t_up;
if((*theFvec)[i] > t_low - eps) theLBbound[i] = t_low; else if((*theFvec)[i] < t_low) theShift -= theLBbound[i] - t_low;
}
else
{
if(theUBbound[i] > t_up)
theShift += theUBbound[i] - t_up;
else if(theLBbound[i] < t_low)
theShift += t_low - theLBbound[i];
}
}
for(i = this->nRows(); i-- > 0;)
{
if(!isBasic(ds.rowStatus(i)))
{
t_up = -this->lhs(i);
t_low = -this->rhs(i);
if(theURbound[i] > t_up) theShift += theURbound[i] - t_up;
if(t_low > theLRbound[i]) theShift += t_low - theLRbound[i];
}
}
for(i = this->nCols(); i-- > 0;)
{
if(!isBasic(ds.colStatus(i)))
{
t_up = this->upper(i);
t_low = this->lower(i);
if(theUCbound[i] > t_up) theShift += theUCbound[i] - t_up;
if(t_low > theLCbound[i]) theShift += t_low - theLCbound[i];
}
}
}
else
{
assert(rep() == ROW);
for(i = dim(); i-- > 0;)
{
SPxId l_id = this->baseId(i);
int l_num = this->number(l_id);
t_up = t_low = 0;
if(l_id.type() == SPxId::ROW_ID)
clearDualBounds(ds.rowStatus(l_num), t_up, t_low);
else
clearDualBounds(ds.colStatus(l_num), t_up, t_low);
if(theUBbound[i] != theLBbound[i])
{
if(theUBbound[i] > t_up)
theShift += theUBbound[i] - t_up;
else
theShift -= theUBbound[i] - t_up;
}
else
{
assert(theLBbound[i] == theUBbound[i] || theUBbound[i] >= t_up);
assert(theLBbound[i] == theUBbound[i] || theLBbound[i] <= t_low);
if((*theFvec)[i] < t_up - eps)
theUBbound[i] = t_up;
else if((*theFvec)[i] > t_up)
theShift += theUBbound[i] - t_up;
if((*theFvec)[i] > t_low + eps)
theLBbound[i] = t_low;
else if((*theFvec)[i] < t_low)
theShift -= theLBbound[i] - t_low;
}
}
for(i = this->nRows(); i-- > 0;)
{
if(!isBasic(ds.rowStatus(i)))
{
t_up = t_low = 0;
clearDualBounds(ds.rowStatus(i), t_up, t_low);
if(theURbound[i] > t_up) theShift += theURbound[i] - t_up;
if(t_low > theLRbound[i]) theShift += t_low - theLRbound[i];
}
}
for(i = this->nCols(); i-- > 0;)
{
if(!isBasic(ds.colStatus(i)))
{
t_up = t_low = 0;
clearDualBounds(ds.colStatus(i), t_up, t_low);
if(theUCbound[i] > t_up) theShift += theUCbound[i] - t_up;
if(t_low > theLCbound[i]) theShift += t_low - theLCbound[i];
}
}
}
}
else
{
assert(type() == LEAVE);
R eps = leavetol();
if(rep() == COLUMN)
{
for(i = this->nRows(); i-- > 0;)
{
t_up = t_low = this->maxRowObj(i);
clearDualBounds(ds.rowStatus(i), t_up, t_low);
if(!isBasic(ds.rowStatus(i)))
{
if((*theCoPvec)[i] < t_up + eps)
{
theURbound[i] = t_up;
if(t_up == t_low)
theLRbound[i] = t_low; }
else
theShift += theURbound[i] - t_up;
if((*theCoPvec)[i] > t_low - eps)
{
theLRbound[i] = t_low;
if(t_up == t_low)
theURbound[i] = t_up; }
else
theShift += t_low - theLRbound[i];
}
else if(theURbound[i] > t_up)
theShift += theURbound[i] - t_up;
else if(theLRbound[i] < t_low)
theShift += t_low - theLRbound[i];
}
for(i = this->nCols(); i-- > 0;)
{
t_up = t_low = -this->maxObj(i);
clearDualBounds(ds.colStatus(i), t_low, t_up);
if(!isBasic(ds.colStatus(i)))
{
if((*thePvec)[i] < -t_up + eps)
{
theUCbound[i] = -t_up;
if(t_up == t_low)
theLCbound[i] = -t_low; }
else
theShift += theUCbound[i] - (-t_up);
if((*thePvec)[i] > -t_low - eps)
{
theLCbound[i] = -t_low;
if(t_up == t_low)
theUCbound[i] = -t_up; }
else
theShift += (-t_low) - theLCbound[i];
}
else if(theUCbound[i] > -t_up)
theShift += theUCbound[i] - (-t_up);
else if(theLCbound[i] < -t_low)
theShift += (-t_low) - theLCbound[i];
}
}
else
{
assert(rep() == ROW);
for(i = this->nRows(); i-- > 0;)
{
t_up = this->rhs(i);
t_low = this->lhs(i);
if(t_up == t_low)
{
if(theURbound[i] > t_up)
theShift += theURbound[i] - t_up;
else
theShift += t_low - theLRbound[i];
}
else if(!isBasic(ds.rowStatus(i)))
{
if((*thePvec)[i] < t_up + eps)
theURbound[i] = t_up; else
theShift += theURbound[i] - t_up;
if((*thePvec)[i] > t_low - eps)
theLRbound[i] = t_low; else
theShift += t_low - theLRbound[i];
}
else if(theURbound[i] > t_up)
theShift += theURbound[i] - t_up;
else if(theLRbound[i] < t_low)
theShift += t_low - theLRbound[i];
}
for(i = this->nCols(); i-- > 0;)
{
t_up = this->upper(i);
t_low = this->lower(i);
if(t_up == t_low)
{
if(theUCbound[i] > t_up)
theShift += theUCbound[i] - t_up;
else
theShift += t_low - theLCbound[i];
}
else if(!isBasic(ds.colStatus(i)))
{
if((*theCoPvec)[i] < t_up + eps)
theUCbound[i] = t_up; else
theShift += theUCbound[i] - t_up;
if((*theCoPvec)[i] > t_low - eps)
theLCbound[i] = t_low; else
theShift += t_low - theLCbound[i];
}
else if(theUCbound[i] > t_up)
theShift += theUCbound[i] - t_up;
else if(theLCbound[i] < t_low)
theShift += t_low - theLCbound[i];
}
}
}
}
}
}