1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.linear;
18
19 import java.io.Serializable;
20 import java.util.Arrays;
21 import java.util.Iterator;
22
23 import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
24 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
25 import org.apache.commons.math4.legacy.exception.NotPositiveException;
26 import org.apache.commons.math4.legacy.exception.NullArgumentException;
27 import org.apache.commons.math4.legacy.exception.NumberIsTooLargeException;
28 import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
29 import org.apache.commons.math4.legacy.exception.OutOfRangeException;
30 import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
31 import org.apache.commons.math4.core.jdkmath.JdkMath;
32
33
34
35
36
37 public class ArrayRealVector extends RealVector implements Serializable {
38
39 private static final long serialVersionUID = -1097961340710804027L;
40
41 private static final RealVectorFormat DEFAULT_FORMAT = RealVectorFormat.getInstance();
42
43
44 private double[] data;
45
46
47
48
49
50
51
52
53
54 public ArrayRealVector() {
55 data = new double[0];
56 }
57
58
59
60
61
62
63 public ArrayRealVector(int size) {
64 data = new double[size];
65 }
66
67
68
69
70
71
72
73 public ArrayRealVector(int size, double preset) {
74 data = new double[size];
75 Arrays.fill(data, preset);
76 }
77
78
79
80
81
82
83 public ArrayRealVector(double[] d) {
84 data = d.clone();
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public ArrayRealVector(double[] d, boolean copyArray)
102 throws NullArgumentException {
103 if (d == null) {
104 throw new NullArgumentException();
105 }
106 data = copyArray ? d.clone() : d;
107 }
108
109
110
111
112
113
114
115
116
117
118
119 public ArrayRealVector(double[] d, int pos, int size)
120 throws NullArgumentException, NumberIsTooLargeException {
121 if (d == null) {
122 throw new NullArgumentException();
123 }
124 if (d.length < pos + size) {
125 throw new NumberIsTooLargeException(pos + size, d.length, true);
126 }
127 data = new double[size];
128 System.arraycopy(d, pos, data, 0, size);
129 }
130
131
132
133
134
135
136 public ArrayRealVector(Double[] d) {
137 data = new double[d.length];
138 for (int i = 0; i < d.length; i++) {
139 data[i] = d[i].doubleValue();
140 }
141 }
142
143
144
145
146
147
148
149
150
151
152
153 public ArrayRealVector(Double[] d, int pos, int size)
154 throws NullArgumentException, NumberIsTooLargeException {
155 if (d == null) {
156 throw new NullArgumentException();
157 }
158 if (d.length < pos + size) {
159 throw new NumberIsTooLargeException(pos + size, d.length, true);
160 }
161 data = new double[size];
162 for (int i = pos; i < pos + size; i++) {
163 data[i - pos] = d[i].doubleValue();
164 }
165 }
166
167
168
169
170
171
172
173 public ArrayRealVector(RealVector v) throws NullArgumentException {
174 if (v == null) {
175 throw new NullArgumentException();
176 }
177 data = new double[v.getDimension()];
178 for (int i = 0; i < data.length; ++i) {
179 data[i] = v.getEntry(i);
180 }
181 }
182
183
184
185
186
187
188
189 public ArrayRealVector(ArrayRealVector v) throws NullArgumentException {
190 this(v, true);
191 }
192
193
194
195
196
197
198
199
200 public ArrayRealVector(ArrayRealVector v, boolean deep) {
201 data = deep ? v.data.clone() : v.data;
202 }
203
204
205
206
207
208
209 public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2) {
210 data = new double[v1.data.length + v2.data.length];
211 System.arraycopy(v1.data, 0, data, 0, v1.data.length);
212 System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length);
213 }
214
215
216
217
218
219
220 public ArrayRealVector(ArrayRealVector v1, RealVector v2) {
221 final int l1 = v1.data.length;
222 final int l2 = v2.getDimension();
223 data = new double[l1 + l2];
224 System.arraycopy(v1.data, 0, data, 0, l1);
225 for (int i = 0; i < l2; ++i) {
226 data[l1 + i] = v2.getEntry(i);
227 }
228 }
229
230
231
232
233
234
235 public ArrayRealVector(RealVector v1, ArrayRealVector v2) {
236 final int l1 = v1.getDimension();
237 final int l2 = v2.data.length;
238 data = new double[l1 + l2];
239 for (int i = 0; i < l1; ++i) {
240 data[i] = v1.getEntry(i);
241 }
242 System.arraycopy(v2.data, 0, data, l1, l2);
243 }
244
245
246
247
248
249
250 public ArrayRealVector(ArrayRealVector v1, double[] v2) {
251 final int l1 = v1.getDimension();
252 final int l2 = v2.length;
253 data = new double[l1 + l2];
254 System.arraycopy(v1.data, 0, data, 0, l1);
255 System.arraycopy(v2, 0, data, l1, l2);
256 }
257
258
259
260
261
262
263 public ArrayRealVector(double[] v1, ArrayRealVector v2) {
264 final int l1 = v1.length;
265 final int l2 = v2.getDimension();
266 data = new double[l1 + l2];
267 System.arraycopy(v1, 0, data, 0, l1);
268 System.arraycopy(v2.data, 0, data, l1, l2);
269 }
270
271
272
273
274
275
276 public ArrayRealVector(double[] v1, double[] v2) {
277 final int l1 = v1.length;
278 final int l2 = v2.length;
279 data = new double[l1 + l2];
280 System.arraycopy(v1, 0, data, 0, l1);
281 System.arraycopy(v2, 0, data, l1, l2);
282 }
283
284
285 @Override
286 public ArrayRealVector copy() {
287 return new ArrayRealVector(this, true);
288 }
289
290
291 @Override
292 public ArrayRealVector add(RealVector v)
293 throws DimensionMismatchException {
294 if (v instanceof ArrayRealVector) {
295 final double[] vData = ((ArrayRealVector) v).data;
296 final int dim = vData.length;
297 checkVectorDimensions(dim);
298 ArrayRealVector result = new ArrayRealVector(dim);
299 double[] resultData = result.data;
300 for (int i = 0; i < dim; i++) {
301 resultData[i] = data[i] + vData[i];
302 }
303 return result;
304 } else {
305 checkVectorDimensions(v);
306 double[] out = data.clone();
307 Iterator<Entry> it = v.iterator();
308 while (it.hasNext()) {
309 final Entry e = it.next();
310 out[e.getIndex()] += e.getValue();
311 }
312 return new ArrayRealVector(out, false);
313 }
314 }
315
316
317 @Override
318 public ArrayRealVector subtract(RealVector v)
319 throws DimensionMismatchException {
320 if (v instanceof ArrayRealVector) {
321 final double[] vData = ((ArrayRealVector) v).data;
322 final int dim = vData.length;
323 checkVectorDimensions(dim);
324 ArrayRealVector result = new ArrayRealVector(dim);
325 double[] resultData = result.data;
326 for (int i = 0; i < dim; i++) {
327 resultData[i] = data[i] - vData[i];
328 }
329 return result;
330 } else {
331 checkVectorDimensions(v);
332 double[] out = data.clone();
333 Iterator<Entry> it = v.iterator();
334 while (it.hasNext()) {
335 final Entry e = it.next();
336 out[e.getIndex()] -= e.getValue();
337 }
338 return new ArrayRealVector(out, false);
339 }
340 }
341
342
343 @Override
344 public ArrayRealVector map(UnivariateFunction function) {
345 return copy().mapToSelf(function);
346 }
347
348
349 @Override
350 public ArrayRealVector mapToSelf(UnivariateFunction function) {
351 for (int i = 0; i < data.length; i++) {
352 data[i] = function.value(data[i]);
353 }
354 return this;
355 }
356
357
358 @Override
359 public RealVector mapAddToSelf(double d) {
360 for (int i = 0; i < data.length; i++) {
361 data[i] += d;
362 }
363 return this;
364 }
365
366
367 @Override
368 public RealVector mapSubtractToSelf(double d) {
369 for (int i = 0; i < data.length; i++) {
370 data[i] -= d;
371 }
372 return this;
373 }
374
375
376 @Override
377 public RealVector mapMultiplyToSelf(double d) {
378 for (int i = 0; i < data.length; i++) {
379 data[i] *= d;
380 }
381 return this;
382 }
383
384
385 @Override
386 public RealVector mapDivideToSelf(double d) {
387 for (int i = 0; i < data.length; i++) {
388 data[i] /= d;
389 }
390 return this;
391 }
392
393
394 @Override
395 public ArrayRealVector ebeMultiply(RealVector v)
396 throws DimensionMismatchException {
397 if (v instanceof ArrayRealVector) {
398 final double[] vData = ((ArrayRealVector) v).data;
399 final int dim = vData.length;
400 checkVectorDimensions(dim);
401 ArrayRealVector result = new ArrayRealVector(dim);
402 double[] resultData = result.data;
403 for (int i = 0; i < dim; i++) {
404 resultData[i] = data[i] * vData[i];
405 }
406 return result;
407 } else {
408 checkVectorDimensions(v);
409 double[] out = data.clone();
410 for (int i = 0; i < data.length; i++) {
411 out[i] *= v.getEntry(i);
412 }
413 return new ArrayRealVector(out, false);
414 }
415 }
416
417
418 @Override
419 public ArrayRealVector ebeDivide(RealVector v)
420 throws DimensionMismatchException {
421 if (v instanceof ArrayRealVector) {
422 final double[] vData = ((ArrayRealVector) v).data;
423 final int dim = vData.length;
424 checkVectorDimensions(dim);
425 ArrayRealVector result = new ArrayRealVector(dim);
426 double[] resultData = result.data;
427 for (int i = 0; i < dim; i++) {
428 resultData[i] = data[i] / vData[i];
429 }
430 return result;
431 } else {
432 checkVectorDimensions(v);
433 double[] out = data.clone();
434 for (int i = 0; i < data.length; i++) {
435 out[i] /= v.getEntry(i);
436 }
437 return new ArrayRealVector(out, false);
438 }
439 }
440
441
442
443
444
445
446
447 public double[] getDataRef() {
448 return data;
449 }
450
451
452 @Override
453 public double dotProduct(RealVector v) throws DimensionMismatchException {
454 if (v instanceof ArrayRealVector) {
455 final double[] vData = ((ArrayRealVector) v).data;
456 checkVectorDimensions(vData.length);
457 double dot = 0;
458 for (int i = 0; i < data.length; i++) {
459 dot += data[i] * vData[i];
460 }
461 return dot;
462 }
463 return super.dotProduct(v);
464 }
465
466
467 @Override
468 public double getNorm() {
469 double sum = 0;
470 for (double a : data) {
471 sum += a * a;
472 }
473 return JdkMath.sqrt(sum);
474 }
475
476
477 @Override
478 public double getL1Norm() {
479 double sum = 0;
480 for (double a : data) {
481 sum += JdkMath.abs(a);
482 }
483 return sum;
484 }
485
486
487 @Override
488 public double getLInfNorm() {
489 double max = 0;
490 for (double a : data) {
491 max = JdkMath.max(max, JdkMath.abs(a));
492 }
493 return max;
494 }
495
496
497 @Override
498 public double getDistance(RealVector v) throws DimensionMismatchException {
499 if (v instanceof ArrayRealVector) {
500 final double[] vData = ((ArrayRealVector) v).data;
501 checkVectorDimensions(vData.length);
502 double sum = 0;
503 for (int i = 0; i < data.length; ++i) {
504 final double delta = data[i] - vData[i];
505 sum += delta * delta;
506 }
507 return JdkMath.sqrt(sum);
508 } else {
509 checkVectorDimensions(v);
510 double sum = 0;
511 for (int i = 0; i < data.length; ++i) {
512 final double delta = data[i] - v.getEntry(i);
513 sum += delta * delta;
514 }
515 return JdkMath.sqrt(sum);
516 }
517 }
518
519
520 @Override
521 public double getL1Distance(RealVector v)
522 throws DimensionMismatchException {
523 if (v instanceof ArrayRealVector) {
524 final double[] vData = ((ArrayRealVector) v).data;
525 checkVectorDimensions(vData.length);
526 double sum = 0;
527 for (int i = 0; i < data.length; ++i) {
528 final double delta = data[i] - vData[i];
529 sum += JdkMath.abs(delta);
530 }
531 return sum;
532 } else {
533 checkVectorDimensions(v);
534 double sum = 0;
535 for (int i = 0; i < data.length; ++i) {
536 final double delta = data[i] - v.getEntry(i);
537 sum += JdkMath.abs(delta);
538 }
539 return sum;
540 }
541 }
542
543
544 @Override
545 public double getLInfDistance(RealVector v)
546 throws DimensionMismatchException {
547 if (v instanceof ArrayRealVector) {
548 final double[] vData = ((ArrayRealVector) v).data;
549 checkVectorDimensions(vData.length);
550 double max = 0;
551 for (int i = 0; i < data.length; ++i) {
552 final double delta = data[i] - vData[i];
553 max = JdkMath.max(max, JdkMath.abs(delta));
554 }
555 return max;
556 } else {
557 checkVectorDimensions(v);
558 double max = 0;
559 for (int i = 0; i < data.length; ++i) {
560 final double delta = data[i] - v.getEntry(i);
561 max = JdkMath.max(max, JdkMath.abs(delta));
562 }
563 return max;
564 }
565 }
566
567
568 @Override
569 public RealMatrix outerProduct(RealVector v) {
570 if (v instanceof ArrayRealVector) {
571 final double[] vData = ((ArrayRealVector) v).data;
572 final int m = data.length;
573 final int n = vData.length;
574 final RealMatrix out = MatrixUtils.createRealMatrix(m, n);
575 for (int i = 0; i < m; i++) {
576 for (int j = 0; j < n; j++) {
577 out.setEntry(i, j, data[i] * vData[j]);
578 }
579 }
580 return out;
581 } else {
582 final int m = data.length;
583 final int n = v.getDimension();
584 final RealMatrix out = MatrixUtils.createRealMatrix(m, n);
585 for (int i = 0; i < m; i++) {
586 for (int j = 0; j < n; j++) {
587 out.setEntry(i, j, data[i] * v.getEntry(j));
588 }
589 }
590 return out;
591 }
592 }
593
594
595 @Override
596 public double getEntry(int index) throws OutOfRangeException {
597 try {
598 return data[index];
599 } catch (IndexOutOfBoundsException e) {
600 throw new OutOfRangeException(LocalizedFormats.INDEX, index, 0,
601 getDimension() - 1);
602 }
603 }
604
605
606 @Override
607 public int getDimension() {
608 return data.length;
609 }
610
611
612 @Override
613 public RealVector append(RealVector v) {
614 if (v instanceof ArrayRealVector) {
615 return new ArrayRealVector(this, (ArrayRealVector) v);
616 }
617 return new ArrayRealVector(this, v);
618 }
619
620
621
622
623
624
625
626 public ArrayRealVector append(ArrayRealVector v) {
627 return new ArrayRealVector(this, v);
628 }
629
630
631 @Override
632 public RealVector append(double in) {
633 final double[] out = new double[data.length + 1];
634 System.arraycopy(data, 0, out, 0, data.length);
635 out[data.length] = in;
636 return new ArrayRealVector(out, false);
637 }
638
639
640 @Override
641 public RealVector getSubVector(int index, int n)
642 throws OutOfRangeException, NotPositiveException {
643 if (n < 0) {
644 throw new NotPositiveException(LocalizedFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, n);
645 }
646 ArrayRealVector out = new ArrayRealVector(n);
647 try {
648 System.arraycopy(data, index, out.data, 0, n);
649 } catch (IndexOutOfBoundsException e) {
650 checkIndex(index);
651 checkIndex(index + n - 1);
652 }
653 return out;
654 }
655
656
657 @Override
658 public void setEntry(int index, double value) throws OutOfRangeException {
659 try {
660 data[index] = value;
661 } catch (IndexOutOfBoundsException e) {
662 checkIndex(index);
663 }
664 }
665
666
667 @Override
668 public void addToEntry(int index, double increment)
669 throws OutOfRangeException {
670 try {
671 data[index] += increment;
672 } catch(IndexOutOfBoundsException e){
673 throw new OutOfRangeException(LocalizedFormats.INDEX,
674 index, 0, data.length - 1);
675 }
676 }
677
678
679 @Override
680 public void setSubVector(int index, RealVector v)
681 throws OutOfRangeException {
682 if (v instanceof ArrayRealVector) {
683 setSubVector(index, ((ArrayRealVector) v).data);
684 } else {
685 try {
686 for (int i = index; i < index + v.getDimension(); ++i) {
687 data[i] = v.getEntry(i - index);
688 }
689 } catch (IndexOutOfBoundsException e) {
690 checkIndex(index);
691 checkIndex(index + v.getDimension() - 1);
692 }
693 }
694 }
695
696
697
698
699
700
701
702
703
704 public void setSubVector(int index, double[] v)
705 throws OutOfRangeException {
706 try {
707 System.arraycopy(v, 0, data, index, v.length);
708 } catch (IndexOutOfBoundsException e) {
709 checkIndex(index);
710 checkIndex(index + v.length - 1);
711 }
712 }
713
714
715 @Override
716 public void set(double value) {
717 Arrays.fill(data, value);
718 }
719
720
721 @Override
722 public double[] toArray(){
723 return data.clone();
724 }
725
726
727 @Override
728 public String toString(){
729 return DEFAULT_FORMAT.format(this);
730 }
731
732
733
734
735
736
737
738
739 @Override
740 protected void checkVectorDimensions(RealVector v)
741 throws DimensionMismatchException {
742 checkVectorDimensions(v.getDimension());
743 }
744
745
746
747
748
749
750
751
752 @Override
753 protected void checkVectorDimensions(int n)
754 throws DimensionMismatchException {
755 if (data.length != n) {
756 throw new DimensionMismatchException(data.length, n);
757 }
758 }
759
760
761
762
763
764
765
766 @Override
767 public boolean isNaN() {
768 for (double v : data) {
769 if (Double.isNaN(v)) {
770 return true;
771 }
772 }
773 return false;
774 }
775
776
777
778
779
780
781
782
783 @Override
784 public boolean isInfinite() {
785 if (isNaN()) {
786 return false;
787 }
788
789 for (double v : data) {
790 if (Double.isInfinite(v)) {
791 return true;
792 }
793 }
794
795 return false;
796 }
797
798
799 @Override
800 public boolean equals(Object other) {
801 if (this == other) {
802 return true;
803 }
804
805 if (!(other instanceof RealVector)) {
806 return false;
807 }
808
809 RealVector rhs = (RealVector) other;
810 if (data.length != rhs.getDimension()) {
811 return false;
812 }
813
814 if (rhs.isNaN()) {
815 return this.isNaN();
816 }
817
818 for (int i = 0; i < data.length; ++i) {
819 if (data[i] != rhs.getEntry(i)) {
820 return false;
821 }
822 }
823 return true;
824 }
825
826
827
828
829 @Override
830 public int hashCode() {
831 if (isNaN()) {
832 return 9;
833 }
834 return Arrays.hashCode(data);
835 }
836
837
838 @Override
839 public ArrayRealVector combine(double a, double b, RealVector y)
840 throws DimensionMismatchException {
841 return copy().combineToSelf(a, b, y);
842 }
843
844
845 @Override
846 public ArrayRealVector combineToSelf(double a, double b, RealVector y)
847 throws DimensionMismatchException {
848 if (y instanceof ArrayRealVector) {
849 final double[] yData = ((ArrayRealVector) y).data;
850 checkVectorDimensions(yData.length);
851 for (int i = 0; i < this.data.length; i++) {
852 data[i] = a * data[i] + b * yData[i];
853 }
854 } else {
855 checkVectorDimensions(y);
856 for (int i = 0; i < this.data.length; i++) {
857 data[i] = a * data[i] + b * y.getEntry(i);
858 }
859 }
860 return this;
861 }
862
863
864 @Override
865 public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor) {
866 visitor.start(data.length, 0, data.length - 1);
867 for (int i = 0; i < data.length; i++) {
868 visitor.visit(i, data[i]);
869 }
870 return visitor.end();
871 }
872
873
874 @Override
875 public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
876 final int start, final int end) throws NumberIsTooSmallException,
877 OutOfRangeException {
878 checkIndices(start, end);
879 visitor.start(data.length, start, end);
880 for (int i = start; i <= end; i++) {
881 visitor.visit(i, data[i]);
882 }
883 return visitor.end();
884 }
885
886
887
888
889
890
891 @Override
892 public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
893 return walkInDefaultOrder(visitor);
894 }
895
896
897
898
899
900
901 @Override
902 public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
903 final int start, final int end) throws NumberIsTooSmallException,
904 OutOfRangeException {
905 return walkInDefaultOrder(visitor, start, end);
906 }
907
908
909 @Override
910 public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
911 visitor.start(data.length, 0, data.length - 1);
912 for (int i = 0; i < data.length; i++) {
913 data[i] = visitor.visit(i, data[i]);
914 }
915 return visitor.end();
916 }
917
918
919 @Override
920 public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
921 final int start, final int end) throws NumberIsTooSmallException,
922 OutOfRangeException {
923 checkIndices(start, end);
924 visitor.start(data.length, start, end);
925 for (int i = start; i <= end; i++) {
926 data[i] = visitor.visit(i, data[i]);
927 }
928 return visitor.end();
929 }
930
931
932
933
934
935
936 @Override
937 public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
938 return walkInDefaultOrder(visitor);
939 }
940
941
942
943
944
945
946 @Override
947 public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
948 final int start, final int end) throws NumberIsTooSmallException,
949 OutOfRangeException {
950 return walkInDefaultOrder(visitor, start, end);
951 }
952 }