001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math3.linear;
018
019 import java.io.Serializable;
020 import java.util.Arrays;
021 import java.util.Iterator;
022
023 import org.apache.commons.math3.analysis.UnivariateFunction;
024 import org.apache.commons.math3.exception.NotPositiveException;
025 import org.apache.commons.math3.exception.NullArgumentException;
026 import org.apache.commons.math3.exception.DimensionMismatchException;
027 import org.apache.commons.math3.exception.NumberIsTooLargeException;
028 import org.apache.commons.math3.exception.NumberIsTooSmallException;
029 import org.apache.commons.math3.exception.OutOfRangeException;
030 import org.apache.commons.math3.exception.util.LocalizedFormats;
031 import org.apache.commons.math3.util.MathUtils;
032 import org.apache.commons.math3.util.FastMath;
033
034 /**
035 * This class implements the {@link RealVector} interface with a double array.
036 * @version $Id: ArrayRealVector.java 1416643 2012-12-03 19:37:14Z tn $
037 * @since 2.0
038 */
039 public class ArrayRealVector extends RealVector implements Serializable {
040 /** Serializable version identifier. */
041 private static final long serialVersionUID = -1097961340710804027L;
042 /** Default format. */
043 private static final RealVectorFormat DEFAULT_FORMAT = RealVectorFormat.getInstance();
044
045 /** Entries of the vector. */
046 private double data[];
047
048 /**
049 * Build a 0-length vector.
050 * Zero-length vectors may be used to initialized construction of vectors
051 * by data gathering. We start with zero-length and use either the {@link
052 * #ArrayRealVector(ArrayRealVector, ArrayRealVector)} constructor
053 * or one of the {@code append} method ({@link #append(double)},
054 * {@link #append(ArrayRealVector)}) to gather data into this vector.
055 */
056 public ArrayRealVector() {
057 data = new double[0];
058 }
059
060 /**
061 * Construct a vector of zeroes.
062 *
063 * @param size Size of the vector.
064 */
065 public ArrayRealVector(int size) {
066 data = new double[size];
067 }
068
069 /**
070 * Construct a vector with preset values.
071 *
072 * @param size Size of the vector
073 * @param preset All entries will be set with this value.
074 */
075 public ArrayRealVector(int size, double preset) {
076 data = new double[size];
077 Arrays.fill(data, preset);
078 }
079
080 /**
081 * Construct a vector from an array, copying the input array.
082 *
083 * @param d Array.
084 */
085 public ArrayRealVector(double[] d) {
086 data = d.clone();
087 }
088
089 /**
090 * Create a new ArrayRealVector using the input array as the underlying
091 * data array.
092 * If an array is built specially in order to be embedded in a
093 * ArrayRealVector and not used directly, the {@code copyArray} may be
094 * set to {@code false}. This will prevent the copying and improve
095 * performance as no new array will be built and no data will be copied.
096 *
097 * @param d Data for the new vector.
098 * @param copyArray if {@code true}, the input array will be copied,
099 * otherwise it will be referenced.
100 * @throws NullArgumentException if {@code d} is {@code null}.
101 * @see #ArrayRealVector(double[])
102 */
103 public ArrayRealVector(double[] d, boolean copyArray)
104 throws NullArgumentException {
105 if (d == null) {
106 throw new NullArgumentException();
107 }
108 data = copyArray ? d.clone() : d;
109 }
110
111 /**
112 * Construct a vector from part of a array.
113 *
114 * @param d Array.
115 * @param pos Position of first entry.
116 * @param size Number of entries to copy.
117 * @throws NullArgumentException if {@code d} is {@code null}.
118 * @throws NumberIsTooLargeException if the size of {@code d} is less
119 * than {@code pos + size}.
120 */
121 public ArrayRealVector(double[] d, int pos, int size)
122 throws NullArgumentException, NumberIsTooLargeException {
123 if (d == null) {
124 throw new NullArgumentException();
125 }
126 if (d.length < pos + size) {
127 throw new NumberIsTooLargeException(pos + size, d.length, true);
128 }
129 data = new double[size];
130 System.arraycopy(d, pos, data, 0, size);
131 }
132
133 /**
134 * Construct a vector from an array.
135 *
136 * @param d Array of {@code Double}s.
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 * Construct a vector from part of an array.
147 *
148 * @param d Array.
149 * @param pos Position of first entry.
150 * @param size Number of entries to copy.
151 * @throws NullArgumentException if {@code d} is {@code null}.
152 * @throws NumberIsTooLargeException if the size of {@code d} is less
153 * than {@code pos + size}.
154 */
155 public ArrayRealVector(Double[] d, int pos, int size)
156 throws NullArgumentException, NumberIsTooLargeException {
157 if (d == null) {
158 throw new NullArgumentException();
159 }
160 if (d.length < pos + size) {
161 throw new NumberIsTooLargeException(pos + size, d.length, true);
162 }
163 data = new double[size];
164 for (int i = pos; i < pos + size; i++) {
165 data[i - pos] = d[i].doubleValue();
166 }
167 }
168
169 /**
170 * Construct a vector from another vector, using a deep copy.
171 *
172 * @param v vector to copy.
173 * @throws NullArgumentException if {@code v} is {@code null}.
174 */
175 public ArrayRealVector(RealVector v) throws NullArgumentException {
176 if (v == null) {
177 throw new NullArgumentException();
178 }
179 data = new double[v.getDimension()];
180 for (int i = 0; i < data.length; ++i) {
181 data[i] = v.getEntry(i);
182 }
183 }
184
185 /**
186 * Construct a vector from another vector, using a deep copy.
187 *
188 * @param v Vector to copy.
189 * @throws NullArgumentException if {@code v} is {@code null}.
190 */
191 public ArrayRealVector(ArrayRealVector v) throws NullArgumentException {
192 this(v, true);
193 }
194
195 /**
196 * Construct a vector from another vector.
197 *
198 * @param v Vector to copy.
199 * @param deep If {@code true} perform a deep copy, otherwise perform a
200 * shallow copy.
201 */
202 public ArrayRealVector(ArrayRealVector v, boolean deep) {
203 data = deep ? v.data.clone() : v.data;
204 }
205
206 /**
207 * Construct a vector by appending one vector to another vector.
208 * @param v1 First vector (will be put in front of the new vector).
209 * @param v2 Second vector (will be put at back of the new vector).
210 */
211 public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2) {
212 data = new double[v1.data.length + v2.data.length];
213 System.arraycopy(v1.data, 0, data, 0, v1.data.length);
214 System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length);
215 }
216
217 /**
218 * Construct a vector by appending one vector to another vector.
219 * @param v1 First vector (will be put in front of the new vector).
220 * @param v2 Second vector (will be put at back of the new vector).
221 */
222 public ArrayRealVector(ArrayRealVector v1, RealVector v2) {
223 final int l1 = v1.data.length;
224 final int l2 = v2.getDimension();
225 data = new double[l1 + l2];
226 System.arraycopy(v1.data, 0, data, 0, l1);
227 for (int i = 0; i < l2; ++i) {
228 data[l1 + i] = v2.getEntry(i);
229 }
230 }
231
232 /**
233 * Construct a vector by appending one vector to another vector.
234 * @param v1 First vector (will be put in front of the new vector).
235 * @param v2 Second vector (will be put at back of the new vector).
236 */
237 public ArrayRealVector(RealVector v1, ArrayRealVector v2) {
238 final int l1 = v1.getDimension();
239 final int l2 = v2.data.length;
240 data = new double[l1 + l2];
241 for (int i = 0; i < l1; ++i) {
242 data[i] = v1.getEntry(i);
243 }
244 System.arraycopy(v2.data, 0, data, l1, l2);
245 }
246
247 /**
248 * Construct a vector by appending one vector to another vector.
249 * @param v1 First vector (will be put in front of the new vector).
250 * @param v2 Second vector (will be put at back of the new vector).
251 */
252 public ArrayRealVector(ArrayRealVector v1, double[] v2) {
253 final int l1 = v1.getDimension();
254 final int l2 = v2.length;
255 data = new double[l1 + l2];
256 System.arraycopy(v1.data, 0, data, 0, l1);
257 System.arraycopy(v2, 0, data, l1, l2);
258 }
259
260 /**
261 * Construct a vector by appending one vector to another vector.
262 * @param v1 First vector (will be put in front of the new vector).
263 * @param v2 Second vector (will be put at back of the new vector).
264 */
265 public ArrayRealVector(double[] v1, ArrayRealVector v2) {
266 final int l1 = v1.length;
267 final int l2 = v2.getDimension();
268 data = new double[l1 + l2];
269 System.arraycopy(v1, 0, data, 0, l1);
270 System.arraycopy(v2.data, 0, data, l1, l2);
271 }
272
273 /**
274 * Construct a vector by appending one vector to another vector.
275 * @param v1 first vector (will be put in front of the new vector)
276 * @param v2 second vector (will be put at back of the new vector)
277 */
278 public ArrayRealVector(double[] v1, double[] v2) {
279 final int l1 = v1.length;
280 final int l2 = v2.length;
281 data = new double[l1 + l2];
282 System.arraycopy(v1, 0, data, 0, l1);
283 System.arraycopy(v2, 0, data, l1, l2);
284 }
285
286 /** {@inheritDoc} */
287 @Override
288 public ArrayRealVector copy() {
289 return new ArrayRealVector(this, true);
290 }
291
292 /** {@inheritDoc} */
293 @Override
294 public ArrayRealVector add(RealVector v)
295 throws DimensionMismatchException {
296 if (v instanceof ArrayRealVector) {
297 final double[] vData = ((ArrayRealVector) v).data;
298 final int dim = vData.length;
299 checkVectorDimensions(dim);
300 ArrayRealVector result = new ArrayRealVector(dim);
301 double[] resultData = result.data;
302 for (int i = 0; i < dim; i++) {
303 resultData[i] = data[i] + vData[i];
304 }
305 return result;
306 } else {
307 checkVectorDimensions(v);
308 double[] out = data.clone();
309 Iterator<Entry> it = v.iterator();
310 while (it.hasNext()) {
311 final Entry e = it.next();
312 out[e.getIndex()] += e.getValue();
313 }
314 return new ArrayRealVector(out, false);
315 }
316 }
317
318 /** {@inheritDoc} */
319 @Override
320 public ArrayRealVector subtract(RealVector v)
321 throws DimensionMismatchException {
322 if (v instanceof ArrayRealVector) {
323 final double[] vData = ((ArrayRealVector) v).data;
324 final int dim = vData.length;
325 checkVectorDimensions(dim);
326 ArrayRealVector result = new ArrayRealVector(dim);
327 double[] resultData = result.data;
328 for (int i = 0; i < dim; i++) {
329 resultData[i] = data[i] - vData[i];
330 }
331 return result;
332 } else {
333 checkVectorDimensions(v);
334 double[] out = data.clone();
335 Iterator<Entry> it = v.iterator();
336 while (it.hasNext()) {
337 final Entry e = it.next();
338 out[e.getIndex()] -= e.getValue();
339 }
340 return new ArrayRealVector(out, false);
341 }
342 }
343
344 /** {@inheritDoc} */
345 @Override
346 public ArrayRealVector map(UnivariateFunction function) {
347 return copy().mapToSelf(function);
348 }
349
350 /** {@inheritDoc} */
351 @Override
352 public ArrayRealVector mapToSelf(UnivariateFunction function) {
353 for (int i = 0; i < data.length; i++) {
354 data[i] = function.value(data[i]);
355 }
356 return this;
357 }
358
359 /** {@inheritDoc} */
360 @Override
361 public RealVector mapAddToSelf(double d) {
362 for (int i = 0; i < data.length; i++) {
363 data[i] = data[i] + d;
364 }
365 return this;
366 }
367
368 /** {@inheritDoc} */
369 @Override
370 public RealVector mapSubtractToSelf(double d) {
371 for (int i = 0; i < data.length; i++) {
372 data[i] = data[i] - d;
373 }
374 return this;
375 }
376
377 /** {@inheritDoc} */
378 @Override
379 public RealVector mapMultiplyToSelf(double d) {
380 for (int i = 0; i < data.length; i++) {
381 data[i] = data[i] * d;
382 }
383 return this;
384 }
385
386 /** {@inheritDoc} */
387 @Override
388 public RealVector mapDivideToSelf(double d) {
389 for (int i = 0; i < data.length; i++) {
390 data[i] = data[i] / d;
391 }
392 return this;
393 }
394
395 /** {@inheritDoc} */
396 @Override
397 public ArrayRealVector ebeMultiply(RealVector v)
398 throws DimensionMismatchException {
399 if (v instanceof ArrayRealVector) {
400 final double[] vData = ((ArrayRealVector) v).data;
401 final int dim = vData.length;
402 checkVectorDimensions(dim);
403 ArrayRealVector result = new ArrayRealVector(dim);
404 double[] resultData = result.data;
405 for (int i = 0; i < dim; i++) {
406 resultData[i] = data[i] * vData[i];
407 }
408 return result;
409 } else {
410 checkVectorDimensions(v);
411 double[] out = data.clone();
412 for (int i = 0; i < data.length; i++) {
413 out[i] *= v.getEntry(i);
414 }
415 return new ArrayRealVector(out, false);
416 }
417 }
418
419 /** {@inheritDoc} */
420 @Override
421 public ArrayRealVector ebeDivide(RealVector v)
422 throws DimensionMismatchException {
423 if (v instanceof ArrayRealVector) {
424 final double[] vData = ((ArrayRealVector) v).data;
425 final int dim = vData.length;
426 checkVectorDimensions(dim);
427 ArrayRealVector result = new ArrayRealVector(dim);
428 double[] resultData = result.data;
429 for (int i = 0; i < dim; i++) {
430 resultData[i] = data[i] / vData[i];
431 }
432 return result;
433 } else {
434 checkVectorDimensions(v);
435 double[] out = data.clone();
436 for (int i = 0; i < data.length; i++) {
437 out[i] /= v.getEntry(i);
438 }
439 return new ArrayRealVector(out, false);
440 }
441 }
442
443 /**
444 * Get a reference to the underlying data array.
445 * This method does not make a fresh copy of the underlying data.
446 *
447 * @return the array of entries.
448 */
449 public double[] getDataRef() {
450 return data;
451 }
452
453 /** {@inheritDoc} */
454 @Override
455 public double dotProduct(RealVector v) throws DimensionMismatchException {
456 if (v instanceof ArrayRealVector) {
457 final double[] vData = ((ArrayRealVector) v).data;
458 checkVectorDimensions(vData.length);
459 double dot = 0;
460 for (int i = 0; i < data.length; i++) {
461 dot += data[i] * vData[i];
462 }
463 return dot;
464 }
465 return super.dotProduct(v);
466 }
467
468 /** {@inheritDoc} */
469 @Override
470 public double getNorm() {
471 double sum = 0;
472 for (double a : data) {
473 sum += a * a;
474 }
475 return FastMath.sqrt(sum);
476 }
477
478 /** {@inheritDoc} */
479 @Override
480 public double getL1Norm() {
481 double sum = 0;
482 for (double a : data) {
483 sum += FastMath.abs(a);
484 }
485 return sum;
486 }
487
488 /** {@inheritDoc} */
489 @Override
490 public double getLInfNorm() {
491 double max = 0;
492 for (double a : data) {
493 max = FastMath.max(max, FastMath.abs(a));
494 }
495 return max;
496 }
497
498 /** {@inheritDoc} */
499 @Override
500 public double getDistance(RealVector v) throws DimensionMismatchException {
501 if (v instanceof ArrayRealVector) {
502 final double[] vData = ((ArrayRealVector) v).data;
503 checkVectorDimensions(vData.length);
504 double sum = 0;
505 for (int i = 0; i < data.length; ++i) {
506 final double delta = data[i] - vData[i];
507 sum += delta * delta;
508 }
509 return FastMath.sqrt(sum);
510 } else {
511 checkVectorDimensions(v);
512 double sum = 0;
513 for (int i = 0; i < data.length; ++i) {
514 final double delta = data[i] - v.getEntry(i);
515 sum += delta * delta;
516 }
517 return FastMath.sqrt(sum);
518 }
519 }
520
521 /** {@inheritDoc} */
522 @Override
523 public double getL1Distance(RealVector v)
524 throws DimensionMismatchException {
525 if (v instanceof ArrayRealVector) {
526 final double[] vData = ((ArrayRealVector) v).data;
527 checkVectorDimensions(vData.length);
528 double sum = 0;
529 for (int i = 0; i < data.length; ++i) {
530 final double delta = data[i] - vData[i];
531 sum += FastMath.abs(delta);
532 }
533 return sum;
534 } else {
535 checkVectorDimensions(v);
536 double sum = 0;
537 for (int i = 0; i < data.length; ++i) {
538 final double delta = data[i] - v.getEntry(i);
539 sum += FastMath.abs(delta);
540 }
541 return sum;
542 }
543 }
544
545 /** {@inheritDoc} */
546 @Override
547 public double getLInfDistance(RealVector v)
548 throws DimensionMismatchException {
549 if (v instanceof ArrayRealVector) {
550 final double[] vData = ((ArrayRealVector) v).data;
551 checkVectorDimensions(vData.length);
552 double max = 0;
553 for (int i = 0; i < data.length; ++i) {
554 final double delta = data[i] - vData[i];
555 max = FastMath.max(max, FastMath.abs(delta));
556 }
557 return max;
558 } else {
559 checkVectorDimensions(v);
560 double max = 0;
561 for (int i = 0; i < data.length; ++i) {
562 final double delta = data[i] - v.getEntry(i);
563 max = FastMath.max(max, FastMath.abs(delta));
564 }
565 return max;
566 }
567 }
568
569 /** {@inheritDoc} */
570 @Override
571 public RealMatrix outerProduct(RealVector v) {
572 if (v instanceof ArrayRealVector) {
573 final double[] vData = ((ArrayRealVector) v).data;
574 final int m = data.length;
575 final int n = vData.length;
576 final RealMatrix out = MatrixUtils.createRealMatrix(m, n);
577 for (int i = 0; i < m; i++) {
578 for (int j = 0; j < n; j++) {
579 out.setEntry(i, j, data[i] * vData[j]);
580 }
581 }
582 return out;
583 } else {
584 final int m = data.length;
585 final int n = v.getDimension();
586 final RealMatrix out = MatrixUtils.createRealMatrix(m, n);
587 for (int i = 0; i < m; i++) {
588 for (int j = 0; j < n; j++) {
589 out.setEntry(i, j, data[i] * v.getEntry(j));
590 }
591 }
592 return out;
593 }
594 }
595
596 /** {@inheritDoc} */
597 @Override
598 public double getEntry(int index) throws OutOfRangeException {
599 try {
600 return data[index];
601 } catch (IndexOutOfBoundsException e) {
602 throw new OutOfRangeException(LocalizedFormats.INDEX, index, 0,
603 getDimension() - 1);
604 }
605 }
606
607 /** {@inheritDoc} */
608 @Override
609 public int getDimension() {
610 return data.length;
611 }
612
613 /** {@inheritDoc} */
614 @Override
615 public RealVector append(RealVector v) {
616 try {
617 return new ArrayRealVector(this, (ArrayRealVector) v);
618 } catch (ClassCastException cce) {
619 return new ArrayRealVector(this, v);
620 }
621 }
622
623 /**
624 * Construct a vector by appending a vector to this vector.
625 *
626 * @param v Vector to append to this one.
627 * @return a new vector.
628 */
629 public ArrayRealVector append(ArrayRealVector v) {
630 return new ArrayRealVector(this, v);
631 }
632
633 /** {@inheritDoc} */
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 /** {@inheritDoc} */
643 @Override
644 public RealVector getSubVector(int index, int n)
645 throws OutOfRangeException, NotPositiveException {
646 if (n < 0) {
647 throw new NotPositiveException(LocalizedFormats.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 /** {@inheritDoc} */
660 @Override
661 public void setEntry(int index, double value) throws OutOfRangeException {
662 try {
663 data[index] = value;
664 } catch (IndexOutOfBoundsException e) {
665 checkIndex(index);
666 }
667 }
668
669 /** {@inheritDoc} */
670 @Override
671 public void addToEntry(int index, double increment)
672 throws OutOfRangeException {
673 try {
674 data[index] += increment;
675 } catch(IndexOutOfBoundsException e){
676 throw new OutOfRangeException(LocalizedFormats.INDEX,
677 index, 0, data.length - 1);
678 }
679 }
680
681 /** {@inheritDoc} */
682 @Override
683 public void setSubVector(int index, RealVector v)
684 throws OutOfRangeException {
685 if (v instanceof ArrayRealVector) {
686 setSubVector(index, ((ArrayRealVector) v).data);
687 } else {
688 try {
689 for (int i = index; i < index + v.getDimension(); ++i) {
690 data[i] = v.getEntry(i - index);
691 }
692 } catch (IndexOutOfBoundsException e) {
693 checkIndex(index);
694 checkIndex(index + v.getDimension() - 1);
695 }
696 }
697 }
698
699 /**
700 * Set a set of consecutive elements.
701 *
702 * @param index Index of first element to be set.
703 * @param v Vector containing the values to set.
704 * @throws OutOfRangeException if the index is inconsistent with the vector
705 * size.
706 */
707 public void setSubVector(int index, double[] v)
708 throws OutOfRangeException {
709 try {
710 System.arraycopy(v, 0, data, index, v.length);
711 } catch (IndexOutOfBoundsException e) {
712 checkIndex(index);
713 checkIndex(index + v.length - 1);
714 }
715 }
716
717 /** {@inheritDoc} */
718 @Override
719 public void set(double value) {
720 Arrays.fill(data, value);
721 }
722
723 /** {@inheritDoc} */
724 @Override
725 public double[] toArray(){
726 return data.clone();
727 }
728
729 /** {@inheritDoc} */
730 @Override
731 public String toString(){
732 return DEFAULT_FORMAT.format(this);
733 }
734
735 /**
736 * Check if instance and specified vectors have the same dimension.
737 *
738 * @param v Vector to compare instance with.
739 * @throws DimensionMismatchException if the vectors do not
740 * have the same dimension.
741 */
742 @Override
743 protected void checkVectorDimensions(RealVector v)
744 throws DimensionMismatchException {
745 checkVectorDimensions(v.getDimension());
746 }
747
748 /**
749 * Check if instance dimension is equal to some expected value.
750 *
751 * @param n Expected dimension.
752 * @throws DimensionMismatchException if the dimension is
753 * inconsistent with vector size.
754 */
755 @Override
756 protected void checkVectorDimensions(int n)
757 throws DimensionMismatchException {
758 if (data.length != n) {
759 throw new DimensionMismatchException(data.length, n);
760 }
761 }
762
763 /**
764 * Check if any coordinate of this vector is {@code NaN}.
765 *
766 * @return {@code true} if any coordinate of this vector is {@code NaN},
767 * {@code false} otherwise.
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 * Check whether any coordinate of this vector is infinite and none
781 * are {@code NaN}.
782 *
783 * @return {@code true} if any coordinate of this vector is infinite and
784 * none are {@code NaN}, {@code false} otherwise.
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 /** {@inheritDoc} */
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 * {@inheritDoc} All {@code NaN} values have the same hash code.
831 */
832 @Override
833 public int hashCode() {
834 if (isNaN()) {
835 return 9;
836 }
837 return MathUtils.hash(data);
838 }
839
840 /** {@inheritDoc} */
841 @Override
842 public ArrayRealVector combine(double a, double b, RealVector y)
843 throws DimensionMismatchException {
844 return copy().combineToSelf(a, b, y);
845 }
846
847 /** {@inheritDoc} */
848 @Override
849 public ArrayRealVector combineToSelf(double a, double b, RealVector y)
850 throws DimensionMismatchException {
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 /** {@inheritDoc} */
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 /** {@inheritDoc} */
877 @Override
878 public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
879 final int start, final int end) throws NumberIsTooSmallException,
880 OutOfRangeException {
881 checkIndices(start, end);
882 visitor.start(data.length, start, end);
883 for (int i = start; i <= end; i++) {
884 visitor.visit(i, data[i]);
885 }
886 return visitor.end();
887 }
888
889 /**
890 * {@inheritDoc}
891 *
892 * In this implementation, the optimized order is the default order.
893 */
894 @Override
895 public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
896 return walkInDefaultOrder(visitor);
897 }
898
899 /**
900 * {@inheritDoc}
901 *
902 * In this implementation, the optimized order is the default order.
903 */
904 @Override
905 public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
906 final int start, final int end) throws NumberIsTooSmallException,
907 OutOfRangeException {
908 return walkInDefaultOrder(visitor, start, end);
909 }
910
911 /** {@inheritDoc} */
912 @Override
913 public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
914 visitor.start(data.length, 0, data.length - 1);
915 for (int i = 0; i < data.length; i++) {
916 data[i] = visitor.visit(i, data[i]);
917 }
918 return visitor.end();
919 }
920
921 /** {@inheritDoc} */
922 @Override
923 public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
924 final int start, final int end) throws NumberIsTooSmallException,
925 OutOfRangeException {
926 checkIndices(start, end);
927 visitor.start(data.length, start, end);
928 for (int i = start; i <= end; i++) {
929 data[i] = visitor.visit(i, data[i]);
930 }
931 return visitor.end();
932 }
933
934 /**
935 * {@inheritDoc}
936 *
937 * In this implementation, the optimized order is the default order.
938 */
939 @Override
940 public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
941 return walkInDefaultOrder(visitor);
942 }
943
944 /**
945 * {@inheritDoc}
946 *
947 * In this implementation, the optimized order is the default order.
948 */
949 @Override
950 public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
951 final int start, final int end) throws NumberIsTooSmallException,
952 OutOfRangeException {
953 return walkInDefaultOrder(visitor, start, end);
954 }
955 }