@@ -348,16 +348,26 @@ void HighsIis::getLp(const HighsLp& lp) {
348348 iis_lp.clear ();
349349 HighsInt iis_num_col = this ->col_index_ .size ();
350350 HighsInt iis_num_row = this ->row_index_ .size ();
351- assert (lp.a_matrix_ .isColwise ());
352- // Scatter the IIS rows into a full-length vector to identify IIS
353- // rows with LP rows
351+ const bool colwise = lp.a_matrix_ .isColwise ();
352+ // Scatter the IIS rows (cols) into a full-length vector to identify
353+ // IIS rows (cols) with LP rows (cols) according to whether the
354+ // incumbent matrix is col-wise or row-wise
354355 std::vector<HighsInt> iis_row;
355- iis_row.assign (lp.num_row_ , -1 );
356+ std::vector<HighsInt> iis_col;
357+ if (colwise) {
358+ iis_row.assign (lp.num_row_ , -1 );
359+ for (HighsInt iisRow = 0 ; iisRow < iis_num_row; iisRow++)
360+ iis_row[this ->row_index_ [iisRow]] = iisRow;
361+ } else {
362+ iis_col.assign (lp.num_col_ , -1 );
363+ for (HighsInt iisCol = 0 ; iisCol < iis_num_col; iisCol++)
364+ iis_col[this ->col_index_ [iisCol]] = iisCol;
365+ }
356366 double bound;
367+
357368 const bool has_row_name = lp.row_names_ .size () > 0 ;
358369 for (HighsInt iisRow = 0 ; iisRow < iis_num_row; iisRow++) {
359370 HighsInt iRow = this ->row_index_ [iisRow];
360- iis_row[iRow] = iisRow;
361371 if (has_row_name) iis_lp.row_names_ .push_back (lp.row_names_ [iRow]);
362372 HighsInt row_bound = this ->row_bound_ [iisRow];
363373 assert (row_bound == kIisBoundStatusLower ||
@@ -373,6 +383,17 @@ void HighsIis::getLp(const HighsLp& lp) {
373383 ? lp.row_upper_ [iRow]
374384 : kHighsInf ;
375385 iis_lp.row_upper_ .push_back (bound);
386+ if (!colwise) {
387+ for (HighsInt iEl = lp.a_matrix_ .start_ [iRow];
388+ iEl < lp.a_matrix_ .start_ [iRow + 1 ]; iEl++) {
389+ HighsInt iCol = lp.a_matrix_ .index_ [iEl];
390+ HighsInt iisCol = iis_col[iCol];
391+ if (iisCol >= 0 ) {
392+ iis_lp.a_matrix_ .index_ .push_back (iisCol);
393+ iis_lp.a_matrix_ .value_ .push_back (lp.a_matrix_ .value_ [iEl]);
394+ }
395+ }
396+ }
376397 }
377398
378399 const bool has_col_name = lp.col_names_ .size () > 0 ;
@@ -398,13 +419,15 @@ void HighsIis::getLp(const HighsLp& lp) {
398419 ? lp.col_upper_ [iCol]
399420 : kHighsInf ;
400421 iis_lp.col_upper_ .push_back (bound);
401- for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
402- iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
403- HighsInt iRow = lp.a_matrix_ .index_ [iEl];
404- HighsInt iisRow = iis_row[iRow];
405- if (iisRow >= 0 ) {
406- iis_lp.a_matrix_ .index_ .push_back (iisRow);
407- iis_lp.a_matrix_ .value_ .push_back (lp.a_matrix_ .value_ [iEl]);
422+ if (colwise) {
423+ for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
424+ iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
425+ HighsInt iRow = lp.a_matrix_ .index_ [iEl];
426+ HighsInt iisRow = iis_row[iRow];
427+ if (iisRow >= 0 ) {
428+ iis_lp.a_matrix_ .index_ .push_back (iisRow);
429+ iis_lp.a_matrix_ .value_ .push_back (lp.a_matrix_ .value_ [iEl]);
430+ }
408431 }
409432 }
410433 iis_lp.a_matrix_ .start_ .push_back (iis_lp.a_matrix_ .index_ .size ());
@@ -759,16 +782,13 @@ bool HighsIis::lpDataOk(const HighsLp& lp, const HighsOptions& options) const {
759782 if (!(iis_lp.num_col_ == iis_num_col)) return false ;
760783 if (!(iis_lp.num_row_ == iis_num_row)) return false ;
761784
762- assert ( lp.a_matrix_ .isColwise () );
785+ const bool colwise = lp.a_matrix_ .isColwise ();
763786
764787 std::vector<HighsInt> iis_row;
765788 iis_row.assign (lp.num_row_ , -1 );
766789 double bound;
767790 for (HighsInt iisRow = 0 ; iisRow < iis_num_row; iisRow++) {
768791 HighsInt iRow = this ->row_index_ [iisRow];
769- if (iRow < 0 || iRow >= lp.num_row_ ) {
770- printf (" iRow out of range\n " );
771- }
772792 iis_row[iRow] = iisRow;
773793 HighsInt row_bound = this ->row_bound_ [iisRow];
774794 bound =
@@ -783,12 +803,7 @@ bool HighsIis::lpDataOk(const HighsLp& lp, const HighsOptions& options) const {
783803 if (iis_lp.row_upper_ [iisRow] != bound) return false ;
784804 }
785805
786- // Work through the LP columns and matrix, checking the zero costs,
787- // bounds and matrix index/value
788- const HighsInt illegal_index = -1 ;
789- const double illegal_value = kHighsInf ;
790- std::vector<HighsInt> index;
791- std::vector<double > value;
806+ // Work through the LP columns checking the zero costs and bounds
792807 for (HighsInt iisCol = 0 ; iisCol < iis_num_col; iisCol++) {
793808 HighsInt iCol = this ->col_index_ [iisCol];
794809 if (iis_lp.col_cost_ [iisCol]) return false ;
@@ -803,48 +818,106 @@ bool HighsIis::lpDataOk(const HighsLp& lp, const HighsOptions& options) const {
803818 ? lp.col_upper_ [iCol]
804819 : kHighsInf ;
805820 if (iis_lp.col_upper_ [iisCol] != bound) return false ;
806- // Use index/value to scatter the IIS matrix column
807- index.assign (iis_num_row, illegal_index);
808- value.assign (iis_num_row, illegal_value);
809- for (HighsInt iEl = iis_lp.a_matrix_ .start_ [iisCol];
810- iEl < iis_lp.a_matrix_ .start_ [iisCol + 1 ]; iEl++) {
811- HighsInt iisRow = iis_lp.a_matrix_ .index_ [iEl];
812- HighsInt iRow = this ->row_index_ [iisRow];
813- index[iisRow] = iRow;
814- value[iisRow] = iis_lp.a_matrix_ .value_ [iEl];
821+ }
822+ const HighsInt illegal_index = -1 ;
823+ const double illegal_value = kHighsInf ;
824+ std::vector<HighsInt> index;
825+ std::vector<double > value;
826+ // Work through the LP matrix, checking the matrix index/value
827+ if (colwise) {
828+ for (HighsInt iisCol = 0 ; iisCol < iis_num_col; iisCol++) {
829+ HighsInt iCol = this ->col_index_ [iisCol];
830+ // Use index/value to scatter the IIS matrix column
831+ index.assign (iis_num_row, illegal_index);
832+ value.assign (iis_num_row, illegal_value);
833+ for (HighsInt iEl = iis_lp.a_matrix_ .start_ [iisCol];
834+ iEl < iis_lp.a_matrix_ .start_ [iisCol + 1 ]; iEl++) {
835+ HighsInt iisRow = iis_lp.a_matrix_ .index_ [iEl];
836+ HighsInt iRow = this ->row_index_ [iisRow];
837+ index[iisRow] = iRow;
838+ value[iisRow] = iis_lp.a_matrix_ .value_ [iEl];
839+ }
840+ for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
841+ iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
842+ HighsInt iRow = lp.a_matrix_ .index_ [iEl];
843+ HighsInt iisRow = iis_row[iRow];
844+ if (iisRow >= 0 ) {
845+ if (index[iisRow] != iRow) return false ;
846+ if (value[iisRow] != lp.a_matrix_ .value_ [iEl]) return false ;
847+ index[iisRow] = illegal_index;
848+ value[iisRow] = illegal_value;
849+ }
850+ }
815851 }
816- for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
817- iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
818- HighsInt iRow = lp.a_matrix_ .index_ [iEl];
819- HighsInt iisRow = iis_row[iRow];
820- if (iisRow >= 0 ) {
821- if (index[iisRow] != iRow) return false ;
822- if (value[iisRow] != lp.a_matrix_ .value_ [iEl]) return false ;
823- index[iisRow] = illegal_index;
824- value[iisRow] = illegal_value;
852+ } else {
853+ for (HighsInt iisRow = 0 ; iisRow < iis_num_row; iisRow++) {
854+ HighsInt iRow = this ->row_index_ [iisRow];
855+ // Use index/value to scatter the IIS matrix row
856+ index.assign (iis_num_row, illegal_index);
857+ value.assign (iis_num_row, illegal_value);
858+ for (HighsInt iEl = iis_lp.a_matrix_ .start_ [iisRow];
859+ iEl < iis_lp.a_matrix_ .start_ [iisRow + 1 ]; iEl++) {
860+ HighsInt iisCol = iis_lp.a_matrix_ .index_ [iEl];
861+ HighsInt iCol = this ->row_index_ [iisCol];
862+ index[iisCol] = iCol;
863+ value[iisCol] = iis_lp.a_matrix_ .value_ [iEl];
864+ }
865+ for (HighsInt iEl = lp.a_matrix_ .start_ [iRow];
866+ iEl < lp.a_matrix_ .start_ [iRow + 1 ]; iEl++) {
867+ HighsInt iCol = lp.a_matrix_ .index_ [iEl];
868+ HighsInt iisCol = iis_row[iCol];
869+ if (iisCol >= 0 ) {
870+ if (index[iisCol] != iCol) return false ;
871+ if (value[iisCol] != lp.a_matrix_ .value_ [iEl]) return false ;
872+ index[iisCol] = illegal_index;
873+ value[iisCol] = illegal_value;
874+ }
825875 }
826876 }
827877 }
828878 // Work through the IIS LP matrix, making sure that the index/value
829879 // are correct
830- for (HighsInt iisCol = 0 ; iisCol < iis_num_col; iisCol++) {
831- HighsInt iCol = this ->col_index_ [iisCol];
832- // Use index/value to scatter the LP matrix column
833- index.assign (lp.num_row_ , illegal_index);
834- value.assign (lp.num_row_ , illegal_value);
835- for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
836- iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
837- HighsInt iRow = lp.a_matrix_ .index_ [iEl];
838- HighsInt iisRow = iis_row[iRow];
839- index[iRow] = iisRow;
840- value[iRow] = lp.a_matrix_ .value_ [iEl];
880+ if (colwise) {
881+ for (HighsInt iisCol = 0 ; iisCol < iis_num_col; iisCol++) {
882+ HighsInt iCol = this ->col_index_ [iisCol];
883+ // Use index/value to scatter the LP matrix column
884+ index.assign (lp.num_row_ , illegal_index);
885+ value.assign (lp.num_row_ , illegal_value);
886+ for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
887+ iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
888+ HighsInt iRow = lp.a_matrix_ .index_ [iEl];
889+ HighsInt iisRow = iis_row[iRow];
890+ index[iRow] = iisRow;
891+ value[iRow] = lp.a_matrix_ .value_ [iEl];
892+ }
893+ for (HighsInt iEl = iis_lp.a_matrix_ .start_ [iisCol];
894+ iEl < iis_lp.a_matrix_ .start_ [iisCol + 1 ]; iEl++) {
895+ HighsInt iisRow = iis_lp.a_matrix_ .index_ [iEl];
896+ HighsInt iRow = this ->row_index_ [iisRow];
897+ if (index[iRow] != iisRow) return false ;
898+ if (value[iRow] != iis_lp.a_matrix_ .value_ [iEl]) return false ;
899+ }
841900 }
842- for (HighsInt iEl = iis_lp.a_matrix_ .start_ [iisCol];
843- iEl < iis_lp.a_matrix_ .start_ [iisCol + 1 ]; iEl++) {
844- HighsInt iisRow = iis_lp.a_matrix_ .index_ [iEl];
901+ } else {
902+ for (HighsInt iisRow = 0 ; iisRow < iis_num_row; iisRow++) {
845903 HighsInt iRow = this ->row_index_ [iisRow];
846- if (index[iRow] != iisRow) return false ;
847- if (value[iRow] != iis_lp.a_matrix_ .value_ [iEl]) return false ;
904+ // Use index/value to scatter the LP matrix row
905+ index.assign (lp.num_row_ , illegal_index);
906+ value.assign (lp.num_row_ , illegal_value);
907+ for (HighsInt iEl = lp.a_matrix_ .start_ [iRow];
908+ iEl < lp.a_matrix_ .start_ [iRow + 1 ]; iEl++) {
909+ HighsInt iCol = lp.a_matrix_ .index_ [iEl];
910+ HighsInt iisCol = iis_row[iCol];
911+ index[iCol] = iisCol;
912+ value[iCol] = lp.a_matrix_ .value_ [iEl];
913+ }
914+ for (HighsInt iEl = iis_lp.a_matrix_ .start_ [iisRow];
915+ iEl < iis_lp.a_matrix_ .start_ [iisRow + 1 ]; iEl++) {
916+ HighsInt iisCol = iis_lp.a_matrix_ .index_ [iEl];
917+ HighsInt iCol = this ->row_index_ [iisCol];
918+ if (index[iCol] != iisCol) return false ;
919+ if (value[iCol] != iis_lp.a_matrix_ .value_ [iEl]) return false ;
920+ }
848921 }
849922 }
850923 return true ;
0 commit comments