View Javadoc

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  package org.apache.commons.nabla.core;
18  
19  import java.io.Serializable;
20  
21  /** Class representing both a value and a differential.
22   * <p>This class is the workhorse of the Nabla library. It can be
23   * seen as an extension of the primitive double type used throughout
24   * mathematical expressions. In addition to holding parameter,
25   * intermediate computations and result values as double do, instances
26   * of this class also holds the first differential associated with this
27   * parameter, intermediate computations and results.</p>
28   * <p>{@link DifferentialPair} instances can be used directly thanks to
29   * the arithmetic operators provided as static methods by this class
30   * (+, -, *, /, %) and to the mathematical functions provided by the
31   * {@link org.apache.commons.nabla.NablaMath} and the {@link
32   * org.apache.commons.nabla.NablaStrictMath} utility classes.</p>
33   * <p>Implementing complex expressions by hand using these classes is
34   * however a complex and error-prone task, so the classical use is
35   * simply to develop computation code using standard primitive double
36   * values and to use {@link UnivariateDifferentiator differentiators} to create
37   * the {@link DifferentialPair}-based instances.</p>
38   * <p>Instances of this class are guaranteed to be immutable.</p>
39   */
40  public class DifferentialPair implements Serializable {
41  
42      /** -1 constant. */
43      public static final DifferentialPair MINUS_ONE = newConstant(-1);
44  
45      /** 0 constant. */
46      public static final DifferentialPair ZERO      = newConstant( 0);
47  
48      /** +1 constant. */
49      public static final DifferentialPair ONE       = newConstant( 1);
50  
51      /** +2 constant. */
52      public static final DifferentialPair TWO       = newConstant( 2);
53  
54      /** +3 constant. */
55      public static final DifferentialPair THREE     = newConstant( 3);
56  
57  
58      /** &pi; (Archimede) constant. */
59      public static final DifferentialPair PI        = newConstant(Math.PI);
60  
61      /** e (Euler) constant, base of the natural logarithms. */
62      public static final DifferentialPair E         = newConstant(Math.E);
63  
64      /** Serializable UID. */
65      private static final long serialVersionUID = 9015695991152713660L;
66  
67  
68      /** Value part of the differential pair. */
69      private final double value;
70  
71      /** First derivative part of the differential pair. */
72      private final double firstDerivative;
73  
74      /** Build a new instance from its components.
75       * @param u0 value part of the differential pair
76       * @param u1 first derivative part of the differential pair
77       */
78      public DifferentialPair(final double u0, final double u1) {
79          this.value = u0;
80          this.firstDerivative = u1;
81      }
82  
83      /** Build an instance representing a univariate variable.
84       * <p>Instances built using this constructor are considered
85       * to be the free variables with respect to which differentials
86       * are computed. As such, their differential with respect to
87       * themselves is +1. Calling this constructor has the same
88       * effect as calling <code>DifferentialPair(a, 1.0)</code>.</p>
89       * @param a value of the variable
90       * @return the built variable
91       */
92      public static DifferentialPair newVariable(final double a) {
93          return new DifferentialPair(a, 1.0);
94      }
95  
96      /** Build an instance representing a constant.
97       * <p>Constant do not vary ... Hence their differential
98       * is 0. Calling this constructor has the same
99       * 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     /** '&times;' 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&times;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     /** '&times;' 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&times;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     /** '&times;' 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&times;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     /** '&times;' 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&times;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     /** '&times;' 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&times;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     /** '&times;' 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&times;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     /** '&times;' 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&times;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     /** '&divides;' 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&divides;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     /** '&divides;' 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&divides;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     /** '&divides;' 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&divides;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     /** '&divides;' 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&divides;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     /** '&divides;' 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&divides;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     /** '&divides;' 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&divides;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     /** '&divides;' 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&divides;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 }