Skip to content

Commit 124f405

Browse files
committed
NE structure now uses partial rw copy and corresponding entries
1 parent b29e728 commit 124f405

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ Int FactorHiGHSSolver::buildNEstructure(const HighsSparseMatrix& A,
171171
// temporary storage of indices
172172
std::vector<Int> temp_index(A.num_row_);
173173

174+
Clock clock;
175+
174176
for (Int row = 0; row < A.num_row_; ++row) {
175177
// go along the entries of the row, and then down each column.
176178
// this builds the lower triangular part of the row-th column of AAt.
@@ -216,6 +218,98 @@ Int FactorHiGHSSolver::buildNEstructure(const HighsSparseMatrix& A,
216218
}
217219
}
218220

221+
printf("time 1: %f\n", clock.stop());
222+
223+
return kStatusOk;
224+
}
225+
226+
Int FactorHiGHSSolver::buildNEstructure_2(const HighsSparseMatrix& A,
227+
int64_t nz_limit) {
228+
// Build lower triangular structure of AAt.
229+
// This approach uses a column-wise copy of A, a partial row-wise copy and a
230+
// vector of corresponding indices.
231+
232+
// NB: A must have sorted columns for this to work
233+
234+
// create partial row-wise representation
235+
// for now, using the full row-wise matrix
236+
{
237+
HighsSparseMatrix At = A;
238+
At.ensureRowwise();
239+
ptrNE_rw_ = std::move(At.start_);
240+
idxNE_rw_ = std::move(At.index_);
241+
}
242+
243+
{
244+
std::vector<Int> temp = ptrNE_rw_;
245+
corr_NE_.assign(A.numNz(), 0);
246+
247+
// build array or corresponding indices
248+
for (Int col = 0; col < A.num_col_; ++col) {
249+
for (Int el = A.start_[col]; el < A.start_[col + 1]; ++el) {
250+
Int row = A.index_[el];
251+
252+
corr_NE_[temp[row]] = el;
253+
temp[row]++;
254+
}
255+
}
256+
}
257+
258+
std::vector<Int> ptrNE(A.num_row_ + 1);
259+
std::vector<Int> rowsNE;
260+
261+
// keep track if given entry is nonzero, in column considered
262+
std::vector<bool> is_nz(A.num_row_, false);
263+
264+
// temporary storage of indices
265+
std::vector<Int> temp_index(A.num_row_);
266+
267+
Clock clock;
268+
269+
for (Int row = 0; row < A.num_row_; ++row) {
270+
// go along the entries of the row, and then down each column.
271+
// this builds the lower triangular part of the row-th column of AAt.
272+
273+
Int nz_in_col = 0;
274+
275+
for (Int el = ptrNE_rw_[row]; el < ptrNE_rw_[row + 1]; ++el) {
276+
Int col = idxNE_rw_[el];
277+
Int corr = corr_NE_[el];
278+
279+
// for each nonzero in the row, go down corresponding column, starting
280+
// from current position
281+
for (Int colEl = corr; colEl < A.start_[col + 1]; ++colEl) {
282+
Int row2 = A.index_[colEl];
283+
284+
// row2 is guaranteed to be larger or equal than row
285+
// (provided that the columns of A are sorted)
286+
287+
// save information that there is nonzero in position (row2,row).
288+
if (!is_nz[row2]) {
289+
is_nz[row2] = true;
290+
temp_index[nz_in_col] = row2;
291+
++nz_in_col;
292+
}
293+
}
294+
}
295+
// intersection of row with rows below finished.
296+
297+
// if the total number of nonzeros exceeds the maximum, return error
298+
if ((int64_t)ptrNE[row] + (int64_t)nz_in_col >= nz_limit) return kStatusOoM;
299+
300+
// update pointers
301+
ptrNE[row + 1] = ptrNE[row] + nz_in_col;
302+
303+
// now assign indices
304+
for (Int i = 0; i < nz_in_col; ++i) {
305+
Int index = temp_index[i];
306+
rowsNE.push_back(index);
307+
is_nz[index] = false;
308+
}
309+
}
310+
311+
printf("time 2: %f\n", clock.stop());
312+
219313
return kStatusOk;
220314
}
221315

@@ -418,6 +512,8 @@ Int FactorHiGHSSolver::analyseNE(Symbolic& S, int64_t nz_limit) {
418512
if (Int status = buildNEstructure(model_.A(), nz_limit)) return status;
419513
if (info_) info_->matrix_structure_time = clock.stop();
420514

515+
buildNEstructure_2(model_.A(), nz_limit);
516+
421517
// create vector of signs of pivots
422518
std::vector<Int> pivot_signs(model_.A().num_row_, 1);
423519

highs/ipm/hipo/ipm/FactorHiGHSSolver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ class FactorHiGHSSolver : public LinearSolver {
2424
std::vector<double> valNE_;
2525
std::vector<Int> colNE_, nextNE_, headNE_;
2626

27+
std::vector<Int> ptrNE_rw_, idxNE_rw_;
28+
std::vector<Int> corr_NE_;
29+
2730
const Regularisation& regul_;
2831

2932
Info* info_ = nullptr;
@@ -39,6 +42,8 @@ class FactorHiGHSSolver : public LinearSolver {
3942

4043
Int buildNEstructure(const HighsSparseMatrix& A,
4144
int64_t nz_limit = kHighsIInf);
45+
Int buildNEstructure_2(const HighsSparseMatrix& A,
46+
int64_t nz_limit = kHighsIInf);
4247
Int buildNEvalues(const HighsSparseMatrix& A,
4348
const std::vector<double>& scaling);
4449

0 commit comments

Comments
 (0)