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.math.linear; 018 019 import java.io.Serializable; 020 import java.util.Arrays; 021 022 import org.apache.commons.math.MathRuntimeException; 023 import org.apache.commons.math.util.MathUtils; 024 025 /** 026 * This class implements the {@link RealVector} interface with a double array. 027 * @version $Revision: 783702 $ $Date: 2009-06-11 04:54:02 -0400 (Thu, 11 Jun 2009) $ 028 * @since 2.0 029 */ 030 public class ArrayRealVector implements RealVector, Serializable { 031 032 /** Serializable version identifier. */ 033 private static final long serialVersionUID = -1097961340710804027L; 034 035 /** Default format. */ 036 private static final RealVectorFormat DEFAULT_FORMAT = 037 RealVectorFormat.getInstance(); 038 039 /** Entries of the vector. */ 040 protected double data[]; 041 042 /** 043 * Build a 0-length vector. 044 * <p>Zero-length vectors may be used to initialized construction of vectors 045 * by data gathering. We start with zero-length and use either the {@link 046 * #ArrayRealVector(ArrayRealVector, ArrayRealVector)} constructor 047 * or one of the <code>append</code> method ({@link #append(double)}, {@link 048 * #append(double[])}, {@link #append(ArrayRealVector)}) to gather data 049 * into this vector.</p> 050 */ 051 public ArrayRealVector() { 052 data = new double[0]; 053 } 054 055 /** 056 * Construct a (size)-length vector of zeros. 057 * @param size size of the vector 058 */ 059 public ArrayRealVector(int size) { 060 data = new double[size]; 061 } 062 063 /** 064 * Construct an (size)-length vector with preset values. 065 * @param size size of the vector 066 * @param preset fill the vector with this scalar value 067 */ 068 public ArrayRealVector(int size, double preset) { 069 data = new double[size]; 070 Arrays.fill(data, preset); 071 } 072 073 /** 074 * Construct a vector from an array, copying the input array. 075 * @param d array of doubles. 076 */ 077 public ArrayRealVector(double[] d) { 078 data = d.clone(); 079 } 080 081 /** 082 * Create a new ArrayRealVector using the input array as the underlying 083 * data array. 084 * <p>If an array is built specially in order to be embedded in a 085 * ArrayRealVector and not used directly, the <code>copyArray</code> may be 086 * set to <code>false</code. This will prevent the copying and improve 087 * performance as no new array will be built and no data will be copied.</p> 088 * @param d data for new vector 089 * @param copyArray if true, the input array will be copied, otherwise 090 * it will be referenced 091 * @throws IllegalArgumentException if <code>d</code> is empty 092 * @throws NullPointerException if <code>d</code> is null 093 * @see #ArrayRealVector(double[]) 094 */ 095 public ArrayRealVector(double[] d, boolean copyArray) 096 throws NullPointerException, IllegalArgumentException { 097 if (d == null) { 098 throw new NullPointerException(); 099 } 100 if (d.length == 0) { 101 throw MathRuntimeException.createIllegalArgumentException("vector must have at least one element"); 102 } 103 data = copyArray ? d.clone() : d; 104 } 105 106 /** 107 * Construct a vector from part of a array. 108 * @param d array of doubles. 109 * @param pos position of first entry 110 * @param size number of entries to copy 111 */ 112 public ArrayRealVector(double[] d, int pos, int size) { 113 if (d.length < pos + size) { 114 throw MathRuntimeException.createIllegalArgumentException( 115 "position {0} and size {1} don't fit to the size of the input array {2}", 116 pos, size, d.length); 117 } 118 data = new double[size]; 119 System.arraycopy(d, pos, data, 0, size); 120 } 121 122 /** 123 * Construct a vector from an array. 124 * @param d array of Doubles. 125 */ 126 public ArrayRealVector(Double[] d) { 127 data = new double[d.length]; 128 for (int i = 0; i < d.length; i++) { 129 data[i] = d[i].doubleValue(); 130 } 131 } 132 133 /** 134 * Construct a vector from part of a Double array 135 * @param d array of Doubles. 136 * @param pos position of first entry 137 * @param size number of entries to copy 138 */ 139 public ArrayRealVector(Double[] d, int pos, int size) { 140 if (d.length < pos + size) { 141 throw MathRuntimeException.createIllegalArgumentException( 142 "position {0} and size {1} don't fit to the size of the input array {2}", 143 pos, size, d.length); 144 } 145 data = new double[size]; 146 for (int i = pos; i < pos + size; i++) { 147 data[i-pos] = d[i].doubleValue(); 148 } 149 } 150 151 /** 152 * Construct a vector from another vector, using a deep copy. 153 * @param v vector to copy 154 */ 155 public ArrayRealVector(RealVector v) { 156 data = new double[v.getDimension()]; 157 for (int i = 0; i < data.length; ++i) { 158 data[i] = v.getEntry(i); 159 } 160 } 161 162 /** 163 * Construct a vector from another vector, using a deep copy. 164 * @param v vector to copy 165 */ 166 public ArrayRealVector(ArrayRealVector v) { 167 data = v.data.clone(); 168 } 169 170 /** 171 * Construct a vector from another vector. 172 * @param v vector to copy 173 * @param deep if true perform a deep copy otherwise perform a shallow copy 174 */ 175 public ArrayRealVector(ArrayRealVector v, boolean deep) { 176 data = deep ? v.data.clone() : v.data; 177 } 178 179 /** 180 * Construct a vector by appending one vector to another vector. 181 * @param v1 first vector (will be put in front of the new vector) 182 * @param v2 second vector (will be put at back of the new vector) 183 */ 184 public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2) { 185 data = new double[v1.data.length + v2.data.length]; 186 System.arraycopy(v1.data, 0, data, 0, v1.data.length); 187 System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length); 188 } 189 190 /** 191 * Construct a vector by appending one vector to another vector. 192 * @param v1 first vector (will be put in front of the new vector) 193 * @param v2 second vector (will be put at back of the new vector) 194 */ 195 public ArrayRealVector(ArrayRealVector v1, double[] v2) { 196 data = new double[v1.data.length + v2.length]; 197 System.arraycopy(v1.data, 0, data, 0, v1.data.length); 198 System.arraycopy(v2, 0, data, v1.data.length, v2.length); 199 } 200 201 /** 202 * Construct a vector by appending one vector to another vector. 203 * @param v1 first vector (will be put in front of the new vector) 204 * @param v2 second vector (will be put at back of the new vector) 205 */ 206 public ArrayRealVector(double[] v1, ArrayRealVector v2) { 207 data = new double[v1.length + v2.data.length]; 208 System.arraycopy(v1, 0, data, 0, v1.length); 209 System.arraycopy(v2.data, 0, data, v1.length, v2.data.length); 210 } 211 212 /** 213 * Construct a vector by appending one vector to another vector. 214 * @param v1 first vector (will be put in front of the new vector) 215 * @param v2 second vector (will be put at back of the new vector) 216 */ 217 public ArrayRealVector(double[] v1, double[] v2) { 218 data = new double[v1.length + v2.length]; 219 System.arraycopy(v1, 0, data, 0, v1.length); 220 System.arraycopy(v2, 0, data, v1.length, v2.length); 221 } 222 223 /** {@inheritDoc} */ 224 public RealVector copy() { 225 return new ArrayRealVector(this, true); 226 } 227 228 /** {@inheritDoc} */ 229 public RealVector add(RealVector v) 230 throws IllegalArgumentException { 231 try { 232 return add((ArrayRealVector) v); 233 } catch (ClassCastException cce) { 234 checkVectorDimensions(v); 235 double[] out = new double[data.length]; 236 for (int i = 0; i < data.length; i++) { 237 out[i] = data[i] + v.getEntry(i); 238 } 239 return new ArrayRealVector(out); 240 } 241 } 242 243 /** {@inheritDoc} */ 244 public RealVector add(double[] v) 245 throws IllegalArgumentException { 246 checkVectorDimensions(v.length); 247 double[] out = new double[data.length]; 248 for (int i = 0; i < data.length; i++) { 249 out[i] = data[i] + v[i]; 250 } 251 return new ArrayRealVector(out); 252 } 253 254 /** 255 * Compute the sum of this and v. 256 * @param v vector to be added 257 * @return this + v 258 * @throws IllegalArgumentException if v is not the same size as this 259 */ 260 public ArrayRealVector add(ArrayRealVector v) 261 throws IllegalArgumentException { 262 return (ArrayRealVector) add(v.data); 263 } 264 265 /** {@inheritDoc} */ 266 public RealVector subtract(RealVector v) 267 throws IllegalArgumentException { 268 try { 269 return subtract((ArrayRealVector) v); 270 } catch (ClassCastException cce) { 271 checkVectorDimensions(v); 272 double[] out = new double[data.length]; 273 for (int i = 0; i < data.length; i++) { 274 out[i] = data[i] - v.getEntry(i); 275 } 276 return new ArrayRealVector(out); 277 } 278 } 279 280 /** {@inheritDoc} */ 281 public RealVector subtract(double[] v) 282 throws IllegalArgumentException { 283 checkVectorDimensions(v.length); 284 double[] out = new double[data.length]; 285 for (int i = 0; i < data.length; i++) { 286 out[i] = data[i] - v[i]; 287 } 288 return new ArrayRealVector(out); 289 } 290 291 /** 292 * Compute this minus v. 293 * @param v vector to be subtracted 294 * @return this + v 295 * @throws IllegalArgumentException if v is not the same size as this 296 */ 297 public ArrayRealVector subtract(ArrayRealVector v) 298 throws IllegalArgumentException { 299 return (ArrayRealVector) subtract(v.data); 300 } 301 302 /** {@inheritDoc} */ 303 public RealVector mapAdd(double d) { 304 double[] out = new double[data.length]; 305 for (int i = 0; i < data.length; i++) { 306 out[i] = data[i] + d; 307 } 308 return new ArrayRealVector(out); 309 } 310 311 /** {@inheritDoc} */ 312 public RealVector mapAddToSelf(double d) { 313 for (int i = 0; i < data.length; i++) { 314 data[i] = data[i] + d; 315 } 316 return this; 317 } 318 319 /** {@inheritDoc} */ 320 public RealVector mapSubtract(double d) { 321 double[] out = new double[data.length]; 322 for (int i = 0; i < data.length; i++) { 323 out[i] = data[i] - d; 324 } 325 return new ArrayRealVector(out); 326 } 327 328 /** {@inheritDoc} */ 329 public RealVector mapSubtractToSelf(double d) { 330 for (int i = 0; i < data.length; i++) { 331 data[i] = data[i] - d; 332 } 333 return this; 334 } 335 336 /** {@inheritDoc} */ 337 public RealVector mapMultiply(double d) { 338 double[] out = new double[data.length]; 339 for (int i = 0; i < data.length; i++) { 340 out[i] = data[i] * d; 341 } 342 return new ArrayRealVector(out); 343 } 344 345 /** {@inheritDoc} */ 346 public RealVector mapMultiplyToSelf(double d) { 347 for (int i = 0; i < data.length; i++) { 348 data[i] = data[i] * d; 349 } 350 return this; 351 } 352 353 /** {@inheritDoc} */ 354 public RealVector mapDivide(double d) { 355 double[] out = new double[data.length]; 356 for (int i = 0; i < data.length; i++) { 357 out[i] = data[i] / d; 358 } 359 return new ArrayRealVector(out); 360 } 361 362 /** {@inheritDoc} */ 363 public RealVector mapDivideToSelf(double d) { 364 for (int i = 0; i < data.length; i++) { 365 data[i] = data[i] / d; 366 } 367 return this; 368 } 369 370 /** {@inheritDoc} */ 371 public RealVector mapPow(double d) { 372 double[] out = new double[data.length]; 373 for (int i = 0; i < data.length; i++) { 374 out[i] = Math.pow(data[i], d); 375 } 376 return new ArrayRealVector(out); 377 } 378 379 /** {@inheritDoc} */ 380 public RealVector mapPowToSelf(double d) { 381 for (int i = 0; i < data.length; i++) { 382 data[i] = Math.pow(data[i], d); 383 } 384 return this; 385 } 386 387 /** {@inheritDoc} */ 388 public RealVector mapExp() { 389 double[] out = new double[data.length]; 390 for (int i = 0; i < data.length; i++) { 391 out[i] = Math.exp(data[i]); 392 } 393 return new ArrayRealVector(out); 394 } 395 396 /** {@inheritDoc} */ 397 public RealVector mapExpToSelf() { 398 for (int i = 0; i < data.length; i++) { 399 data[i] = Math.exp(data[i]); 400 } 401 return this; 402 } 403 404 /** {@inheritDoc} */ 405 public RealVector mapExpm1() { 406 double[] out = new double[data.length]; 407 for (int i = 0; i < data.length; i++) { 408 out[i] = Math.expm1(data[i]); 409 } 410 return new ArrayRealVector(out); 411 } 412 413 /** {@inheritDoc} */ 414 public RealVector mapExpm1ToSelf() { 415 for (int i = 0; i < data.length; i++) { 416 data[i] = Math.expm1(data[i]); 417 } 418 return this; 419 } 420 421 /** {@inheritDoc} */ 422 public RealVector mapLog() { 423 double[] out = new double[data.length]; 424 for (int i = 0; i < data.length; i++) { 425 out[i] = Math.log(data[i]); 426 } 427 return new ArrayRealVector(out); 428 } 429 430 /** {@inheritDoc} */ 431 public RealVector mapLogToSelf() { 432 for (int i = 0; i < data.length; i++) { 433 data[i] = Math.log(data[i]); 434 } 435 return this; 436 } 437 438 /** {@inheritDoc} */ 439 public RealVector mapLog10() { 440 double[] out = new double[data.length]; 441 for (int i = 0; i < data.length; i++) { 442 out[i] = Math.log10(data[i]); 443 } 444 return new ArrayRealVector(out); 445 } 446 447 /** {@inheritDoc} */ 448 public RealVector mapLog10ToSelf() { 449 for (int i = 0; i < data.length; i++) { 450 data[i] = Math.log10(data[i]); 451 } 452 return this; 453 } 454 455 /** {@inheritDoc} */ 456 public RealVector mapLog1p() { 457 double[] out = new double[data.length]; 458 for (int i = 0; i < data.length; i++) { 459 out[i] = Math.log1p(data[i]); 460 } 461 return new ArrayRealVector(out); 462 } 463 464 /** {@inheritDoc} */ 465 public RealVector mapLog1pToSelf() { 466 for (int i = 0; i < data.length; i++) { 467 data[i] = Math.log1p(data[i]); 468 } 469 return this; 470 } 471 472 /** {@inheritDoc} */ 473 public RealVector mapCosh() { 474 double[] out = new double[data.length]; 475 for (int i = 0; i < data.length; i++) { 476 out[i] = Math.cosh(data[i]); 477 } 478 return new ArrayRealVector(out); 479 } 480 481 /** {@inheritDoc} */ 482 public RealVector mapCoshToSelf() { 483 for (int i = 0; i < data.length; i++) { 484 data[i] = Math.cosh(data[i]); 485 } 486 return this; 487 } 488 489 /** {@inheritDoc} */ 490 public RealVector mapSinh() { 491 double[] out = new double[data.length]; 492 for (int i = 0; i < data.length; i++) { 493 out[i] = Math.sinh(data[i]); 494 } 495 return new ArrayRealVector(out); 496 } 497 498 /** {@inheritDoc} */ 499 public RealVector mapSinhToSelf() { 500 for (int i = 0; i < data.length; i++) { 501 data[i] = Math.sinh(data[i]); 502 } 503 return this; 504 } 505 506 /** {@inheritDoc} */ 507 public RealVector mapTanh() { 508 double[] out = new double[data.length]; 509 for (int i = 0; i < data.length; i++) { 510 out[i] = Math.tanh(data[i]); 511 } 512 return new ArrayRealVector(out); 513 } 514 515 /** {@inheritDoc} */ 516 public RealVector mapTanhToSelf() { 517 for (int i = 0; i < data.length; i++) { 518 data[i] = Math.tanh(data[i]); 519 } 520 return this; 521 } 522 523 /** {@inheritDoc} */ 524 public RealVector mapCos() { 525 double[] out = new double[data.length]; 526 for (int i = 0; i < data.length; i++) { 527 out[i] = Math.cos(data[i]); 528 } 529 return new ArrayRealVector(out); 530 } 531 532 /** {@inheritDoc} */ 533 public RealVector mapCosToSelf() { 534 for (int i = 0; i < data.length; i++) { 535 data[i] = Math.cos(data[i]); 536 } 537 return this; 538 } 539 540 /** {@inheritDoc} */ 541 public RealVector mapSin() { 542 double[] out = new double[data.length]; 543 for (int i = 0; i < data.length; i++) { 544 out[i] = Math.sin(data[i]); 545 } 546 return new ArrayRealVector(out); 547 } 548 549 /** {@inheritDoc} */ 550 public RealVector mapSinToSelf() { 551 for (int i = 0; i < data.length; i++) { 552 data[i] = Math.sin(data[i]); 553 } 554 return this; 555 } 556 557 /** {@inheritDoc} */ 558 public RealVector mapTan() { 559 double[] out = new double[data.length]; 560 for (int i = 0; i < data.length; i++) { 561 out[i] = Math.tan(data[i]); 562 } 563 return new ArrayRealVector(out); 564 } 565 566 /** {@inheritDoc} */ 567 public RealVector mapTanToSelf() { 568 for (int i = 0; i < data.length; i++) { 569 data[i] = Math.tan(data[i]); 570 } 571 return this; 572 } 573 574 /** {@inheritDoc} */ 575 public RealVector mapAcos() { 576 double[] out = new double[data.length]; 577 for (int i = 0; i < data.length; i++) { 578 out[i] = Math.acos(data[i]); 579 } 580 return new ArrayRealVector(out); 581 } 582 583 /** {@inheritDoc} */ 584 public RealVector mapAcosToSelf() { 585 for (int i = 0; i < data.length; i++) { 586 data[i] = Math.acos(data[i]); 587 } 588 return this; 589 } 590 591 /** {@inheritDoc} */ 592 public RealVector mapAsin() { 593 double[] out = new double[data.length]; 594 for (int i = 0; i < data.length; i++) { 595 out[i] = Math.asin(data[i]); 596 } 597 return new ArrayRealVector(out); 598 } 599 600 /** {@inheritDoc} */ 601 public RealVector mapAsinToSelf() { 602 for (int i = 0; i < data.length; i++) { 603 data[i] = Math.asin(data[i]); 604 } 605 return this; 606 } 607 608 /** {@inheritDoc} */ 609 public RealVector mapAtan() { 610 double[] out = new double[data.length]; 611 for (int i = 0; i < data.length; i++) { 612 out[i] = Math.atan(data[i]); 613 } 614 return new ArrayRealVector(out); 615 } 616 617 /** {@inheritDoc} */ 618 public RealVector mapAtanToSelf() { 619 for (int i = 0; i < data.length; i++) { 620 data[i] = Math.atan(data[i]); 621 } 622 return this; 623 } 624 625 /** {@inheritDoc} */ 626 public RealVector mapInv() { 627 double[] out = new double[data.length]; 628 for (int i = 0; i < data.length; i++) { 629 out[i] = 1.0 / data[i]; 630 } 631 return new ArrayRealVector(out); 632 } 633 634 /** {@inheritDoc} */ 635 public RealVector mapInvToSelf() { 636 for (int i = 0; i < data.length; i++) { 637 data[i] = 1.0 / data[i]; 638 } 639 return this; 640 } 641 642 /** {@inheritDoc} */ 643 public RealVector mapAbs() { 644 double[] out = new double[data.length]; 645 for (int i = 0; i < data.length; i++) { 646 out[i] = Math.abs(data[i]); 647 } 648 return new ArrayRealVector(out); 649 } 650 651 /** {@inheritDoc} */ 652 public RealVector mapAbsToSelf() { 653 for (int i = 0; i < data.length; i++) { 654 data[i] = Math.abs(data[i]); 655 } 656 return this; 657 } 658 659 /** {@inheritDoc} */ 660 public RealVector mapSqrt() { 661 double[] out = new double[data.length]; 662 for (int i = 0; i < data.length; i++) { 663 out[i] = Math.sqrt(data[i]); 664 } 665 return new ArrayRealVector(out); 666 } 667 668 /** {@inheritDoc} */ 669 public RealVector mapSqrtToSelf() { 670 for (int i = 0; i < data.length; i++) { 671 data[i] = Math.sqrt(data[i]); 672 } 673 return this; 674 } 675 676 /** {@inheritDoc} */ 677 public RealVector mapCbrt() { 678 double[] out = new double[data.length]; 679 for (int i = 0; i < data.length; i++) { 680 out[i] = Math.cbrt(data[i]); 681 } 682 return new ArrayRealVector(out); 683 } 684 685 /** {@inheritDoc} */ 686 public RealVector mapCbrtToSelf() { 687 for (int i = 0; i < data.length; i++) { 688 data[i] = Math.cbrt(data[i]); 689 } 690 return this; 691 } 692 693 /** {@inheritDoc} */ 694 public RealVector mapCeil() { 695 double[] out = new double[data.length]; 696 for (int i = 0; i < data.length; i++) { 697 out[i] = Math.ceil(data[i]); 698 } 699 return new ArrayRealVector(out); 700 } 701 702 /** {@inheritDoc} */ 703 public RealVector mapCeilToSelf() { 704 for (int i = 0; i < data.length; i++) { 705 data[i] = Math.ceil(data[i]); 706 } 707 return this; 708 } 709 710 /** {@inheritDoc} */ 711 public RealVector mapFloor() { 712 double[] out = new double[data.length]; 713 for (int i = 0; i < data.length; i++) { 714 out[i] = Math.floor(data[i]); 715 } 716 return new ArrayRealVector(out); 717 } 718 719 /** {@inheritDoc} */ 720 public RealVector mapFloorToSelf() { 721 for (int i = 0; i < data.length; i++) { 722 data[i] = Math.floor(data[i]); 723 } 724 return this; 725 } 726 727 /** {@inheritDoc} */ 728 public RealVector mapRint() { 729 double[] out = new double[data.length]; 730 for (int i = 0; i < data.length; i++) { 731 out[i] = Math.rint(data[i]); 732 } 733 return new ArrayRealVector(out); 734 } 735 736 /** {@inheritDoc} */ 737 public RealVector mapRintToSelf() { 738 for (int i = 0; i < data.length; i++) { 739 data[i] = Math.rint(data[i]); 740 } 741 return this; 742 } 743 744 /** {@inheritDoc} */ 745 public RealVector mapSignum() { 746 double[] out = new double[data.length]; 747 for (int i = 0; i < data.length; i++) { 748 out[i] = Math.signum(data[i]); 749 } 750 return new ArrayRealVector(out); 751 } 752 753 /** {@inheritDoc} */ 754 public RealVector mapSignumToSelf() { 755 for (int i = 0; i < data.length; i++) { 756 data[i] = Math.signum(data[i]); 757 } 758 return this; 759 } 760 761 /** {@inheritDoc} */ 762 public RealVector mapUlp() { 763 double[] out = new double[data.length]; 764 for (int i = 0; i < data.length; i++) { 765 out[i] = Math.ulp(data[i]); 766 } 767 return new ArrayRealVector(out); 768 } 769 770 /** {@inheritDoc} */ 771 public RealVector mapUlpToSelf() { 772 for (int i = 0; i < data.length; i++) { 773 data[i] = Math.ulp(data[i]); 774 } 775 return this; 776 } 777 778 /** {@inheritDoc} */ 779 public RealVector ebeMultiply(RealVector v) 780 throws IllegalArgumentException { 781 try { 782 return ebeMultiply((ArrayRealVector) v); 783 } catch (ClassCastException cce) { 784 checkVectorDimensions(v); 785 double[] out = new double[data.length]; 786 for (int i = 0; i < data.length; i++) { 787 out[i] = data[i] * v.getEntry(i); 788 } 789 return new ArrayRealVector(out); 790 } 791 } 792 793 /** {@inheritDoc} */ 794 public RealVector ebeMultiply(double[] v) 795 throws IllegalArgumentException { 796 checkVectorDimensions(v.length); 797 double[] out = new double[data.length]; 798 for (int i = 0; i < data.length; i++) { 799 out[i] = data[i] * v[i]; 800 } 801 return new ArrayRealVector(out); 802 } 803 804 /** 805 * Element-by-element multiplication. 806 * @param v vector by which instance elements must be multiplied 807 * @return a vector containing this[i] * v[i] for all i 808 * @exception IllegalArgumentException if v is not the same size as this 809 */ 810 public ArrayRealVector ebeMultiply(ArrayRealVector v) 811 throws IllegalArgumentException { 812 return (ArrayRealVector) ebeMultiply(v.data); 813 } 814 815 /** {@inheritDoc} */ 816 public RealVector ebeDivide(RealVector v) 817 throws IllegalArgumentException { 818 try { 819 return ebeDivide((ArrayRealVector) v); 820 } catch (ClassCastException cce) { 821 checkVectorDimensions(v); 822 double[] out = new double[data.length]; 823 for (int i = 0; i < data.length; i++) { 824 out[i] = data[i] / v.getEntry(i); 825 } 826 return new ArrayRealVector(out); 827 } 828 } 829 830 /** {@inheritDoc} */ 831 public RealVector ebeDivide(double[] v) 832 throws IllegalArgumentException { 833 checkVectorDimensions(v.length); 834 double[] out = new double[data.length]; 835 for (int i = 0; i < data.length; i++) { 836 out[i] = data[i] / v[i]; 837 } 838 return new ArrayRealVector(out); 839 } 840 841 /** 842 * Element-by-element division. 843 * @param v vector by which instance elements must be divided 844 * @return a vector containing this[i] / v[i] for all i 845 * @throws IllegalArgumentException if v is not the same size as this 846 */ 847 public ArrayRealVector ebeDivide(ArrayRealVector v) 848 throws IllegalArgumentException { 849 return (ArrayRealVector) ebeDivide(v.data); 850 } 851 852 /** {@inheritDoc} */ 853 public double[] getData() { 854 return data.clone(); 855 } 856 857 /** 858 * Returns a reference to the underlying data array. 859 * <p>Does not make a fresh copy of the underlying data.</p> 860 * @return array of entries 861 */ 862 public double[] getDataRef() { 863 return data; 864 } 865 866 /** {@inheritDoc} */ 867 public double dotProduct(RealVector v) 868 throws IllegalArgumentException { 869 try { 870 return dotProduct((ArrayRealVector) v); 871 } catch (ClassCastException cce) { 872 checkVectorDimensions(v); 873 double dot = 0; 874 for (int i = 0; i < data.length; i++) { 875 dot += data[i] * v.getEntry(i); 876 } 877 return dot; 878 } 879 } 880 881 /** {@inheritDoc} */ 882 public double dotProduct(double[] v) 883 throws IllegalArgumentException { 884 checkVectorDimensions(v.length); 885 double dot = 0; 886 for (int i = 0; i < data.length; i++) { 887 dot += data[i] * v[i]; 888 } 889 return dot; 890 } 891 892 /** 893 * Compute the dot product. 894 * @param v vector with which dot product should be computed 895 * @return the scalar dot product between instance and v 896 * @exception IllegalArgumentException if v is not the same size as this 897 */ 898 public double dotProduct(ArrayRealVector v) 899 throws IllegalArgumentException { 900 return dotProduct(v.data); 901 } 902 903 /** {@inheritDoc} */ 904 public double getNorm() { 905 double sum = 0; 906 for (double a : data) { 907 sum += a * a; 908 } 909 return Math.sqrt(sum); 910 } 911 912 /** {@inheritDoc} */ 913 public double getL1Norm() { 914 double sum = 0; 915 for (double a : data) { 916 sum += Math.abs(a); 917 } 918 return sum; 919 } 920 921 /** {@inheritDoc} */ 922 public double getLInfNorm() { 923 double max = 0; 924 for (double a : data) { 925 max += Math.max(max, Math.abs(a)); 926 } 927 return max; 928 } 929 930 /** {@inheritDoc} */ 931 public double getDistance(RealVector v) 932 throws IllegalArgumentException { 933 try { 934 return getDistance((ArrayRealVector) v); 935 } catch (ClassCastException cce) { 936 checkVectorDimensions(v); 937 double sum = 0; 938 for (int i = 0; i < data.length; ++i) { 939 final double delta = data[i] - v.getEntry(i); 940 sum += delta * delta; 941 } 942 return Math.sqrt(sum); 943 } 944 } 945 946 /** {@inheritDoc} */ 947 public double getDistance(double[] v) 948 throws IllegalArgumentException { 949 checkVectorDimensions(v.length); 950 double sum = 0; 951 for (int i = 0; i < data.length; ++i) { 952 final double delta = data[i] - v[i]; 953 sum += delta * delta; 954 } 955 return Math.sqrt(sum); 956 } 957 958 /** 959 * Distance between two vectors. 960 * <p>This method computes the distance consistent with the 961 * L<sub>2</sub> norm, i.e. the square root of the sum of 962 * elements differences, or euclidian distance.</p> 963 * @param v vector to which distance is requested 964 * @return distance between two vectors. 965 * @exception IllegalArgumentException if v is not the same size as this 966 * @see #getDistance(RealVector) 967 * @see #getL1Distance(ArrayRealVector) 968 * @see #getLInfDistance(ArrayRealVector) 969 * @see #getNorm() 970 */ 971 public double getDistance(ArrayRealVector v) 972 throws IllegalArgumentException { 973 return getDistance(v.data); 974 } 975 976 /** {@inheritDoc} */ 977 public double getL1Distance(RealVector v) 978 throws IllegalArgumentException { 979 try { 980 return getL1Distance((ArrayRealVector) v); 981 } catch (ClassCastException cce) { 982 checkVectorDimensions(v); 983 double sum = 0; 984 for (int i = 0; i < data.length; ++i) { 985 final double delta = data[i] - v.getEntry(i); 986 sum += Math.abs(delta); 987 } 988 return sum; 989 } 990 } 991 992 /** {@inheritDoc} */ 993 public double getL1Distance(double[] v) 994 throws IllegalArgumentException { 995 checkVectorDimensions(v.length); 996 double sum = 0; 997 for (int i = 0; i < data.length; ++i) { 998 final double delta = data[i] - v[i]; 999 sum += Math.abs(delta); 1000 } 1001 return sum; 1002 } 1003 1004 /** 1005 * Distance between two vectors. 1006 * <p>This method computes the distance consistent with 1007 * L<sub>1</sub> norm, i.e. the sum of the absolute values of 1008 * elements differences.</p> 1009 * @param v vector to which distance is requested 1010 * @return distance between two vectors. 1011 * @exception IllegalArgumentException if v is not the same size as this 1012 * @see #getDistance(RealVector) 1013 * @see #getL1Distance(ArrayRealVector) 1014 * @see #getLInfDistance(ArrayRealVector) 1015 * @see #getNorm() 1016 */ 1017 public double getL1Distance(ArrayRealVector v) 1018 throws IllegalArgumentException { 1019 return getL1Distance(v.data); 1020 } 1021 1022 /** {@inheritDoc} */ 1023 public double getLInfDistance(RealVector v) 1024 throws IllegalArgumentException { 1025 try { 1026 return getLInfDistance((ArrayRealVector) v); 1027 } catch (ClassCastException cce) { 1028 checkVectorDimensions(v); 1029 double max = 0; 1030 for (int i = 0; i < data.length; ++i) { 1031 final double delta = data[i] - v.getEntry(i); 1032 max = Math.max(max, Math.abs(delta)); 1033 } 1034 return max; 1035 } 1036 } 1037 1038 /** {@inheritDoc} */ 1039 public double getLInfDistance(double[] v) 1040 throws IllegalArgumentException { 1041 checkVectorDimensions(v.length); 1042 double max = 0; 1043 for (int i = 0; i < data.length; ++i) { 1044 final double delta = data[i] - v[i]; 1045 max = Math.max(max, Math.abs(delta)); 1046 } 1047 return max; 1048 } 1049 1050 /** 1051 * Distance between two vectors. 1052 * <p>This method computes the distance consistent with 1053 * L<sub>∞</sub> norm, i.e. the max of the absolute values of 1054 * elements differences.</p> 1055 * @param v vector to which distance is requested 1056 * @return distance between two vectors. 1057 * @exception IllegalArgumentException if v is not the same size as this 1058 * @see #getDistance(RealVector) 1059 * @see #getL1Distance(ArrayRealVector) 1060 * @see #getLInfDistance(ArrayRealVector) 1061 * @see #getNorm() 1062 */ 1063 public double getLInfDistance(ArrayRealVector v) 1064 throws IllegalArgumentException { 1065 return getLInfDistance(v.data); 1066 } 1067 1068 /** {@inheritDoc} */ 1069 public RealVector unitVector() throws ArithmeticException { 1070 final double norm = getNorm(); 1071 if (norm == 0) { 1072 throw MathRuntimeException.createArithmeticException("zero norm"); 1073 } 1074 return mapDivide(getNorm()); 1075 } 1076 1077 /** {@inheritDoc} */ 1078 public void unitize() throws ArithmeticException { 1079 final double norm = getNorm(); 1080 if (norm == 0) { 1081 throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector"); 1082 } 1083 for (int i = 0; i < data.length; i++) { 1084 data[i] /= norm; 1085 } 1086 } 1087 1088 /** {@inheritDoc} */ 1089 public RealVector projection(RealVector v) { 1090 return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); 1091 } 1092 1093 /** {@inheritDoc} */ 1094 public RealVector projection(double[] v) { 1095 return projection(new ArrayRealVector(v, false)); 1096 } 1097 1098 /** Find the orthogonal projection of this vector onto another vector. 1099 * @param v vector onto which instance must be projected 1100 * @return projection of the instance onto v 1101 * @throws IllegalArgumentException if v is not the same size as this 1102 */ 1103 public ArrayRealVector projection(ArrayRealVector v) { 1104 return (ArrayRealVector) v.mapMultiply(dotProduct(v) / v.dotProduct(v)); 1105 } 1106 1107 /** {@inheritDoc} */ 1108 public RealMatrix outerProduct(RealVector v) 1109 throws IllegalArgumentException { 1110 try { 1111 return outerProduct((ArrayRealVector) v); 1112 } catch (ClassCastException cce) { 1113 checkVectorDimensions(v); 1114 final int m = data.length; 1115 final RealMatrix out = MatrixUtils.createRealMatrix(m, m); 1116 for (int i = 0; i < data.length; i++) { 1117 for (int j = 0; j < data.length; j++) { 1118 out.setEntry(i, j, data[i] * v.getEntry(j)); 1119 } 1120 } 1121 return out; 1122 } 1123 } 1124 1125 /** 1126 * Compute the outer product. 1127 * @param v vector with which outer product should be computed 1128 * @return the square matrix outer product between instance and v 1129 * @exception IllegalArgumentException if v is not the same size as this 1130 */ 1131 public RealMatrix outerProduct(ArrayRealVector v) 1132 throws IllegalArgumentException { 1133 return outerProduct(v.data); 1134 } 1135 1136 /** {@inheritDoc} */ 1137 public RealMatrix outerProduct(double[] v) 1138 throws IllegalArgumentException { 1139 checkVectorDimensions(v.length); 1140 final int m = data.length; 1141 final RealMatrix out = MatrixUtils.createRealMatrix(m, m); 1142 for (int i = 0; i < data.length; i++) { 1143 for (int j = 0; j < data.length; j++) { 1144 out.setEntry(i, j, data[i] * v[j]); 1145 } 1146 } 1147 return out; 1148 } 1149 1150 /** {@inheritDoc} */ 1151 public double getEntry(int index) throws MatrixIndexException { 1152 return data[index]; 1153 } 1154 1155 /** {@inheritDoc} */ 1156 public int getDimension() { 1157 return data.length; 1158 } 1159 1160 /** {@inheritDoc} */ 1161 public RealVector append(RealVector v) { 1162 try { 1163 return append((ArrayRealVector) v); 1164 } catch (ClassCastException cce) { 1165 return new ArrayRealVector(this,new ArrayRealVector(v)); 1166 } 1167 } 1168 1169 /** 1170 * Construct a vector by appending a vector to this vector. 1171 * @param v vector to append to this one. 1172 * @return a new vector 1173 */ 1174 public ArrayRealVector append(ArrayRealVector v) { 1175 return new ArrayRealVector(this, v); 1176 } 1177 1178 /** {@inheritDoc} */ 1179 public RealVector append(double in) { 1180 final double[] out = new double[data.length + 1]; 1181 System.arraycopy(data, 0, out, 0, data.length); 1182 out[data.length] = in; 1183 return new ArrayRealVector(out); 1184 } 1185 1186 /** {@inheritDoc} */ 1187 public RealVector append(double[] in) { 1188 return new ArrayRealVector(this, in); 1189 } 1190 1191 /** {@inheritDoc} */ 1192 public RealVector getSubVector(int index, int n) { 1193 ArrayRealVector out = new ArrayRealVector(n); 1194 try { 1195 System.arraycopy(data, index, out.data, 0, n); 1196 } catch (IndexOutOfBoundsException e) { 1197 checkIndex(index); 1198 checkIndex(index + n - 1); 1199 } 1200 return out; 1201 } 1202 1203 /** {@inheritDoc} */ 1204 public void setEntry(int index, double value) { 1205 try { 1206 data[index] = value; 1207 } catch (IndexOutOfBoundsException e) { 1208 checkIndex(index); 1209 } 1210 } 1211 1212 /** {@inheritDoc} */ 1213 public void setSubVector(int index, RealVector v) { 1214 try { 1215 try { 1216 set(index, (ArrayRealVector) v); 1217 } catch (ClassCastException cce) { 1218 for (int i = index; i < index + v.getDimension(); ++i) { 1219 data[i] = v.getEntry(i-index); 1220 } 1221 } 1222 } catch (IndexOutOfBoundsException e) { 1223 checkIndex(index); 1224 checkIndex(index + v.getDimension() - 1); 1225 } 1226 } 1227 1228 /** {@inheritDoc} */ 1229 public void setSubVector(int index, double[] v) { 1230 try { 1231 System.arraycopy(v, 0, data, index, v.length); 1232 } catch (IndexOutOfBoundsException e) { 1233 checkIndex(index); 1234 checkIndex(index + v.length - 1); 1235 } 1236 } 1237 1238 /** 1239 * Set a set of consecutive elements. 1240 * 1241 * @param index index of first element to be set. 1242 * @param v vector containing the values to set. 1243 * @exception MatrixIndexException if the index is 1244 * inconsistent with vector size 1245 */ 1246 public void set(int index, ArrayRealVector v) 1247 throws MatrixIndexException { 1248 setSubVector(index, v.data); 1249 } 1250 1251 /** {@inheritDoc} */ 1252 public void set(double value) { 1253 Arrays.fill(data, value); 1254 } 1255 1256 /** {@inheritDoc} */ 1257 public double[] toArray(){ 1258 return data.clone(); 1259 } 1260 1261 /** {@inheritDoc} */ 1262 @Override 1263 public String toString(){ 1264 return DEFAULT_FORMAT.format(this); 1265 } 1266 1267 /** 1268 * Check if instance and specified vectors have the same dimension. 1269 * @param v vector to compare instance with 1270 * @exception IllegalArgumentException if the vectors do not 1271 * have the same dimension 1272 */ 1273 protected void checkVectorDimensions(RealVector v) 1274 throws IllegalArgumentException { 1275 checkVectorDimensions(v.getDimension()); 1276 } 1277 1278 /** 1279 * Check if instance dimension is equal to some expected value. 1280 * 1281 * @param n expected dimension. 1282 * @exception IllegalArgumentException if the dimension is 1283 * inconsistent with vector size 1284 */ 1285 protected void checkVectorDimensions(int n) 1286 throws IllegalArgumentException { 1287 if (data.length != n) { 1288 throw MathRuntimeException.createIllegalArgumentException( 1289 "vector length mismatch: got {0} but expected {1}", 1290 data.length, n); 1291 } 1292 } 1293 1294 /** 1295 * Returns true if any coordinate of this vector is NaN; false otherwise 1296 * @return true if any coordinate of this vector is NaN; false otherwise 1297 */ 1298 public boolean isNaN() { 1299 for (double v : data) { 1300 if (Double.isNaN(v)) { 1301 return true; 1302 } 1303 } 1304 return false; 1305 } 1306 1307 /** 1308 * Returns true if any coordinate of this vector is infinite and none are NaN; 1309 * false otherwise 1310 * @return true if any coordinate of this vector is infinite and none are NaN; 1311 * false otherwise 1312 */ 1313 public boolean isInfinite() { 1314 1315 if (isNaN()) { 1316 return false; 1317 } 1318 1319 for (double v : data) { 1320 if (Double.isInfinite(v)) { 1321 return true; 1322 } 1323 } 1324 1325 return false; 1326 1327 } 1328 1329 /** 1330 * Test for the equality of two real vectors. 1331 * <p> 1332 * If all coordinates of two real vectors are exactly the same, and none are 1333 * <code>Double.NaN</code>, the two real vectors are considered to be equal. 1334 * </p> 1335 * <p> 1336 * <code>NaN</code> coordinates are considered to affect globally the vector 1337 * and be equals to each other - i.e, if either (or all) coordinates of the 1338 * real vector are equal to <code>Double.NaN</code>, the real vector is equal to 1339 * a vector with all <code>Double.NaN</code> coordinates. 1340 * </p> 1341 * 1342 * @param other Object to test for equality to this 1343 * @return true if two vector objects are equal, false if 1344 * object is null, not an instance of RealVector, or 1345 * not equal to this RealVector instance 1346 * 1347 */ 1348 @Override 1349 public boolean equals(Object other) { 1350 1351 if (this == other) { 1352 return true; 1353 } 1354 1355 if (other == null) { 1356 return false; 1357 } 1358 1359 try { 1360 1361 RealVector rhs = (RealVector) other; 1362 if (data.length != rhs.getDimension()) { 1363 return false; 1364 } 1365 1366 if (rhs.isNaN()) { 1367 return this.isNaN(); 1368 } 1369 1370 for (int i = 0; i < data.length; ++i) { 1371 if (data[i] != rhs.getEntry(i)) { 1372 return false; 1373 } 1374 } 1375 return true; 1376 1377 } catch (ClassCastException ex) { 1378 // ignore exception 1379 return false; 1380 } 1381 1382 } 1383 1384 /** 1385 * Get a hashCode for the real vector. 1386 * <p>All NaN values have the same hash code.</p> 1387 * @return a hash code value for this object 1388 */ 1389 @Override 1390 public int hashCode() { 1391 if (isNaN()) { 1392 return 9; 1393 } 1394 return MathUtils.hash(data); 1395 } 1396 1397 /** 1398 * Check if an index is valid. 1399 * @param index index to check 1400 * @exception MatrixIndexException if index is not valid 1401 */ 1402 private void checkIndex(final int index) 1403 throws MatrixIndexException { 1404 if (index < 0 || index >= getDimension()) { 1405 throw new MatrixIndexException( 1406 "index {0} out of allowed range [{1}, {2}]", 1407 index, 0, getDimension() - 1); 1408 } 1409 } 1410 1411 }