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