1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.math3.linear;
19
20 import java.util.Iterator;
21 import java.util.NoSuchElementException;
22
23 import org.apache.commons.math3.exception.MathUnsupportedOperationException;
24 import org.apache.commons.math3.exception.DimensionMismatchException;
25 import org.apache.commons.math3.exception.NotPositiveException;
26 import org.apache.commons.math3.exception.NumberIsTooSmallException;
27 import org.apache.commons.math3.exception.OutOfRangeException;
28 import org.apache.commons.math3.exception.MathArithmeticException;
29 import org.apache.commons.math3.analysis.FunctionUtils;
30 import org.apache.commons.math3.analysis.function.Add;
31 import org.apache.commons.math3.analysis.function.Multiply;
32 import org.apache.commons.math3.analysis.function.Divide;
33 import org.apache.commons.math3.analysis.UnivariateFunction;
34 import org.apache.commons.math3.exception.util.LocalizedFormats;
35 import org.apache.commons.math3.util.FastMath;
36
37 /**
38 * Class defining a real-valued vector with basic algebraic operations.
39 * <p>
40 * vector element indexing is 0-based -- e.g., {@code getEntry(0)}
41 * returns the first element of the vector.
42 * </p>
43 * <p>
44 * The {@code code map} and {@code mapToSelf} methods operate
45 * on vectors element-wise, i.e. they perform the same operation (adding a scalar,
46 * applying a function ...) on each element in turn. The {@code map}
47 * versions create a new vector to hold the result and do not change the instance.
48 * The {@code mapToSelf} version uses the instance itself to store the
49 * results, so the instance is changed by this method. In all cases, the result
50 * vector is returned by the methods, allowing the <i>fluent API</i>
51 * style, like this:
52 * </p>
53 * <pre>
54 * RealVector result = v.mapAddToSelf(3.4).mapToSelf(new Tan()).mapToSelf(new Power(2.3));
55 * </pre>
56 *
57 * @since 2.1
58 */
59 public abstract class RealVector {
60 /**
61 * Returns the size of the vector.
62 *
63 * @return the size of this vector.
64 */
65 public abstract int getDimension();
66
67 /**
68 * Return the entry at the specified index.
69 *
70 * @param index Index location of entry to be fetched.
71 * @return the vector entry at {@code index}.
72 * @throws OutOfRangeException if the index is not valid.
73 * @see #setEntry(int, double)
74 */
75 public abstract double getEntry(int index) throws OutOfRangeException;
76
77 /**
78 * Set a single element.
79 *
80 * @param index element index.
81 * @param value new value for the element.
82 * @throws OutOfRangeException if the index is not valid.
83 * @see #getEntry(int)
84 */
85 public abstract void setEntry(int index, double value)
86 throws OutOfRangeException;
87
88 /**
89 * Change an entry at the specified index.
90 *
91 * @param index Index location of entry to be set.
92 * @param increment Value to add to the vector entry.
93 * @throws OutOfRangeException if the index is not valid.
94 * @since 3.0
95 */
96 public void addToEntry(int index, double increment)
97 throws OutOfRangeException {
98 setEntry(index, getEntry(index) + increment);
99 }
100
101 /**
102 * Construct a new vector by appending a vector to this vector.
103 *
104 * @param v vector to append to this one.
105 * @return a new vector.
106 */
107 public abstract RealVector append(RealVector v);
108
109 /**
110 * Construct a new vector by appending a double to this vector.
111 *
112 * @param d double to append.
113 * @return a new vector.
114 */
115 public abstract RealVector append(double d);
116
117 /**
118 * Get a subvector from consecutive elements.
119 *
120 * @param index index of first element.
121 * @param n number of elements to be retrieved.
122 * @return a vector containing n elements.
123 * @throws OutOfRangeException if the index is not valid.
124 * @throws NotPositiveException if the number of elements is not positive.
125 */
126 public abstract RealVector getSubVector(int index, int n)
127 throws NotPositiveException, OutOfRangeException;
128
129 /**
130 * Set a sequence of consecutive elements.
131 *
132 * @param index index of first element to be set.
133 * @param v vector containing the values to set.
134 * @throws OutOfRangeException if the index is not valid.
135 */
136 public abstract void setSubVector(int index, RealVector v)
137 throws OutOfRangeException;
138
139 /**
140 * Check whether any coordinate of this vector is {@code NaN}.
141 *
142 * @return {@code true} if any coordinate of this vector is {@code NaN},
143 * {@code false} otherwise.
144 */
145 public abstract boolean isNaN();
146
147 /**
148 * Check whether any coordinate of this vector is infinite and none are {@code NaN}.
149 *
150 * @return {@code true} if any coordinate of this vector is infinite and
151 * none are {@code NaN}, {@code false} otherwise.
152 */
153 public abstract boolean isInfinite();
154
155 /**
156 * Check if instance and specified vectors have the same dimension.
157 *
158 * @param v Vector to compare instance with.
159 * @throws DimensionMismatchException if the vectors do not
160 * have the same dimension.
161 */
162 protected void checkVectorDimensions(RealVector v)
163 throws DimensionMismatchException {
164 checkVectorDimensions(v.getDimension());
165 }
166
167 /**
168 * Check if instance dimension is equal to some expected value.
169 *
170 * @param n Expected dimension.
171 * @throws DimensionMismatchException if the dimension is
172 * inconsistent with the vector size.
173 */
174 protected void checkVectorDimensions(int n)
175 throws DimensionMismatchException {
176 int d = getDimension();
177 if (d != n) {
178 throw new DimensionMismatchException(d, n);
179 }
180 }
181
182 /**
183 * Check if an index is valid.
184 *
185 * @param index Index to check.
186 * @exception OutOfRangeException if {@code index} is not valid.
187 */
188 protected void checkIndex(final int index) throws OutOfRangeException {
189 if (index < 0 ||
190 index >= getDimension()) {
191 throw new OutOfRangeException(LocalizedFormats.INDEX,
192 index, 0, getDimension() - 1);
193 }
194 }
195
196 /**
197 * Checks that the indices of a subvector are valid.
198 *
199 * @param start the index of the first entry of the subvector
200 * @param end the index of the last entry of the subvector (inclusive)
201 * @throws OutOfRangeException if {@code start} of {@code end} are not valid
202 * @throws NumberIsTooSmallException if {@code end < start}
203 * @since 3.1
204 */
205 protected void checkIndices(final int start, final int end)
206 throws NumberIsTooSmallException, OutOfRangeException {
207 final int dim = getDimension();
208 if ((start < 0) || (start >= dim)) {
209 throw new OutOfRangeException(LocalizedFormats.INDEX, start, 0,
210 dim - 1);
211 }
212 if ((end < 0) || (end >= dim)) {
213 throw new OutOfRangeException(LocalizedFormats.INDEX, end, 0,
214 dim - 1);
215 }
216 if (end < start) {
217 // TODO Use more specific error message
218 throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
219 end, start, false);
220 }
221 }
222
223 /**
224 * Compute the sum of this vector and {@code v}.
225 * Returns a new vector. Does not change instance data.
226 *
227 * @param v Vector to be added.
228 * @return {@code this} + {@code v}.
229 * @throws DimensionMismatchException if {@code v} is not the same size as
230 * {@code this} vector.
231 */
232 public RealVector add(RealVector v) throws DimensionMismatchException {
233 checkVectorDimensions(v);
234 RealVector result = v.copy();
235 Iterator<Entry> it = iterator();
236 while (it.hasNext()) {
237 final Entry e = it.next();
238 final int index = e.getIndex();
239 result.setEntry(index, e.getValue() + result.getEntry(index));
240 }
241 return result;
242 }
243
244 /**
245 * Subtract {@code v} from this vector.
246 * Returns a new vector. Does not change instance data.
247 *
248 * @param v Vector to be subtracted.
249 * @return {@code this} - {@code v}.
250 * @throws DimensionMismatchException if {@code v} is not the same size as
251 * {@code this} vector.
252 */
253 public RealVector subtract(RealVector v) throws DimensionMismatchException {
254 checkVectorDimensions(v);
255 RealVector result = v.mapMultiply(-1d);
256 Iterator<Entry> it = iterator();
257 while (it.hasNext()) {
258 final Entry e = it.next();
259 final int index = e.getIndex();
260 result.setEntry(index, e.getValue() + result.getEntry(index));
261 }
262 return result;
263 }
264
265 /**
266 * Add a value to each entry.
267 * Returns a new vector. Does not change instance data.
268 *
269 * @param d Value to be added to each entry.
270 * @return {@code this} + {@code d}.
271 */
272 public RealVector mapAdd(double d) {
273 return copy().mapAddToSelf(d);
274 }
275
276 /**
277 * Add a value to each entry.
278 * The instance is changed in-place.
279 *
280 * @param d Value to be added to each entry.
281 * @return {@code this}.
282 */
283 public RealVector mapAddToSelf(double d) {
284 if (d != 0) {
285 return mapToSelf(FunctionUtils.fix2ndArgument(new Add(), d));
286 }
287 return this;
288 }
289
290 /**
291 * Returns a (deep) copy of this vector.
292 *
293 * @return a vector copy.
294 */
295 public abstract RealVector copy();
296
297 /**
298 * Compute the dot product of this vector with {@code v}.
299 *
300 * @param v Vector with which dot product should be computed
301 * @return the scalar dot product between this instance and {@code v}.
302 * @throws DimensionMismatchException if {@code v} is not the same size as
303 * {@code this} vector.
304 */
305 public double dotProduct(RealVector v) throws DimensionMismatchException {
306 checkVectorDimensions(v);
307 double d = 0;
308 final int n = getDimension();
309 for (int i = 0; i < n; i++) {
310 d += getEntry(i) * v.getEntry(i);
311 }
312 return d;
313 }
314
315 /**
316 * Computes the cosine of the angle between this vector and the
317 * argument.
318 *
319 * @param v Vector.
320 * @return the cosine of the angle between this vector and {@code v}.
321 * @throws MathArithmeticException if {@code this} or {@code v} is the null
322 * vector
323 * @throws DimensionMismatchException if the dimensions of {@code this} and
324 * {@code v} do not match
325 */
326 public double cosine(RealVector v) throws DimensionMismatchException,
327 MathArithmeticException {
328 final double norm = getNorm();
329 final double vNorm = v.getNorm();
330
331 if (norm == 0 ||
332 vNorm == 0) {
333 throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
334 }
335 return dotProduct(v) / (norm * vNorm);
336 }
337
338 /**
339 * Element-by-element division.
340 *
341 * @param v Vector by which instance elements must be divided.
342 * @return a vector containing this[i] / v[i] for all i.
343 * @throws DimensionMismatchException if {@code v} is not the same size as
344 * {@code this} vector.
345 */
346 public abstract RealVector ebeDivide(RealVector v)
347 throws DimensionMismatchException;
348
349 /**
350 * Element-by-element multiplication.
351 *
352 * @param v Vector by which instance elements must be multiplied
353 * @return a vector containing this[i] * v[i] for all i.
354 * @throws DimensionMismatchException if {@code v} is not the same size as
355 * {@code this} vector.
356 */
357 public abstract RealVector ebeMultiply(RealVector v)
358 throws DimensionMismatchException;
359
360 /**
361 * Distance between two vectors.
362 * <p>This method computes the distance consistent with the
363 * L<sub>2</sub> norm, i.e. the square root of the sum of
364 * element differences, or Euclidean distance.</p>
365 *
366 * @param v Vector to which distance is requested.
367 * @return the distance between two vectors.
368 * @throws DimensionMismatchException if {@code v} is not the same size as
369 * {@code this} vector.
370 * @see #getL1Distance(RealVector)
371 * @see #getLInfDistance(RealVector)
372 * @see #getNorm()
373 */
374 public double getDistance(RealVector v) throws DimensionMismatchException {
375 checkVectorDimensions(v);
376 double d = 0;
377 Iterator<Entry> it = iterator();
378 while (it.hasNext()) {
379 final Entry e = it.next();
380 final double diff = e.getValue() - v.getEntry(e.getIndex());
381 d += diff * diff;
382 }
383 return FastMath.sqrt(d);
384 }
385
386 /**
387 * Returns the L<sub>2</sub> norm of the vector.
388 * <p>The L<sub>2</sub> norm is the root of the sum of
389 * the squared elements.</p>
390 *
391 * @return the norm.
392 * @see #getL1Norm()
393 * @see #getLInfNorm()
394 * @see #getDistance(RealVector)
395 */
396 public double getNorm() {
397 double sum = 0;
398 Iterator<Entry> it = iterator();
399 while (it.hasNext()) {
400 final Entry e = it.next();
401 final double value = e.getValue();
402 sum += value * value;
403 }
404 return FastMath.sqrt(sum);
405 }
406
407 /**
408 * Returns the L<sub>1</sub> norm of the vector.
409 * <p>The L<sub>1</sub> norm is the sum of the absolute
410 * values of the elements.</p>
411 *
412 * @return the norm.
413 * @see #getNorm()
414 * @see #getLInfNorm()
415 * @see #getL1Distance(RealVector)
416 */
417 public double getL1Norm() {
418 double norm = 0;
419 Iterator<Entry> it = iterator();
420 while (it.hasNext()) {
421 final Entry e = it.next();
422 norm += FastMath.abs(e.getValue());
423 }
424 return norm;
425 }
426
427 /**
428 * Returns the L<sub>∞</sub> norm of the vector.
429 * <p>The L<sub>∞</sub> norm is the max of the absolute
430 * values of the elements.</p>
431 *
432 * @return the norm.
433 * @see #getNorm()
434 * @see #getL1Norm()
435 * @see #getLInfDistance(RealVector)
436 */
437 public double getLInfNorm() {
438 double norm = 0;
439 Iterator<Entry> it = iterator();
440 while (it.hasNext()) {
441 final Entry e = it.next();
442 norm = FastMath.max(norm, FastMath.abs(e.getValue()));
443 }
444 return norm;
445 }
446
447 /**
448 * Distance between two vectors.
449 * <p>This method computes the distance consistent with
450 * L<sub>1</sub> norm, i.e. the sum of the absolute values of
451 * the elements differences.</p>
452 *
453 * @param v Vector to which distance is requested.
454 * @return the distance between two vectors.
455 * @throws DimensionMismatchException if {@code v} is not the same size as
456 * {@code this} vector.
457 */
458 public double getL1Distance(RealVector v)
459 throws DimensionMismatchException {
460 checkVectorDimensions(v);
461 double d = 0;
462 Iterator<Entry> it = iterator();
463 while (it.hasNext()) {
464 final Entry e = it.next();
465 d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
466 }
467 return d;
468 }
469
470 /**
471 * Distance between two vectors.
472 * <p>This method computes the distance consistent with
473 * L<sub>∞</sub> norm, i.e. the max of the absolute values of
474 * element differences.</p>
475 *
476 * @param v Vector to which distance is requested.
477 * @return the distance between two vectors.
478 * @throws DimensionMismatchException if {@code v} is not the same size as
479 * {@code this} vector.
480 * @see #getDistance(RealVector)
481 * @see #getL1Distance(RealVector)
482 * @see #getLInfNorm()
483 */
484 public double getLInfDistance(RealVector v)
485 throws DimensionMismatchException {
486 checkVectorDimensions(v);
487 double d = 0;
488 Iterator<Entry> it = iterator();
489 while (it.hasNext()) {
490 final Entry e = it.next();
491 d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
492 }
493 return d;
494 }
495
496 /**
497 * Get the index of the minimum entry.
498 *
499 * @return the index of the minimum entry or -1 if vector length is 0
500 * or all entries are {@code NaN}.
501 */
502 public int getMinIndex() {
503 int minIndex = -1;
504 double minValue = Double.POSITIVE_INFINITY;
505 Iterator<Entry> iterator = iterator();
506 while (iterator.hasNext()) {
507 final Entry entry = iterator.next();
508 if (entry.getValue() <= minValue) {
509 minIndex = entry.getIndex();
510 minValue = entry.getValue();
511 }
512 }
513 return minIndex;
514 }
515
516 /**
517 * Get the value of the minimum entry.
518 *
519 * @return the value of the minimum entry or {@code NaN} if all
520 * entries are {@code NaN}.
521 */
522 public double getMinValue() {
523 final int minIndex = getMinIndex();
524 return minIndex < 0 ? Double.NaN : getEntry(minIndex);
525 }
526
527 /**
528 * Get the index of the maximum entry.
529 *
530 * @return the index of the maximum entry or -1 if vector length is 0
531 * or all entries are {@code NaN}
532 */
533 public int getMaxIndex() {
534 int maxIndex = -1;
535 double maxValue = Double.NEGATIVE_INFINITY;
536 Iterator<Entry> iterator = iterator();
537 while (iterator.hasNext()) {
538 final Entry entry = iterator.next();
539 if (entry.getValue() >= maxValue) {
540 maxIndex = entry.getIndex();
541 maxValue = entry.getValue();
542 }
543 }
544 return maxIndex;
545 }
546
547 /**
548 * Get the value of the maximum entry.
549 *
550 * @return the value of the maximum entry or {@code NaN} if all
551 * entries are {@code NaN}.
552 */
553 public double getMaxValue() {
554 final int maxIndex = getMaxIndex();
555 return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
556 }
557
558
559 /**
560 * Multiply each entry by the argument. Returns a new vector.
561 * Does not change instance data.
562 *
563 * @param d Multiplication factor.
564 * @return {@code this} * {@code d}.
565 */
566 public RealVector mapMultiply(double d) {
567 return copy().mapMultiplyToSelf(d);
568 }
569
570 /**
571 * Multiply each entry.
572 * The instance is changed in-place.
573 *
574 * @param d Multiplication factor.
575 * @return {@code this}.
576 */
577 public RealVector mapMultiplyToSelf(double d){
578 return mapToSelf(FunctionUtils.fix2ndArgument(new Multiply(), d));
579 }
580
581 /**
582 * Subtract a value from each entry. Returns a new vector.
583 * Does not change instance data.
584 *
585 * @param d Value to be subtracted.
586 * @return {@code this} - {@code d}.
587 */
588 public RealVector mapSubtract(double d) {
589 return copy().mapSubtractToSelf(d);
590 }
591
592 /**
593 * Subtract a value from each entry.
594 * The instance is changed in-place.
595 *
596 * @param d Value to be subtracted.
597 * @return {@code this}.
598 */
599 public RealVector mapSubtractToSelf(double d){
600 return mapAddToSelf(-d);
601 }
602
603 /**
604 * Divide each entry by the argument. Returns a new vector.
605 * Does not change instance data.
606 *
607 * @param d Value to divide by.
608 * @return {@code this} / {@code d}.
609 */
610 public RealVector mapDivide(double d) {
611 return copy().mapDivideToSelf(d);
612 }
613
614 /**
615 * Divide each entry by the argument.
616 * The instance is changed in-place.
617 *
618 * @param d Value to divide by.
619 * @return {@code this}.
620 */
621 public RealVector mapDivideToSelf(double d){
622 return mapToSelf(FunctionUtils.fix2ndArgument(new Divide(), d));
623 }
624
625 /**
626 * Compute the outer product.
627 *
628 * @param v Vector with which outer product should be computed.
629 * @return the matrix outer product between this instance and {@code v}.
630 */
631 public RealMatrix outerProduct(RealVector v) {
632 final int m = this.getDimension();
633 final int n = v.getDimension();
634 final RealMatrix product;
635 if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
636 product = new OpenMapRealMatrix(m, n);
637 } else {
638 product = new Array2DRowRealMatrix(m, n);
639 }
640 for (int i = 0; i < m; i++) {
641 for (int j = 0; j < n; j++) {
642 product.setEntry(i, j, this.getEntry(i) * v.getEntry(j));
643 }
644 }
645 return product;
646 }
647
648 /**
649 * Find the orthogonal projection of this vector onto another vector.
650 *
651 * @param v vector onto which instance must be projected.
652 * @return projection of the instance onto {@code v}.
653 * @throws DimensionMismatchException if {@code v} is not the same size as
654 * {@code this} vector.
655 * @throws MathArithmeticException if {@code this} or {@code v} is the null
656 * vector
657 */
658 public RealVector projection(final RealVector v)
659 throws DimensionMismatchException, MathArithmeticException {
660 final double norm2 = v.dotProduct(v);
661 if (norm2 == 0.0) {
662 throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
663 }
664 return v.mapMultiply(dotProduct(v) / v.dotProduct(v));
665 }
666
667 /**
668 * Set all elements to a single value.
669 *
670 * @param value Single value to set for all elements.
671 */
672 public void set(double value) {
673 Iterator<Entry> it = iterator();
674 while (it.hasNext()) {
675 final Entry e = it.next();
676 e.setValue(value);
677 }
678 }
679
680 /**
681 * Convert the vector to an array of {@code double}s.
682 * The array is independent from this vector data: the elements
683 * are copied.
684 *
685 * @return an array containing a copy of the vector elements.
686 */
687 public double[] toArray() {
688 int dim = getDimension();
689 double[] values = new double[dim];
690 for (int i = 0; i < dim; i++) {
691 values[i] = getEntry(i);
692 }
693 return values;
694 }
695
696 /**
697 * Creates a unit vector pointing in the direction of this vector.
698 * The instance is not changed by this method.
699 *
700 * @return a unit vector pointing in direction of this vector.
701 * @throws MathArithmeticException if the norm is zero.
702 */
703 public RealVector unitVector() throws MathArithmeticException {
704 final double norm = getNorm();
705 if (norm == 0) {
706 throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
707 }
708 return mapDivide(norm);
709 }
710
711 /**
712 * Converts this vector into a unit vector.
713 * The instance itself is changed by this method.
714 *
715 * @throws MathArithmeticException if the norm is zero.
716 */
717 public void unitize() throws MathArithmeticException {
718 final double norm = getNorm();
719 if (norm == 0) {
720 throw new MathArithmeticException(LocalizedFormats.ZERO_NORM);
721 }
722 mapDivideToSelf(getNorm());
723 }
724
725 /**
726 * Create a sparse iterator over the vector, which may omit some entries.
727 * The ommitted entries are either exact zeroes (for dense implementations)
728 * or are the entries which are not stored (for real sparse vectors).
729 * No guarantees are made about order of iteration.
730 *
731 * <p>Note: derived classes are required to return an {@link Iterator} that
732 * returns non-null {@link Entry} objects as long as {@link Iterator#hasNext()}
733 * returns {@code true}.</p>
734 *
735 * @return a sparse iterator.
736 */
737 public Iterator<Entry> sparseIterator() {
738 return new SparseEntryIterator();
739 }
740
741 /**
742 * Generic dense iterator. Iteration is in increasing order
743 * of the vector index.
744 *
745 * <p>Note: derived classes are required to return an {@link Iterator} that
746 * returns non-null {@link Entry} objects as long as {@link Iterator#hasNext()}
747 * returns {@code true}.</p>
748 *
749 * @return a dense iterator.
750 */
751 public Iterator<Entry> iterator() {
752 final int dim = getDimension();
753 return new Iterator<Entry>() {
754
755 /** Current index. */
756 private int i = 0;
757
758 /** Current entry. */
759 private Entry e = new Entry();
760
761 /** {@inheritDoc} */
762 public boolean hasNext() {
763 return i < dim;
764 }
765
766 /** {@inheritDoc} */
767 public Entry next() {
768 if (i < dim) {
769 e.setIndex(i++);
770 return e;
771 } else {
772 throw new NoSuchElementException();
773 }
774 }
775
776 /**
777 * {@inheritDoc}
778 *
779 * @throws MathUnsupportedOperationException in all circumstances.
780 */
781 public void remove() throws MathUnsupportedOperationException {
782 throw new MathUnsupportedOperationException();
783 }
784 };
785 }
786
787 /**
788 * Acts as if implemented as:
789 * <pre>
790 * return copy().mapToSelf(function);
791 * </pre>
792 * Returns a new vector. Does not change instance data.
793 *
794 * @param function Function to apply to each entry.
795 * @return a new vector.
796 */
797 public RealVector map(UnivariateFunction function) {
798 return copy().mapToSelf(function);
799 }
800
801 /**
802 * Acts as if it is implemented as:
803 * <pre>
804 * Entry e = null;
805 * for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
806 * e.setValue(function.value(e.getValue()));
807 * }
808 * </pre>
809 * Entries of this vector are modified in-place by this method.
810 *
811 * @param function Function to apply to each entry.
812 * @return a reference to this vector.
813 */
814 public RealVector mapToSelf(UnivariateFunction function) {
815 Iterator<Entry> it = iterator();
816 while (it.hasNext()) {
817 final Entry e = it.next();
818 e.setValue(function.value(e.getValue()));
819 }
820 return this;
821 }
822
823 /**
824 * Returns a new vector representing {@code a * this + b * y}, the linear
825 * combination of {@code this} and {@code y}.
826 * Returns a new vector. Does not change instance data.
827 *
828 * @param a Coefficient of {@code this}.
829 * @param b Coefficient of {@code y}.
830 * @param y Vector with which {@code this} is linearly combined.
831 * @return a vector containing {@code a * this[i] + b * y[i]} for all
832 * {@code i}.
833 * @throws DimensionMismatchException if {@code y} is not the same size as
834 * {@code this} vector.
835 */
836 public RealVector combine(double a, double b, RealVector y)
837 throws DimensionMismatchException {
838 return copy().combineToSelf(a, b, y);
839 }
840
841 /**
842 * Updates {@code this} with the linear combination of {@code this} and
843 * {@code y}.
844 *
845 * @param a Weight of {@code this}.
846 * @param b Weight of {@code y}.
847 * @param y Vector with which {@code this} is linearly combined.
848 * @return {@code this}, with components equal to
849 * {@code a * this[i] + b * y[i]} for all {@code i}.
850 * @throws DimensionMismatchException if {@code y} is not the same size as
851 * {@code this} vector.
852 */
853 public RealVector combineToSelf(double a, double b, RealVector y)
854 throws DimensionMismatchException {
855 checkVectorDimensions(y);
856 for (int i = 0; i < getDimension(); i++) {
857 final double xi = getEntry(i);
858 final double yi = y.getEntry(i);
859 setEntry(i, a * xi + b * yi);
860 }
861 return this;
862 }
863
864 /**
865 * Visits (but does not alter) all entries of this vector in default order
866 * (increasing index).
867 *
868 * @param visitor the visitor to be used to process the entries of this
869 * vector
870 * @return the value returned by {@link RealVectorPreservingVisitor#end()}
871 * at the end of the walk
872 * @since 3.1
873 */
874 public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor) {
875 final int dim = getDimension();
876 visitor.start(dim, 0, dim - 1);
877 for (int i = 0; i < dim; i++) {
878 visitor.visit(i, getEntry(i));
879 }
880 return visitor.end();
881 }
882
883 /**
884 * Visits (but does not alter) some entries of this vector in default order
885 * (increasing index).
886 *
887 * @param visitor visitor to be used to process the entries of this vector
888 * @param start the index of the first entry to be visited
889 * @param end the index of the last entry to be visited (inclusive)
890 * @return the value returned by {@link RealVectorPreservingVisitor#end()}
891 * at the end of the walk
892 * @throws NumberIsTooSmallException if {@code end < start}.
893 * @throws OutOfRangeException if the indices are not valid.
894 * @since 3.1
895 */
896 public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
897 final int start, final int end)
898 throws NumberIsTooSmallException, OutOfRangeException {
899 checkIndices(start, end);
900 visitor.start(getDimension(), start, end);
901 for (int i = start; i <= end; i++) {
902 visitor.visit(i, getEntry(i));
903 }
904 return visitor.end();
905 }
906
907 /**
908 * Visits (but does not alter) all entries of this vector in optimized
909 * order. The order in which the entries are visited is selected so as to
910 * lead to the most efficient implementation; it might depend on the
911 * concrete implementation of this abstract class.
912 *
913 * @param visitor the visitor to be used to process the entries of this
914 * vector
915 * @return the value returned by {@link RealVectorPreservingVisitor#end()}
916 * at the end of the walk
917 * @since 3.1
918 */
919 public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
920 return walkInDefaultOrder(visitor);
921 }
922
923 /**
924 * Visits (but does not alter) some entries of this vector in optimized
925 * order. The order in which the entries are visited is selected so as to
926 * lead to the most efficient implementation; it might depend on the
927 * concrete implementation of this abstract class.
928 *
929 * @param visitor visitor to be used to process the entries of this vector
930 * @param start the index of the first entry to be visited
931 * @param end the index of the last entry to be visited (inclusive)
932 * @return the value returned by {@link RealVectorPreservingVisitor#end()}
933 * at the end of the walk
934 * @throws NumberIsTooSmallException if {@code end < start}.
935 * @throws OutOfRangeException if the indices are not valid.
936 * @since 3.1
937 */
938 public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
939 final int start, final int end)
940 throws NumberIsTooSmallException, OutOfRangeException {
941 return walkInDefaultOrder(visitor, start, end);
942 }
943
944 /**
945 * Visits (and possibly alters) all entries of this vector in default order
946 * (increasing index).
947 *
948 * @param visitor the visitor to be used to process and modify the entries
949 * of this vector
950 * @return the value returned by {@link RealVectorChangingVisitor#end()}
951 * at the end of the walk
952 * @since 3.1
953 */
954 public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
955 final int dim = getDimension();
956 visitor.start(dim, 0, dim - 1);
957 for (int i = 0; i < dim; i++) {
958 setEntry(i, visitor.visit(i, getEntry(i)));
959 }
960 return visitor.end();
961 }
962
963 /**
964 * Visits (and possibly alters) some entries of this vector in default order
965 * (increasing index).
966 *
967 * @param visitor visitor to be used to process the entries of this vector
968 * @param start the index of the first entry to be visited
969 * @param end the index of the last entry to be visited (inclusive)
970 * @return the value returned by {@link RealVectorChangingVisitor#end()}
971 * at the end of the walk
972 * @throws NumberIsTooSmallException if {@code end < start}.
973 * @throws OutOfRangeException if the indices are not valid.
974 * @since 3.1
975 */
976 public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
977 final int start, final int end)
978 throws NumberIsTooSmallException, OutOfRangeException {
979 checkIndices(start, end);
980 visitor.start(getDimension(), start, end);
981 for (int i = start; i <= end; i++) {
982 setEntry(i, visitor.visit(i, getEntry(i)));
983 }
984 return visitor.end();
985 }
986
987 /**
988 * Visits (and possibly alters) all entries of this vector in optimized
989 * order. The order in which the entries are visited is selected so as to
990 * lead to the most efficient implementation; it might depend on the
991 * concrete implementation of this abstract class.
992 *
993 * @param visitor the visitor to be used to process the entries of this
994 * vector
995 * @return the value returned by {@link RealVectorChangingVisitor#end()}
996 * at the end of the walk
997 * @since 3.1
998 */
999 public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
1000 return walkInDefaultOrder(visitor);
1001 }
1002
1003 /**
1004 * Visits (and possibly change) some entries of this vector in optimized
1005 * order. The order in which the entries are visited is selected so as to
1006 * lead to the most efficient implementation; it might depend on the
1007 * concrete implementation of this abstract class.
1008 *
1009 * @param visitor visitor to be used to process the entries of this vector
1010 * @param start the index of the first entry to be visited
1011 * @param end the index of the last entry to be visited (inclusive)
1012 * @return the value returned by {@link RealVectorChangingVisitor#end()}
1013 * at the end of the walk
1014 * @throws NumberIsTooSmallException if {@code end < start}.
1015 * @throws OutOfRangeException if the indices are not valid.
1016 * @since 3.1
1017 */
1018 public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
1019 final int start, final int end)
1020 throws NumberIsTooSmallException, OutOfRangeException {
1021 return walkInDefaultOrder(visitor, start, end);
1022 }
1023
1024 /** An entry in the vector. */
1025 protected class Entry {
1026 /** Index of this entry. */
1027 private int index;
1028
1029 /** Simple constructor. */
1030 public Entry() {
1031 setIndex(0);
1032 }
1033
1034 /**
1035 * Get the value of the entry.
1036 *
1037 * @return the value of the entry.
1038 */
1039 public double getValue() {
1040 return getEntry(getIndex());
1041 }
1042
1043 /**
1044 * Set the value of the entry.
1045 *
1046 * @param value New value for the entry.
1047 */
1048 public void setValue(double value) {
1049 setEntry(getIndex(), value);
1050 }
1051
1052 /**
1053 * Get the index of the entry.
1054 *
1055 * @return the index of the entry.
1056 */
1057 public int getIndex() {
1058 return index;
1059 }
1060
1061 /**
1062 * Set the index of the entry.
1063 *
1064 * @param index New index for the entry.
1065 */
1066 public void setIndex(int index) {
1067 this.index = index;
1068 }
1069 }
1070
1071 /**
1072 * <p>
1073 * Test for the equality of two real vectors. If all coordinates of two real
1074 * vectors are exactly the same, and none are {@code NaN}, the two real
1075 * vectors are considered to be equal. {@code NaN} coordinates are
1076 * considered to affect globally the vector and be equals to each other -
1077 * i.e, if either (or all) coordinates of the real vector are equal to
1078 * {@code NaN}, the real vector is equal to a vector with all {@code NaN}
1079 * coordinates.
1080 * </p>
1081 * <p>
1082 * This method <em>must</em> be overriden by concrete subclasses of
1083 * {@link RealVector} (the current implementation throws an exception).
1084 * </p>
1085 *
1086 * @param other Object to test for equality.
1087 * @return {@code true} if two vector objects are equal, {@code false} if
1088 * {@code other} is null, not an instance of {@code RealVector}, or
1089 * not equal to this {@code RealVector} instance.
1090 * @throws MathUnsupportedOperationException if this method is not
1091 * overridden.
1092 */
1093 @Override
1094 public boolean equals(Object other)
1095 throws MathUnsupportedOperationException {
1096 throw new MathUnsupportedOperationException();
1097 }
1098
1099 /**
1100 * {@inheritDoc}. This method <em>must</em> be overriden by concrete
1101 * subclasses of {@link RealVector} (current implementation throws an
1102 * exception).
1103 *
1104 * @throws MathUnsupportedOperationException if this method is not
1105 * overridden.
1106 */
1107 @Override
1108 public int hashCode() throws MathUnsupportedOperationException {
1109 throw new MathUnsupportedOperationException();
1110 }
1111
1112 /**
1113 * This class should rarely be used, but is here to provide
1114 * a default implementation of sparseIterator(), which is implemented
1115 * by walking over the entries, skipping those that are zero.
1116 *
1117 * Concrete subclasses which are SparseVector implementations should
1118 * make their own sparse iterator, rather than using this one.
1119 *
1120 * This implementation might be useful for ArrayRealVector, when expensive
1121 * operations which preserve the default value are to be done on the entries,
1122 * and the fraction of non-default values is small (i.e. someone took a
1123 * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
1124
1125 */
1126 protected class SparseEntryIterator implements Iterator<Entry> {
1127 /** Dimension of the vector. */
1128 private final int dim;
1129 /** Last entry returned by {@link #next()}. */
1130 private Entry current;
1131 /** Next entry for {@link #next()} to return. */
1132 private Entry next;
1133
1134 /** Simple constructor. */
1135 protected SparseEntryIterator() {
1136 dim = getDimension();
1137 current = new Entry();
1138 next = new Entry();
1139 if (next.getValue() == 0) {
1140 advance(next);
1141 }
1142 }
1143
1144 /**
1145 * Advance an entry up to the next nonzero one.
1146 *
1147 * @param e entry to advance.
1148 */
1149 protected void advance(Entry e) {
1150 if (e == null) {
1151 return;
1152 }
1153 do {
1154 e.setIndex(e.getIndex() + 1);
1155 } while (e.getIndex() < dim && e.getValue() == 0);
1156 if (e.getIndex() >= dim) {
1157 e.setIndex(-1);
1158 }
1159 }
1160
1161 /** {@inheritDoc} */
1162 public boolean hasNext() {
1163 return next.getIndex() >= 0;
1164 }
1165
1166 /** {@inheritDoc} */
1167 public Entry next() {
1168 int index = next.getIndex();
1169 if (index < 0) {
1170 throw new NoSuchElementException();
1171 }
1172 current.setIndex(index);
1173 advance(next);
1174 return current;
1175 }
1176
1177 /**
1178 * {@inheritDoc}
1179 *
1180 * @throws MathUnsupportedOperationException in all circumstances.
1181 */
1182 public void remove() throws MathUnsupportedOperationException {
1183 throw new MathUnsupportedOperationException();
1184 }
1185 }
1186
1187 /**
1188 * Returns an unmodifiable view of the specified vector.
1189 * The returned vector has read-only access. An attempt to modify it will
1190 * result in a {@link MathUnsupportedOperationException}. However, the
1191 * returned vector is <em>not</em> immutable, since any modification of
1192 * {@code v} will also change the returned view.
1193 * For example, in the following piece of code
1194 * <pre>
1195 * RealVector v = new ArrayRealVector(2);
1196 * RealVector w = RealVector.unmodifiableRealVector(v);
1197 * v.setEntry(0, 1.2);
1198 * v.setEntry(1, -3.4);
1199 * </pre>
1200 * the changes will be seen in the {@code w} view of {@code v}.
1201 *
1202 * @param v Vector for which an unmodifiable view is to be returned.
1203 * @return an unmodifiable view of {@code v}.
1204 */
1205 public static RealVector unmodifiableRealVector(final RealVector v) {
1206 /**
1207 * This anonymous class is an implementation of {@link RealVector}
1208 * with read-only access.
1209 * It wraps any {@link RealVector}, and exposes all methods which
1210 * do not modify it. Invoking methods which should normally result
1211 * in the modification of the calling {@link RealVector} results in
1212 * a {@link MathUnsupportedOperationException}. It should be noted
1213 * that {@link UnmodifiableVector} is <em>not</em> immutable.
1214 */
1215 return new RealVector() {
1216 /**
1217 * {@inheritDoc}
1218 *
1219 * @throws MathUnsupportedOperationException in all circumstances.
1220 */
1221 @Override
1222 public RealVector mapToSelf(UnivariateFunction function)
1223 throws MathUnsupportedOperationException {
1224 throw new MathUnsupportedOperationException();
1225 }
1226
1227 /** {@inheritDoc} */
1228 @Override
1229 public RealVector map(UnivariateFunction function) {
1230 return v.map(function);
1231 }
1232
1233 /** {@inheritDoc} */
1234 @Override
1235 public Iterator<Entry> iterator() {
1236 final Iterator<Entry> i = v.iterator();
1237 return new Iterator<Entry>() {
1238 /** The current entry. */
1239 private final UnmodifiableEntry e = new UnmodifiableEntry();
1240
1241 /** {@inheritDoc} */
1242 public boolean hasNext() {
1243 return i.hasNext();
1244 }
1245
1246 /** {@inheritDoc} */
1247 public Entry next() {
1248 e.setIndex(i.next().getIndex());
1249 return e;
1250 }
1251
1252 /**
1253 * {@inheritDoc}
1254 *
1255 * @throws MathUnsupportedOperationException in all
1256 * circumstances.
1257 */
1258 public void remove() throws MathUnsupportedOperationException {
1259 throw new MathUnsupportedOperationException();
1260 }
1261 };
1262 }
1263
1264 /** {@inheritDoc} */
1265 @Override
1266 public Iterator<Entry> sparseIterator() {
1267 final Iterator<Entry> i = v.sparseIterator();
1268
1269 return new Iterator<Entry>() {
1270 /** The current entry. */
1271 private final UnmodifiableEntry e = new UnmodifiableEntry();
1272
1273 /** {@inheritDoc} */
1274 public boolean hasNext() {
1275 return i.hasNext();
1276 }
1277
1278 /** {@inheritDoc} */
1279 public Entry next() {
1280 e.setIndex(i.next().getIndex());
1281 return e;
1282 }
1283
1284 /**
1285 * {@inheritDoc}
1286 *
1287 * @throws MathUnsupportedOperationException in all
1288 * circumstances.
1289 */
1290 public void remove()
1291 throws MathUnsupportedOperationException {
1292 throw new MathUnsupportedOperationException();
1293 }
1294 };
1295 }
1296
1297 /** {@inheritDoc} */
1298 @Override
1299 public RealVector copy() {
1300 return v.copy();
1301 }
1302
1303 /** {@inheritDoc} */
1304 @Override
1305 public RealVector add(RealVector w)
1306 throws DimensionMismatchException {
1307 return v.add(w);
1308 }
1309
1310 /** {@inheritDoc} */
1311 @Override
1312 public RealVector subtract(RealVector w)
1313 throws DimensionMismatchException {
1314 return v.subtract(w);
1315 }
1316
1317 /** {@inheritDoc} */
1318 @Override
1319 public RealVector mapAdd(double d) {
1320 return v.mapAdd(d);
1321 }
1322
1323 /**
1324 * {@inheritDoc}
1325 *
1326 * @throws MathUnsupportedOperationException in all
1327 * circumstances.
1328 */
1329 @Override
1330 public RealVector mapAddToSelf(double d)
1331 throws MathUnsupportedOperationException {
1332 throw new MathUnsupportedOperationException();
1333 }
1334
1335 /** {@inheritDoc} */
1336 @Override
1337 public RealVector mapSubtract(double d) {
1338 return v.mapSubtract(d);
1339 }
1340
1341 /**
1342 * {@inheritDoc}
1343 *
1344 * @throws MathUnsupportedOperationException in all
1345 * circumstances.
1346 */
1347 @Override
1348 public RealVector mapSubtractToSelf(double d)
1349 throws MathUnsupportedOperationException {
1350 throw new MathUnsupportedOperationException();
1351 }
1352
1353 /** {@inheritDoc} */
1354 @Override
1355 public RealVector mapMultiply(double d) {
1356 return v.mapMultiply(d);
1357 }
1358
1359 /**
1360 * {@inheritDoc}
1361 *
1362 * @throws MathUnsupportedOperationException in all
1363 * circumstances.
1364 */
1365 @Override
1366 public RealVector mapMultiplyToSelf(double d)
1367 throws MathUnsupportedOperationException {
1368 throw new MathUnsupportedOperationException();
1369 }
1370
1371 /** {@inheritDoc} */
1372 @Override
1373 public RealVector mapDivide(double d) {
1374 return v.mapDivide(d);
1375 }
1376
1377 /**
1378 * {@inheritDoc}
1379 *
1380 * @throws MathUnsupportedOperationException in all
1381 * circumstances.
1382 */
1383 @Override
1384 public RealVector mapDivideToSelf(double d)
1385 throws MathUnsupportedOperationException {
1386 throw new MathUnsupportedOperationException();
1387 }
1388
1389 /** {@inheritDoc} */
1390 @Override
1391 public RealVector ebeMultiply(RealVector w)
1392 throws DimensionMismatchException {
1393 return v.ebeMultiply(w);
1394 }
1395
1396 /** {@inheritDoc} */
1397 @Override
1398 public RealVector ebeDivide(RealVector w)
1399 throws DimensionMismatchException {
1400 return v.ebeDivide(w);
1401 }
1402
1403 /** {@inheritDoc} */
1404 @Override
1405 public double dotProduct(RealVector w)
1406 throws DimensionMismatchException {
1407 return v.dotProduct(w);
1408 }
1409
1410 /** {@inheritDoc} */
1411 @Override
1412 public double cosine(RealVector w)
1413 throws DimensionMismatchException, MathArithmeticException {
1414 return v.cosine(w);
1415 }
1416
1417 /** {@inheritDoc} */
1418 @Override
1419 public double getNorm() {
1420 return v.getNorm();
1421 }
1422
1423 /** {@inheritDoc} */
1424 @Override
1425 public double getL1Norm() {
1426 return v.getL1Norm();
1427 }
1428
1429 /** {@inheritDoc} */
1430 @Override
1431 public double getLInfNorm() {
1432 return v.getLInfNorm();
1433 }
1434
1435 /** {@inheritDoc} */
1436 @Override
1437 public double getDistance(RealVector w)
1438 throws DimensionMismatchException {
1439 return v.getDistance(w);
1440 }
1441
1442 /** {@inheritDoc} */
1443 @Override
1444 public double getL1Distance(RealVector w)
1445 throws DimensionMismatchException {
1446 return v.getL1Distance(w);
1447 }
1448
1449 /** {@inheritDoc} */
1450 @Override
1451 public double getLInfDistance(RealVector w)
1452 throws DimensionMismatchException {
1453 return v.getLInfDistance(w);
1454 }
1455
1456 /** {@inheritDoc} */
1457 @Override
1458 public RealVector unitVector() throws MathArithmeticException {
1459 return v.unitVector();
1460 }
1461
1462 /**
1463 * {@inheritDoc}
1464 *
1465 * @throws MathUnsupportedOperationException in all
1466 * circumstances.
1467 */
1468 @Override
1469 public void unitize() throws MathUnsupportedOperationException {
1470 throw new MathUnsupportedOperationException();
1471 }
1472
1473 /** {@inheritDoc} */
1474 @Override
1475 public RealMatrix outerProduct(RealVector w) {
1476 return v.outerProduct(w);
1477 }
1478
1479 /** {@inheritDoc} */
1480 @Override
1481 public double getEntry(int index) throws OutOfRangeException {
1482 return v.getEntry(index);
1483 }
1484
1485 /**
1486 * {@inheritDoc}
1487 *
1488 * @throws MathUnsupportedOperationException in all
1489 * circumstances.
1490 */
1491 @Override
1492 public void setEntry(int index, double value)
1493 throws MathUnsupportedOperationException {
1494 throw new MathUnsupportedOperationException();
1495 }
1496
1497 /**
1498 * {@inheritDoc}
1499 *
1500 * @throws MathUnsupportedOperationException in all
1501 * circumstances.
1502 */
1503 @Override
1504 public void addToEntry(int index, double value)
1505 throws MathUnsupportedOperationException {
1506 throw new MathUnsupportedOperationException();
1507 }
1508
1509 /** {@inheritDoc} */
1510 @Override
1511 public int getDimension() {
1512 return v.getDimension();
1513 }
1514
1515 /** {@inheritDoc} */
1516 @Override
1517 public RealVector append(RealVector w) {
1518 return v.append(w);
1519 }
1520
1521 /** {@inheritDoc} */
1522 @Override
1523 public RealVector append(double d) {
1524 return v.append(d);
1525 }
1526
1527 /** {@inheritDoc} */
1528 @Override
1529 public RealVector getSubVector(int index, int n)
1530 throws OutOfRangeException, NotPositiveException {
1531 return v.getSubVector(index, n);
1532 }
1533
1534 /**
1535 * {@inheritDoc}
1536 *
1537 * @throws MathUnsupportedOperationException in all
1538 * circumstances.
1539 */
1540 @Override
1541 public void setSubVector(int index, RealVector w)
1542 throws MathUnsupportedOperationException {
1543 throw new MathUnsupportedOperationException();
1544 }
1545
1546 /**
1547 * {@inheritDoc}
1548 *
1549 * @throws MathUnsupportedOperationException in all
1550 * circumstances.
1551 */
1552 @Override
1553 public void set(double value)
1554 throws MathUnsupportedOperationException {
1555 throw new MathUnsupportedOperationException();
1556 }
1557
1558 /** {@inheritDoc} */
1559 @Override
1560 public double[] toArray() {
1561 return v.toArray();
1562 }
1563
1564 /** {@inheritDoc} */
1565 @Override
1566 public boolean isNaN() {
1567 return v.isNaN();
1568 }
1569
1570 /** {@inheritDoc} */
1571 @Override
1572 public boolean isInfinite() {
1573 return v.isInfinite();
1574 }
1575
1576 /** {@inheritDoc} */
1577 @Override
1578 public RealVector combine(double a, double b, RealVector y)
1579 throws DimensionMismatchException {
1580 return v.combine(a, b, y);
1581 }
1582
1583 /**
1584 * {@inheritDoc}
1585 *
1586 * @throws MathUnsupportedOperationException in all
1587 * circumstances.
1588 */
1589 @Override
1590 public RealVector combineToSelf(double a, double b, RealVector y)
1591 throws MathUnsupportedOperationException {
1592 throw new MathUnsupportedOperationException();
1593 }
1594
1595 /** An entry in the vector. */
1596 class UnmodifiableEntry extends Entry {
1597 /** {@inheritDoc} */
1598 @Override
1599 public double getValue() {
1600 return v.getEntry(getIndex());
1601 }
1602
1603 /**
1604 * {@inheritDoc}
1605 *
1606 * @throws MathUnsupportedOperationException in all
1607 * circumstances.
1608 */
1609 @Override
1610 public void setValue(double value)
1611 throws MathUnsupportedOperationException {
1612 throw new MathUnsupportedOperationException();
1613 }
1614 }
1615 };
1616 }
1617 }