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 }