001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.nabla.core;
018
019 import java.io.Serializable;
020
021 /** Class representing both a value and a differential.
022 * <p>This class is the workhorse of the Nabla library. It can be
023 * seen as an extension of the primitive double type used throughout
024 * mathematical expressions. In addition to holding parameter,
025 * intermediate computations and result values as double do, instances
026 * of this class also holds the first differential associated with this
027 * parameter, intermediate computations and results.</p>
028 * <p>{@link DifferentialPair} instances can be used directly thanks to
029 * the arithmetic operators provided as static methods by this class
030 * (+, -, *, /, %) and to the mathematical functions provided by the
031 * {@link org.apache.commons.nabla.NablaMath} and the {@link
032 * org.apache.commons.nabla.NablaStrictMath} utility classes.</p>
033 * <p>Implementing complex expressions by hand using these classes is
034 * however a complex and error-prone task, so the classical use is
035 * simply to develop computation code using standard primitive double
036 * values and to use {@link UnivariateDifferentiator differentiators} to create
037 * the {@link DifferentialPair}-based instances.</p>
038 * <p>Instances of this class are guaranteed to be immutable.</p>
039 */
040 public class DifferentialPair implements Serializable {
041
042 /** -1 constant. */
043 public static final DifferentialPair MINUS_ONE = newConstant(-1);
044
045 /** 0 constant. */
046 public static final DifferentialPair ZERO = newConstant( 0);
047
048 /** +1 constant. */
049 public static final DifferentialPair ONE = newConstant( 1);
050
051 /** +2 constant. */
052 public static final DifferentialPair TWO = newConstant( 2);
053
054 /** +3 constant. */
055 public static final DifferentialPair THREE = newConstant( 3);
056
057
058 /** π (Archimede) constant. */
059 public static final DifferentialPair PI = newConstant(Math.PI);
060
061 /** e (Euler) constant, base of the natural logarithms. */
062 public static final DifferentialPair E = newConstant(Math.E);
063
064 /** Serializable UID. */
065 private static final long serialVersionUID = 9015695991152713660L;
066
067
068 /** Value part of the differential pair. */
069 private final double value;
070
071 /** First derivative part of the differential pair. */
072 private final double firstDerivative;
073
074 /** Build a new instance from its components.
075 * @param u0 value part of the differential pair
076 * @param u1 first derivative part of the differential pair
077 */
078 public DifferentialPair(final double u0, final double u1) {
079 this.value = u0;
080 this.firstDerivative = u1;
081 }
082
083 /** Build an instance representing a univariate variable.
084 * <p>Instances built using this constructor are considered
085 * to be the free variables with respect to which differentials
086 * are computed. As such, their differential with respect to
087 * themselves is +1. Calling this constructor has the same
088 * effect as calling <code>DifferentialPair(a, 1.0)</code>.</p>
089 * @param a value of the variable
090 * @return the built variable
091 */
092 public static DifferentialPair newVariable(final double a) {
093 return new DifferentialPair(a, 1.0);
094 }
095
096 /** Build an instance representing a constant.
097 * <p>Constant do not vary ... Hence their differential
098 * is 0. Calling this constructor has the same
099 * effect as calling <code>DifferentialPair(a, 0.0)</code>.</p>
100 * @param a value of the constant
101 * @return the built constant
102 */
103 public static DifferentialPair newConstant(final double a) {
104 return new DifferentialPair(a, 0.0);
105 }
106
107 /** Get the value part of the differential pair.
108 * @return value part of the differential pair
109 * @see #getFirstDerivative()
110 */
111 public double getValue() {
112 return value;
113 }
114
115 /** Get the first derivative part of the differential pair.
116 * @return first derivative part of the differential pair
117 * @see #getValue()
118 */
119 public double getFirstDerivative() {
120 return firstDerivative;
121 }
122
123 /** '+' operator, for differential pairs.
124 * @param a left hand side parameter of the operator
125 * @param b right hand side parameter of the operator
126 * @return a+b
127 */
128 public static DifferentialPair add(final DifferentialPair a,
129 final int b) {
130 return new DifferentialPair(a.value + b, a.firstDerivative);
131 }
132
133 /** '+' operator, for differential pairs.
134 * @param a left hand side parameter of the operator
135 * @param b right hand side parameter of the operator
136 * @return a+b
137 */
138 public static DifferentialPair add(final int a,
139 final DifferentialPair b) {
140 return new DifferentialPair(a + b.value, b.firstDerivative);
141 }
142
143 /** '+' operator, for differential pairs.
144 * @param a left hand side parameter of the operator
145 * @param b right hand side parameter of the operator
146 * @return a+b
147 */
148 public static DifferentialPair add(final DifferentialPair a,
149 final long b) {
150 return new DifferentialPair(a.value + b, a.firstDerivative);
151 }
152
153 /** '+' operator, for differential pairs.
154 * @param a left hand side parameter of the operator
155 * @param b right hand side parameter of the operator
156 * @return a+b
157 */
158 public static DifferentialPair add(final long a,
159 final DifferentialPair b) {
160 return new DifferentialPair(a + b.value, b.firstDerivative);
161 }
162
163 /** '+' operator, for differential pairs.
164 * @param a left hand side parameter of the operator
165 * @param b right hand side parameter of the operator
166 * @return a+b
167 */
168 public static DifferentialPair add(final DifferentialPair a,
169 final double b) {
170 return new DifferentialPair(a.value + b, a.firstDerivative);
171 }
172
173 /** '+' operator, for differential pairs.
174 * @param a left hand side parameter of the operator
175 * @param b right hand side parameter of the operator
176 * @return a+b
177 */
178 public static DifferentialPair add(final double a,
179 final DifferentialPair b) {
180 return new DifferentialPair(a + b.value, b.firstDerivative);
181 }
182
183 /** '+' operator, for differential pairs.
184 * @param a left hand side parameter of the operator
185 * @param b right hand side parameter of the operator
186 * @return a+b
187 */
188 public static DifferentialPair add(final DifferentialPair a,
189 final DifferentialPair b) {
190 return new DifferentialPair(a.value + b.value, a.firstDerivative + b.firstDerivative);
191 }
192
193 /** '-' operator, for differential pairs.
194 * @param a left hand side parameter of the operator
195 * @param b right hand side parameter of the operator
196 * @return a-b
197 */
198 public static DifferentialPair subtract(final DifferentialPair a,
199 final int b) {
200 return new DifferentialPair(a.value - b, a.firstDerivative);
201 }
202
203 /** '-' operator, for differential pairs.
204 * @param a left hand side parameter of the operator
205 * @param b right hand side parameter of the operator
206 * @return a-b
207 */
208 public static DifferentialPair subtract(final int a,
209 final DifferentialPair b) {
210 return new DifferentialPair(a - b.value, -b.firstDerivative);
211 }
212
213 /** '-' operator, for differential pairs.
214 * @param a left hand side parameter of the operator
215 * @param b right hand side parameter of the operator
216 * @return a-b
217 */
218 public static DifferentialPair subtract(final DifferentialPair a,
219 final long b) {
220 return new DifferentialPair(a.value - b, a.firstDerivative);
221 }
222
223 /** '-' operator, for differential pairs.
224 * @param a left hand side parameter of the operator
225 * @param b right hand side parameter of the operator
226 * @return a-b
227 */
228 public static DifferentialPair subtract(final long a,
229 final DifferentialPair b) {
230 return new DifferentialPair(a - b.value, -b.firstDerivative);
231 }
232
233 /** '-' operator, for differential pairs.
234 * @param a left hand side parameter of the operator
235 * @param b right hand side parameter of the operator
236 * @return a-b
237 */
238 public static DifferentialPair subtract(final DifferentialPair a,
239 final double b) {
240 return new DifferentialPair(a.value - b, a.firstDerivative);
241 }
242
243 /** '-' operator, for differential pairs.
244 * @param a left hand side parameter of the operator
245 * @param b right hand side parameter of the operator
246 * @return a-b
247 */
248 public static DifferentialPair subtract(final double a,
249 final DifferentialPair b) {
250 return new DifferentialPair(a - b.value, -b.firstDerivative);
251 }
252
253 /** '-' operator, for differential pairs.
254 * @param a left hand side parameter of the operator
255 * @param b right hand side parameter of the operator
256 * @return a-b
257 */
258 public static DifferentialPair subtract(final DifferentialPair a,
259 final DifferentialPair b) {
260 return new DifferentialPair(a.value - b.value, a.firstDerivative - b.firstDerivative);
261 }
262
263 /** '×' operator, for differential pairs.
264 * @param a left hand side parameter of the operator
265 * @param b right hand side parameter of the operator
266 * @return a×b
267 */
268 public static DifferentialPair multiply(final DifferentialPair a,
269 final int b) {
270 return new DifferentialPair(a.value * b, a.firstDerivative * b);
271 }
272
273 /** '×' operator, for differential pairs.
274 * @param a left hand side parameter of the operator
275 * @param b right hand side parameter of the operator
276 * @return a×b
277 */
278 public static DifferentialPair multiply(final int a,
279 final DifferentialPair b) {
280 return new DifferentialPair(a * b.value, a * b.firstDerivative);
281 }
282
283 /** '×' operator, for differential pairs.
284 * @param a left hand side parameter of the operator
285 * @param b right hand side parameter of the operator
286 * @return a×b
287 */
288 public static DifferentialPair multiply(final DifferentialPair a,
289 final long b) {
290 return new DifferentialPair(a.value * b, a.firstDerivative * b);
291 }
292
293 /** '×' operator, for differential pairs.
294 * @param a left hand side parameter of the operator
295 * @param b right hand side parameter of the operator
296 * @return a×b
297 */
298 public static DifferentialPair multiply(final long a,
299 final DifferentialPair b) {
300 return new DifferentialPair(a * b.value, a * b.firstDerivative);
301 }
302
303 /** '×' operator, for differential pairs.
304 * @param a left hand side parameter of the operator
305 * @param b right hand side parameter of the operator
306 * @return a×b
307 */
308 public static DifferentialPair multiply(final DifferentialPair a,
309 final double b) {
310 return new DifferentialPair(a.value * b, a.firstDerivative * b);
311 }
312
313 /** '×' operator, for differential pairs.
314 * @param a left hand side parameter of the operator
315 * @param b right hand side parameter of the operator
316 * @return a×b
317 */
318 public static DifferentialPair multiply(final double a,
319 final DifferentialPair b) {
320 return new DifferentialPair(a * b.value, a * b.firstDerivative);
321 }
322
323 /** '×' operator, for differential pairs.
324 * @param a left hand side parameter of the operator
325 * @param b right hand side parameter of the operator
326 * @return a×b
327 */
328 public static DifferentialPair multiply(final DifferentialPair a,
329 final DifferentialPair b) {
330 return new DifferentialPair(a.value * b.value, a.firstDerivative * b.value + a.value * b.firstDerivative);
331 }
332
333 /** '÷s;' operator, for differential pairs.
334 * @param a left hand side parameter of the operator
335 * @param b right hand side parameter of the operator
336 * @return a÷s;b
337 */
338 public static DifferentialPair divide(final DifferentialPair a,
339 final int b) {
340 return new DifferentialPair(a.value / b, a.firstDerivative / b);
341 }
342
343 /** '÷s;' operator, for differential pairs.
344 * @param a left hand side parameter of the operator
345 * @param b right hand side parameter of the operator
346 * @return a÷s;b
347 */
348 public static DifferentialPair divide(final int a,
349 final DifferentialPair b) {
350 return new DifferentialPair(a / b.value, -a * b.firstDerivative / (b.value * b.value));
351 }
352
353 /** '÷s;' operator, for differential pairs.
354 * @param a left hand side parameter of the operator
355 * @param b right hand side parameter of the operator
356 * @return a÷s;b
357 */
358 public static DifferentialPair divide(final DifferentialPair a,
359 final long b) {
360 return new DifferentialPair(a.value / b, a.firstDerivative / b);
361 }
362
363 /** '÷s;' operator, for differential pairs.
364 * @param a left hand side parameter of the operator
365 * @param b right hand side parameter of the operator
366 * @return a÷s;b
367 */
368 public static DifferentialPair divide(final long a,
369 final DifferentialPair b) {
370 return new DifferentialPair(a / b.value, -a * b.firstDerivative / (b.value * b.value));
371 }
372
373 /** '÷s;' operator, for differential pairs.
374 * @param a left hand side parameter of the operator
375 * @param b right hand side parameter of the operator
376 * @return a÷s;b
377 */
378 public static DifferentialPair divide(final DifferentialPair a,
379 final double b) {
380 return new DifferentialPair(a.value / b, a.firstDerivative / b);
381 }
382
383 /** '÷s;' operator, for differential pairs.
384 * @param a left hand side parameter of the operator
385 * @param b right hand side parameter of the operator
386 * @return a÷s;b
387 */
388 public static DifferentialPair divide(final double a,
389 final DifferentialPair b) {
390 return new DifferentialPair(a / b.value, -a * b.firstDerivative / (b.value * b.value));
391 }
392
393 /** '÷s;' operator, for differential pairs.
394 * @param a left hand side parameter of the operator
395 * @param b right hand side parameter of the operator
396 * @return a÷s;b
397 */
398 public static DifferentialPair divide(final DifferentialPair a,
399 final DifferentialPair b) {
400 return new DifferentialPair(a.value / b.value, (a.firstDerivative * b.value - a.value * b.firstDerivative) / (b.value * b.value));
401 }
402
403 /** '%' operator, for differential pairs.
404 * @param a left hand side parameter of the operator
405 * @param b right hand side parameter of the operator
406 * @return a%b
407 */
408 public static DifferentialPair remainder(final int a,
409 final DifferentialPair b) {
410 final double remainder = a % b.value;
411 return new DifferentialPair(remainder, (remainder - a) * b.firstDerivative / b.value);
412 }
413
414 /** '%' operator, for differential pairs.
415 * @param a left hand side parameter of the operator
416 * @param b right hand side parameter of the operator
417 * @return a%b
418 */
419 public static DifferentialPair remainder(final DifferentialPair a,
420 final int b) {
421 return new DifferentialPair(a.value % b, a.firstDerivative);
422 }
423
424 /** '%' operator, for differential pairs.
425 * @param a left hand side parameter of the operator
426 * @param b right hand side parameter of the operator
427 * @return a%b
428 */
429 public static DifferentialPair remainder(final long a,
430 final DifferentialPair b) {
431 final double remainder = a % b.value;
432 return new DifferentialPair(remainder, (remainder - a) * b.firstDerivative / b.value);
433 }
434
435 /** '%' operator, for differential pairs.
436 * @param a left hand side parameter of the operator
437 * @param b right hand side parameter of the operator
438 * @return a%b
439 */
440 public static DifferentialPair remainder(final DifferentialPair a,
441 final long b) {
442 return new DifferentialPair(a.value % b, a.firstDerivative);
443 }
444
445 /** '%' operator, for differential pairs.
446 * @param a left hand side parameter of the operator
447 * @param b right hand side parameter of the operator
448 * @return a%b
449 */
450 public static DifferentialPair remainder(final double a,
451 final DifferentialPair b) {
452 final double remainder = a % b.value;
453 return new DifferentialPair(remainder, (remainder - a) * b.firstDerivative / b.value);
454 }
455
456 /** '%' operator, for differential pairs.
457 * @param a left hand side parameter of the operator
458 * @param b right hand side parameter of the operator
459 * @return a%b
460 */
461 public static DifferentialPair remainder(final DifferentialPair a,
462 final double b) {
463 return new DifferentialPair(a.value % b, a.firstDerivative);
464 }
465
466 /** '%' operator, for differential pairs.
467 * @param a left hand side parameter of the operator
468 * @param b right hand side parameter of the operator
469 * @return a%b
470 */
471 public static DifferentialPair remainder(final DifferentialPair a,
472 final DifferentialPair b) {
473 final double remainder = a.value % b.value;
474 return new DifferentialPair(remainder, (remainder - a.value) * b.firstDerivative / b.value + a.firstDerivative);
475 }
476
477 /** unary '-' operator, for differential pairs.
478 * @param a parameter of the operator
479 * @return -a
480 */
481 public static DifferentialPair negate(final DifferentialPair a) {
482 return new DifferentialPair(-a.value , -a.firstDerivative);
483 }
484
485 /** squaring operation, for differential pairs.
486 * @param a parameter of the operator
487 * @return a<sup>2</sup>
488 */
489 public static DifferentialPair square(final DifferentialPair a) {
490 return new DifferentialPair(a.value * a.value, 2 * a.value * a.firstDerivative);
491 }
492
493 /** cubing operation, for differential pairs.
494 * @param a parameter of the operator
495 * @return a<sup>3</sup>
496 */
497 public static DifferentialPair cube(final DifferentialPair a) {
498 final double u02 = a.value * a.value;
499 return new DifferentialPair(a.value * u02, 3 * u02 * a.firstDerivative);
500 }
501
502 }