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