45 : parameters_(parameters),
48 variables_info_(variables_info),
49 basis_factorization_(basis_factorization),
50 dual_edge_norms_(dual_edge_norms),
51 dual_prices_(dual_prices),
52 stats_(
"VariableValues") {}
56 const DenseRow& lower_bounds = variables_info_.GetVariableLowerBounds();
57 const DenseRow& upper_bounds = variables_info_.GetVariableUpperBounds();
58 variable_values_.resize(matrix_.num_cols(), 0.0);
59 switch (variables_info_.GetStatusRow()[col]) {
62 DCHECK_EQ(lower_bounds[col], upper_bounds[col]);
63 variable_values_[col] = lower_bounds[col];
67 variable_values_[col] = lower_bounds[col];
71 variable_values_[col] = upper_bounds[col];
74 LOG(DFATAL) <<
"SetNonBasicVariableValueFromStatus() shouldn't "
75 <<
"be called on a FREE variable.";
78 LOG(DFATAL) <<
"SetNonBasicVariableValueFromStatus() shouldn't "
79 <<
"be called on a BASIC variable.";
87 const DenseRow& free_initial_value) {
88 const DenseRow& lower_bounds = variables_info_.GetVariableLowerBounds();
89 const DenseRow& upper_bounds = variables_info_.GetVariableUpperBounds();
91 const ColIndex num_cols = matrix_.num_cols();
92 variable_values_.resize(num_cols, 0.0);
93 for (ColIndex col(0); col < num_cols; ++col) {
94 switch (statuses[col]) {
96 ABSL_FALLTHROUGH_INTENDED;
98 variable_values_[col] = lower_bounds[col];
101 variable_values_[col] = upper_bounds[col];
104 variable_values_[col] =
105 col < free_initial_value.
size() ? free_initial_value[col] : 0.0;
115 DCHECK(basis_factorization_.IsRefactorized());
116 const RowIndex num_rows = matrix_.num_rows();
117 scratchpad_.non_zeros.clear();
118 scratchpad_.values.AssignToZero(num_rows);
119 for (
const ColIndex col : variables_info_.GetNotBasicBitRow()) {
120 const Fractional value = variable_values_[col];
121 matrix_.ColumnAddMultipleToDenseColumn(col, -value, &scratchpad_.values);
123 basis_factorization_.RightSolve(&scratchpad_);
124 for (RowIndex row(0); row < num_rows; ++row) {
125 variable_values_[basis_[row]] = scratchpad_[row];
129 dual_prices_->Clear();
134 scratchpad_.non_zeros.clear();
135 scratchpad_.values.AssignToZero(matrix_.num_rows());
136 const ColIndex num_cols = matrix_.num_cols();
137 for (ColIndex col(0); col < num_cols; ++col) {
138 const Fractional value = variable_values_[col];
139 matrix_.ColumnAddMultipleToDenseColumn(col, value, &scratchpad_.values);
147 const ColIndex num_cols = matrix_.num_cols();
150 variables_info_.GetVariableLowerBounds().const_view();
152 variables_info_.GetVariableUpperBounds().const_view();
153 for (ColIndex col(0); col < num_cols; ++col) {
155 GetColInfeasibility(col, values, lower_bounds, upper_bounds);
156 primal_infeasibility = std::max(primal_infeasibility, infeasibility);
158 return primal_infeasibility;
164 const ColIndex num_cols = matrix_.num_cols();
167 variables_info_.GetVariableLowerBounds().const_view();
169 variables_info_.GetVariableUpperBounds().const_view();
170 for (ColIndex col(0); col < num_cols; ++col) {
172 GetColInfeasibility(col, values, lower_bounds, upper_bounds);
173 sum += std::max(0.0, infeasibility);
204 absl::Span<const ColIndex> cols_to_update,
bool update_basic_variables) {
206 if (!update_basic_variables) {
207 for (ColIndex col : cols_to_update) {
213 const RowIndex num_rows = matrix_.num_rows();
214 initially_all_zero_scratchpad_.values.resize(num_rows, 0.0);
215 DCHECK(
IsAllZero(initially_all_zero_scratchpad_.values));
216 initially_all_zero_scratchpad_.ClearSparseMask();
217 bool use_dense =
false;
218 for (ColIndex col : cols_to_update) {
219 const Fractional old_value = variable_values_[col];
222 matrix_.ColumnAddMultipleToDenseColumn(
223 col, variable_values_[col] - old_value,
224 &initially_all_zero_scratchpad_.values);
226 matrix_.ColumnAddMultipleToSparseScatteredColumn(
227 col, variable_values_[col] - old_value,
228 &initially_all_zero_scratchpad_);
229 use_dense = initially_all_zero_scratchpad_.ShouldUseDenseIteration();
232 initially_all_zero_scratchpad_.ClearSparseMask();
233 initially_all_zero_scratchpad_.ClearNonZerosIfTooDense();
235 basis_factorization_.RightSolve(&initially_all_zero_scratchpad_);
236 if (initially_all_zero_scratchpad_.non_zeros.empty()) {
237 for (RowIndex row(0); row < num_rows; ++row) {
238 variable_values_[basis_[row]] -= initially_all_zero_scratchpad_[row];
240 initially_all_zero_scratchpad_.values.AssignToZero(num_rows);
245 for (
const auto e : initially_all_zero_scratchpad_) {
246 variable_values_[basis_[e.row()]] -= e.coefficient();
247 initially_all_zero_scratchpad_[e.row()] = 0.0;
250 initially_all_zero_scratchpad_.non_zeros.clear();
255 const RowIndex num_rows = matrix_.num_rows();
256 dual_prices_->ClearAndResize(num_rows);
257 dual_prices_->StartDenseUpdates();
259 put_more_importance_on_norm_ = put_more_importance_on_norm;
260 const Fractional tolerance = parameters_.primal_feasibility_tolerance();
262 dual_edge_norms_->GetEdgeSquaredNorms();
266 variables_info_.GetVariableLowerBounds().const_view();
268 variables_info_.GetVariableUpperBounds().const_view();
269 if (put_more_importance_on_norm) {
270 for (RowIndex row(0); row < num_rows; ++row) {
271 const ColIndex col = basis[row];
273 GetColInfeasibility(col, values, lower_bounds, upper_bounds);
274 if (infeasibility > tolerance) {
275 dual_prices_->DenseAddOrUpdate(
276 row, std::abs(infeasibility) / squared_norms[row]);
280 for (RowIndex row(0); row < num_rows; ++row) {
281 const ColIndex col = basis[row];
283 GetColInfeasibility(col, values, lower_bounds, upper_bounds);
284 if (infeasibility > tolerance) {
285 dual_prices_->DenseAddOrUpdate(
286 row,
Square(infeasibility) / squared_norms[row]);
293 if (dual_prices_->Size() != matrix_.num_rows()) {
301 const Fractional tolerance = parameters_.primal_feasibility_tolerance();
304 dual_edge_norms_->GetEdgeSquaredNorms();
307 variables_info_.GetVariableLowerBounds().const_view();
309 variables_info_.GetVariableUpperBounds().const_view();
310 if (put_more_importance_on_norm_) {
311 for (
const RowIndex row : rows) {
312 const ColIndex col = basis[row];
314 GetColInfeasibility(col, values, lower_bounds, upper_bounds);
315 if (infeasibility > tolerance) {
316 dual_prices_->AddOrUpdate(row,
317 std::abs(infeasibility) / squared_norms[row]);
319 dual_prices_->Remove(row);
323 for (
const RowIndex row : rows) {
324 const ColIndex col = basis[row];
326 GetColInfeasibility(col, values, lower_bounds, upper_bounds);
327 if (infeasibility > tolerance) {
328 dual_prices_->AddOrUpdate(row,
329 Square(infeasibility) / squared_norms[row]);
331 dual_prices_->Remove(row);
VariableValues(const GlopParameters ¶meters, const CompactSparseMatrix &matrix, const RowToColMapping &basis, const VariablesInfo &variables_info, const BasisFactorization &basis_factorization, DualEdgeNorms *dual_edge_norms, DynamicMaximum< RowIndex > *dual_prices)