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