29 #ifndef OR_TOOLS_LP_DATA_SPARSE_H_
30 #define OR_TOOLS_LP_DATA_SPARSE_H_
47 class CompactSparseMatrixView;
73 #if (!defined(_MSC_VER) || _MSC_VER >= 1800)
75 std::initializer_list<std::initializer_list<Fractional>> init_list);
124 template <
typename Matrix>
133 template <
typename Matrix>
180 ColIndex
num_cols()
const {
return ColIndex(columns_.size()); }
201 std::string
Dump()
const;
264 bool IsEmpty()
const {
return columns_.empty(); }
266 ColIndex
num_cols()
const {
return columns_.size(); }
277 extern template void SparseMatrix::PopulateFromTranspose<SparseMatrix>(
278 const SparseMatrix&
input);
279 extern template void SparseMatrix::PopulateFromPermutedMatrix<SparseMatrix>(
283 SparseMatrix::PopulateFromPermutedMatrix<CompactSparseMatrixView>(
299 : coefficients_(matrix->coefficients_.data()),
300 rows_(matrix->rows_.data()),
301 starts_(matrix->starts_.data()) {}
310 return ::util::IntegerRange<EntryIndex>(starts_[
col.value()],
311 starts_[
col.value() + 1]);
314 return coefficients_[i.value()];
316 RowIndex
EntryRow(EntryIndex i)
const {
return rows_[i.value()]; }
319 return starts_[
col.value() + 1] - starts_[
col.value()];
329 const RowIndex*
const rows_;
330 const EntryIndex*
const starts_;
359 void Reset(RowIndex num_rows);
364 ColIndex AddDenseColumn(
const DenseColumn& dense_column);
367 ColIndex AddDenseColumnPrefix(
const DenseColumn& dense_column,
372 ColIndex AddDenseColumnWithNonZeros(
const DenseColumn& dense_column,
373 const std::vector<RowIndex>& non_zeros);
380 std::vector<RowIndex>* non_zeros);
384 return starts_[
col + 1] - starts_[
col];
389 DCHECK_EQ(coefficients_.size(), rows_.size());
390 return coefficients_.size();
397 DCHECK_EQ(coefficients_.size(), rows_.size());
398 return coefficients_.empty();
404 DCHECK_LT(
col, num_cols_);
408 const EntryIndex
start = starts_[
col];
410 coefficients_.data() +
start.value());
416 return starts_[
col + 1] == starts_[
col];
431 if (multiplier == 0.0)
return;
432 const auto entry_rows = rows_.view();
433 const auto entry_coeffs = coefficients_.view();
434 for (
const EntryIndex i : Column(
col)) {
435 (*dense_column)[entry_rows[i]] += multiplier * entry_coeffs[i];
446 if (multiplier == 0.0)
return;
447 const auto entry_rows = rows_.view();
448 const auto entry_coeffs = coefficients_.view();
449 for (
const EntryIndex i : Column(
col)) {
450 column->Add(entry_rows[i], multiplier * entry_coeffs[i]);
459 ColumnCopyToClearedDenseColumn(
col, dense_column);
467 dense_column->
resize(num_rows_, 0.0);
468 const auto entry_rows = rows_.view();
469 const auto entry_coeffs = coefficients_.view();
470 for (
const EntryIndex i : Column(
col)) {
471 (*dense_column)[entry_rows[i]] = entry_coeffs[i];
480 dense_column->
resize(num_rows_, 0.0);
482 const auto entry_rows = rows_.view();
483 const auto entry_coeffs = coefficients_.view();
484 for (
const EntryIndex i : Column(
col)) {
485 const RowIndex
row = entry_rows[i];
486 (*dense_column)[
row] = entry_coeffs[i];
487 non_zeros->push_back(
row);
496 return ::util::IntegerRange<EntryIndex>(starts_[
col], starts_[
col + 1]);
518 int i = starts_[
col.value()].value();
519 const int end = starts_[
col.value() + 1].value();
520 const int shifted_end =
end - 3;
525 for (; i < shifted_end; i += 4) {
526 result1 += coefficients_[i] * vector[
RowToColIndex(rows_[i])];
527 result2 += coefficients_[i + 1] * vector[
RowToColIndex(rows_[i + 1])];
528 result3 += coefficients_[i + 2] * vector[
RowToColIndex(rows_[i + 2])];
529 result4 += coefficients_[i + 3] * vector[
RowToColIndex(rows_[i + 3])];
531 Fractional result = result1 + result2 + result3 + result4;
533 result += coefficients_[i] * vector[
RowToColIndex(rows_[i])];
535 result += coefficients_[i + 1] * vector[
RowToColIndex(rows_[i + 1])];
537 result += coefficients_[i + 2] * vector[
RowToColIndex(rows_[i + 2])];
552 : compact_matrix_(*compact_matrix),
553 columns_(basis->data(), basis->size().
value()) {}
555 const std::vector<ColIndex>* columns)
556 : compact_matrix_(*compact_matrix), columns_(*columns) {}
559 bool IsEmpty()
const {
return compact_matrix_.IsEmpty(); }
560 RowIndex
num_rows()
const {
return compact_matrix_.num_rows(); }
561 ColIndex
num_cols()
const {
return ColIndex(columns_.size()); }
563 return compact_matrix_.column(columns_[
col.value()]);
573 const absl::Span<const ColIndex> columns_;
592 bool IsEmpty()
const {
return diagonal_coefficients_.empty(); }
624 RowIndex diagonal_row,
626 void AddDiagonalOnlyColumn(
Fractional diagonal_value);
633 RowIndex diagonal_row,
637 void ApplyRowPermutationToNonDiagonalEntries(
const RowPermutation& row_perm);
640 void CopyColumnToSparseColumn(ColIndex
col,
SparseColumn* output)
const;
649 return first_non_identity_column_;
654 return diagonal_coefficients_[
col];
717 void HyperSparseSolveWithReversedNonZeros(
721 void TransposeHyperSparseSolveWithReversedNonZeros(
729 void ComputeRowsToConsiderWithDfs(
RowIndexVector* non_zero_rows)
const;
735 void ComputeRowsToConsiderInSortedOrder(
RowIndexVector* non_zero_rows,
738 void ComputeRowsToConsiderInSortedOrder(
RowIndexVector* non_zero_rows)
const;
776 void PermutedLowerSparseSolve(
const ColumnView& rhs,
782 return num_fp_operations_;
789 bool IsLowerTriangular()
const;
790 bool IsUpperTriangular()
const;
807 void PermutedComputeRowsToConsider(
const ColumnView& rhs,
815 Fractional ComputeInverseInfinityNormUpperBound()
const;
816 Fractional ComputeInverseInfinityNorm()
const;
820 template <
bool diagonal_of_ones>
821 void LowerSolveStartingAtInternal(ColIndex
start,
823 template <
bool diagonal_of_ones>
825 template <
bool diagonal_of_ones>
827 template <
bool diagonal_of_ones>
829 template <
bool diagonal_of_ones>
832 template <
bool diagonal_of_ones>
833 void HyperSparseSolveWithReversedNonZerosInternal(
835 template <
bool diagonal_of_ones>
838 template <
bool diagonal_of_ones>
839 void TransposeHyperSparseSolveWithReversedNonZerosInternal(
844 void CloseCurrentColumn(
Fractional diagonal_value);
852 ColIndex first_non_identity_column_;
856 bool all_diagonal_coefficients_are_one_;
861 mutable std::vector<RowIndex> nodes_to_explore_;
864 int64_t num_fp_operations_;
865 mutable std::vector<RowIndex> lower_column_rows_;
866 mutable std::vector<RowIndex> upper_column_rows_;
867 mutable DenseColumn initially_all_zero_scratchpad_;
ConstView(const CompactSparseMatrix *matrix)
::util::IntegerRange< EntryIndex > Column(ColIndex col) const
Fractional EntryCoefficient(EntryIndex i) const
Fractional ColumnScalarProduct(ColIndex col, DenseRow::ConstView vector) const
RowIndex EntryRow(EntryIndex i) const
EntryIndex ColumnNumEntries(ColIndex col) const
bool ColumnIsEmpty(ColIndex col) const
void ColumnCopyToDenseColumn(ColIndex col, DenseColumn *dense_column) const
StrictITIVector< ColIndex, EntryIndex > starts_
ColIndex num_cols() const
::util::IntegerRange< EntryIndex > Column(ColIndex col) const
void ColumnAddMultipleToSparseScatteredColumn(ColIndex col, Fractional multiplier, ScatteredColumn *column) const
void Swap(CompactSparseMatrix *other)
void ColumnCopyToClearedDenseColumnWithNonZeros(ColIndex col, DenseColumn *dense_column, RowIndexVector *non_zeros) const
StrictITIVector< EntryIndex, RowIndex > rows_
RowIndex num_rows() const
CompactSparseMatrix(const SparseMatrix &matrix)
StrictITIVector< EntryIndex, Fractional > coefficients_
void PopulateFromTranspose(const CompactSparseMatrix &input)
void ColumnCopyToClearedDenseColumn(ColIndex col, DenseColumn *dense_column) const
Fractional ColumnScalarProduct(ColIndex col, const DenseRow &vector) const
void Reset(RowIndex num_rows)
void ColumnAddMultipleToDenseColumn(ColIndex col, Fractional multiplier, DenseColumn *dense_column) const
EntryIndex num_entries() const
ColumnView column(ColIndex col) const
EntryIndex ColumnNumEntries(ColIndex col) const
ColIndex num_cols() const
const ColumnView column(ColIndex col) const
CompactSparseMatrixView(const CompactSparseMatrix *compact_matrix, const RowToColMapping *basis)
CompactSparseMatrixView(const CompactSparseMatrix *compact_matrix, const std::vector< ColIndex > *columns)
RowIndex num_rows() const
Fractional ComputeInfinityNorm() const
ColIndex num_cols() const
void PopulateFromMatrix(const SparseMatrix &matrix)
Fractional ComputeOneNorm() const
void PopulateFromMatrixPair(const SparseMatrix &matrix_a, const SparseMatrix &matrix_b)
RowIndex num_rows() const
MatrixView(const SparseMatrix &matrix)
const SparseColumn & column(ColIndex col) const
void PopulateFromBasis(const MatrixView &matrix, const RowToColMapping &basis)
EntryIndex num_entries() const
void AppendUnitVector(RowIndex row, Fractional value)
void PopulateFromLinearCombination(Fractional alpha, const SparseMatrix &a, Fractional beta, const SparseMatrix &b)
SparseColumn * mutable_column(ColIndex col)
void PopulateFromPermutedMatrix(const Matrix &a, const RowPermutation &row_perm, const ColumnPermutation &inverse_col_perm)
bool CheckNoDuplicates() const
void PopulateFromTranspose(const Matrix &input)
void PopulateFromIdentity(ColIndex num_cols)
Fractional ComputeInfinityNorm() const
ColIndex num_cols() const
void SetNumRows(RowIndex num_rows)
Fractional LookUpValue(RowIndex row, ColIndex col) const
void Swap(SparseMatrix *matrix)
Fractional ComputeOneNorm() const
void ComputeMinAndMaxMagnitudes(Fractional *min_magnitude, Fractional *max_magnitude) const
void DeleteRows(RowIndex num_rows, const RowPermutation &permutation)
ColIndex AppendEmptyColumn()
RowIndex num_rows() const
void PopulateFromProduct(const SparseMatrix &a, const SparseMatrix &b)
bool AppendRowsFromSparseMatrix(const SparseMatrix &matrix)
void DeleteColumns(const DenseBooleanRow &columns_to_delete)
void PopulateFromSparseMatrix(const SparseMatrix &matrix)
void ApplyRowPermutation(const RowPermutation &row_perm)
const SparseColumn & column(ColIndex col) const
void PopulateFromZero(RowIndex num_rows, ColIndex num_cols)
EntryIndex num_entries() const
bool Equals(const SparseMatrix &a, Fractional tolerance) const
void AssignToZero(IntType size)
void resize(IntType size)
ConstView const_view() const
StrictITISpan< ColIndex, const Fractional > ConstView
ColIndex GetFirstNonIdentityColumn() const
ColIndex num_cols() const
Fractional GetDiagonalCoefficient(ColIndex col) const
RowIndex num_rows() const
int64_t NumFpOperationsInLastPermutedLowerSparseSolve() const
bool ColumnIsDiagonalOnly(ColIndex col) const
EntryIndex num_entries() const
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Permutation< ColIndex > ColumnPermutation
ColIndex RowToColIndex(RowIndex row)
std::vector< RowIndex > RowIndexVector
Permutation< RowIndex > RowPermutation
IntegerValue ComputeInfinityNorm(const LinearConstraint &constraint)
Collection of objects used to extend the Constraint Solver library.
static int input(yyscan_t yyscanner)
#define RETURN_IF_NULL(x)
std::optional< int64_t > end