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        /** &pi; (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        /** '&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    }