ADMMQPConvergenceChecker.java

  1. /*
  2.  * Licensed to the Hipparchus project under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.hipparchus.optim.nonlinear.vector.constrained;

  18. import org.hipparchus.linear.RealMatrix;
  19. import org.hipparchus.linear.RealVector;
  20. import org.hipparchus.optim.ConvergenceChecker;
  21. import org.hipparchus.optim.OptimizationData;
  22. import org.hipparchus.util.FastMath;

  23. /** Convergence Checker for ADMM QP Optimizer.
  24.  * @since 3.1
  25.  */
  26. public class ADMMQPConvergenceChecker implements ConvergenceChecker<LagrangeSolution>, OptimizationData  {

  27.     /** Quadratic term matrix. */
  28.     private  final RealMatrix h;

  29.     /** Constraint coefficients matrix. */
  30.     private  final RealMatrix a;

  31.     /** Linear term matrix. */
  32.     private  final RealVector q;

  33.     /** Absolute tolerance for convergence. */
  34.     private  final double epsAbs;

  35.     /** Relative tolerance for convergence. */
  36.     private  final double epsRel;

  37.     /** Convergence indicator. */
  38.     private  boolean converged;

  39.     /** Simple constructor.
  40.      * @param h quadratic term matrix
  41.      * @param a constraint coefficients matrix
  42.      * @param q linear term matrix
  43.      * @param epsAbs
  44.      * @param epsRel
  45.      */
  46.     ADMMQPConvergenceChecker(final RealMatrix h, final RealMatrix a, final RealVector q,
  47.                              final double epsAbs, final double epsRel) {
  48.         this.h         = h;
  49.         this.a         = a;
  50.         this.q         = q;
  51.         this.epsAbs    = epsAbs;
  52.         this.epsRel    = epsRel;
  53.         this.converged = false;
  54.     }

  55.     /** {@inheritDoc} */
  56.     @Override
  57.     public boolean converged(final int i, final LagrangeSolution previous, final LagrangeSolution current) {
  58.         return converged;
  59.     }

  60.     /** Evaluate convergence.
  61.      * @param rp primal residual
  62.      * @param rd dual residual
  63.      * @param maxPrimal primal vectors max
  64.      * @param maxDual dual vectors max
  65.      * @return true of convergence has been reached
  66.      */
  67.     public boolean converged(final double rp, final double rd, final double maxPrimal, final double maxDual) {
  68.         boolean result = false;

  69.         if (rp <= epsPrimalDual(maxPrimal) && rd <= epsPrimalDual(maxDual)) {
  70.             result = true;
  71.             converged = true;
  72.         }
  73.         return result;
  74.     }

  75.     /** Compute primal residual.
  76.      * @param x primal problem solution
  77.      * @param z auxiliary variable
  78.      * @return primal residual
  79.      */
  80.     public double residualPrime(final RealVector x, final RealVector z) {
  81.         return a.operate(x).subtract(z).getLInfNorm();
  82.     }

  83.     /** Compute dual residual.
  84.      * @param x primal problem solution
  85.      * @param y dual problem solution
  86.      * @return dual residual
  87.      */
  88.     public double residualDual(final RealVector x, final RealVector y) {
  89.         return q.add(a.transpose().operate(y)).add(h.operate(x)).getLInfNorm();
  90.     }

  91.     /** Compute primal vectors max.
  92.      * @param x primal problem solution
  93.      * @param z auxiliary variable
  94.      * @return primal vectors max
  95.      */
  96.     public double maxPrimal(final RealVector x, final RealVector z) {
  97.         return FastMath.max(a.operate(x).getLInfNorm(), z.getLInfNorm());
  98.     }

  99.     /** Compute dual vectors max.
  100.      * @param x primal problem solution
  101.      * @param y dual problem solution
  102.      * @return dual vectors max
  103.      */
  104.     public double maxDual(final RealVector x, final RealVector y) {
  105.         return FastMath.max(FastMath.max(h.operate(x).getLInfNorm(),
  106.                                          a.transpose().operate(y).getLInfNorm()),
  107.                             q.getLInfNorm());
  108.     }

  109.     /** Combine absolute and relative tolerances.
  110.      * @param maxPrimalDual either {@link #maxPrimal(RealVector, RealVector)}
  111.      * or {@link #maxDual(RealVector, RealVector)}
  112.      * @return global tolerance
  113.      */
  114.     private double epsPrimalDual(final double maxPrimalDual) {
  115.         return epsAbs + epsRel * maxPrimalDual;
  116.     }

  117. }