25 #include "absl/log/check.h"
35 using ::Eigen::VectorXd;
75 class VectorTrustRegionProblem {
77 VectorTrustRegionProblem(
const VectorXd* objective,
81 const VectorXd* norm_weight)
86 norm_weight_(*norm_weight) {}
90 double CenterPoint(int64_t
index)
const {
return center_point_(
index); }
91 double NormWeight(int64_t
index)
const {
return norm_weight_(
index); }
95 const VectorXd& lower_bound_;
96 const VectorXd& upper_bound_;
97 const VectorXd& center_point_;
98 const VectorXd& norm_weight_;
115 class JointTrustRegionProblem {
117 JointTrustRegionProblem(
const QuadraticProgram* qp,
118 const VectorXd* primal_solution,
119 const VectorXd* dual_solution,
120 const VectorXd* primal_gradient,
121 const VectorXd* dual_gradient,
122 const double primal_weight)
125 primal_solution_(*primal_solution),
126 dual_solution_(*dual_solution),
127 primal_gradient_(*primal_gradient),
128 dual_gradient_(*dual_gradient),
129 primal_weight_(primal_weight) {}
130 double Objective(int64_t
index)
const {
131 return index < primal_size_ ? primal_gradient_[
index]
132 : -dual_gradient_[
index - primal_size_];
135 return index < primal_size_ ? qp_.variable_lower_bounds[
index]
136 : std::isfinite(qp_.constraint_upper_bounds[
index - primal_size_])
137 ? -std::numeric_limits<double>::infinity()
141 return index < primal_size_ ? qp_.variable_upper_bounds[
index]
142 : std::isfinite(qp_.constraint_lower_bounds[
index - primal_size_])
143 ? std::numeric_limits<double>::infinity()
146 double CenterPoint(int64_t
index)
const {
147 return index < primal_size_ ? primal_solution_[
index]
148 : dual_solution_[
index - primal_size_];
150 double NormWeight(int64_t
index)
const {
151 return index < primal_size_ ? 0.5 * primal_weight_ : 0.5 / primal_weight_;
155 const QuadraticProgram& qp_;
156 const int64_t primal_size_;
157 const VectorXd& primal_solution_;
158 const VectorXd& dual_solution_;
159 const VectorXd& primal_gradient_;
160 const VectorXd& dual_gradient_;
161 const double primal_weight_;
164 struct TrustRegionResultStepSize {
177 template <
typename TrustRegionProblem>
178 double MedianOfShardMedians(
179 const TrustRegionProblem& problem,
180 const std::vector<std::vector<int64_t>>& indexed_components_by_shard,
181 const Sharder& sharder) {
182 std::vector<std::optional<double>> shard_medians(sharder.NumShards(),
184 sharder.ParallelForEachShard([&](
const Sharder::Shard& shard) {
185 const auto& indexed_shard_components =
186 indexed_components_by_shard[shard.Index()];
187 if (!indexed_shard_components.empty()) {
188 shard_medians[shard.Index()] = internal::EasyMedian(
189 indexed_shard_components, [&](const int64_t index) {
190 return internal::CriticalStepSize(problem, index);
194 std::vector<double> non_empty_medians;
195 for (
const auto& median : shard_medians) {
196 if (median.has_value()) {
197 non_empty_medians.push_back(*median);
200 CHECK(!non_empty_medians.empty());
202 [](
const double x) {
return x; });
205 struct InitialState {
210 template <
typename TrustRegionProblem>
211 InitialState ComputeInitialState(
const TrustRegionProblem& problem,
212 const Sharder& sharder) {
214 result.undecided_components_by_shard.resize(sharder.NumShards());
215 result.radius_coefficient_of_decided_components =
216 sharder.ParallelSumOverShards([&](
const Sharder::Shard& shard) {
217 const int64_t shard_start = sharder.ShardStart(shard.Index());
218 const int64_t shard_size = sharder.ShardSize(shard.Index());
220 problem, shard_start, shard_start + shard_size,
221 result.undecided_components_by_shard[shard.Index()]);
226 template <
typename TrustRegionProblem>
228 const TrustRegionProblem& problem,
const double step_size,
229 const Sharder& sharder,
231 return sharder.ParallelSumOverShards([&](
const Sharder::Shard& shard) {
237 template <
typename TrustRegionProblem>
239 const TrustRegionProblem& problem,
const double step_size_threshold,
240 const Sharder& sharder,
242 return sharder.ParallelSumOverShards([&](
const Sharder::Shard& shard) {
244 problem, step_size_threshold,
249 template <
typename TrustRegionProblem>
251 const TrustRegionProblem& problem,
const double step_size_threshold,
252 const Sharder& sharder,
254 return sharder.ParallelSumOverShards([&](
const Sharder::Shard& shard) {
256 problem, step_size_threshold,
261 int64_t NumUndecidedComponents(
263 int64_t num_undecided_components = 0;
265 num_undecided_components += undecided_components.size();
267 return num_undecided_components;
270 int64_t MaxUndecidedComponentsInAnyShard(
274 max = std::max<int64_t>(
max, undecided_components.size());
279 template <
typename TrustRegionProblem>
280 VectorXd ComputeSolution(
const TrustRegionProblem& problem,
281 const double step_size,
const Sharder& sharder) {
282 VectorXd solution(sharder.NumElements());
283 sharder.ParallelForEachShard([&](
const Sharder::Shard& shard) {
284 const int64_t shard_start = sharder.ShardStart(shard.Index());
285 const int64_t shard_size = sharder.ShardSize(shard.Index());
286 for (int64_t
index = shard_start;
index < shard_start + shard_size;
294 template <
typename TrustRegionProblem>
296 const double step_size,
const Sharder& sharder) {
297 return sharder.ParallelSumOverShards([&](
const Sharder::Shard& shard) {
298 const int64_t shard_start = sharder.ShardStart(shard.Index());
299 const int64_t shard_size = sharder.ShardSize(shard.Index());
300 double shard_value = 0.0;
301 for (int64_t
index = shard_start;
index < shard_start + shard_size;
303 shard_value += problem.Objective(
index) *
305 problem.CenterPoint(
index));
332 template <
typename TrustRegionProblem>
333 TrustRegionResultStepSize SolveTrustRegionStepSize(
334 const TrustRegionProblem& problem,
const double target_radius,
335 const Sharder& sharder) {
336 CHECK_GE(target_radius, 0.0);
338 const bool norm_weights_are_positive =
339 sharder.ParallelTrueForAllShards([&](
const Sharder::Shard& shard) {
340 const int64_t shard_start = sharder.ShardStart(shard.Index());
341 const int64_t shard_size = sharder.ShardSize(shard.Index());
342 for (int64_t
index = shard_start;
index < shard_start + shard_size;
344 if (problem.NormWeight(
index) <= 0.0)
return false;
348 CHECK(norm_weights_are_positive);
350 if (target_radius == 0.0) {
351 return {.solution_step_size = 0.0, .objective_value = 0.0};
354 const bool objective_is_all_zeros =
355 sharder.ParallelTrueForAllShards([&](
const Sharder::Shard& shard) {
356 const int64_t shard_start = sharder.ShardStart(shard.Index());
357 const int64_t shard_size = sharder.ShardSize(shard.Index());
358 for (int64_t
index = shard_start;
index < shard_start + shard_size;
360 if (problem.Objective(
index) != 0.0)
return false;
364 if (objective_is_all_zeros) {
365 return {.solution_step_size = 0.0, .objective_value = 0.0};
368 InitialState initial_state = ComputeInitialState(problem, sharder);
372 double fixed_radius_squared = 0.0;
378 double variable_radius_coefficient =
379 initial_state.radius_coefficient_of_decided_components;
385 std::move(initial_state.undecided_components_by_shard));
392 int64_t actual_elements_seen = sharder.NumElements();
393 int64_t worst_case_elements_seen = sharder.NumElements();
396 worst_case_elements_seen +=
399 actual_elements_seen +=
402 const double step_size_threshold =
404 const double radius_squared_of_undecided_components =
406 problem, step_size_threshold, sharder,
409 const double radius_squared_at_threshold =
410 radius_squared_of_undecided_components + fixed_radius_squared +
421 VLOG(1) <<
"Total passes through variables: "
422 << actual_elements_seen /
static_cast<double>(sharder.NumElements());
423 VLOG(1) <<
"Theoretical slowdown because of shard imbalance: "
424 <<
static_cast<double>(worst_case_elements_seen) /
425 actual_elements_seen -
432 double step_size = 0.0;
433 if (variable_radius_coefficient > 0.0) {
436 variable_radius_coefficient);
447 .solution_step_size = step_size,
458 const double target_radius,
463 TrustRegionResultStepSize solution =
464 SolveTrustRegionStepSize(problem, target_radius, sharder);
467 .objective_value = solution.objective_value,
469 ComputeSolution(problem, solution.solution_step_size, sharder),
502 return variable_lower_bounds_[
index];
506 return variable_upper_bounds_[
index];
512 return objective_matrix_diagonal_[
index];
516 const VectorXd& objective_vector_;
517 const VectorXd& objective_matrix_diagonal_;
518 const VectorXd& variable_lower_bounds_;
519 const VectorXd& variable_upper_bounds_;
520 const VectorXd& center_point_;
521 const VectorXd& norm_weight_;
543 const VectorXd* primal_solution,
544 const VectorXd* dual_solution,
545 const VectorXd* primal_gradient,
546 const VectorXd* dual_gradient,
547 const double primal_weight)
549 primal_solution_(*primal_solution),
550 dual_solution_(*dual_solution),
551 primal_gradient_(*primal_gradient),
552 dual_gradient_(*dual_gradient),
553 primal_size_(primal_solution->size()),
554 primal_weight_(primal_weight) {}
557 return (
index < primal_size_) ? primal_solution_[
index]
558 : dual_solution_[
index - primal_size_];
562 return (
index < primal_size_) ? 0.5 * primal_weight_ : 0.5 / primal_weight_;
566 if (
index < primal_size_) {
567 return qp_.variable_lower_bounds[
index];
569 return std::isfinite(qp_.constraint_upper_bounds[
index - primal_size_])
570 ? -std::numeric_limits<double>::infinity()
576 if (
index < primal_size_) {
577 return qp_.variable_upper_bounds[
index];
579 return std::isfinite(qp_.constraint_lower_bounds[
index - primal_size_])
580 ? std::numeric_limits<double>::infinity()
586 return (
index < primal_size_) ? primal_gradient_[
index]
587 : -dual_gradient_[
index - primal_size_];
591 if (qp_.objective_matrix.has_value()) {
592 return (
index < primal_size_) ? qp_.objective_matrix->diagonal()[
index]
601 const VectorXd& primal_solution_;
602 const VectorXd& dual_solution_;
603 const VectorXd& primal_gradient_;
604 const VectorXd& dual_gradient_;
605 const int64_t primal_size_;
606 const double primal_weight_;
615 template <
typename DiagonalTrustRegionProblem>
618 const double scaling_factor) {
635 template <
typename DiagonalTrustRegionProblem>
638 const double scaling_factor) {
639 const double squared_norm =
642 const int64_t shard_end =
645 for (int64_t i = shard_start; i < shard_end; ++i) {
646 const double projected_coordinate =
652 return std::sqrt(squared_norm);
662 template <
typename DiagonalTrustRegionProblem>
664 const Sharder& sharder,
const double target_radius,
665 const double solve_tol) {
668 double scaling_factor_lower_bound = 0.0;
669 double scaling_factor_upper_bound = 1.0;
672 scaling_factor_lower_bound = scaling_factor_upper_bound;
673 scaling_factor_upper_bound *= 2;
676 while ((scaling_factor_upper_bound - scaling_factor_lower_bound) >=
677 solve_tol *
std::max(1.0, scaling_factor_lower_bound)) {
678 const double middle =
679 (scaling_factor_lower_bound + scaling_factor_upper_bound) / 2.0;
682 scaling_factor_upper_bound = middle;
684 scaling_factor_lower_bound = middle;
687 return (scaling_factor_upper_bound + scaling_factor_lower_bound) / 2.0;
693 template <
typename DiagonalTrustRegionProblem>
696 const double target_radius,
const double solve_tol) {
697 CHECK_GE(target_radius, 0.0);
698 const bool norm_weights_are_positive =
701 for (int64_t i = shard_start;
703 if (problem.NormWeight(i) <= 0) {
709 CHECK(norm_weights_are_positive);
710 const double optimal_scaling =
712 VectorXd solution(sharder.NumElements());
713 sharder.ParallelForEachShard([&](
const Sharder::Shard& shard) {
714 const int64_t shard_start = sharder.ShardStart(shard.Index());
715 const int64_t shard_size = sharder.ShardSize(shard.Index());
716 for (int64_t i = shard_start; i < shard_start + shard_size; ++i) {
717 const double weight = problem.NormWeight(i);
718 const double projected_value =
721 problem.CenterPoint(i) + std::sqrt(1 /
weight) * projected_value;
724 const double final_objective_value =
725 sharder.ParallelSumOverShards([&](
const Sharder::Shard& shard) {
726 double local_sum = 0.0;
727 const int64_t shard_start = sharder.ShardStart(shard.Index());
728 for (int64_t i = shard_start;
729 i < shard_start + sharder.ShardSize(shard.Index()); ++i) {
730 const double diff = solution[i] - problem.CenterPoint(i);
732 0.5 * diff * problem.ObjectiveMatrixDiagonalAt(i) * diff +
733 diff * problem.Objective(i);
737 return {.solution_step_size = optimal_scaling,
738 .objective_value = final_objective_value,
739 .solution = solution};
746 const VectorXd&
norm_weights,
const double target_radius,
747 const Sharder& sharder,
const double solve_tolerance) {
757 const VectorXd& dual_solution,
const VectorXd& primal_gradient,
758 const VectorXd& dual_gradient,
const double primal_weight,
759 double target_radius,
const double solve_tolerance) {
762 &dual_solution, &primal_gradient,
763 &dual_gradient, primal_weight);
766 const bool norm_weights_are_positive =
769 for (int64_t i = shard_start;
771 if (problem.NormWeight(i) <= 0) {
777 CHECK(norm_weights_are_positive);
784 struct MaxNormBoundResult {
799 MaxNormBoundResult ComputeMaxNormPrimalTrustRegionBound(
800 const ShardedQuadraticProgram& sharded_qp,
const VectorXd& primal_solution,
801 const double primal_radius,
const VectorXd& dual_product) {
802 LagrangianPart primal_part =
804 internal::PrimalTrustRegionProblem primal_problem(
805 &sharded_qp.Qp(), &primal_solution, &primal_part.gradient);
806 TrustRegionResultStepSize trust_region_result = SolveTrustRegionStepSize(
807 primal_problem, primal_radius, sharded_qp.PrimalSharder());
808 return {.part_of_lagrangian_value = primal_part.value,
809 .trust_region_objective_delta = trust_region_result.objective_value};
812 MaxNormBoundResult ComputeMaxNormDualTrustRegionBound(
813 const ShardedQuadraticProgram& sharded_qp,
const VectorXd& dual_solution,
814 const double dual_radius,
const VectorXd& primal_product) {
815 LagrangianPart dual_part =
817 internal::DualTrustRegionProblem dual_problem(
818 &sharded_qp.Qp(), &dual_solution, &dual_part.gradient);
819 TrustRegionResultStepSize trust_region_result = SolveTrustRegionStepSize(
820 dual_problem, dual_radius, sharded_qp.DualSharder());
821 return {.part_of_lagrangian_value = dual_part.value,
822 .trust_region_objective_delta = -trust_region_result.objective_value};
828 double MaximumPrimalDistanceGivenWeightedDistance(
829 const double weighted_distance,
const double primal_weight) {
830 return std::sqrt(2) * weighted_distance / std::sqrt(primal_weight);
837 double MaximumDualDistanceGivenWeightedDistance(
const double weighted_distance,
838 const double primal_weight) {
839 return std::sqrt(2) * weighted_distance * std::sqrt(primal_weight);
842 LocalizedLagrangianBounds ComputeMaxNormLocalizedLagrangianBounds(
843 const ShardedQuadraticProgram& sharded_qp,
const VectorXd& primal_solution,
844 const VectorXd& dual_solution,
const double primal_weight,
845 const double radius,
const Eigen::VectorXd& primal_product,
846 const Eigen::VectorXd& dual_product) {
847 const double primal_radius =
848 MaximumPrimalDistanceGivenWeightedDistance(radius, primal_weight);
849 const double dual_radius =
850 MaximumDualDistanceGivenWeightedDistance(radius, primal_weight);
855 MaxNormBoundResult primal_result = ComputeMaxNormPrimalTrustRegionBound(
856 sharded_qp, primal_solution, primal_radius, dual_product);
858 MaxNormBoundResult dual_result = ComputeMaxNormDualTrustRegionBound(
859 sharded_qp, dual_solution, dual_radius, primal_product);
861 const double lagrangian_value = primal_result.part_of_lagrangian_value +
862 dual_result.part_of_lagrangian_value;
864 return LocalizedLagrangianBounds{
865 .lagrangian_value = lagrangian_value,
867 lagrangian_value + primal_result.trust_region_objective_delta,
869 lagrangian_value + dual_result.trust_region_objective_delta,
873 LocalizedLagrangianBounds ComputeEuclideanNormLocalizedLagrangianBounds(
874 const ShardedQuadraticProgram& sharded_qp,
const VectorXd& primal_solution,
875 const VectorXd& dual_solution,
const double primal_weight,
876 const double radius,
const Eigen::VectorXd& primal_product,
877 const Eigen::VectorXd& dual_product,
878 const bool use_diagonal_qp_trust_region_solver,
879 const double diagonal_qp_trust_region_solver_tolerance) {
880 const QuadraticProgram& qp = sharded_qp.Qp();
881 const LagrangianPart primal_part =
883 const LagrangianPart dual_part =
886 VectorXd trust_region_solution;
887 const double lagrangian_value = primal_part.value + dual_part.value;
889 Sharder joint_sharder(
890 sharded_qp.PrimalSharder(),
891 sharded_qp.PrimalSize() + sharded_qp.DualSize());
893 if (use_diagonal_qp_trust_region_solver) {
894 DiagonalTrustRegionProblemFromQp problem(
895 &qp, &primal_solution, &dual_solution, &primal_part.gradient,
896 &dual_part.gradient, primal_weight);
899 problem, joint_sharder, radius,
900 diagonal_qp_trust_region_solver_tolerance)
903 JointTrustRegionProblem joint_problem(&qp, &primal_solution, &dual_solution,
904 &primal_part.gradient,
905 &dual_part.gradient, primal_weight);
907 TrustRegionResultStepSize trust_region_result =
908 SolveTrustRegionStepSize(joint_problem, radius, joint_sharder);
910 trust_region_solution = ComputeSolution(
911 joint_problem, trust_region_result.solution_step_size, joint_sharder);
914 auto primal_trust_region_solution =
915 trust_region_solution.segment(0, sharded_qp.PrimalSize());
916 auto dual_trust_region_solution = trust_region_solution.segment(
917 sharded_qp.PrimalSize(), sharded_qp.DualSize());
920 double primal_objective_delta =
921 sharded_qp.PrimalSharder().ParallelSumOverShards(
922 [&](
const Sharder::Shard& shard) {
923 return shard(primal_part.gradient)
924 .dot(shard(primal_trust_region_solution) -
925 shard(primal_solution));
930 if (use_diagonal_qp_trust_region_solver &&
931 sharded_qp.Qp().objective_matrix.has_value()) {
932 primal_objective_delta += sharded_qp.PrimalSharder().ParallelSumOverShards(
933 [&](
const Sharder::Shard& shard) {
934 const int shard_start =
935 sharded_qp.PrimalSharder().ShardStart(shard.Index());
936 const int shard_size =
937 sharded_qp.PrimalSharder().ShardSize(shard.Index());
939 for (
int i = shard_start; i < shard_start + shard_size; ++i) {
940 sum += 0.5 * sharded_qp.Qp().objective_matrix->diagonal()[i] *
949 const double dual_objective_delta =
950 sharded_qp.DualSharder().ParallelSumOverShards(
951 [&](
const Sharder::Shard& shard) {
952 return shard(dual_part.gradient)
953 .dot(shard(dual_trust_region_solution) - shard(dual_solution));
956 return LocalizedLagrangianBounds{
957 .lagrangian_value = lagrangian_value,
958 .lower_bound = lagrangian_value + primal_objective_delta,
959 .upper_bound = lagrangian_value + dual_objective_delta,
967 const VectorXd& dual_solution,
const PrimalDualNorm primal_dual_norm,
968 const double primal_weight,
const double radius,
969 const VectorXd* primal_product,
const VectorXd* dual_product,
970 const bool use_diagonal_qp_trust_region_solver,
971 const double diagonal_qp_trust_region_solver_tolerance) {
973 VectorXd primal_product_storage;
974 VectorXd dual_product_storage;
976 if (primal_product ==
nullptr) {
980 primal_product = &primal_product_storage;
982 if (dual_product ==
nullptr) {
983 dual_product_storage =
986 dual_product = &dual_product_storage;
989 switch (primal_dual_norm) {
990 case PrimalDualNorm::kMaxNorm:
991 return ComputeMaxNormLocalizedLagrangianBounds(
992 sharded_qp, primal_solution, dual_solution, primal_weight, radius,
993 *primal_product, *dual_product);
994 case PrimalDualNorm::kEuclideanNorm:
995 return ComputeEuclideanNormLocalizedLagrangianBounds(
996 sharded_qp, primal_solution, dual_solution, primal_weight, radius,
997 *primal_product, *dual_product, use_diagonal_qp_trust_region_solver,
998 diagonal_qp_trust_region_solver_tolerance);
1000 LOG(FATAL) <<
"Unrecognized primal dual norm";
static T Square(const T x)
double Objective(int64_t index) const
double UpperBound(int64_t index) const
double ObjectiveMatrixDiagonalAt(int64_t index) const
double LowerBound(int64_t index) const
DiagonalTrustRegionProblemFromQp(const QuadraticProgram *qp, const VectorXd *primal_solution, const VectorXd *dual_solution, const VectorXd *primal_gradient, const VectorXd *dual_gradient, const double primal_weight)
double CenterPoint(int64_t index) const
double NormWeight(int64_t index) const
double Objective(int64_t index) const
double UpperBound(int64_t index) const
double ObjectiveMatrixDiagonalAt(int64_t index) const
double LowerBound(int64_t index) const
DiagonalTrustRegionProblem(const VectorXd *objective_vector, const VectorXd *objective_matrix_diagonal, const VectorXd *lower_bounds, const VectorXd *upper_bounds, const VectorXd *center_point, const VectorXd *norm_weights)
double CenterPoint(int64_t index) const
double NormWeight(int64_t index) const
const Eigen::SparseMatrix< double, Eigen::ColMajor, int64_t > & TransposedConstraintMatrix() const
const Sharder & ConstraintMatrixSharder() const
const Sharder & PrimalSharder() const
int64_t PrimalSize() const
const Sharder & TransposedConstraintMatrixSharder() const
const QuadraticProgram & Qp() const
double ParallelSumOverShards(const std::function< double(const Shard &)> &func) const
bool ParallelTrueForAllShards(const std::function< bool(const Shard &)> &func) const
int64_t ShardSize(int shard) const
int64_t ShardStart(int shard) const
Fractional Square(Fractional f)
double ComputeInitialUndecidedComponents(const TrustRegionProblem &problem, int64_t start_index, int64_t end_index, std::vector< int64_t > &undecided_components)
double ProjectedValue(const TrustRegionProblem &problem, const int64_t index, const double step_size)
double RemoveCriticalStepsAboveThreshold(const TrustRegionProblem &problem, const double step_size_threshold, std::vector< int64_t > &undecided_components)
double RemoveCriticalStepsBelowThreshold(const TrustRegionProblem &problem, const double step_size_threshold, std::vector< int64_t > &undecided_components)
double EasyMedian(ArrayType array, ValueFunction value_function)
double RadiusSquaredOfUndecidedComponents(const TrustRegionProblem &problem, const double step_size, const std::vector< int64_t > &undecided_components)
LagrangianPart ComputeDualGradient(const ShardedQuadraticProgram &sharded_qp, const VectorXd &dual_solution, const VectorXd &primal_product)
LagrangianPart ComputePrimalGradient(const ShardedQuadraticProgram &sharded_qp, const VectorXd &primal_solution, const VectorXd &dual_product)
TrustRegionResult SolveDiagonalTrustRegionProblem(const DiagonalTrustRegionProblem &problem, const Sharder &sharder, const double target_radius, const double solve_tol)
double NormOfDeltaProjection(const DiagonalTrustRegionProblem &problem, const Sharder &sharder, const double scaling_factor)
VectorXd TransposedMatrixVectorProduct(const Eigen::SparseMatrix< double, Eigen::ColMajor, int64_t > &matrix, const VectorXd &vector, const Sharder &sharder)
TrustRegionResult SolveDiagonalTrustRegion(const VectorXd &objective_vector, const VectorXd &objective_matrix_diagonal, const VectorXd &variable_lower_bounds, const VectorXd &variable_upper_bounds, const VectorXd ¢er_point, const VectorXd &norm_weights, const double target_radius, const Sharder &sharder, const double solve_tolerance)
TrustRegionResult SolveDiagonalQpTrustRegion(const ShardedQuadraticProgram &sharded_qp, const VectorXd &primal_solution, const VectorXd &dual_solution, const VectorXd &primal_gradient, const VectorXd &dual_gradient, const double primal_weight, double target_radius, const double solve_tolerance)
double FindScalingFactor(const DiagonalTrustRegionProblem &problem, const Sharder &sharder, const double target_radius, const double solve_tol)
TrustRegionResult SolveTrustRegion(const VectorXd &objective_vector, const VectorXd &variable_lower_bounds, const VectorXd &variable_upper_bounds, const VectorXd ¢er_point, const VectorXd &norm_weights, const double target_radius, const Sharder &sharder)
double ProjectedValueOfScaledDifference(const DiagonalTrustRegionProblem &problem, const int64_t index, const double scaling_factor)
LocalizedLagrangianBounds ComputeLocalizedLagrangianBounds(const ShardedQuadraticProgram &sharded_qp, const VectorXd &primal_solution, const VectorXd &dual_solution, const PrimalDualNorm primal_dual_norm, const double primal_weight, const double radius, const VectorXd *primal_product, const VectorXd *dual_product, const bool use_diagonal_qp_trust_region_solver, const double diagonal_qp_trust_region_solver_tolerance)
std::function< int64_t(const Model &)> UpperBound(IntegerVariable v)
Coefficient ComputeObjectiveValue(const LinearBooleanProblem &problem, const std::vector< bool > &assignment)
std::function< int64_t(const Model &)> LowerBound(IntegerVariable v)
std::vector< double > lower_bounds
std::vector< double > upper_bounds
Eigen::SparseMatrix< double, Eigen::ColMajor, int64_t > constraint_matrix
double solution_step_size
double trust_region_objective_delta
double part_of_lagrangian_value
std::vector< std::vector< int64_t > > undecided_components_by_shard
double solution_step_size
double radius_coefficient_of_decided_components
VectorXd variable_lower_bounds
VectorXd variable_upper_bounds
VectorXd objective_vector
VectorXd objective_matrix_diagonal
#define VLOG(verboselevel)