source: src/main/java/agents/anac/y2019/harddealer/math3/analysis/function/Logistic.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

  • Property svn:executable set to *
File size: 9.0 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) 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 ASF 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 * http://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
18package agents.anac.y2019.harddealer.math3.analysis.function;
19
20import agents.anac.y2019.harddealer.math3.analysis.FunctionUtils;
21import agents.anac.y2019.harddealer.math3.analysis.UnivariateFunction;
22import agents.anac.y2019.harddealer.math3.analysis.DifferentiableUnivariateFunction;
23import agents.anac.y2019.harddealer.math3.analysis.ParametricUnivariateFunction;
24import agents.anac.y2019.harddealer.math3.analysis.differentiation.DerivativeStructure;
25import agents.anac.y2019.harddealer.math3.analysis.differentiation.UnivariateDifferentiableFunction;
26import agents.anac.y2019.harddealer.math3.exception.NotStrictlyPositiveException;
27import agents.anac.y2019.harddealer.math3.exception.NullArgumentException;
28import agents.anac.y2019.harddealer.math3.exception.DimensionMismatchException;
29import agents.anac.y2019.harddealer.math3.util.FastMath;
30
31/**
32 * <a href="http://en.wikipedia.org/wiki/Generalised_logistic_function">
33 * Generalised logistic</a> function.
34 *
35 * @since 3.0
36 */
37public class Logistic implements UnivariateDifferentiableFunction, DifferentiableUnivariateFunction {
38 /** Lower asymptote. */
39 private final double a;
40 /** Upper asymptote. */
41 private final double k;
42 /** Growth rate. */
43 private final double b;
44 /** Parameter that affects near which asymptote maximum growth occurs. */
45 private final double oneOverN;
46 /** Parameter that affects the position of the curve along the ordinate axis. */
47 private final double q;
48 /** Abscissa of maximum growth. */
49 private final double m;
50
51 /**
52 * @param k If {@code b > 0}, value of the function for x going towards +&infin;.
53 * If {@code b < 0}, value of the function for x going towards -&infin;.
54 * @param m Abscissa of maximum growth.
55 * @param b Growth rate.
56 * @param q Parameter that affects the position of the curve along the
57 * ordinate axis.
58 * @param a If {@code b > 0}, value of the function for x going towards -&infin;.
59 * If {@code b < 0}, value of the function for x going towards +&infin;.
60 * @param n Parameter that affects near which asymptote the maximum
61 * growth occurs.
62 * @throws NotStrictlyPositiveException if {@code n <= 0}.
63 */
64 public Logistic(double k,
65 double m,
66 double b,
67 double q,
68 double a,
69 double n)
70 throws NotStrictlyPositiveException {
71 if (n <= 0) {
72 throw new NotStrictlyPositiveException(n);
73 }
74
75 this.k = k;
76 this.m = m;
77 this.b = b;
78 this.q = q;
79 this.a = a;
80 oneOverN = 1 / n;
81 }
82
83 /** {@inheritDoc} */
84 public double value(double x) {
85 return value(m - x, k, b, q, a, oneOverN);
86 }
87
88 /** {@inheritDoc}
89 * @deprecated as of 3.1, replaced by {@link #value(DerivativeStructure)}
90 */
91 @Deprecated
92 public UnivariateFunction derivative() {
93 return FunctionUtils.toDifferentiableUnivariateFunction(this).derivative();
94 }
95
96 /**
97 * Parametric function where the input array contains the parameters of
98 * the {@link Logistic#Logistic(double,double,double,double,double,double)
99 * logistic function}, ordered as follows:
100 * <ul>
101 * <li>k</li>
102 * <li>m</li>
103 * <li>b</li>
104 * <li>q</li>
105 * <li>a</li>
106 * <li>n</li>
107 * </ul>
108 */
109 public static class Parametric implements ParametricUnivariateFunction {
110 /**
111 * Computes the value of the sigmoid at {@code x}.
112 *
113 * @param x Value for which the function must be computed.
114 * @param param Values for {@code k}, {@code m}, {@code b}, {@code q},
115 * {@code a} and {@code n}.
116 * @return the value of the function.
117 * @throws NullArgumentException if {@code param} is {@code null}.
118 * @throws DimensionMismatchException if the size of {@code param} is
119 * not 6.
120 * @throws NotStrictlyPositiveException if {@code param[5] <= 0}.
121 */
122 public double value(double x, double ... param)
123 throws NullArgumentException,
124 DimensionMismatchException,
125 NotStrictlyPositiveException {
126 validateParameters(param);
127 return Logistic.value(param[1] - x, param[0],
128 param[2], param[3],
129 param[4], 1 / param[5]);
130 }
131
132 /**
133 * Computes the value of the gradient at {@code x}.
134 * The components of the gradient vector are the partial
135 * derivatives of the function with respect to each of the
136 * <em>parameters</em>.
137 *
138 * @param x Value at which the gradient must be computed.
139 * @param param Values for {@code k}, {@code m}, {@code b}, {@code q},
140 * {@code a} and {@code n}.
141 * @return the gradient vector at {@code x}.
142 * @throws NullArgumentException if {@code param} is {@code null}.
143 * @throws DimensionMismatchException if the size of {@code param} is
144 * not 6.
145 * @throws NotStrictlyPositiveException if {@code param[5] <= 0}.
146 */
147 public double[] gradient(double x, double ... param)
148 throws NullArgumentException,
149 DimensionMismatchException,
150 NotStrictlyPositiveException {
151 validateParameters(param);
152
153 final double b = param[2];
154 final double q = param[3];
155
156 final double mMinusX = param[1] - x;
157 final double oneOverN = 1 / param[5];
158 final double exp = FastMath.exp(b * mMinusX);
159 final double qExp = q * exp;
160 final double qExp1 = qExp + 1;
161 final double factor1 = (param[0] - param[4]) * oneOverN / FastMath.pow(qExp1, oneOverN);
162 final double factor2 = -factor1 / qExp1;
163
164 // Components of the gradient.
165 final double gk = Logistic.value(mMinusX, 1, b, q, 0, oneOverN);
166 final double gm = factor2 * b * qExp;
167 final double gb = factor2 * mMinusX * qExp;
168 final double gq = factor2 * exp;
169 final double ga = Logistic.value(mMinusX, 0, b, q, 1, oneOverN);
170 final double gn = factor1 * FastMath.log(qExp1) * oneOverN;
171
172 return new double[] { gk, gm, gb, gq, ga, gn };
173 }
174
175 /**
176 * Validates parameters to ensure they are appropriate for the evaluation of
177 * the {@link #value(double,double[])} and {@link #gradient(double,double[])}
178 * methods.
179 *
180 * @param param Values for {@code k}, {@code m}, {@code b}, {@code q},
181 * {@code a} and {@code n}.
182 * @throws NullArgumentException if {@code param} is {@code null}.
183 * @throws DimensionMismatchException if the size of {@code param} is
184 * not 6.
185 * @throws NotStrictlyPositiveException if {@code param[5] <= 0}.
186 */
187 private void validateParameters(double[] param)
188 throws NullArgumentException,
189 DimensionMismatchException,
190 NotStrictlyPositiveException {
191 if (param == null) {
192 throw new NullArgumentException();
193 }
194 if (param.length != 6) {
195 throw new DimensionMismatchException(param.length, 6);
196 }
197 if (param[5] <= 0) {
198 throw new NotStrictlyPositiveException(param[5]);
199 }
200 }
201 }
202
203 /**
204 * @param mMinusX {@code m - x}.
205 * @param k {@code k}.
206 * @param b {@code b}.
207 * @param q {@code q}.
208 * @param a {@code a}.
209 * @param oneOverN {@code 1 / n}.
210 * @return the value of the function.
211 */
212 private static double value(double mMinusX,
213 double k,
214 double b,
215 double q,
216 double a,
217 double oneOverN) {
218 return a + (k - a) / FastMath.pow(1 + q * FastMath.exp(b * mMinusX), oneOverN);
219 }
220
221 /** {@inheritDoc}
222 * @since 3.1
223 */
224 public DerivativeStructure value(final DerivativeStructure t) {
225 return t.negate().add(m).multiply(b).exp().multiply(q).add(1).pow(oneOverN).reciprocal().multiply(k - a).add(a);
226 }
227
228}
Note: See TracBrowser for help on using the repository browser.