1 // ******************************************************************************
2 //
3 // Title: Force Field X.
4 // Description: Force Field X - Software for Molecular Biophysics.
5 // Copyright: Copyright (c) Michael J. Schnieders 2001-2025.
6 //
7 // This file is part of Force Field X.
8 //
9 // Force Field X is free software; you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License version 3 as published by
11 // the Free Software Foundation.
12 //
13 // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 // details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20 // Place, Suite 330, Boston, MA 02111-1307 USA
21 //
22 // Linking this library statically or dynamically with other modules is making a
23 // combined work based on this library. Thus, the terms and conditions of the
24 // GNU General Public License cover the whole combination.
25 //
26 // As a special exception, the copyright holders of this library give you
27 // permission to link this library with independent modules to produce an
28 // executable, regardless of the license terms of these independent modules, and
29 // to copy and distribute the resulting executable under terms of your choice,
30 // provided that you also meet, for each linked independent module, the terms
31 // and conditions of the license of that module. An independent module is a
32 // module which is not derived from or based on this library. If you modify this
33 // library, you may extend this exception to your version of the library, but
34 // you are not obligated to do so. If you do not wish to do so, delete this
35 // exception statement from your version.
36 //
37 // ******************************************************************************
38 package ffx.numerics.switching;
39
40 import ffx.numerics.func1d.UnivariateDiffFunction;
41
42 /**
43 * A UnivariateSwitchingFunction describes a function of a single value (often lambda), where f(lb) =
44 * 0, f(ub) = 1, and df(x)/dx >= 0 for all x lb-ub.
45 *
46 * <p>Additionally, it's often useful for switching functions to have zero first and second
47 * derivatives at the lower and upper bound.
48 *
49 * <p>A number of methods exist to check for various properties of a switching function; these will
50 * often be implemented as simple return-boolean methods.
51 *
52 * @author Jacob M. Litman
53 * @author Michael J. Schnieders
54 */
55 public interface UnivariateSwitchingFunction extends UnivariateDiffFunction {
56
57 /**
58 * Remains 0 below the lower bound, and 1 above the upper bound (i.e. a multiplicative switch).
59 *
60 * @return df(x)/dx is zero outside range lb-ub.
61 */
62 boolean constantOutsideBounds();
63
64 /**
65 * The highest-order derivative that is zero at the bounds.
66 *
67 * @return Maximum order zero derivative at bounds.
68 */
69 int getHighestOrderZeroDerivative();
70
71 /**
72 * Gets the one bound, where f(x) becomes one.
73 *
74 * @return One bound
75 */
76 double getOneBound();
77
78 /**
79 * Gets the zero bound, where f(x) becomes zero.
80 *
81 * @return Zero bound
82 */
83 double getZeroBound();
84
85 /**
86 * Returns the highest-order, guaranteed-zero derivative at the zero bound.
87 *
88 * @return Highest-order zero derivative at zero bound.
89 */
90 default int highestOrderZeroDerivativeAtZeroBound() {
91 return getHighestOrderZeroDerivative();
92 }
93
94 /**
95 * True if f(lb + delta) + f(ub - delta) = 1 for all delta between 0 and (ub - lb). For example, a
96 * power switch with beta 1 is symmetric to unity, as f(l) + f(1-l) = 1, but beta 2 produces a
97 * non-unity result, where f(0.5) + f(0.5) = 0.5.
98 *
99 * @return If symmetry produces unity result.
100 */
101 boolean symmetricToUnity();
102
103 /**
104 * Remains in the range 0-1 outside the bounds. Implied to be true if constantOutsideBounds is
105 * true.
106 *
107 * @return min(f ( x)) = 0 and max(f(x)) = 1.
108 */
109 boolean validOutsideBounds();
110 }