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