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}