source: src/main/java/agents/anac/y2019/harddealer/math3/linear/SparseFieldVector.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

  • Property svn:executable set to *
File size: 27.9 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) 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 ASF 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 * http://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 */
17package agents.anac.y2019.harddealer.math3.linear;
18
19import java.io.Serializable;
20
21import agents.anac.y2019.harddealer.math3.Field;
22import agents.anac.y2019.harddealer.math3.FieldElement;
23import agents.anac.y2019.harddealer.math3.exception.DimensionMismatchException;
24import agents.anac.y2019.harddealer.math3.exception.MathArithmeticException;
25import agents.anac.y2019.harddealer.math3.exception.NotPositiveException;
26import agents.anac.y2019.harddealer.math3.exception.NullArgumentException;
27import agents.anac.y2019.harddealer.math3.exception.NumberIsTooSmallException;
28import agents.anac.y2019.harddealer.math3.exception.OutOfRangeException;
29import agents.anac.y2019.harddealer.math3.exception.util.LocalizedFormats;
30import agents.anac.y2019.harddealer.math3.util.MathArrays;
31import agents.anac.y2019.harddealer.math3.util.MathUtils;
32import agents.anac.y2019.harddealer.math3.util.OpenIntToFieldHashMap;
33
34/**
35 * This class implements the {@link FieldVector} interface with a {@link OpenIntToFieldHashMap} backing store.
36 * <p>
37 * Caveat: This implementation assumes that, for any {@code x},
38 * the equality {@code x * 0d == 0d} holds. But it is is not true for
39 * {@code NaN}. Moreover, zero entries will lose their sign.
40 * Some operations (that involve {@code NaN} and/or infinities) may
41 * thus give incorrect results.
42 * </p>
43 * @param <T> the type of the field elements
44 * @since 2.0
45 */
46public class SparseFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable {
47 /** Serialization identifier. */
48 private static final long serialVersionUID = 7841233292190413362L;
49 /** Field to which the elements belong. */
50 private final Field<T> field;
51 /** Entries of the vector. */
52 private final OpenIntToFieldHashMap<T> entries;
53 /** Dimension of the vector. */
54 private final int virtualSize;
55
56 /**
57 * Build a 0-length vector.
58 * Zero-length vectors may be used to initialize construction of vectors
59 * by data gathering. We start with zero-length and use either the {@link
60 * #SparseFieldVector(SparseFieldVector, int)} constructor
61 * or one of the {@code append} method ({@link #append(FieldVector)} or
62 * {@link #append(SparseFieldVector)}) to gather data into this vector.
63 *
64 * @param field Field to which the elements belong.
65 */
66 public SparseFieldVector(Field<T> field) {
67 this(field, 0);
68 }
69
70
71 /**
72 * Construct a vector of zeroes.
73 *
74 * @param field Field to which the elements belong.
75 * @param dimension Size of the vector.
76 */
77 public SparseFieldVector(Field<T> field, int dimension) {
78 this.field = field;
79 virtualSize = dimension;
80 entries = new OpenIntToFieldHashMap<T>(field);
81 }
82
83 /**
84 * Build a resized vector, for use with append.
85 *
86 * @param v Original vector
87 * @param resize Amount to add.
88 */
89 protected SparseFieldVector(SparseFieldVector<T> v, int resize) {
90 field = v.field;
91 virtualSize = v.getDimension() + resize;
92 entries = new OpenIntToFieldHashMap<T>(v.entries);
93 }
94
95
96 /**
97 * Build a vector with known the sparseness (for advanced use only).
98 *
99 * @param field Field to which the elements belong.
100 * @param dimension Size of the vector.
101 * @param expectedSize Expected number of non-zero entries.
102 */
103 public SparseFieldVector(Field<T> field, int dimension, int expectedSize) {
104 this.field = field;
105 virtualSize = dimension;
106 entries = new OpenIntToFieldHashMap<T>(field,expectedSize);
107 }
108
109 /**
110 * Create from a Field array.
111 * Only non-zero entries will be stored.
112 *
113 * @param field Field to which the elements belong.
114 * @param values Set of values to create from.
115 * @exception NullArgumentException if values is null
116 */
117 public SparseFieldVector(Field<T> field, T[] values) throws NullArgumentException {
118 MathUtils.checkNotNull(values);
119 this.field = field;
120 virtualSize = values.length;
121 entries = new OpenIntToFieldHashMap<T>(field);
122 for (int key = 0; key < values.length; key++) {
123 T value = values[key];
124 entries.put(key, value);
125 }
126 }
127
128 /**
129 * Copy constructor.
130 *
131 * @param v Instance to copy.
132 */
133 public SparseFieldVector(SparseFieldVector<T> v) {
134 field = v.field;
135 virtualSize = v.getDimension();
136 entries = new OpenIntToFieldHashMap<T>(v.getEntries());
137 }
138
139 /**
140 * Get the entries of this instance.
141 *
142 * @return the entries of this instance
143 */
144 private OpenIntToFieldHashMap<T> getEntries() {
145 return entries;
146 }
147
148 /**
149 * Optimized method to add sparse vectors.
150 *
151 * @param v Vector to add.
152 * @return {@code this + v}.
153 * @throws DimensionMismatchException if {@code v} is not the same size as
154 * {@code this}.
155 */
156 public FieldVector<T> add(SparseFieldVector<T> v)
157 throws DimensionMismatchException {
158 checkVectorDimensions(v.getDimension());
159 SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
160 OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
161 while (iter.hasNext()) {
162 iter.advance();
163 int key = iter.key();
164 T value = iter.value();
165 if (entries.containsKey(key)) {
166 res.setEntry(key, entries.get(key).add(value));
167 } else {
168 res.setEntry(key, value);
169 }
170 }
171 return res;
172
173 }
174
175 /**
176 * Construct a vector by appending a vector to this vector.
177 *
178 * @param v Vector to append to this one.
179 * @return a new vector.
180 */
181 public FieldVector<T> append(SparseFieldVector<T> v) {
182 SparseFieldVector<T> res = new SparseFieldVector<T>(this, v.getDimension());
183 OpenIntToFieldHashMap<T>.Iterator iter = v.entries.iterator();
184 while (iter.hasNext()) {
185 iter.advance();
186 res.setEntry(iter.key() + virtualSize, iter.value());
187 }
188 return res;
189 }
190
191 /** {@inheritDoc} */
192 public FieldVector<T> append(FieldVector<T> v) {
193 if (v instanceof SparseFieldVector<?>) {
194 return append((SparseFieldVector<T>) v);
195 } else {
196 final int n = v.getDimension();
197 FieldVector<T> res = new SparseFieldVector<T>(this, n);
198 for (int i = 0; i < n; i++) {
199 res.setEntry(i + virtualSize, v.getEntry(i));
200 }
201 return res;
202 }
203 }
204
205 /** {@inheritDoc}
206 * @exception NullArgumentException if d is null
207 */
208 public FieldVector<T> append(T d) throws NullArgumentException {
209 MathUtils.checkNotNull(d);
210 FieldVector<T> res = new SparseFieldVector<T>(this, 1);
211 res.setEntry(virtualSize, d);
212 return res;
213 }
214
215 /** {@inheritDoc} */
216 public FieldVector<T> copy() {
217 return new SparseFieldVector<T>(this);
218 }
219
220 /** {@inheritDoc} */
221 public T dotProduct(FieldVector<T> v) throws DimensionMismatchException {
222 checkVectorDimensions(v.getDimension());
223 T res = field.getZero();
224 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
225 while (iter.hasNext()) {
226 iter.advance();
227 res = res.add(v.getEntry(iter.key()).multiply(iter.value()));
228 }
229 return res;
230 }
231
232 /** {@inheritDoc} */
233 public FieldVector<T> ebeDivide(FieldVector<T> v)
234 throws DimensionMismatchException, MathArithmeticException {
235 checkVectorDimensions(v.getDimension());
236 SparseFieldVector<T> res = new SparseFieldVector<T>(this);
237 OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
238 while (iter.hasNext()) {
239 iter.advance();
240 res.setEntry(iter.key(), iter.value().divide(v.getEntry(iter.key())));
241 }
242 return res;
243 }
244
245 /** {@inheritDoc} */
246 public FieldVector<T> ebeMultiply(FieldVector<T> v)
247 throws DimensionMismatchException {
248 checkVectorDimensions(v.getDimension());
249 SparseFieldVector<T> res = new SparseFieldVector<T>(this);
250 OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
251 while (iter.hasNext()) {
252 iter.advance();
253 res.setEntry(iter.key(), iter.value().multiply(v.getEntry(iter.key())));
254 }
255 return res;
256 }
257
258 /**
259 * {@inheritDoc}
260 *
261 * @deprecated as of 3.1, to be removed in 4.0. Please use the {@link #toArray()} method instead.
262 */
263 @Deprecated
264 public T[] getData() {
265 return toArray();
266 }
267
268 /** {@inheritDoc} */
269 public int getDimension() {
270 return virtualSize;
271 }
272
273 /** {@inheritDoc} */
274 public T getEntry(int index) throws OutOfRangeException {
275 checkIndex(index);
276 return entries.get(index);
277 }
278
279 /** {@inheritDoc} */
280 public Field<T> getField() {
281 return field;
282 }
283
284 /** {@inheritDoc} */
285 public FieldVector<T> getSubVector(int index, int n)
286 throws OutOfRangeException, NotPositiveException {
287 if (n < 0) {
288 throw new NotPositiveException(LocalizedFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, n);
289 }
290 checkIndex(index);
291 checkIndex(index + n - 1);
292 SparseFieldVector<T> res = new SparseFieldVector<T>(field,n);
293 int end = index + n;
294 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
295 while (iter.hasNext()) {
296 iter.advance();
297 int key = iter.key();
298 if (key >= index && key < end) {
299 res.setEntry(key - index, iter.value());
300 }
301 }
302 return res;
303 }
304
305 /** {@inheritDoc} */
306 public FieldVector<T> mapAdd(T d) throws NullArgumentException {
307 return copy().mapAddToSelf(d);
308 }
309
310 /** {@inheritDoc} */
311 public FieldVector<T> mapAddToSelf(T d) throws NullArgumentException {
312 for (int i = 0; i < virtualSize; i++) {
313 setEntry(i, getEntry(i).add(d));
314 }
315 return this;
316 }
317
318 /** {@inheritDoc} */
319 public FieldVector<T> mapDivide(T d)
320 throws NullArgumentException, MathArithmeticException {
321 return copy().mapDivideToSelf(d);
322 }
323
324 /** {@inheritDoc} */
325 public FieldVector<T> mapDivideToSelf(T d)
326 throws NullArgumentException, MathArithmeticException {
327 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
328 while (iter.hasNext()) {
329 iter.advance();
330 entries.put(iter.key(), iter.value().divide(d));
331 }
332 return this;
333 }
334
335 /** {@inheritDoc} */
336 public FieldVector<T> mapInv() throws MathArithmeticException {
337 return copy().mapInvToSelf();
338 }
339
340 /** {@inheritDoc} */
341 public FieldVector<T> mapInvToSelf() throws MathArithmeticException {
342 for (int i = 0; i < virtualSize; i++) {
343 setEntry(i, field.getOne().divide(getEntry(i)));
344 }
345 return this;
346 }
347
348 /** {@inheritDoc} */
349 public FieldVector<T> mapMultiply(T d) throws NullArgumentException {
350 return copy().mapMultiplyToSelf(d);
351 }
352
353 /** {@inheritDoc} */
354 public FieldVector<T> mapMultiplyToSelf(T d) throws NullArgumentException {
355 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
356 while (iter.hasNext()) {
357 iter.advance();
358 entries.put(iter.key(), iter.value().multiply(d));
359 }
360 return this;
361 }
362
363 /** {@inheritDoc} */
364 public FieldVector<T> mapSubtract(T d) throws NullArgumentException {
365 return copy().mapSubtractToSelf(d);
366 }
367
368 /** {@inheritDoc} */
369 public FieldVector<T> mapSubtractToSelf(T d) throws NullArgumentException {
370 return mapAddToSelf(field.getZero().subtract(d));
371 }
372
373 /**
374 * Optimized method to compute outer product when both vectors are sparse.
375 * @param v vector with which outer product should be computed
376 * @return the matrix outer product between instance and v
377 */
378 public FieldMatrix<T> outerProduct(SparseFieldVector<T> v) {
379 final int n = v.getDimension();
380 SparseFieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, n);
381 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
382 while (iter.hasNext()) {
383 iter.advance();
384 OpenIntToFieldHashMap<T>.Iterator iter2 = v.entries.iterator();
385 while (iter2.hasNext()) {
386 iter2.advance();
387 res.setEntry(iter.key(), iter2.key(), iter.value().multiply(iter2.value()));
388 }
389 }
390 return res;
391 }
392
393 /** {@inheritDoc} */
394 public FieldMatrix<T> outerProduct(FieldVector<T> v) {
395 if (v instanceof SparseFieldVector<?>) {
396 return outerProduct((SparseFieldVector<T>)v);
397 } else {
398 final int n = v.getDimension();
399 FieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, n);
400 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
401 while (iter.hasNext()) {
402 iter.advance();
403 int row = iter.key();
404 FieldElement<T>value = iter.value();
405 for (int col = 0; col < n; col++) {
406 res.setEntry(row, col, value.multiply(v.getEntry(col)));
407 }
408 }
409 return res;
410 }
411 }
412
413 /** {@inheritDoc} */
414 public FieldVector<T> projection(FieldVector<T> v)
415 throws DimensionMismatchException, MathArithmeticException {
416 checkVectorDimensions(v.getDimension());
417 return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
418 }
419
420 /** {@inheritDoc}
421 * @exception NullArgumentException if value is null
422 */
423 public void set(T value) {
424 MathUtils.checkNotNull(value);
425 for (int i = 0; i < virtualSize; i++) {
426 setEntry(i, value);
427 }
428 }
429
430 /** {@inheritDoc}
431 * @exception NullArgumentException if value is null
432 */
433 public void setEntry(int index, T value) throws NullArgumentException, OutOfRangeException {
434 MathUtils.checkNotNull(value);
435 checkIndex(index);
436 entries.put(index, value);
437 }
438
439 /** {@inheritDoc} */
440 public void setSubVector(int index, FieldVector<T> v)
441 throws OutOfRangeException {
442 checkIndex(index);
443 checkIndex(index + v.getDimension() - 1);
444 final int n = v.getDimension();
445 for (int i = 0; i < n; i++) {
446 setEntry(i + index, v.getEntry(i));
447 }
448 }
449
450 /**
451 * Optimized method to compute {@code this} minus {@code v}.
452 * @param v vector to be subtracted
453 * @return {@code this - v}
454 * @throws DimensionMismatchException if {@code v} is not the same size as
455 * {@code this}.
456 */
457 public SparseFieldVector<T> subtract(SparseFieldVector<T> v)
458 throws DimensionMismatchException {
459 checkVectorDimensions(v.getDimension());
460 SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
461 OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
462 while (iter.hasNext()) {
463 iter.advance();
464 int key = iter.key();
465 if (entries.containsKey(key)) {
466 res.setEntry(key, entries.get(key).subtract(iter.value()));
467 } else {
468 res.setEntry(key, field.getZero().subtract(iter.value()));
469 }
470 }
471 return res;
472 }
473
474 /** {@inheritDoc} */
475 public FieldVector<T> subtract(FieldVector<T> v)
476 throws DimensionMismatchException {
477 if (v instanceof SparseFieldVector<?>) {
478 return subtract((SparseFieldVector<T>)v);
479 } else {
480 final int n = v.getDimension();
481 checkVectorDimensions(n);
482 SparseFieldVector<T> res = new SparseFieldVector<T>(this);
483 for (int i = 0; i < n; i++) {
484 if (entries.containsKey(i)) {
485 res.setEntry(i, entries.get(i).subtract(v.getEntry(i)));
486 } else {
487 res.setEntry(i, field.getZero().subtract(v.getEntry(i)));
488 }
489 }
490 return res;
491 }
492 }
493
494 /** {@inheritDoc} */
495 public T[] toArray() {
496 T[] res = MathArrays.buildArray(field, virtualSize);
497 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
498 while (iter.hasNext()) {
499 iter.advance();
500 res[iter.key()] = iter.value();
501 }
502 return res;
503 }
504
505 /**
506 * Check whether an index is valid.
507 *
508 * @param index Index to check.
509 * @throws OutOfRangeException if the index is not valid.
510 */
511 private void checkIndex(final int index) throws OutOfRangeException {
512 if (index < 0 || index >= getDimension()) {
513 throw new OutOfRangeException(index, 0, getDimension() - 1);
514 }
515 }
516
517 /**
518 * Checks that the indices of a subvector are valid.
519 *
520 * @param start the index of the first entry of the subvector
521 * @param end the index of the last entry of the subvector (inclusive)
522 * @throws OutOfRangeException if {@code start} of {@code end} are not valid
523 * @throws NumberIsTooSmallException if {@code end < start}
524 * @since 3.3
525 */
526 private void checkIndices(final int start, final int end)
527 throws NumberIsTooSmallException, OutOfRangeException {
528 final int dim = getDimension();
529 if ((start < 0) || (start >= dim)) {
530 throw new OutOfRangeException(LocalizedFormats.INDEX, start, 0,
531 dim - 1);
532 }
533 if ((end < 0) || (end >= dim)) {
534 throw new OutOfRangeException(LocalizedFormats.INDEX, end, 0,
535 dim - 1);
536 }
537 if (end < start) {
538 throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
539 end, start, false);
540 }
541 }
542
543 /**
544 * Check if instance dimension is equal to some expected value.
545 *
546 * @param n Expected dimension.
547 * @throws DimensionMismatchException if the dimensions do not match.
548 */
549 protected void checkVectorDimensions(int n)
550 throws DimensionMismatchException {
551 if (getDimension() != n) {
552 throw new DimensionMismatchException(getDimension(), n);
553 }
554 }
555
556 /** {@inheritDoc} */
557 public FieldVector<T> add(FieldVector<T> v) throws DimensionMismatchException {
558 if (v instanceof SparseFieldVector<?>) {
559 return add((SparseFieldVector<T>) v);
560 } else {
561 final int n = v.getDimension();
562 checkVectorDimensions(n);
563 SparseFieldVector<T> res = new SparseFieldVector<T>(field,
564 getDimension());
565 for (int i = 0; i < n; i++) {
566 res.setEntry(i, v.getEntry(i).add(getEntry(i)));
567 }
568 return res;
569 }
570 }
571
572 /**
573 * Visits (but does not alter) all entries of this vector in default order
574 * (increasing index).
575 *
576 * @param visitor the visitor to be used to process the entries of this
577 * vector
578 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
579 * at the end of the walk
580 * @since 3.3
581 */
582 public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor) {
583 final int dim = getDimension();
584 visitor.start(dim, 0, dim - 1);
585 for (int i = 0; i < dim; i++) {
586 visitor.visit(i, getEntry(i));
587 }
588 return visitor.end();
589 }
590
591 /**
592 * Visits (but does not alter) some entries of this vector in default order
593 * (increasing index).
594 *
595 * @param visitor visitor to be used to process the entries of this vector
596 * @param start the index of the first entry to be visited
597 * @param end the index of the last entry to be visited (inclusive)
598 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
599 * at the end of the walk
600 * @throws NumberIsTooSmallException if {@code end < start}.
601 * @throws OutOfRangeException if the indices are not valid.
602 * @since 3.3
603 */
604 public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor,
605 final int start, final int end)
606 throws NumberIsTooSmallException, OutOfRangeException {
607 checkIndices(start, end);
608 visitor.start(getDimension(), start, end);
609 for (int i = start; i <= end; i++) {
610 visitor.visit(i, getEntry(i));
611 }
612 return visitor.end();
613 }
614
615 /**
616 * Visits (but does not alter) all entries of this vector in optimized
617 * order. The order in which the entries are visited is selected so as to
618 * lead to the most efficient implementation; it might depend on the
619 * concrete implementation of this abstract class.
620 *
621 * @param visitor the visitor to be used to process the entries of this
622 * vector
623 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
624 * at the end of the walk
625 * @since 3.3
626 */
627 public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor) {
628 return walkInDefaultOrder(visitor);
629 }
630
631 /**
632 * Visits (but does not alter) some entries of this vector in optimized
633 * order. The order in which the entries are visited is selected so as to
634 * lead to the most efficient implementation; it might depend on the
635 * concrete implementation of this abstract class.
636 *
637 * @param visitor visitor to be used to process the entries of this vector
638 * @param start the index of the first entry to be visited
639 * @param end the index of the last entry to be visited (inclusive)
640 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
641 * at the end of the walk
642 * @throws NumberIsTooSmallException if {@code end < start}.
643 * @throws OutOfRangeException if the indices are not valid.
644 * @since 3.3
645 */
646 public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor,
647 final int start, final int end)
648 throws NumberIsTooSmallException, OutOfRangeException {
649 return walkInDefaultOrder(visitor, start, end);
650 }
651
652 /**
653 * Visits (and possibly alters) all entries of this vector in default order
654 * (increasing index).
655 *
656 * @param visitor the visitor to be used to process and modify the entries
657 * of this vector
658 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
659 * at the end of the walk
660 * @since 3.3
661 */
662 public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor) {
663 final int dim = getDimension();
664 visitor.start(dim, 0, dim - 1);
665 for (int i = 0; i < dim; i++) {
666 setEntry(i, visitor.visit(i, getEntry(i)));
667 }
668 return visitor.end();
669 }
670
671 /**
672 * Visits (and possibly alters) some entries of this vector in default order
673 * (increasing index).
674 *
675 * @param visitor visitor to be used to process the entries of this vector
676 * @param start the index of the first entry to be visited
677 * @param end the index of the last entry to be visited (inclusive)
678 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
679 * at the end of the walk
680 * @throws NumberIsTooSmallException if {@code end < start}.
681 * @throws OutOfRangeException if the indices are not valid.
682 * @since 3.3
683 */
684 public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor,
685 final int start, final int end)
686 throws NumberIsTooSmallException, OutOfRangeException {
687 checkIndices(start, end);
688 visitor.start(getDimension(), start, end);
689 for (int i = start; i <= end; i++) {
690 setEntry(i, visitor.visit(i, getEntry(i)));
691 }
692 return visitor.end();
693 }
694
695 /**
696 * Visits (and possibly alters) all entries of this vector in optimized
697 * order. The order in which the entries are visited is selected so as to
698 * lead to the most efficient implementation; it might depend on the
699 * concrete implementation of this abstract class.
700 *
701 * @param visitor the visitor to be used to process the entries of this
702 * vector
703 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
704 * at the end of the walk
705 * @since 3.3
706 */
707 public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor) {
708 return walkInDefaultOrder(visitor);
709 }
710
711 /**
712 * Visits (and possibly change) some entries of this vector in optimized
713 * order. The order in which the entries are visited is selected so as to
714 * lead to the most efficient implementation; it might depend on the
715 * concrete implementation of this abstract class.
716 *
717 * @param visitor visitor to be used to process the entries of this vector
718 * @param start the index of the first entry to be visited
719 * @param end the index of the last entry to be visited (inclusive)
720 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
721 * at the end of the walk
722 * @throws NumberIsTooSmallException if {@code end < start}.
723 * @throws OutOfRangeException if the indices are not valid.
724 * @since 3.3
725 */
726 public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor,
727 final int start, final int end)
728 throws NumberIsTooSmallException, OutOfRangeException {
729 return walkInDefaultOrder(visitor, start, end);
730 }
731
732 /** {@inheritDoc} */
733 @Override
734 public int hashCode() {
735 final int prime = 31;
736 int result = 1;
737 result = prime * result + ((field == null) ? 0 : field.hashCode());
738 result = prime * result + virtualSize;
739 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
740 while (iter.hasNext()) {
741 iter.advance();
742 int temp = iter.value().hashCode();
743 result = prime * result + temp;
744 }
745 return result;
746 }
747
748
749 /** {@inheritDoc} */
750 @Override
751 public boolean equals(Object obj) {
752
753 if (this == obj) {
754 return true;
755 }
756
757 if (!(obj instanceof SparseFieldVector<?>)) {
758 return false;
759 }
760
761 @SuppressWarnings("unchecked") // OK, because "else if" check below ensures that
762 // other must be the same type as this
763 SparseFieldVector<T> other = (SparseFieldVector<T>) obj;
764 if (field == null) {
765 if (other.field != null) {
766 return false;
767 }
768 } else if (!field.equals(other.field)) {
769 return false;
770 }
771 if (virtualSize != other.virtualSize) {
772 return false;
773 }
774
775 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
776 while (iter.hasNext()) {
777 iter.advance();
778 T test = other.getEntry(iter.key());
779 if (!test.equals(iter.value())) {
780 return false;
781 }
782 }
783 iter = other.getEntries().iterator();
784 while (iter.hasNext()) {
785 iter.advance();
786 T test = iter.value();
787 if (!test.equals(getEntry(iter.key()))) {
788 return false;
789 }
790 }
791 return true;
792 }
793}
Note: See TracBrowser for help on using the repository browser.