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