@@ -9,7 +9,7 @@ namespace hipo {
99Int Model::init (const Int num_var, const Int num_con, const double * obj,
1010 const double * rhs, const double * lower, const double * upper,
1111 const Int* A_ptr, const Int* A_rows, const double * A_vals,
12- const char * constraints, double offset) {
12+ const char * constraints, double offset, OptionScaling opt ) {
1313 // copy the input into the model
1414
1515 if (checkData (num_var, num_con, obj, rhs, lower, upper, A_ptr, A_rows, A_vals,
@@ -45,7 +45,7 @@ Int Model::init(const Int num_var, const Int num_con, const double* obj,
4545 constraints_ = std::vector<char >(constraints, constraints + m_);
4646
4747 preprocess ();
48- scale ();
48+ scale (opt );
4949 reformulate ();
5050 denseColumns ();
5151 computeNorms ();
@@ -317,17 +317,14 @@ void Model::print(const LogHighs& log) const {
317317 }
318318 if (std::isinf (bmin)) bmin = 0.0 ;
319319
320- // compute max and min for bounds
320+ // compute max and min inerval for bounds
321321 double boundmin = kHighsInf ;
322322 double boundmax = 0.0 ;
323323 for (Int i = 0 ; i < n_; ++i) {
324- if (lower_[i] != 0.0 && std::isfinite (lower_[i])) {
325- boundmin = std::min (boundmin, std::abs (lower_[i]));
326- boundmax = std::max (boundmax, std::abs (lower_[i]));
327- }
328- if (upper_[i] != 0.0 && std::isfinite (upper_[i])) {
329- boundmin = std::min (boundmin, std::abs (upper_[i]));
330- boundmax = std::max (boundmax, std::abs (upper_[i]));
324+ if (std::isfinite (lower_[i]) && std::isfinite (upper_[i])) {
325+ const double interval = std::abs (upper_[i] - lower_[i]);
326+ boundmin = std::min (boundmin, interval);
327+ boundmax = std::max (boundmax, interval);
331328 }
332329 }
333330 if (std::isinf (boundmin)) boundmin = 0.0 ;
@@ -405,7 +402,7 @@ static double roundToPowerOf2(double d) {
405402 return std::ldexp (1.0 , exp);
406403}
407404
408- void Model::scale () {
405+ void Model::scale (OptionScaling opt ) {
409406 // Compute scaling:
410407 // A -> R * A * C
411408 // b -> R * b
@@ -420,7 +417,16 @@ void Model::scale() {
420417 colscale_.resize (n_, 1.0 );
421418 rowscale_.resize (m_, 1.0 );
422419
423- CRscaling ();
420+ if (opt == kOptionCRscaling ) {
421+ CRscaling ();
422+ } else if (opt == kOptionNormScaling ) {
423+ const Int num_passes = 2 ;
424+ for (Int pass = 0 ; pass < num_passes; ++pass) {
425+ onePassNormScaling ();
426+ boundScaling ();
427+ }
428+ }
429+
424430 applyScaling ();
425431}
426432
@@ -434,15 +440,15 @@ bool Model::needScaling() {
434440 }
435441 }
436442
437- return false ;
438-
439443 // check bounds
440444 for (Int i = 0 ; i < n_; ++i) {
441445 if (std::isfinite (lower_[i]) && std::isfinite (upper_[i])) {
442446 const double diff = std::abs (lower_[i] - upper_[i]);
443447 if (diff < kSmallBoundDiff || diff > kLargeBoundDiff ) return true ;
444448 }
445449 }
450+
451+ return false ;
446452}
447453
448454void Model::CRscaling () {
@@ -483,8 +489,8 @@ void Model::applyScaling() {
483489}
484490
485491void Model::onePassNormScaling () {
486- // Compute a single pass of infinity-norm row scaling and a single pass of
487- // infinity-norm col scaling.
492+ // Compute a single pass of infinity-norm geo-mean row scaling and col
493+ // scaling.
488494
489495 // infinity norm of rows
490496 std::vector<double > norm_rows (m_);
@@ -500,7 +506,7 @@ void Model::onePassNormScaling() {
500506
501507 // apply row scaling
502508 for (Int i = 0 ; i < m_; ++i)
503- rowscale_[i] *= roundToPowerOf2 (1.0 / norm_rows[i]);
509+ rowscale_[i] *= roundToPowerOf2 (1.0 / std::sqrt ( norm_rows[i]) );
504510
505511 // infinity norm of columns
506512 std::vector<double > norm_cols (n_);
@@ -516,20 +522,24 @@ void Model::onePassNormScaling() {
516522
517523 // apply col scaling
518524 for (Int i = 0 ; i < n_; ++i)
519- colscale_[i] *= roundToPowerOf2 (1.0 / norm_cols[i]);
525+ colscale_[i] *= roundToPowerOf2 (1.0 / std::sqrt ( norm_cols[i]) );
520526}
521527
522528void Model::boundScaling () {
529+ // Compute scaling so that bound intervals (upper-lower) are not too small or
530+ // too large.
531+
523532 for (Int i = 0 ; i < n_; ++i) {
524533 if (std::isfinite (lower_[i]) && std::isfinite (upper_[i])) {
525- const double l = lower_[i] * colscale_[i];
526- const double u = upper_[i] * colscale_[i];
534+ const double l = lower_[i] / colscale_[i];
535+ const double u = upper_[i] / colscale_[i];
527536 const double diff = std::abs (u - l);
528537
529538 if (diff < kSmallBoundDiff )
530- colscale_[i] *= roundToPowerOf2 (kSmallBoundDiff / diff);
531- else if (diff > kLargeBoundDiff )
532- colscale_[i] *= roundToPowerOf2 (kLargeBoundDiff / diff);
539+ colscale_[i] *= roundToPowerOf2 (diff / kSmallBoundDiff );
540+ else if (diff > kLargeBoundDiff ) {
541+ colscale_[i] *= roundToPowerOf2 (diff / kLargeBoundDiff );
542+ }
533543 }
534544 }
535545}
0 commit comments