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 }