Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
lp_utils.cc
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <algorithm>
17
18#include "absl/log/check.h"
19#include "absl/types/span.h"
23
24namespace operations_research {
25namespace glop {
26
27template <typename SparseColumnLike>
28Fractional SquaredNormTemplate(const SparseColumnLike& column) {
29 Fractional sum(0.0);
30 for (const SparseColumn::Entry e : column) {
31 sum += Square(e.coefficient());
32 }
33 return sum;
34}
35
39
43
45 KahanSum sum;
46 for (const SparseColumn::Entry e : v) {
47 sum.Add(Square(e.coefficient()));
48 }
49 return sum.Value();
50}
51
54 return SquaredNorm(v.values);
55 }
56 Fractional sum(0.0);
57 for (const RowIndex row : v.non_zeros) {
58 sum += Square(v[row]);
59 }
60 return sum;
61}
62
65 return PreciseSquaredNorm(v.values);
66 }
67 KahanSum sum;
68 for (const RowIndex row : v.non_zeros) {
69 sum.Add(Square(v[row]));
70 }
71 return sum.Value();
72}
73
74Fractional SquaredNorm(absl::Span<const Fractional> data) {
75 // We expand ourselves since we don't really care about the floating
76 // point order of operation and this seems faster.
77 int i = 0;
78 const int end = data.size();
79 const int shifted_end = end - 3;
80 Fractional sum1 = 0.0;
81 Fractional sum2 = 0.0;
82 Fractional sum3 = 0.0;
83 Fractional sum4 = 0.0;
84 for (; i < shifted_end; i += 4) {
85 sum1 += data[i] * data[i];
86 sum2 += data[i + 1] * data[i + 1];
87 sum3 += data[i + 2] * data[i + 2];
88 sum4 += data[i + 3] * data[i + 3];
89 }
90 Fractional sum = sum1 + sum2 + sum3 + sum4;
91 if (i < end) {
92 sum += data[i] * data[i];
93 if (i + 1 < end) {
94 sum += data[i + 1] * data[i + 1];
95 if (i + 2 < end) {
96 sum += data[i + 2] * data[i + 2];
97 }
98 }
99 }
100 return sum;
101}
102
103Fractional SquaredNormAndResetToZero(absl::Span<Fractional> data) {
104 // We expand ourselves since we don't really care about the floating
105 // point order of operation and this seems faster.
106 int i = 0;
107 const int end = data.size();
108 const int shifted_end = end - 3;
109 Fractional sum1 = 0.0;
110 Fractional sum2 = 0.0;
111 Fractional sum3 = 0.0;
112 Fractional sum4 = 0.0;
113 for (; i < shifted_end; i += 4) {
114 sum1 += data[i] * data[i];
115 sum2 += data[i + 1] * data[i + 1];
116 sum3 += data[i + 2] * data[i + 2];
117 sum4 += data[i + 3] * data[i + 3];
118 data[i] = 0.0;
119 data[i + 1] = 0.0;
120 data[i + 2] = 0.0;
121 data[i + 3] = 0.0;
122 }
123 Fractional sum = sum1 + sum2 + sum3 + sum4;
124 if (i < end) {
125 sum += data[i] * data[i];
126 data[i] = 0.0;
127 if (i + 1 < end) {
128 sum += data[i + 1] * data[i + 1];
129 data[i + 1] = 0.0;
130 if (i + 2 < end) {
131 sum += data[i + 2] * data[i + 2];
132 data[i + 2] = 0.0;
133 }
134 }
135 }
136 return sum;
137}
138
140 return SquaredNorm(absl::MakeSpan(column.data(), column.size().value()));
141}
142
144 KahanSum sum;
145 for (RowIndex row(0); row < column.size(); ++row) {
146 sum.Add(Square(column[row]));
147 }
148 return sum.Value();
149}
150
152 Fractional infinity_norm = 0.0;
153 for (RowIndex row(0); row < v.size(); ++row) {
154 infinity_norm = std::max(infinity_norm, fabs(v[row]));
155 }
156 return infinity_norm;
157}
158
159template <typename SparseColumnLike>
160Fractional InfinityNormTemplate(const SparseColumnLike& column) {
161 Fractional infinity_norm = 0.0;
162 for (const SparseColumn::Entry e : column) {
163 infinity_norm = std::max(infinity_norm, fabs(e.coefficient()));
164 }
165 return infinity_norm;
166}
167
171
175
176double Density(const DenseRow& row) {
177 if (row.empty()) return 0.0;
178 int sum = 0.0;
179 for (ColIndex col(0); col < row.size(); ++col) {
180 if (row[col] != Fractional(0.0)) ++sum;
181 }
182 return static_cast<double>(sum) / row.size().value();
183}
184
186 if (threshold == Fractional(0.0)) return;
187 for (ColIndex col(0); col < row->size(); ++col) {
188 if (fabs((*row)[col]) < threshold) {
189 (*row)[col] = Fractional(0.0);
190 }
191 }
192}
193
195 if (threshold == Fractional(0.0)) return;
196 for (RowIndex row(0); row < column->size(); ++row) {
197 if (fabs((*column)[row]) < threshold) {
198 (*column)[row] = Fractional(0.0);
199 }
200 }
201}
202
204 const DenseBooleanColumn& rows_to_consider,
205 RowIndex* row_index) {
206 Fractional infinity_norm = 0.0;
207 for (const SparseColumn::Entry e : column) {
208 if (rows_to_consider[e.row()] && fabs(e.coefficient()) > infinity_norm) {
209 infinity_norm = fabs(e.coefficient());
210 *row_index = e.row();
211 }
212 }
213 return infinity_norm;
214}
215
217 for (const SparseColumn::Entry e : column) {
218 if (e.coefficient() != 0.0) {
219 (*b)[e.row()] = false;
220 }
221 }
222}
223
224bool IsDominated(const ColumnView& column, const DenseColumn& radius) {
225 for (const SparseColumn::Entry e : column) {
226 DCHECK_GE(radius[e.row()], 0.0);
227 if (fabs(e.coefficient()) > radius[e.row()]) return false;
228 }
229 return true;
230}
231
232} // namespace glop
233} // namespace operations_research
void Add(const FpNumber &value)
Adds an FpNumber to the sum.
FpNumber Value() const
Gets the value of the sum.
int64_t b
Definition table.cc:45
ColIndex col
Definition markowitz.cc:187
RowIndex row
Definition markowitz.cc:186
double Density(const DenseRow &row)
Definition lp_utils.cc:176
void RemoveNearZeroEntries(Fractional threshold, DenseRow *row)
Definition lp_utils.cc:185
Fractional Square(Fractional f)
Definition lp_utils.h:41
Fractional InfinityNormTemplate(const SparseColumnLike &column)
Definition lp_utils.cc:160
Fractional SquaredNormTemplate(const SparseColumnLike &column)
Definition lp_utils.cc:28
Fractional PreciseSquaredNorm(const SparseColumn &v)
Definition lp_utils.cc:44
Fractional RestrictedInfinityNorm(const ColumnView &column, const DenseBooleanColumn &rows_to_consider, RowIndex *row_index)
Definition lp_utils.cc:203
Fractional InfinityNorm(const DenseColumn &v)
Returns the maximum of the coefficients of 'v'.
Definition lp_utils.cc:151
void SetSupportToFalse(const ColumnView &column, DenseBooleanColumn *b)
Definition lp_utils.cc:216
Fractional SquaredNorm(const SparseColumn &v)
Definition lp_utils.cc:36
StrictITIVector< RowIndex, Fractional > DenseColumn
Column-vector types. Column-vector types are indexed by a row index.
Definition lp_types.h:382
bool IsDominated(const ColumnView &column, const DenseColumn &radius)
Returns true iff for all 'row' we have '|column[row]| <= radius[row]'.
Definition lp_utils.cc:224
Fractional SquaredNormAndResetToZero(absl::Span< Fractional > data)
Definition lp_utils.cc:103
In SWIG mode, we don't want anything besides these top-level includes.
int column
std::optional< int64_t > end
StrictITIVector< Index, Fractional > values
bool ShouldUseDenseIteration(double ratio_for_using_dense_representation) const