View Javadoc
1   /*
2    * Licensed to the Hipparchus project under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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   * This class allows to perform the same computation of all components of a Tuple at once.
27   * @since 1.2
28   */
29  public class Tuple implements CalculusFieldElement<Tuple> {
30  
31      /** Components of the tuple. */
32      private final double[] values;
33  
34      /** Field the instance belongs to. */
35      private final transient TupleField field;
36  
37      /** Creates a new instance from its components.
38       * @param x components of the tuple
39       */
40      public Tuple(final double... x) {
41          this(new TupleField(x.length), x.clone());
42      }
43  
44      /** Creates a new instance from its components.
45       * @param field field the instance belongs to
46       * @param x components of the tuple (beware, it is <em>not</em> copied, it is shared with caller)
47       */
48      private Tuple(final TupleField field, final double[] x) {// NOPMD - storing user-supplied array is intentional and documented here
49          this.values = x;
50          this.field  = field;
51      }
52  
53      /** {@inheritDoc} */
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      /** Get the dimension of the tuple.
62       * @return dimension of the tuple
63       */
64      public int getDimension() {
65          return values.length;
66      }
67  
68      /** Get one component of the tuple.
69       * @param index index of the component, between 0 and {@link #getDimension() getDimension()} - 1
70       * @return value of the component
71       */
72      public double getComponent(final int index) {
73          return values[index];
74      }
75  
76      /** Get all components of the tuple.
77       * @return all components
78       */
79      public double[] getComponents() {
80          return values.clone();
81      }
82  
83      /** {@inheritDoc} */
84      @Override
85      public Field<Tuple> getField() {
86          return field;
87      }
88  
89      /** {@inheritDoc} */
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      /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
140     @Override
141     public Tuple square() {
142         return multiply(this);
143     }
144 
145     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
182     @Override
183     public int hashCode() {
184         return  0x34b1a444 + Arrays.hashCode(values);
185     }
186 
187     /** {@inheritDoc} */
188     @Override
189     public double getReal() {
190         return values[0];
191     }
192 
193     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** Field for {link Tuple} instances.
770      */
771     private static class TupleField implements Field<Tuple> {
772 
773         /** Constant function evaluating to 0.0. */
774         private final Tuple zero;
775 
776         /** Constant function evaluating to 1.0. */
777         private final Tuple one;
778 
779         /** Simple constructor.
780          * @param dimension dimension of the tuple
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         /** {@inheritDoc} */
791         @Override
792         public Tuple getZero() {
793             return zero;
794         }
795 
796         /** {@inheritDoc} */
797         @Override
798         public Tuple getOne() {
799             return one;
800         }
801 
802         /** {@inheritDoc} */
803         @Override
804         public Class<Tuple> getRuntimeClass() {
805             return Tuple.class;
806         }
807 
808         /** {@inheritDoc} */
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         /** {@inheritDoc} */
819         @Override
820         public int hashCode() {
821             return 0x6672493d ^ zero.getDimension();
822         }
823 
824     }
825 
826 }