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