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) {
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);
255 const IndexType permuted_index(
256 permutation[PermutationIndexType(
index.value())].value());
257 (*input_output)[permuted_index] =
value;
265template <
typename IndexType>
270 std::vector<IndexType>* non_zeros) {
272 zero_scratchpad->
swap(*output);
274 for (IndexType& index_ref : *non_zeros) {
276 (*zero_scratchpad)[index_ref] = 0.0;
277 const IndexType permuted_index(permutation[index_ref]);
278 (*output)[permuted_index] =
value;
279 index_ref = permuted_index;
284template <
typename IndexType,
typename ScatteredRowOrCol>
286 ScatteredRowOrCol* v) {
290 const double kSparseThreshold = 0.05;
291 if (!v->non_zeros.empty() &&
292 v->non_zeros.size() < kSparseThreshold *
size.value()) {
293 for (
const IndexType
index : v->non_zeros) {
294 DCHECK_LT(
index, v->values.size());
297 v->values.resize(
size, 0.0);
300 v->values.AssignToZero(
size);
302 v->non_zeros.clear();
306template <
typename IndexType>
308 const IndexType
end = data->
size();
309 for (IndexType i(0); i <
end; ++i) {
310 (*data)[i] = -(*data)[i];
327template <
bool supported_infinity_is_positive>
333 DCHECK(!std::isnan(
x));
336 DCHECK_EQ(
x, Infinity());
350 DCHECK_GE(num_infinities_, 1);
355 if (num_infinities_ > 0)
return Infinity();
361 if (num_infinities_ > 0)
return Infinity();
364 DCHECK_EQ(Infinity(),
x);
365 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.
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
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.
static int input(yyscan_t yyscanner)
std::optional< int64_t > end
StrictITIVector< Index, Fractional > values
bool ShouldUseDenseIteration(double ratio_for_using_dense_representation) const