1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.util;
18
19 import java.util.Arrays;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.Field;
23 import org.hipparchus.exception.MathIllegalArgumentException;
24
25
26
27
28
29 public class Tuple implements CalculusFieldElement<Tuple> {
30
31
32 private final double[] values;
33
34
35 private final transient TupleField field;
36
37
38
39
40 public Tuple(final double... x) {
41 this(new TupleField(x.length), x.clone());
42 }
43
44
45
46
47
48 private Tuple(final TupleField field, final double[] x) {
49 this.values = x;
50 this.field = field;
51 }
52
53
54 @Override
55 public Tuple newInstance(final double value) {
56 final Tuple t = new Tuple(field, new double[values.length]);
57 Arrays.fill(t.values, value);
58 return t;
59 }
60
61
62
63
64 public int getDimension() {
65 return values.length;
66 }
67
68
69
70
71
72 public double getComponent(final int index) {
73 return values[index];
74 }
75
76
77
78
79 public double[] getComponents() {
80 return values.clone();
81 }
82
83
84 @Override
85 public Field<Tuple> getField() {
86 return field;
87 }
88
89
90 @Override
91 public Tuple add(final Tuple a) {
92 final Tuple result = new Tuple(field, new double[values.length]);
93 for (int i = 0; i < values.length; ++i) {
94 result.values[i] = values[i] + a.values[i];
95 }
96 return result;
97 }
98
99
100 @Override
101 public Tuple subtract(final Tuple a) {
102 final Tuple result = new Tuple(field, new double[values.length]);
103 for (int i = 0; i < values.length; ++i) {
104 result.values[i] = values[i] - a.values[i];
105 }
106 return result;
107 }
108
109
110 @Override
111 public Tuple negate() {
112 final Tuple result = new Tuple(field, new double[values.length]);
113 for (int i = 0; i < values.length; ++i) {
114 result.values[i] = -values[i];
115 }
116 return result;
117 }
118
119
120 @Override
121 public Tuple multiply(final Tuple a) {
122 final Tuple result = new Tuple(field, new double[values.length]);
123 for (int i = 0; i < values.length; ++i) {
124 result.values[i] = values[i] * a.values[i];
125 }
126 return result;
127 }
128
129
130 @Override
131 public Tuple multiply(final int n) {
132 final Tuple result = new Tuple(field, new double[values.length]);
133 for (int i = 0; i < values.length; ++i) {
134 result.values[i] = values[i] * n;
135 }
136 return result;
137 }
138
139
140 @Override
141 public Tuple divide(final Tuple a) {
142 final Tuple result = new Tuple(field, new double[values.length]);
143 for (int i = 0; i < values.length; ++i) {
144 result.values[i] = values[i] / a.values[i];
145 }
146 return result;
147 }
148
149
150 @Override
151 public Tuple reciprocal() {
152 final Tuple result = new Tuple(field, new double[values.length]);
153 for (int i = 0; i < values.length; ++i) {
154 result.values[i] = 1.0 / values[i];
155 }
156 return result;
157 }
158
159
160 @Override
161 public boolean equals(final Object obj) {
162 if (obj instanceof Tuple) {
163 final Tuple that = (Tuple) obj;
164 if (getDimension() == that.getDimension()) {
165 boolean equals = true;
166 for (int i = 0; i < values.length; ++i) {
167 equals &= Double.doubleToRawLongBits(values[i]) == Double.doubleToRawLongBits(that.values[i]);
168 }
169 return equals;
170 }
171 }
172 return false;
173 }
174
175
176 @Override
177 public int hashCode() {
178 return 0x34b1a444 + Arrays.hashCode(values);
179 }
180
181
182 @Override
183 public double getReal() {
184 return values[0];
185 }
186
187
188 @Override
189 public Tuple add(final double a) {
190 final Tuple result = new Tuple(field, new double[values.length]);
191 for (int i = 0; i < values.length; ++i) {
192 result.values[i] = values[i] + a;
193 }
194 return result;
195 }
196
197
198 @Override
199 public Tuple subtract(final double a) {
200 final Tuple result = new Tuple(field, new double[values.length]);
201 for (int i = 0; i < values.length; ++i) {
202 result.values[i] = values[i] - a;
203 }
204 return result;
205 }
206
207
208 @Override
209 public Tuple multiply(final double a) {
210 final Tuple result = new Tuple(field, new double[values.length]);
211 for (int i = 0; i < values.length; ++i) {
212 result.values[i] = values[i] * a;
213 }
214 return result;
215 }
216
217
218 @Override
219 public Tuple divide(final double a) {
220 final Tuple result = new Tuple(field, new double[values.length]);
221 for (int i = 0; i < values.length; ++i) {
222 result.values[i] = values[i] / a;
223 }
224 return result;
225 }
226
227
228 @Override
229 public Tuple remainder(final double a) {
230 final Tuple result = new Tuple(field, new double[values.length]);
231 for (int i = 0; i < values.length; ++i) {
232 result.values[i] = FastMath.IEEEremainder(values[i], a);
233 }
234 return result;
235 }
236
237
238 @Override
239 public Tuple remainder(final Tuple a) {
240 final Tuple result = new Tuple(field, new double[values.length]);
241 for (int i = 0; i < values.length; ++i) {
242 result.values[i] = FastMath.IEEEremainder(values[i], a.values[i]);
243 }
244 return result;
245 }
246
247
248 @Override
249 public Tuple abs() {
250 final Tuple result = new Tuple(field, new double[values.length]);
251 for (int i = 0; i < values.length; ++i) {
252 result.values[i] = FastMath.abs(values[i]);
253 }
254 return result;
255 }
256
257
258 @Override
259 public Tuple ceil() {
260 final Tuple result = new Tuple(field, new double[values.length]);
261 for (int i = 0; i < values.length; ++i) {
262 result.values[i] = FastMath.ceil(values[i]);
263 }
264 return result;
265 }
266
267
268 @Override
269 public Tuple floor() {
270 final Tuple result = new Tuple(field, new double[values.length]);
271 for (int i = 0; i < values.length; ++i) {
272 result.values[i] = FastMath.floor(values[i]);
273 }
274 return result;
275 }
276
277
278 @Override
279 public Tuple rint() {
280 final Tuple result = new Tuple(field, new double[values.length]);
281 for (int i = 0; i < values.length; ++i) {
282 result.values[i] = FastMath.rint(values[i]);
283 }
284 return result;
285 }
286
287
288 @Override
289 public Tuple sign() {
290 final Tuple result = new Tuple(field, new double[values.length]);
291 for (int i = 0; i < values.length; ++i) {
292 result.values[i] = FastMath.signum(values[i]);
293 }
294 return result;
295 }
296
297
298 @Override
299 public Tuple copySign(final Tuple sign) {
300 final Tuple result = new Tuple(field, new double[values.length]);
301 for (int i = 0; i < values.length; ++i) {
302 result.values[i] = FastMath.copySign(values[i], sign.values[i]);
303 }
304 return result;
305 }
306
307
308 @Override
309 public Tuple copySign(final double sign) {
310 final Tuple result = new Tuple(field, new double[values.length]);
311 for (int i = 0; i < values.length; ++i) {
312 result.values[i] = FastMath.copySign(values[i], sign);
313 }
314 return result;
315 }
316
317
318 @Override
319 public Tuple scalb(final int n) {
320 final Tuple result = new Tuple(field, new double[values.length]);
321 for (int i = 0; i < values.length; ++i) {
322 result.values[i] = FastMath.scalb(values[i], n);
323 }
324 return result;
325 }
326
327
328 @Override
329 public Tuple ulp() {
330 final Tuple result = new Tuple(field, new double[values.length]);
331 for (int i = 0; i < values.length; ++i) {
332 result.values[i] = FastMath.ulp(values[i]);
333 }
334 return result;
335 }
336
337
338 @Override
339 public Tuple hypot(final Tuple y) {
340 final Tuple result = new Tuple(field, new double[values.length]);
341 for (int i = 0; i < values.length; ++i) {
342 result.values[i] = FastMath.hypot(values[i], y.values[i]);
343 }
344 return result;
345 }
346
347
348 @Override
349 public Tuple sqrt() {
350 final Tuple result = new Tuple(field, new double[values.length]);
351 for (int i = 0; i < values.length; ++i) {
352 result.values[i] = FastMath.sqrt(values[i]);
353 }
354 return result;
355 }
356
357
358 @Override
359 public Tuple cbrt() {
360 final Tuple result = new Tuple(field, new double[values.length]);
361 for (int i = 0; i < values.length; ++i) {
362 result.values[i] = FastMath.cbrt(values[i]);
363 }
364 return result;
365 }
366
367
368 @Override
369 public Tuple rootN(final int n) {
370 final Tuple result = new Tuple(field, new double[values.length]);
371 for (int i = 0; i < values.length; ++i) {
372 if (values[i] < 0) {
373 result.values[i] = -FastMath.pow(-values[i], 1.0 / n);
374 } else {
375 result.values[i] = FastMath.pow(values[i], 1.0 / n);
376 }
377 }
378 return result;
379 }
380
381
382 @Override
383 public Tuple pow(final double p) {
384 final Tuple result = new Tuple(field, new double[values.length]);
385 for (int i = 0; i < values.length; ++i) {
386 result.values[i] = FastMath.pow(values[i], p);
387 }
388 return result;
389 }
390
391
392 @Override
393 public Tuple pow(final int n) {
394 final Tuple result = new Tuple(field, new double[values.length]);
395 for (int i = 0; i < values.length; ++i) {
396 result.values[i] = FastMath.pow(values[i], n);
397 }
398 return result;
399 }
400
401
402 @Override
403 public Tuple pow(final Tuple e) {
404 final Tuple result = new Tuple(field, new double[values.length]);
405 for (int i = 0; i < values.length; ++i) {
406 result.values[i] = FastMath.pow(values[i], e.values[i]);
407 }
408 return result;
409 }
410
411
412 @Override
413 public Tuple exp() {
414 final Tuple result = new Tuple(field, new double[values.length]);
415 for (int i = 0; i < values.length; ++i) {
416 result.values[i] = FastMath.exp(values[i]);
417 }
418 return result;
419 }
420
421
422 @Override
423 public Tuple expm1() {
424 final Tuple result = new Tuple(field, new double[values.length]);
425 for (int i = 0; i < values.length; ++i) {
426 result.values[i] = FastMath.expm1(values[i]);
427 }
428 return result;
429 }
430
431
432 @Override
433 public Tuple log() {
434 final Tuple result = new Tuple(field, new double[values.length]);
435 for (int i = 0; i < values.length; ++i) {
436 result.values[i] = FastMath.log(values[i]);
437 }
438 return result;
439 }
440
441
442 @Override
443 public Tuple log1p() {
444 final Tuple result = new Tuple(field, new double[values.length]);
445 for (int i = 0; i < values.length; ++i) {
446 result.values[i] = FastMath.log1p(values[i]);
447 }
448 return result;
449 }
450
451
452 @Override
453 public Tuple log10() {
454 final Tuple result = new Tuple(field, new double[values.length]);
455 for (int i = 0; i < values.length; ++i) {
456 result.values[i] = FastMath.log10(values[i]);
457 }
458 return result;
459 }
460
461
462 @Override
463 public Tuple cos() {
464 final Tuple result = new Tuple(field, new double[values.length]);
465 for (int i = 0; i < values.length; ++i) {
466 result.values[i] = FastMath.cos(values[i]);
467 }
468 return result;
469 }
470
471
472 @Override
473 public Tuple sin() {
474 final Tuple result = new Tuple(field, new double[values.length]);
475 for (int i = 0; i < values.length; ++i) {
476 result.values[i] = FastMath.sin(values[i]);
477 }
478 return result;
479 }
480
481
482 @Override
483 public FieldSinCos<Tuple> sinCos() {
484 final Tuple sin = new Tuple(field, new double[values.length]);
485 final Tuple cos = new Tuple(field, new double[values.length]);
486 for (int i = 0; i < values.length; ++i) {
487 final SinCos sc = FastMath.sinCos(values[i]);
488 sin.values[i] = sc.sin();
489 cos.values[i] = sc.cos();
490 }
491 return new FieldSinCos<>(sin, cos);
492 }
493
494
495 @Override
496 public Tuple tan() {
497 final Tuple result = new Tuple(field, new double[values.length]);
498 for (int i = 0; i < values.length; ++i) {
499 result.values[i] = FastMath.tan(values[i]);
500 }
501 return result;
502 }
503
504
505 @Override
506 public Tuple acos() {
507 final Tuple result = new Tuple(field, new double[values.length]);
508 for (int i = 0; i < values.length; ++i) {
509 result.values[i] = FastMath.acos(values[i]);
510 }
511 return result;
512 }
513
514
515 @Override
516 public Tuple asin() {
517 final Tuple result = new Tuple(field, new double[values.length]);
518 for (int i = 0; i < values.length; ++i) {
519 result.values[i] = FastMath.asin(values[i]);
520 }
521 return result;
522 }
523
524
525 @Override
526 public Tuple atan() {
527 final Tuple result = new Tuple(field, new double[values.length]);
528 for (int i = 0; i < values.length; ++i) {
529 result.values[i] = FastMath.atan(values[i]);
530 }
531 return result;
532 }
533
534
535 @Override
536 public Tuple atan2(final Tuple x) {
537 final Tuple result = new Tuple(field, new double[values.length]);
538 for (int i = 0; i < values.length; ++i) {
539 result.values[i] = FastMath.atan2(values[i], x.values[i]);
540 }
541 return result;
542 }
543
544
545 @Override
546 public Tuple cosh() {
547 final Tuple result = new Tuple(field, new double[values.length]);
548 for (int i = 0; i < values.length; ++i) {
549 result.values[i] = FastMath.cosh(values[i]);
550 }
551 return result;
552 }
553
554
555 @Override
556 public Tuple sinh() {
557 final Tuple result = new Tuple(field, new double[values.length]);
558 for (int i = 0; i < values.length; ++i) {
559 result.values[i] = FastMath.sinh(values[i]);
560 }
561 return result;
562 }
563
564
565 @Override
566 public FieldSinhCosh<Tuple> sinhCosh() {
567 final Tuple sinh = new Tuple(field, new double[values.length]);
568 final Tuple cosh = new Tuple(field, new double[values.length]);
569 for (int i = 0; i < values.length; ++i) {
570 final SinhCosh sch = FastMath.sinhCosh(values[i]);
571 sinh.values[i] = sch.sinh();
572 cosh.values[i] = sch.cosh();
573 }
574 return new FieldSinhCosh<>(sinh, cosh);
575 }
576
577
578 @Override
579 public Tuple tanh() {
580 final Tuple result = new Tuple(field, new double[values.length]);
581 for (int i = 0; i < values.length; ++i) {
582 result.values[i] = FastMath.tanh(values[i]);
583 }
584 return result;
585 }
586
587
588 @Override
589 public Tuple acosh() {
590 final Tuple result = new Tuple(field, new double[values.length]);
591 for (int i = 0; i < values.length; ++i) {
592 result.values[i] = FastMath.acosh(values[i]);
593 }
594 return result;
595 }
596
597
598 @Override
599 public Tuple asinh() {
600 final Tuple result = new Tuple(field, new double[values.length]);
601 for (int i = 0; i < values.length; ++i) {
602 result.values[i] = FastMath.asinh(values[i]);
603 }
604 return result;
605 }
606
607
608 @Override
609 public Tuple atanh() {
610 final Tuple result = new Tuple(field, new double[values.length]);
611 for (int i = 0; i < values.length; ++i) {
612 result.values[i] = FastMath.atanh(values[i]);
613 }
614 return result;
615 }
616
617
618 @Override
619 public Tuple toDegrees() {
620 final Tuple result = new Tuple(field, new double[values.length]);
621 for (int i = 0; i < values.length; ++i) {
622 result.values[i] = FastMath.toDegrees(values[i]);
623 }
624 return result;
625 }
626
627
628 @Override
629 public Tuple toRadians() {
630 final Tuple result = new Tuple(field, new double[values.length]);
631 for (int i = 0; i < values.length; ++i) {
632 result.values[i] = FastMath.toRadians(values[i]);
633 }
634 return result;
635 }
636
637
638 @Override
639 public Tuple linearCombination(final Tuple[] a, final Tuple[] b)
640 throws MathIllegalArgumentException {
641 final Tuple result = new Tuple(field, new double[values.length]);
642 MathUtils.checkDimension(a.length, b.length);
643 final double[] aDouble = new double[a.length];
644 final double[] bDouble = new double[b.length];
645 for (int i = 0; i < values.length; ++i) {
646 for (int j = 0; j < a.length; ++j) {
647 aDouble[j] = a[j].values[i];
648 bDouble[j] = b[j].values[i];
649 }
650 result.values[i] = MathArrays.linearCombination(aDouble, bDouble);
651 }
652 return result;
653 }
654
655
656 @Override
657 public Tuple linearCombination(final double[] a, final Tuple[] b)
658 throws MathIllegalArgumentException {
659 final Tuple result = new Tuple(field, new double[values.length]);
660 MathUtils.checkDimension(a.length, b.length);
661 final double[] bDouble = new double[b.length];
662 for (int i = 0; i < values.length; ++i) {
663 for (int j = 0; j < a.length; ++j) {
664 bDouble[j] = b[j].values[i];
665 }
666 result.values[i] = MathArrays.linearCombination(a, bDouble);
667 }
668 return result;
669 }
670
671
672 @Override
673 public Tuple linearCombination(final Tuple a1, final Tuple b1,
674 final Tuple a2, final Tuple b2) {
675 final Tuple result = new Tuple(field, new double[values.length]);
676 for (int i = 0; i < values.length; ++i) {
677 result.values[i] = MathArrays.linearCombination(a1.values[i], b1.values[i],
678 a2.values[i], b2.values[i]);
679 }
680 return result;
681 }
682
683
684 @Override
685 public Tuple linearCombination(final double a1, final Tuple b1,
686 final double a2, final Tuple b2) {
687 final Tuple result = new Tuple(field, new double[values.length]);
688 for (int i = 0; i < values.length; ++i) {
689 result.values[i] = MathArrays.linearCombination(a1, b1.values[i],
690 a2, b2.values[i]);
691 }
692 return result;
693 }
694
695
696 @Override
697 public Tuple linearCombination(final Tuple a1, final Tuple b1,
698 final Tuple a2, final Tuple b2,
699 final Tuple a3, final Tuple b3) {
700 final Tuple result = new Tuple(field, new double[values.length]);
701 for (int i = 0; i < values.length; ++i) {
702 result.values[i] = MathArrays.linearCombination(a1.values[i], b1.values[i],
703 a2.values[i], b2.values[i],
704 a3.values[i], b3.values[i]);
705 }
706 return result;
707 }
708
709
710 @Override
711 public Tuple linearCombination(final double a1, final Tuple b1,
712 final double a2, final Tuple b2,
713 final double a3, final Tuple b3) {
714 final Tuple result = new Tuple(field, new double[values.length]);
715 for (int i = 0; i < values.length; ++i) {
716 result.values[i] = MathArrays.linearCombination(a1, b1.values[i],
717 a2, b2.values[i],
718 a3, b3.values[i]);
719 }
720 return result;
721 }
722
723
724 @Override
725 public Tuple linearCombination(final Tuple a1, final Tuple b1,
726 final Tuple a2, final Tuple b2,
727 final Tuple a3, final Tuple b3,
728 final Tuple a4, final Tuple b4) {
729 final Tuple result = new Tuple(field, new double[values.length]);
730 for (int i = 0; i < values.length; ++i) {
731 result.values[i] = MathArrays.linearCombination(a1.values[i], b1.values[i],
732 a2.values[i], b2.values[i],
733 a3.values[i], b3.values[i],
734 a4.values[i], b4.values[i]);
735 }
736 return result;
737 }
738
739
740 @Override
741 public Tuple linearCombination(final double a1, final Tuple b1,
742 final double a2, final Tuple b2,
743 final double a3, final Tuple b3,
744 final double a4, final Tuple b4) {
745 final Tuple result = new Tuple(field, new double[values.length]);
746 for (int i = 0; i < values.length; ++i) {
747 result.values[i] = MathArrays.linearCombination(a1, b1.values[i],
748 a2, b2.values[i],
749 a3, b3.values[i],
750 a4, b4.values[i]);
751 }
752 return result;
753 }
754
755
756 @Override
757 public Tuple getPi() {
758 final Tuple result = new Tuple(field, new double[values.length]);
759 Arrays.fill(result.values, FastMath.PI);
760 return result;
761 }
762
763
764
765 private static class TupleField implements Field<Tuple> {
766
767
768 private final Tuple zero;
769
770
771 private final Tuple one;
772
773
774
775
776 TupleField(final int dimension) {
777 final double[] zeroData = new double[dimension];
778 final double[] oneData = new double[dimension];
779 Arrays.fill(oneData, 1.0);
780 this.zero = new Tuple(this, zeroData);
781 this.one = new Tuple(this, oneData);
782 }
783
784
785 @Override
786 public Tuple getZero() {
787 return zero;
788 }
789
790
791 @Override
792 public Tuple getOne() {
793 return one;
794 }
795
796
797 @Override
798 public Class<Tuple> getRuntimeClass() {
799 return Tuple.class;
800 }
801
802
803 @Override
804 public boolean equals(final Object other) {
805 if (other instanceof TupleField) {
806 return zero.getDimension() == ((TupleField) other).zero.getDimension();
807 } else {
808 return false;
809 }
810 }
811
812
813 @Override
814 public int hashCode() {
815 return 0x6672493d ^ zero.getDimension();
816 }
817
818 }
819
820 }