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 }