@@ -185,12 +185,16 @@ void PDLPSolver::preprocessLp() {
185185 scaling_.passLp (&processed_lp);
186186 unscaled_processed_lp_ = processed_lp; // store for postsolve
187187
188- // 7. Convert COO matrix to CSC for the processed_lp
189- //
188+ // 7. Compute and store norms of unscaled cost and rhs
189+ unscaled_c_norm_ = linalg::vector_norm (processed_lp.col_cost_ );
190+ unscaled_rhs_norm_ = linalg::vector_norm (processed_lp.row_lower_ );
191+
190192 // Already achieved by construction
191193 logger_.info (" Preprocessing complete. New dimensions: " +
192194 std::to_string (processed_lp.num_row_ ) + " rows, " +
193195 std::to_string (processed_lp.num_col_ ) + " cols." );
196+ logger_.info (" Unscaled norms: ||c|| = " + std::to_string (unscaled_c_norm_) +
197+ " , ||b|| = " + std::to_string (unscaled_rhs_norm_));
194198}
195199
196200PostSolveRetcode PDLPSolver::postprocess (HighsSolution& solution) {
@@ -684,9 +688,8 @@ std::pair<double, double> PDLPSolver::ComputePrimalFeasibility(
684688 }
685689
686690 double primal_feasibility = linalg::vector_norm (primal_residual);
687- double rhs_norm = linalg::vector_norm (lp_.row_lower_ ); // why don't need to rescale?
688-
689- return std::make_pair (primal_feasibility, rhs_norm);
691+
692+ return std::make_pair (primal_feasibility, unscaled_rhs_norm_);
690693}
691694
692695void PDLPSolver::ComputeDualSlacks (const std::vector<double >& ATy_vector) {
@@ -712,18 +715,12 @@ std::pair<double, double> PDLPSolver::ComputeDualFeasibility(
712715 const std::vector<double >& ATy_vector) {
713716 ComputeDualSlacks (ATy_vector); // This updates dSlackPos_ and dSlackNeg_
714717
715- double dual_feasibility_squared = 0.0 ;
716718 std::vector<double > dual_residual (lp_.num_col_ );
717719
718720 for (HighsInt i = 0 ; i < lp_.num_col_ ; ++i) {
719- // Compute c - A'y - (slackPos - slackNeg)
720- double residual = lp_.col_cost_ [i] - ATy_vector[i];
721-
722- // Subtract the projection onto the bound constraints
723- residual = residual - dSlackPos_[i] + dSlackNeg_[i];
724-
725- dual_residual[i] = residual;
726- dual_feasibility_squared += residual * residual;
721+ // Matching CUPDLP: c - A'y - dSlackPos + dSlackNeg
722+ dual_residual[i] = lp_.col_cost_ [i] - ATy_vector[i]
723+ - dSlackPos_[i] + dSlackNeg_[i];
727724 }
728725
729726 // Apply scaling if needed
@@ -734,10 +731,9 @@ std::pair<double, double> PDLPSolver::ComputeDualFeasibility(
734731 }
735732 }
736733
737- double dual_feasibility = sqrt (dual_feasibility_squared);
738- double c_norm = linalg::vector_norm (lp_.col_cost_ );
734+ double dual_feasibility = linalg::vector_norm (dual_residual);
739735
740- return std::make_pair (dual_feasibility, c_norm );
736+ return std::make_pair (dual_feasibility, unscaled_c_norm_ );
741737}
742738
743739std::tuple<double , double , double , double , double >
0 commit comments