don't use local-file-change context for mapreduce
[hiphop-php.git] / hphp / util / pidcontroller.h
blobb3a05a4b40c225e88025069546a12de4af055346
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_PIDCONTOLLER_H_
18 #define incl_HPHP_PIDCONTOLLER_H_
20 #include <cmath>
21 #include <limits>
23 namespace HPHP {
24 /**
25 * Like anything useful, we benefit from using a pid controller in certain
26 * applications. This is the 10 millionth implementation of a naive one.
29 struct PIDController {
30 PIDController() = default;
31 PIDController(double dt, double max, double min,
32 double kP, double kI, double kD)
33 : dt(dt)
34 , max(max)
35 , min(min)
36 , kP(kP)
37 , kI(kI)
38 , kD(kD) {}
40 // This returns the new value for the controlled variable, and takes
41 // `curValue`, the process variable, and the `setpoint`.
42 double determineOutput(double setpoint, double curValue) {
43 double error = setpoint - curValue;
45 double proportionalTerm = kP * error;
47 double integralDelta = error * dt;
48 m_integral += integralDelta;
50 double integralTerm = kI * m_integral;
51 // This stops integral windup issues in cases the controlled variable is
52 // temporarily not influenced by the contoller output.
54 // You may need to widen the max an min values slightly to have proper pid
55 // behavior near those areas.
56 if (integralTerm > max) {
57 m_integral = max / kI;
58 integralTerm = max;
60 if (integralTerm < min) {
61 m_integral = min / kI;
62 integralTerm = min;
65 // The derivative is based on values rather than error to not overrespond
66 // during setpoint changes.
67 double derivativeTerm = 0;
68 if (m_initialized) {
69 derivativeTerm = (m_lastValue - curValue) / dt * kD;
70 } else {
71 m_initialized = true;
74 m_lastValue = curValue;
76 auto const output = proportionalTerm + integralTerm + derivativeTerm;
77 if (output > max) return max;
78 if (output < min) return min;
79 return output;
82 double dt;
83 double max;
84 double min;
85 double kP;
86 double kI;
87 double kD;
89 private:
90 double m_integral{0};
91 double m_lastValue{std::numeric_limits<double>::max()};
92 bool m_initialized{false};
98 #endif // incl_HPHP_PIDCONTOLLER_H_