001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package org.wpilib.math.autodiff; 006 007/** An autodiff variable pointing to an expression node. */ 008public class Variable implements AutoCloseable { 009 /** Handle type tag. */ 010 public static final class Handle { 011 /** Constructor for Handle. */ 012 public Handle() {} 013 } 014 015 /** Instance of handle type tag. */ 016 public static final Handle HANDLE = new Handle(); 017 018 private long m_handle; 019 020 /** Constructs a linear Variable with a value of zero. */ 021 @SuppressWarnings("this-escape") 022 public Variable() { 023 m_handle = VariableJNI.createDefault(); 024 VariablePool.register(this); 025 } 026 027 /** 028 * Constructs a Variable from a floating point type. 029 * 030 * @param value The value of the Variable. 031 */ 032 @SuppressWarnings("this-escape") 033 public Variable(double value) { 034 m_handle = VariableJNI.createDouble(value); 035 VariablePool.register(this); 036 } 037 038 /** 039 * Constructs a Variable from an integral type. 040 * 041 * @param value The value of the Variable. 042 */ 043 @SuppressWarnings("this-escape") 044 public Variable(int value) { 045 m_handle = VariableJNI.createInt(value); 046 VariablePool.register(this); 047 } 048 049 /** 050 * Constructs a Variable from the given handle. 051 * 052 * <p>This constructor is for internal use only. 053 * 054 * @param handleTypeTag Handle type tag. 055 * @param handle Variable handle. 056 */ 057 @SuppressWarnings("this-escape") 058 public Variable(Handle handleTypeTag, long handle) { 059 m_handle = handle; 060 VariablePool.register(this); 061 } 062 063 @Override 064 public void close() { 065 if (m_handle != 0) { 066 VariableJNI.destroy(m_handle); 067 m_handle = 0; 068 } 069 } 070 071 /** 072 * Sets Variable's internal value. 073 * 074 * @param value The value of the Variable. 075 */ 076 public void setValue(double value) { 077 VariableJNI.setValue(m_handle, value); 078 } 079 080 /** 081 * Returns the value of this variable. 082 * 083 * @return The value of this variable. 084 */ 085 public double value() { 086 return VariableJNI.value(m_handle); 087 } 088 089 /** 090 * Returns the type of this expression (constant, linear, quadratic, or nonlinear). 091 * 092 * @return The type of this expression. 093 */ 094 public ExpressionType type() { 095 return ExpressionType.fromInt(VariableJNI.type(m_handle)); 096 } 097 098 /** 099 * Returns internal handle. 100 * 101 * @return Internal handle. 102 */ 103 public long getHandle() { 104 return m_handle; 105 } 106 107 /** 108 * Variable-Variable multiplication operator. 109 * 110 * @param rhs Operator right-hand side. 111 * @return Result of multiplication. 112 */ 113 public Variable times(Variable rhs) { 114 return new Variable(HANDLE, VariableJNI.times(m_handle, rhs.getHandle())); 115 } 116 117 /** 118 * Variable-Variable multiplication operator. 119 * 120 * @param rhs Operator right-hand side. 121 * @return Result of multiplication. 122 */ 123 public Variable times(double rhs) { 124 return times(new Variable(rhs)); 125 } 126 127 /** 128 * Variable-Variable division operator. 129 * 130 * @param rhs Operator right-hand side. 131 * @return Result of division. 132 */ 133 public Variable div(Variable rhs) { 134 return new Variable(HANDLE, VariableJNI.div(m_handle, rhs.getHandle())); 135 } 136 137 /** 138 * Variable-Variable division operator. 139 * 140 * @param rhs Operator right-hand side. 141 * @return Result of division. 142 */ 143 public Variable div(double rhs) { 144 return div(new Variable(rhs)); 145 } 146 147 /** 148 * Variable-Variable addition operator. 149 * 150 * @param rhs Operator right-hand side. 151 * @return Result of addition. 152 */ 153 public Variable plus(Variable rhs) { 154 return new Variable(HANDLE, VariableJNI.plus(m_handle, rhs.getHandle())); 155 } 156 157 /** 158 * Variable-Variable addition operator. 159 * 160 * @param rhs Operator right-hand side. 161 * @return Result of addition. 162 */ 163 public Variable plus(double rhs) { 164 return plus(new Variable(rhs)); 165 } 166 167 /** 168 * Variable-Variable subtraction operator. 169 * 170 * @param rhs Operator right-hand side. 171 * @return Result of subtraction. 172 */ 173 public Variable minus(Variable rhs) { 174 return new Variable(HANDLE, VariableJNI.minus(m_handle, rhs.getHandle())); 175 } 176 177 /** 178 * Variable-Variable subtraction operator. 179 * 180 * @param rhs Operator right-hand side. 181 * @return Result of subtraction. 182 */ 183 public Variable minus(double rhs) { 184 return minus(new Variable(rhs)); 185 } 186 187 /** 188 * Unary minus operator. 189 * 190 * @return Result of unary minus. 191 */ 192 public Variable unaryMinus() { 193 return new Variable(HANDLE, VariableJNI.unaryMinus(m_handle)); 194 } 195 196 /** 197 * Unary plus operator. 198 * 199 * @return Result of unary plus. 200 */ 201 public Variable unaryPlus() { 202 return this; 203 } 204 205 /** 206 * Math.abs() for Variables. 207 * 208 * @param x The argument. 209 * @return Result of abs(). 210 */ 211 public static Variable abs(Variable x) { 212 return new Variable(HANDLE, VariableJNI.abs(x.getHandle())); 213 } 214 215 /** 216 * Math.acos() for Variables. 217 * 218 * @param x The argument. 219 * @return Result of acos(). 220 */ 221 public static Variable acos(Variable x) { 222 return new Variable(HANDLE, VariableJNI.acos(x.getHandle())); 223 } 224 225 /** 226 * Math.asin() for Variables. 227 * 228 * @param x The argument. 229 * @return Result of asin(). 230 */ 231 public static Variable asin(Variable x) { 232 return new Variable(HANDLE, VariableJNI.asin(x.getHandle())); 233 } 234 235 /** 236 * Math.atan() for Variables. 237 * 238 * @param x The argument. 239 * @return Result of atan(). 240 */ 241 public static Variable atan(Variable x) { 242 return new Variable(HANDLE, VariableJNI.atan(x.getHandle())); 243 } 244 245 /** 246 * Math.atan2() for Variables. 247 * 248 * @param y The y argument. 249 * @param x The x argument. 250 * @return Result of atan2(). 251 */ 252 public static Variable atan2(double y, Variable x) { 253 return atan2(new Variable(y), x); 254 } 255 256 /** 257 * Math.atan2() for Variables. 258 * 259 * @param y The y argument. 260 * @param x The x argument. 261 * @return Result of atan2(). 262 */ 263 public static Variable atan2(Variable y, double x) { 264 return atan2(y, new Variable(x)); 265 } 266 267 /** 268 * Math.atan2() for Variables. 269 * 270 * @param y The y argument. 271 * @param x The x argument. 272 * @return Result of atan2(). 273 */ 274 public static Variable atan2(Variable y, Variable x) { 275 return new Variable(HANDLE, VariableJNI.atan2(y.getHandle(), x.getHandle())); 276 } 277 278 /** 279 * Math.cbrt() for Variables. 280 * 281 * @param x The argument. 282 * @return Result of cbrt(). 283 */ 284 public static Variable cbrt(Variable x) { 285 return new Variable(HANDLE, VariableJNI.cbrt(x.getHandle())); 286 } 287 288 /** 289 * Math.cos() for Variables. 290 * 291 * @param x The argument. 292 * @return Result of cos(). 293 */ 294 public static Variable cos(Variable x) { 295 return new Variable(HANDLE, VariableJNI.cos(x.getHandle())); 296 } 297 298 /** 299 * Math.cosh() for Variables. 300 * 301 * @param x The argument. 302 * @return Result of cosh(). 303 */ 304 public static Variable cosh(Variable x) { 305 return new Variable(HANDLE, VariableJNI.cosh(x.getHandle())); 306 } 307 308 /** 309 * Math.exp() for Variables. 310 * 311 * @param x The argument. 312 * @return Result of exp(). 313 */ 314 public static Variable exp(Variable x) { 315 return new Variable(HANDLE, VariableJNI.exp(x.getHandle())); 316 } 317 318 /** 319 * Math.hypot() for Variables. 320 * 321 * @param x The x argument. 322 * @param y The y argument. 323 * @return Result of hypot(). 324 */ 325 public static Variable hypot(double x, Variable y) { 326 return hypot(new Variable(x), y); 327 } 328 329 /** 330 * Math.hypot() for Variables. 331 * 332 * @param x The x argument. 333 * @param y The y argument. 334 * @return Result of hypot(). 335 */ 336 public static Variable hypot(Variable x, double y) { 337 return hypot(x, new Variable(y)); 338 } 339 340 /** 341 * Math.hypot() for Variables. 342 * 343 * @param x The x argument. 344 * @param y The y argument. 345 * @return Result of hypot(). 346 */ 347 public static Variable hypot(Variable x, Variable y) { 348 return new Variable(HANDLE, VariableJNI.hypot(x.getHandle(), y.getHandle())); 349 } 350 351 /** 352 * Math.hypot() for Variables. 353 * 354 * @param x The x argument. 355 * @param y The y argument. 356 * @param z The z argument. 357 * @return Result of hypot(). 358 */ 359 public static Variable hypot(double x, double y, Variable z) { 360 return hypot(new Variable(x), new Variable(y), z); 361 } 362 363 /** 364 * Math.hypot() for Variables. 365 * 366 * @param x The x argument. 367 * @param y The y argument. 368 * @param z The z argument. 369 * @return Result of hypot(). 370 */ 371 public static Variable hypot(double x, Variable y, double z) { 372 return hypot(new Variable(x), y, new Variable(z)); 373 } 374 375 /** 376 * Math.hypot() for Variables. 377 * 378 * @param x The x argument. 379 * @param y The y argument. 380 * @param z The z argument. 381 * @return Result of hypot(). 382 */ 383 public static Variable hypot(double x, Variable y, Variable z) { 384 return hypot(new Variable(x), y, z); 385 } 386 387 /** 388 * Math.hypot() for Variables. 389 * 390 * @param x The x argument. 391 * @param y The y argument. 392 * @param z The z argument. 393 * @return Result of hypot(). 394 */ 395 public static Variable hypot(Variable x, double y, double z) { 396 return hypot(x, new Variable(y), new Variable(z)); 397 } 398 399 /** 400 * Math.hypot() for Variables. 401 * 402 * @param x The x argument. 403 * @param y The y argument. 404 * @param z The z argument. 405 * @return Result of hypot(). 406 */ 407 public static Variable hypot(Variable x, double y, Variable z) { 408 return hypot(x, new Variable(y), z); 409 } 410 411 /** 412 * Math.hypot() for Variables. 413 * 414 * @param x The x argument. 415 * @param y The y argument. 416 * @param z The z argument. 417 * @return Result of hypot(). 418 */ 419 public static Variable hypot(Variable x, Variable y, double z) { 420 return hypot(x, y, new Variable(z)); 421 } 422 423 /** 424 * Math.hypot() for Variables. 425 * 426 * @param x The x argument. 427 * @param y The y argument. 428 * @param z The z argument. 429 * @return Result of hypot(). 430 */ 431 public static Variable hypot(Variable x, Variable y, Variable z) { 432 return sqrt(pow(x, 2).plus(pow(y, 2)).plus(pow(z, 2))); 433 } 434 435 /** 436 * Math.log() for Variables. 437 * 438 * @param x The argument. 439 * @return Result of log(). 440 */ 441 public static Variable log(Variable x) { 442 return new Variable(HANDLE, VariableJNI.log(x.getHandle())); 443 } 444 445 /** 446 * Math.log10() for Variables. 447 * 448 * @param x The argument. 449 * @return Result of log10(). 450 */ 451 public static Variable log10(Variable x) { 452 return new Variable(HANDLE, VariableJNI.log10(x.getHandle())); 453 } 454 455 /** 456 * Math.max() for Variables. 457 * 458 * <p>Returns the greater of a and b. If the values are equivalent, returns a. 459 * 460 * @param a The a argument. 461 * @param b The b argument. 462 * @return Result of max(). 463 */ 464 public static Variable max(double a, Variable b) { 465 return max(new Variable(a), b); 466 } 467 468 /** 469 * Math.max() for Variables. 470 * 471 * <p>Returns the greater of a and b. If the values are equivalent, returns a. 472 * 473 * @param a The a argument. 474 * @param b The b argument. 475 * @return Result of max(). 476 */ 477 public static Variable max(Variable a, double b) { 478 return max(a, new Variable(b)); 479 } 480 481 /** 482 * Math.max() for Variables. 483 * 484 * <p>Returns the greater of a and b. If the values are equivalent, returns a. 485 * 486 * @param a The a argument. 487 * @param b The b argument. 488 * @return Result of max(). 489 */ 490 public static Variable max(Variable a, Variable b) { 491 return new Variable(HANDLE, VariableJNI.max(a.getHandle(), b.getHandle())); 492 } 493 494 /** 495 * min() for Variables. 496 * 497 * <p>Returns the lesser of a and b. If the values are equivalent, returns a. 498 * 499 * @param a The a argument. 500 * @param b The b argument. 501 * @return Result of min(). 502 */ 503 public static Variable min(double a, Variable b) { 504 return min(new Variable(a), b); 505 } 506 507 /** 508 * min() for Variables. 509 * 510 * <p>Returns the lesser of a and b. If the values are equivalent, returns a. 511 * 512 * @param a The a argument. 513 * @param b The b argument. 514 * @return Result of min(). 515 */ 516 public static Variable min(Variable a, double b) { 517 return min(a, new Variable(b)); 518 } 519 520 /** 521 * min() for Variables. 522 * 523 * <p>Returns the lesser of a and b. If the values are equivalent, returns a. 524 * 525 * @param a The a argument. 526 * @param b The b argument. 527 * @return Result of min(). 528 */ 529 public static Variable min(Variable a, Variable b) { 530 return new Variable(HANDLE, VariableJNI.min(a.getHandle(), b.getHandle())); 531 } 532 533 /** 534 * Math.pow() for Variables. 535 * 536 * @param base The base. 537 * @param power The power. 538 * @return Result of pow(). 539 */ 540 public static Variable pow(double base, Variable power) { 541 return pow(new Variable(base), power); 542 } 543 544 /** 545 * Math.pow() for Variables. 546 * 547 * @param base The base. 548 * @param power The power. 549 * @return Result of pow(). 550 */ 551 public static Variable pow(Variable base, double power) { 552 return pow(base, new Variable(power)); 553 } 554 555 /** 556 * Math.pow() for Variables. 557 * 558 * @param base The base. 559 * @param power The power. 560 * @return Result of pow(). 561 */ 562 public static Variable pow(Variable base, Variable power) { 563 return new Variable(HANDLE, VariableJNI.pow(base.getHandle(), power.getHandle())); 564 } 565 566 /** 567 * Math.signum() for Variables. 568 * 569 * @param x The argument. 570 * @return Result of signum(). 571 */ 572 public static Variable signum(Variable x) { 573 return new Variable(HANDLE, VariableJNI.signum(x.getHandle())); 574 } 575 576 /** 577 * Math.sin() for Variables. 578 * 579 * @param x The argument. 580 * @return Result of sin(). 581 */ 582 public static Variable sin(Variable x) { 583 return new Variable(HANDLE, VariableJNI.sin(x.getHandle())); 584 } 585 586 /** 587 * Math.sinh() for Variables. 588 * 589 * @param x The argument. 590 * @return Result of sinh(). 591 */ 592 public static Variable sinh(Variable x) { 593 return new Variable(HANDLE, VariableJNI.sinh(x.getHandle())); 594 } 595 596 /** 597 * Math.sqrt() for Variables. 598 * 599 * @param x The argument. 600 * @return Result of sqrt(). 601 */ 602 public static Variable sqrt(Variable x) { 603 return new Variable(HANDLE, VariableJNI.sqrt(x.getHandle())); 604 } 605 606 /** 607 * Math.tan() for Variables. 608 * 609 * @param x The argument. 610 * @return Result of tan(). 611 */ 612 public static Variable tan(Variable x) { 613 return new Variable(HANDLE, VariableJNI.tan(x.getHandle())); 614 } 615 616 /** 617 * Math.tanh() for Variables. 618 * 619 * @param x The argument. 620 * @return Result of tanh(). 621 */ 622 public static Variable tanh(Variable x) { 623 return new Variable(HANDLE, VariableJNI.tanh(x.getHandle())); 624 } 625 626 /** 627 * Returns the total native memory usage of all Variables in bytes. 628 * 629 * @return The total native memory usage of all Variables in bytes. 630 */ 631 public static long totalNativeMemoryUsage() { 632 return VariableJNI.totalNativeMemoryUsage(); 633 } 634}