11#include " FactorHiGHSSolver.h"
22
3- #include < limits>
4-
53#include " Status.h"
64#include " ipm/hipo/auxiliary/Auxiliary.h"
75#include " ipm/hipo/auxiliary/Log.h"
@@ -92,9 +90,9 @@ Int FactorHiGHSSolver::buildNEvalues(const HighsSparseMatrix& A,
9290 const std::vector<double >& scaling) {
9391 // given the NE structure already computed, fill in the NE values
9492
95- assert (!ptrNE_ .empty () && !rowsNE_ .empty ());
93+ assert (!ptrLower_ .empty () && !rowsLower_ .empty ());
9694
97- valNE_ .assign (rowsNE_ .size (), 0.0 );
95+ valLower_ .assign (rowsLower_ .size (), 0.0 );
9896
9997 std::vector<double > work (A.num_row_ , 0.0 );
10098
@@ -127,9 +125,9 @@ Int FactorHiGHSSolver::buildNEvalues(const HighsSparseMatrix& A,
127125 // intersection of row with rows below finished.
128126
129127 // read from work, using indices of column "row" of AAt
130- for (Int el = ptrNE_ [row]; el < ptrNE_ [row + 1 ]; ++el) {
131- Int index = rowsNE_ [el];
132- valNE_ [el] = work[index];
128+ for (Int el = ptrLower_ [row]; el < ptrLower_ [row + 1 ]; ++el) {
129+ Int index = rowsLower_ [el];
130+ valLower_ [el] = work[index];
133131 work[index] = 0.0 ;
134132 }
135133 }
@@ -170,11 +168,11 @@ Int FactorHiGHSSolver::buildNEstructure(const HighsSparseMatrix& A,
170168 }
171169 }
172170
173- ptrNE_ .clear ();
174- rowsNE_ .clear ();
171+ ptrLower_ .clear ();
172+ rowsLower_ .clear ();
175173
176174 // ptr is allocated its exact size
177- ptrNE_ .resize (A.num_row_ + 1 , 0 );
175+ ptrLower_ .resize (A.num_row_ + 1 , 0 );
178176
179177 // keep track if given entry is nonzero, in column considered
180178 std::vector<bool > is_nz (A.num_row_ , false );
@@ -211,74 +209,101 @@ Int FactorHiGHSSolver::buildNEstructure(const HighsSparseMatrix& A,
211209 // intersection of row with rows below finished.
212210
213211 // if the total number of nonzeros exceeds the maximum, return error.
214- if ((Int64)ptrNE_ [row] + nz_in_col >= nz_limit) return kStatusOverflow ;
212+ if ((Int64)ptrLower_ [row] + nz_in_col >= nz_limit) return kStatusOverflow ;
215213
216214 // update pointers
217- ptrNE_ [row + 1 ] = ptrNE_ [row] + nz_in_col;
215+ ptrLower_ [row + 1 ] = ptrLower_ [row] + nz_in_col;
218216
219217 // now assign indices
220218 for (Int i = 0 ; i < nz_in_col; ++i) {
221219 Int index = temp_index[i];
222220 // push_back is better then reserve, because the final length is not known
223- rowsNE_ .push_back (index);
221+ rowsLower_ .push_back (index);
224222 is_nz[index] = false ;
225223 }
226224 }
227225
228226 return kStatusOk ;
229227}
230228
231- Int FactorHiGHSSolver::factorAS (const HighsSparseMatrix& A,
232- const std::vector<double >& scaling) {
233- // only execute factorisation if it has not been done yet
234- assert (!this ->valid_ );
235-
236- Clock clock;
237-
238- // initialise
239- std::vector<Int> ptrLower;
240- std::vector<Int> rowsLower;
241- std::vector<double > valLower;
242-
229+ Int FactorHiGHSSolver::buildASstructure (const HighsSparseMatrix& A,
230+ const std::vector<double >& scaling) {
243231 Int nA = A.num_col_ ;
244232 Int mA = A.num_row_ ;
245233 Int nzA = A.numNz ();
246234
247- ptrLower .resize (nA + mA + 1 );
248- rowsLower .resize (nA + nzA + mA );
249- valLower .resize (nA + nzA + mA );
235+ ptrLower_ .resize (nA + mA + 1 );
236+ rowsLower_ .resize (nA + nzA + mA );
237+ valLower_ .resize (nA + nzA + mA );
250238
251239 // build lower triangle
252240 Int next = 0 ;
253241
254242 for (Int i = 0 ; i < nA; ++i) {
255243 // diagonal element
256- rowsLower[next] = i;
257- valLower[next++] = -scaling[i];
244+ rowsLower_[next] = i;
245+ valLower_[next] = -scaling[i];
246+ next++;
258247
259248 // column of A
260249 for (Int el = A.start_ [i]; el < A.start_ [i + 1 ]; ++el) {
261- rowsLower[next] = A.index_ [el] + nA;
262- valLower[next++] = A.value_ [el];
250+ rowsLower_[next] = A.index_ [el] + nA;
251+ valLower_[next] = A.value_ [el];
252+ next++;
263253 }
264254
265- ptrLower [i + 1 ] = next;
255+ ptrLower_ [i + 1 ] = next;
266256 }
267257
268258 // 2,2 block
269259 for (Int i = 0 ; i < mA ; ++i) {
270- rowsLower[next] = nA + i;
271- valLower[next++] = 0.0 ;
272- ptrLower[nA + i + 1 ] = ptrLower[nA + i] + 1 ;
260+ rowsLower_[next] = nA + i;
261+ valLower_[next++] = 0.0 ;
262+ ptrLower_[nA + i + 1 ] = ptrLower_[nA + i] + 1 ;
263+ }
264+ return 0 ;
265+ }
266+
267+ Int FactorHiGHSSolver::updateASdiagonal (const HighsSparseMatrix& A,
268+ const std::vector<double >& scaling) {
269+ Int nA = A.num_col_ ;
270+
271+ // build lower triangle
272+ Int next = 0 ;
273+
274+ for (Int i = 0 ; i < nA; ++i) {
275+ // diagonal element
276+ valLower_[next] = -scaling[i];
277+ next++;
278+
279+ // move the pointer by the number of nonzeros in the i-th column of A
280+ next += A.start_ [i + 1 ] - A.start_ [i];
281+ }
282+ return 0 ;
283+ }
284+
285+ Int FactorHiGHSSolver::factorAS (const HighsSparseMatrix& A,
286+ const std::vector<double >& scaling) {
287+ // only execute factorisation if it has not been done yet
288+ assert (!this ->valid_ );
289+
290+ Clock clock;
291+
292+ if (amat_set_ == true ) {
293+ std::ignore = updateASdiagonal (A, scaling);
294+ } else {
295+ std::ignore = buildASstructure (A, scaling);
296+ amat_set_ = true ;
273297 }
298+
274299 if (info_) info_->matrix_time += clock.stop ();
275300
276301 // set static regularisation, since it may have changed
277302 FH_.setRegularisation (regul_.primal , regul_.dual );
278303
279304 // factorise matrix
280305 clock.start ();
281- if (FH_.factorise (S_, rowsLower, ptrLower, valLower ))
306+ if (FH_.factorise (S_, rowsLower_, ptrLower_, valLower_ ))
282307 return kStatusErrorFactorise ;
283308 if (info_) {
284309 info_->factor_time += clock.stop ();
@@ -305,11 +330,8 @@ Int FactorHiGHSSolver::factorNE(const HighsSparseMatrix& A,
305330
306331 // factorise
307332 clock.start ();
308- // make copies of structure, because factorise object will take ownership and
309- // modify them.
310- std::vector<Int> ptrNE (ptrNE_);
311- std::vector<Int> rowsNE (rowsNE_);
312- if (FH_.factorise (S_, rowsNE, ptrNE, valNE_)) return kStatusErrorFactorise ;
333+ if (FH_.factorise (S_, rowsLower_, ptrLower_, valLower_))
334+ return kStatusErrorFactorise ;
313335 if (info_) {
314336 info_->factor_time += clock.stop ();
315337 info_->factor_number ++;
@@ -385,9 +407,7 @@ Int FactorHiGHSSolver::analyseAS(Symbolic& S) {
385407 log_.printDevInfo (" Building AS structure\n " );
386408
387409 Clock clock;
388- std::vector<Int> ptrLower;
389- std::vector<Int> rowsLower;
390- if (Int status = getASstructure (model_.A (), ptrLower, rowsLower))
410+ if (Int status = getASstructure (model_.A (), ptrLower_, rowsLower_))
391411 return status;
392412 if (info_) info_->matrix_structure_time = clock.stop ();
393413
@@ -399,7 +419,7 @@ Int FactorHiGHSSolver::analyseAS(Symbolic& S) {
399419 log_.printDevInfo (" Performing AS analyse phase\n " );
400420
401421 clock.start ();
402- Int status = FH_.analyse (S, rowsLower, ptrLower , pivot_signs);
422+ Int status = FH_.analyse (S, rowsLower_, ptrLower_ , pivot_signs);
403423 if (info_) info_->analyse_AS_time = clock.stop ();
404424
405425 if (status && log_.debug (2 )) {
@@ -410,17 +430,6 @@ Int FactorHiGHSSolver::analyseAS(Symbolic& S) {
410430 return status ? kStatusErrorAnalyse : kStatusOk ;
411431}
412432
413- void FactorHiGHSSolver::freeNEmemory () {
414- // Swap NE data structures with empty vectors, to guarantee that memory is
415- // freed.
416-
417- std::vector<Int>().swap (ptrNE_);
418- std::vector<Int>().swap (rowsNE_);
419- std::vector<Int>().swap (ptrA_rw_);
420- std::vector<Int>().swap (idxA_rw_);
421- std::vector<Int>().swap (corr_A_);
422- }
423-
424433Int FactorHiGHSSolver::analyseNE (Symbolic& S, Int64 nz_limit) {
425434 // Perform analyse phase of augmented system and return symbolic factorisation
426435 // in object S and the status. If building the matrix failed, the status is
@@ -438,7 +447,7 @@ Int FactorHiGHSSolver::analyseNE(Symbolic& S, Int64 nz_limit) {
438447 log_.printDevInfo (" Performing NE analyse phase\n " );
439448
440449 clock.start ();
441- Int status = FH_.analyse (S, rowsNE_, ptrNE_ , pivot_signs);
450+ Int status = FH_.analyse (S, rowsLower_, ptrLower_ , pivot_signs);
442451 if (info_) info_->analyse_NE_time = clock.stop ();
443452
444453 if (status && log_.debug (2 )) {
@@ -548,7 +557,6 @@ Int FactorHiGHSSolver::chooseNla() {
548557 if (status == kStatusOk ) {
549558 if (options_.nla == kOptionNlaAugmented ) {
550559 S_ = std::move (symb_AS);
551- freeNEmemory ();
552560 } else {
553561 S_ = std::move (symb_NE);
554562 }
@@ -681,4 +689,4 @@ void FactorHiGHSSolver::setParallel() {
681689 S_.setParallel (parallel_tree, parallel_node);
682690}
683691
684- } // namespace hipo
692+ } // namespace hipo
0 commit comments