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