View Javadoc
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  
19  import org.hipparchus.linear.RealMatrix;
20  import org.hipparchus.linear.RealVector;
21  import org.hipparchus.optim.ConvergenceChecker;
22  import org.hipparchus.optim.OptimizationData;
23  import org.hipparchus.util.FastMath;
24  
25  /** Convergence Checker for ADMM QP Optimizer.
26   * @since 3.1
27   */
28  public class ADMMQPConvergenceChecker implements ConvergenceChecker<LagrangeSolution>, OptimizationData  {
29  
30      /** Quadratic term matrix. */
31      private  final RealMatrix h;
32  
33      /** Constraint coefficients matrix. */
34      private  final RealMatrix a;
35  
36      /** Linear term matrix. */
37      private  final RealVector q;
38  
39      /** Absolute tolerance for convergence. */
40      private  final double epsAbs;
41  
42      /** Relative tolerance for convergence. */
43      private  final double epsRel;
44  
45      /** Convergence indicator. */
46      private  boolean converged;
47  
48      /** Simple constructor.
49       * @param h quadratic term matrix
50       * @param a constraint coefficients matrix
51       * @param q linear term matrix
52       * @param epsAbs
53       * @param epsRel
54       */
55      ADMMQPConvergenceChecker(final RealMatrix h, final RealMatrix a, final RealVector q,
56                               final double epsAbs, final double epsRel) {
57          this.h         = h;
58          this.a         = a;
59          this.q         = q;
60          this.epsAbs    = epsAbs;
61          this.epsRel    = epsRel;
62          this.converged = false;
63      }
64  
65      /** {@inheritDoc} */
66      @Override
67      public boolean converged(final int i, final LagrangeSolution previous, final LagrangeSolution current) {
68          return converged;
69      }
70  
71      /** Evaluate convergence.
72       * @param rp primal residual
73       * @param rd dual residual
74       * @param maxPrimal primal vectors max
75       * @param maxDual dual vectors max
76       * @return true of convergence has been reached
77       */
78      public boolean converged(final double rp, final double rd, final double maxPrimal, final double maxDual) {
79          boolean result = false;
80  
81          if (rp <= epsPrimalDual(maxPrimal) && rd <= epsPrimalDual(maxDual)) {
82              result = true;
83              converged = true;
84          }
85          return result;
86      }
87  
88      /** Compute primal residual.
89       * @param x primal problem solution
90       * @param z auxiliary variable
91       * @return primal residual
92       */
93      public double residualPrime(final RealVector x, final RealVector z) {
94          return a.operate(x).subtract(z).getLInfNorm();
95      }
96  
97      /** Compute dual residual.
98       * @param x primal problem solution
99       * @param y dual problem solution
100      * @return dual residual
101      */
102     public double residualDual(final RealVector x, final RealVector y) {
103         return q.add(a.transpose().operate(y)).add(h.operate(x)).getLInfNorm();
104     }
105 
106     /** Compute primal vectors max.
107      * @param x primal problem solution
108      * @param z auxiliary variable
109      * @return primal vectors max
110      */
111     public double maxPrimal(final RealVector x, final RealVector z) {
112         return FastMath.max(a.operate(x).getLInfNorm(), z.getLInfNorm());
113     }
114 
115     /** Compute dual vectors max.
116      * @param x primal problem solution
117      * @param y dual problem solution
118      * @return dual vectors max
119      */
120     public double maxDual(final RealVector x, final RealVector y) {
121         return FastMath.max(FastMath.max(h.operate(x).getLInfNorm(),
122                                          a.transpose().operate(y).getLInfNorm()),
123                             q.getLInfNorm());
124     }
125 
126     /** Combine absolute and relative tolerances.
127      * @param maxPrimalDual either {@link #maxPrimal(RealVector, RealVector)}
128      * or {@link #maxDual(RealVector, RealVector)}
129      * @return global tolerance
130      */
131     private double epsPrimalDual(final double maxPrimalDual) {
132         return epsAbs + epsRel * maxPrimalDual;
133     }
134 
135 }