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