16#ifndef OR_TOOLS_LP_DATA_LP_UTILS_H_
17#define OR_TOOLS_LP_DATA_LP_UTILS_H_
22#include "absl/log/check.h"
46 return std::abs(f - std::round(f));
51template <
class DenseRowOrColumn1,
class DenseRowOrColumn2>
53 const DenseRowOrColumn2& v) {
54 DCHECK_EQ(u.size().value(), v.size().value());
56 typename DenseRowOrColumn1::IndexType i(0);
57 typename DenseRowOrColumn2::IndexType j(0);
58 const size_t num_blocks = u.size().value() / 4;
59 for (
size_t block = 0; block < num_blocks; ++block) {
73 sum += (u[i++] * v[j++]) + (u[i++] * v[j++]) + (u[i++] * v[j++]) +
76 while (i < u.size()) {
77 sum += u[i++] * v[j++];
86template <
class DenseRowOrColumn>
89 for (
const SparseColumn::Entry e : v) {
90 sum += u[
typename DenseRowOrColumn::IndexType(e.row().value())] *
96template <
class DenseRowOrColumn>
98 DCHECK_EQ(u.size().value(), v.
values.
size().value());
103 for (
const auto e : v) {
104 sum += (u[
typename DenseRowOrColumn::IndexType(e.row().value())] *
110template <
class DenseRowOrColumn,
class DenseRowOrColumn2>
112 const DenseRowOrColumn2& v) {
113 DCHECK_EQ(u.size().value(), v.size().value());
115 for (
typename DenseRowOrColumn::IndexType i(0); i < u.size(); ++i) {
116 sum.
Add(u[i] * v[
typename DenseRowOrColumn2::IndexType(i.value())]);
121template <
class DenseRowOrColumn>
125 for (
const SparseColumn::Entry e : v) {
126 sum.
Add(u[
typename DenseRowOrColumn::IndexType(e.row().value())] *
133template <
class DenseRowOrColumn>
137 for (
const SparseColumn::Entry e : v) {
138 if (e.row().value() >= max_index) {
141 sum += u[
typename DenseRowOrColumn::IndexType(e.row().value())] *
185 RowIndex* row_index);
202 DCHECK(col.empty() || (&(col[RowIndex(0)]) == &(row[ColIndex(0)])));
210 DCHECK(col.empty() || (&(col[RowIndex(0)]) == &(row[ColIndex(0)])));
215template <
typename IndexType>
217 std::vector<IndexType>* non_zeros) {
219 const IndexType end =
input.size();
220 for (IndexType index(0); index < end; ++index) {
221 if (
input[index] != 0.0) {
222 non_zeros->push_back(index);
228template <
typename Container>
231 if (value != 0.0)
return false;
237template <
typename BoolVector>
239 return std::all_of(v.begin(), v.end(), [](
bool value) { return !value; });
243template <
typename IndexType,
typename PermutationIndexType>
249 const IndexType size = input_output->
size();
250 zero_scratchpad->
swap(*input_output);
251 input_output->
resize(size, 0.0);
255 const IndexType*
const perm = permutation.
data();
257 for (
int i = 0; i < size; ++i) {
258 DCHECK_GE(perm[i], 0);
259 DCHECK_LT(perm[i], size);
262 output[perm[i].value()] = value;
265 zero_scratchpad->
assign(size, 0.0);
270template <
typename IndexType>
275 std::vector<IndexType>* non_zeros) {
277 zero_scratchpad->
swap(*output);
279 for (IndexType& index_ref : *non_zeros) {
280 const Fractional value = (*zero_scratchpad)[index_ref];
281 (*zero_scratchpad)[index_ref] = 0.0;
282 const IndexType permuted_index(permutation[index_ref]);
283 (*output)[permuted_index] = value;
284 index_ref = permuted_index;
289template <
typename IndexType,
typename ScatteredRowOrCol>
291 ScatteredRowOrCol* v) {
295 const double kSparseThreshold = 0.05;
296 if (!v->non_zeros.empty() &&
297 v->non_zeros.size() < kSparseThreshold * size.value()) {
298 for (
const IndexType index : v->non_zeros) {
299 DCHECK_LT(index, v->values.size());
302 v->values.resize(size, 0.0);
305 v->values.AssignToZero(size);
307 v->non_zeros.clear();
311template <
typename IndexType>
313 const IndexType end = data->
size();
314 for (IndexType i(0); i < end; ++i) {
315 (*data)[i] = -(*data)[i];
332template <
bool supported_infinity_is_positive>
338 DCHECK(!std::isnan(x));
341 DCHECK_EQ(x, Infinity());
349 if (!
IsFinite(sum_.Value()))
return;
355 DCHECK_GE(num_infinities_, 1);
360 if (num_infinities_ > 0)
return Infinity();
366 if (num_infinities_ > 0)
return Infinity();
367 return sum_.Value() - x;
369 DCHECK_EQ(Infinity(), x);
370 if (num_infinities_ > 1)
return Infinity();
void Add(const FpNumber &value)
Adds an FpNumber to the sum.
FpNumber Value() const
Gets the value of the sum.
const IndexType * data() const
void assign(IntType size, const T &v)
void resize(IntType size)
Fractional SumWithout(Fractional x) const
Fractional SumWithoutUb(Fractional c) const
Fractional SumWithoutLb(Fractional c) const
value_type * data()
– Pass-through methods to STL vector ----------------------------------—
void swap(StrongVector &x) noexcept
double Density(const DenseRow &row)
constexpr double kInfinity
Infinity for type Fractional.
void PermuteWithScratchpad(const Permutation< PermutationIndexType > &permutation, StrictITIVector< IndexType, Fractional > *zero_scratchpad, StrictITIVector< IndexType, Fractional > *input_output)
Permutes the given dense vector. It uses for this an all zero scratchpad.
void RemoveNearZeroEntries(Fractional threshold, DenseRow *row)
Fractional Square(Fractional f)
StrictITIVector< RowIndex, bool > DenseBooleanColumn
Column of booleans.
bool IsAllZero(const Container &input)
Returns true if the given Fractional container is all zeros.
Fractional ScalarProduct(const DenseRowOrColumn1 &u, const DenseRowOrColumn2 &v)
void ComputeNonZeros(const StrictITIVector< IndexType, Fractional > &input, std::vector< IndexType > *non_zeros)
Computes the positions of the non-zeros of a dense vector.
AccurateSum< Fractional > KahanSum
Fractional PreciseScalarProduct(const DenseRowOrColumn &u, const DenseRowOrColumn2 &v)
SumWithOneMissing< true > SumWithPositiveInfiniteAndOneMissing
const DenseRow & Transpose(const DenseColumn &col)
Similar comment as the other Transpose() implementation above.
bool IsAllFalse(const BoolVector &v)
Returns true if the given vector of bool is all false.
void PermuteWithKnownNonZeros(const Permutation< IndexType > &permutation, StrictITIVector< IndexType, Fractional > *zero_scratchpad, StrictITIVector< IndexType, Fractional > *output, std::vector< IndexType > *non_zeros)
bool IsFinite(Fractional value)
void ClearAndResizeVectorWithNonZeros(IndexType size, ScatteredRowOrCol *v)
Sets a dense vector for which the non zeros are known to be non_zeros.
Fractional PreciseSquaredNorm(const SparseColumn &v)
Fractional RestrictedInfinityNorm(const ColumnView &column, const DenseBooleanColumn &rows_to_consider, RowIndex *row_index)
Fractional InfinityNorm(const DenseColumn &v)
Returns the maximum of the coefficients of 'v'.
void SetSupportToFalse(const ColumnView &column, DenseBooleanColumn *b)
RowIndex ColToRowIndex(ColIndex col)
Get the RowIndex corresponding to the row # col.
void ChangeSign(StrictITIVector< IndexType, Fractional > *data)
Changes the sign of all the entries in the given vector.
static Fractional Fractionality(Fractional f)
Fractional SquaredNorm(const SparseColumn &v)
Fractional PartialScalarProduct(const DenseRowOrColumn &u, const SparseColumn &v, int max_index)
Computes a scalar product for entries with index not greater than max_index.
StrictITIVector< RowIndex, Fractional > DenseColumn
Column-vector types. Column-vector types are indexed by a row index.
StrictITIVector< ColIndex, Fractional > DenseRow
Row-vector types. Row-vector types are indexed by a column index.
bool IsDominated(const ColumnView &column, const DenseColumn &radius)
Returns true iff for all 'row' we have '|column[row]| <= radius[row]'.
SumWithOneMissing< false > SumWithNegativeInfiniteAndOneMissing
Fractional SquaredNormAndResetToZero(absl::Span< Fractional > data)
In SWIG mode, we don't want anything besides these top-level includes.
util_intops::StrongVector< ColumnEntryIndex, ElementIndex > SparseColumn
static int input(yyscan_t yyscanner)
StrictITIVector< Index, Fractional > values
bool ShouldUseDenseIteration(double ratio_for_using_dense_representation) const