1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.commons.math.linear; 19 20 import java.util.Iterator; 21 import java.util.NoSuchElementException; 22 23 import org.apache.commons.math.FunctionEvaluationException; 24 import org.apache.commons.math.exception.MathUnsupportedOperationException; 25 import org.apache.commons.math.exception.DimensionMismatchException; 26 import org.apache.commons.math.analysis.BinaryFunction; 27 import org.apache.commons.math.analysis.ComposableFunction; 28 import org.apache.commons.math.analysis.UnivariateRealFunction; 29 import org.apache.commons.math.exception.util.LocalizedFormats; 30 import org.apache.commons.math.util.FastMath; 31 32 /** 33 * This class provides default basic implementations for many methods in the 34 * {@link RealVector} interface. 35 * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ 36 * @since 2.1 37 */ 38 public abstract class AbstractRealVector implements RealVector { 39 40 /** 41 * Check if instance and specified vectors have the same dimension. 42 * @param v vector to compare instance with 43 * @exception DimensionMismatchException if the vectors do not 44 * have the same dimension 45 */ checkVectorDimensions(RealVector v)46 protected void checkVectorDimensions(RealVector v) { 47 checkVectorDimensions(v.getDimension()); 48 } 49 50 /** 51 * Check if instance dimension is equal to some expected value. 52 * 53 * @param n expected dimension. 54 * @exception DimensionMismatchException if the dimension is 55 * inconsistent with vector size 56 */ checkVectorDimensions(int n)57 protected void checkVectorDimensions(int n) 58 throws DimensionMismatchException { 59 int d = getDimension(); 60 if (d != n) { 61 throw new DimensionMismatchException(d, n); 62 } 63 } 64 65 /** 66 * Check if an index is valid. 67 * @param index index to check 68 * @exception MatrixIndexException if index is not valid 69 */ checkIndex(final int index)70 protected void checkIndex(final int index) 71 throws MatrixIndexException { 72 if (index < 0 || index >= getDimension()) { 73 throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE, 74 index, 0, getDimension() - 1); 75 } 76 } 77 78 /** {@inheritDoc} */ setSubVector(int index, RealVector v)79 public void setSubVector(int index, RealVector v) throws MatrixIndexException { 80 checkIndex(index); 81 checkIndex(index + v.getDimension() - 1); 82 setSubVector(index, v.getData()); 83 } 84 85 /** {@inheritDoc} */ setSubVector(int index, double[] v)86 public void setSubVector(int index, double[] v) throws MatrixIndexException { 87 checkIndex(index); 88 checkIndex(index + v.length - 1); 89 for (int i = 0; i < v.length; i++) { 90 setEntry(i + index, v[i]); 91 } 92 } 93 94 /** {@inheritDoc} */ add(double[] v)95 public RealVector add(double[] v) throws IllegalArgumentException { 96 double[] result = v.clone(); 97 Iterator<Entry> it = sparseIterator(); 98 Entry e; 99 while (it.hasNext() && (e = it.next()) != null) { 100 result[e.getIndex()] += e.getValue(); 101 } 102 return new ArrayRealVector(result, false); 103 } 104 105 /** {@inheritDoc} */ add(RealVector v)106 public RealVector add(RealVector v) throws IllegalArgumentException { 107 if (v instanceof ArrayRealVector) { 108 double[] values = ((ArrayRealVector)v).getDataRef(); 109 return add(values); 110 } 111 RealVector result = v.copy(); 112 Iterator<Entry> it = sparseIterator(); 113 Entry e; 114 while (it.hasNext() && (e = it.next()) != null) { 115 final int index = e.getIndex(); 116 result.setEntry(index, e.getValue() + result.getEntry(index)); 117 } 118 return result; 119 } 120 121 /** {@inheritDoc} */ subtract(double[] v)122 public RealVector subtract(double[] v) throws IllegalArgumentException { 123 double[] result = v.clone(); 124 Iterator<Entry> it = sparseIterator(); 125 Entry e; 126 while (it.hasNext() && (e = it.next()) != null) { 127 final int index = e.getIndex(); 128 result[index] = e.getValue() - result[index]; 129 } 130 return new ArrayRealVector(result, false); 131 } 132 133 /** {@inheritDoc} */ subtract(RealVector v)134 public RealVector subtract(RealVector v) throws IllegalArgumentException { 135 if (v instanceof ArrayRealVector) { 136 double[] values = ((ArrayRealVector)v).getDataRef(); 137 return add(values); 138 } 139 RealVector result = v.copy(); 140 Iterator<Entry> it = sparseIterator(); 141 Entry e; 142 while (it.hasNext() && (e = it.next()) != null) { 143 final int index = e.getIndex(); 144 v.setEntry(index, e.getValue() - result.getEntry(index)); 145 } 146 return result; 147 } 148 149 /** {@inheritDoc} */ mapAdd(double d)150 public RealVector mapAdd(double d) { 151 return copy().mapAddToSelf(d); 152 } 153 154 /** {@inheritDoc} */ mapAddToSelf(double d)155 public RealVector mapAddToSelf(double d) { 156 if (d != 0) { 157 try { 158 return mapToSelf(BinaryFunction.ADD.fix1stArgument(d)); 159 } catch (FunctionEvaluationException e) { 160 throw new IllegalArgumentException(e); 161 } 162 } 163 return this; 164 } 165 166 /** {@inheritDoc} */ copy()167 public abstract AbstractRealVector copy(); 168 169 /** {@inheritDoc} */ dotProduct(double[] v)170 public double dotProduct(double[] v) throws IllegalArgumentException { 171 return dotProduct(new ArrayRealVector(v, false)); 172 } 173 174 /** {@inheritDoc} */ dotProduct(RealVector v)175 public double dotProduct(RealVector v) throws IllegalArgumentException { 176 checkVectorDimensions(v); 177 double d = 0; 178 Iterator<Entry> it = sparseIterator(); 179 Entry e; 180 while (it.hasNext() && (e = it.next()) != null) { 181 d += e.getValue() * v.getEntry(e.getIndex()); 182 } 183 return d; 184 } 185 186 /** {@inheritDoc} */ ebeDivide(double[] v)187 public RealVector ebeDivide(double[] v) throws IllegalArgumentException { 188 return ebeDivide(new ArrayRealVector(v, false)); 189 } 190 191 /** {@inheritDoc} */ ebeMultiply(double[] v)192 public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { 193 return ebeMultiply(new ArrayRealVector(v, false)); 194 } 195 196 /** {@inheritDoc} */ getDistance(RealVector v)197 public double getDistance(RealVector v) throws IllegalArgumentException { 198 checkVectorDimensions(v); 199 double d = 0; 200 Iterator<Entry> it = iterator(); 201 Entry e; 202 while (it.hasNext() && (e = it.next()) != null) { 203 final double diff = e.getValue() - v.getEntry(e.getIndex()); 204 d += diff * diff; 205 } 206 return FastMath.sqrt(d); 207 } 208 209 /** {@inheritDoc} */ getNorm()210 public double getNorm() { 211 double sum = 0; 212 Iterator<Entry> it = sparseIterator(); 213 Entry e; 214 while (it.hasNext() && (e = it.next()) != null) { 215 final double value = e.getValue(); 216 sum += value * value; 217 } 218 return FastMath.sqrt(sum); 219 } 220 221 /** {@inheritDoc} */ getL1Norm()222 public double getL1Norm() { 223 double norm = 0; 224 Iterator<Entry> it = sparseIterator(); 225 Entry e; 226 while (it.hasNext() && (e = it.next()) != null) { 227 norm += FastMath.abs(e.getValue()); 228 } 229 return norm; 230 } 231 232 /** {@inheritDoc} */ getLInfNorm()233 public double getLInfNorm() { 234 double norm = 0; 235 Iterator<Entry> it = sparseIterator(); 236 Entry e; 237 while (it.hasNext() && (e = it.next()) != null) { 238 norm = FastMath.max(norm, FastMath.abs(e.getValue())); 239 } 240 return norm; 241 } 242 243 /** {@inheritDoc} */ getDistance(double[] v)244 public double getDistance(double[] v) throws IllegalArgumentException { 245 return getDistance(new ArrayRealVector(v,false)); 246 } 247 248 /** {@inheritDoc} */ getL1Distance(RealVector v)249 public double getL1Distance(RealVector v) throws IllegalArgumentException { 250 checkVectorDimensions(v); 251 double d = 0; 252 Iterator<Entry> it = iterator(); 253 Entry e; 254 while (it.hasNext() && (e = it.next()) != null) { 255 d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex())); 256 } 257 return d; 258 } 259 260 /** {@inheritDoc} */ getL1Distance(double[] v)261 public double getL1Distance(double[] v) throws IllegalArgumentException { 262 checkVectorDimensions(v.length); 263 double d = 0; 264 Iterator<Entry> it = iterator(); 265 Entry e; 266 while (it.hasNext() && (e = it.next()) != null) { 267 d += FastMath.abs(e.getValue() - v[e.getIndex()]); 268 } 269 return d; 270 } 271 272 /** {@inheritDoc} */ getLInfDistance(RealVector v)273 public double getLInfDistance(RealVector v) throws IllegalArgumentException { 274 checkVectorDimensions(v); 275 double d = 0; 276 Iterator<Entry> it = iterator(); 277 Entry e; 278 while (it.hasNext() && (e = it.next()) != null) { 279 d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d); 280 } 281 return d; 282 } 283 284 /** {@inheritDoc} */ getLInfDistance(double[] v)285 public double getLInfDistance(double[] v) throws IllegalArgumentException { 286 checkVectorDimensions(v.length); 287 double d = 0; 288 Iterator<Entry> it = iterator(); 289 Entry e; 290 while (it.hasNext() && (e = it.next()) != null) { 291 d = FastMath.max(FastMath.abs(e.getValue() - v[e.getIndex()]), d); 292 } 293 return d; 294 } 295 296 /** Get the index of the minimum entry. 297 * @return index of the minimum entry or -1 if vector length is 0 298 * or all entries are NaN 299 */ getMinIndex()300 public int getMinIndex() { 301 int minIndex = -1; 302 double minValue = Double.POSITIVE_INFINITY; 303 Iterator<Entry> iterator = iterator(); 304 while (iterator.hasNext()) { 305 final Entry entry = iterator.next(); 306 if (entry.getValue() <= minValue) { 307 minIndex = entry.getIndex(); 308 minValue = entry.getValue(); 309 } 310 } 311 return minIndex; 312 } 313 314 /** Get the value of the minimum entry. 315 * @return value of the minimum entry or NaN if all entries are NaN 316 */ getMinValue()317 public double getMinValue() { 318 final int minIndex = getMinIndex(); 319 return minIndex < 0 ? Double.NaN : getEntry(minIndex); 320 } 321 322 /** Get the index of the maximum entry. 323 * @return index of the maximum entry or -1 if vector length is 0 324 * or all entries are NaN 325 */ getMaxIndex()326 public int getMaxIndex() { 327 int maxIndex = -1; 328 double maxValue = Double.NEGATIVE_INFINITY; 329 Iterator<Entry> iterator = iterator(); 330 while (iterator.hasNext()) { 331 final Entry entry = iterator.next(); 332 if (entry.getValue() >= maxValue) { 333 maxIndex = entry.getIndex(); 334 maxValue = entry.getValue(); 335 } 336 } 337 return maxIndex; 338 } 339 340 /** Get the value of the maximum entry. 341 * @return value of the maximum entry or NaN if all entries are NaN 342 */ getMaxValue()343 public double getMaxValue() { 344 final int maxIndex = getMaxIndex(); 345 return maxIndex < 0 ? Double.NaN : getEntry(maxIndex); 346 } 347 348 /** {@inheritDoc} */ mapAbs()349 public RealVector mapAbs() { 350 return copy().mapAbsToSelf(); 351 } 352 353 /** {@inheritDoc} */ mapAbsToSelf()354 public RealVector mapAbsToSelf() { 355 try { 356 return mapToSelf(ComposableFunction.ABS); 357 } catch (FunctionEvaluationException e) { 358 throw new IllegalArgumentException(e); 359 } 360 } 361 362 /** {@inheritDoc} */ mapAcos()363 public RealVector mapAcos() { 364 return copy().mapAcosToSelf(); 365 } 366 367 /** {@inheritDoc} */ mapAcosToSelf()368 public RealVector mapAcosToSelf() { 369 try { 370 return mapToSelf(ComposableFunction.ACOS); 371 } catch (FunctionEvaluationException e) { 372 throw new IllegalArgumentException(e); 373 } 374 } 375 376 /** {@inheritDoc} */ mapAsin()377 public RealVector mapAsin() { 378 return copy().mapAsinToSelf(); 379 } 380 381 /** {@inheritDoc} */ mapAsinToSelf()382 public RealVector mapAsinToSelf() { 383 try { 384 return mapToSelf(ComposableFunction.ASIN); 385 } catch (FunctionEvaluationException e) { 386 throw new IllegalArgumentException(e); 387 } 388 } 389 390 /** {@inheritDoc} */ mapAtan()391 public RealVector mapAtan() { 392 return copy().mapAtanToSelf(); 393 } 394 395 /** {@inheritDoc} */ mapAtanToSelf()396 public RealVector mapAtanToSelf() { 397 try { 398 return mapToSelf(ComposableFunction.ATAN); 399 } catch (FunctionEvaluationException e) { 400 throw new IllegalArgumentException(e); 401 } 402 } 403 404 /** {@inheritDoc} */ mapCbrt()405 public RealVector mapCbrt() { 406 return copy().mapCbrtToSelf(); 407 } 408 409 /** {@inheritDoc} */ mapCbrtToSelf()410 public RealVector mapCbrtToSelf() { 411 try { 412 return mapToSelf(ComposableFunction.CBRT); 413 } catch (FunctionEvaluationException e) { 414 throw new IllegalArgumentException(e); 415 } 416 } 417 418 /** {@inheritDoc} */ mapCeil()419 public RealVector mapCeil() { 420 return copy().mapCeilToSelf(); 421 } 422 423 /** {@inheritDoc} */ mapCeilToSelf()424 public RealVector mapCeilToSelf() { 425 try { 426 return mapToSelf(ComposableFunction.CEIL); 427 } catch (FunctionEvaluationException e) { 428 throw new IllegalArgumentException(e); 429 } 430 } 431 432 /** {@inheritDoc} */ mapCos()433 public RealVector mapCos() { 434 return copy().mapCosToSelf(); 435 } 436 437 /** {@inheritDoc} */ mapCosToSelf()438 public RealVector mapCosToSelf() { 439 try { 440 return mapToSelf(ComposableFunction.COS); 441 } catch (FunctionEvaluationException e) { 442 throw new IllegalArgumentException(e); 443 } 444 } 445 446 /** {@inheritDoc} */ mapCosh()447 public RealVector mapCosh() { 448 return copy().mapCoshToSelf(); 449 } 450 451 /** {@inheritDoc} */ mapCoshToSelf()452 public RealVector mapCoshToSelf() { 453 try { 454 return mapToSelf(ComposableFunction.COSH); 455 } catch (FunctionEvaluationException e) { 456 throw new IllegalArgumentException(e); 457 } 458 } 459 460 /** {@inheritDoc} */ mapDivide(double d)461 public RealVector mapDivide(double d) { 462 return copy().mapDivideToSelf(d); 463 } 464 465 /** {@inheritDoc} */ mapDivideToSelf(double d)466 public RealVector mapDivideToSelf(double d){ 467 try { 468 return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d)); 469 } catch (FunctionEvaluationException e) { 470 throw new IllegalArgumentException(e); 471 } 472 } 473 474 /** {@inheritDoc} */ mapExp()475 public RealVector mapExp() { 476 return copy().mapExpToSelf(); 477 } 478 479 /** {@inheritDoc} */ mapExpToSelf()480 public RealVector mapExpToSelf() { 481 try { 482 return mapToSelf(ComposableFunction.EXP); 483 } catch (FunctionEvaluationException e) { 484 throw new IllegalArgumentException(e); 485 } 486 } 487 488 /** {@inheritDoc} */ mapExpm1()489 public RealVector mapExpm1() { 490 return copy().mapExpm1ToSelf(); 491 } 492 493 /** {@inheritDoc} */ mapExpm1ToSelf()494 public RealVector mapExpm1ToSelf() { 495 try { 496 return mapToSelf(ComposableFunction.EXPM1); 497 } catch (FunctionEvaluationException e) { 498 throw new IllegalArgumentException(e); 499 } 500 } 501 502 /** {@inheritDoc} */ mapFloor()503 public RealVector mapFloor() { 504 return copy().mapFloorToSelf(); 505 } 506 507 /** {@inheritDoc} */ mapFloorToSelf()508 public RealVector mapFloorToSelf() { 509 try { 510 return mapToSelf(ComposableFunction.FLOOR); 511 } catch (FunctionEvaluationException e) { 512 throw new IllegalArgumentException(e); 513 } 514 } 515 516 /** {@inheritDoc} */ mapInv()517 public RealVector mapInv() { 518 return copy().mapInvToSelf(); 519 } 520 521 /** {@inheritDoc} */ mapInvToSelf()522 public RealVector mapInvToSelf() { 523 try { 524 return mapToSelf(ComposableFunction.INVERT); 525 } catch (FunctionEvaluationException e) { 526 throw new IllegalArgumentException(e); 527 } 528 } 529 530 /** {@inheritDoc} */ mapLog()531 public RealVector mapLog() { 532 return copy().mapLogToSelf(); 533 } 534 535 /** {@inheritDoc} */ mapLogToSelf()536 public RealVector mapLogToSelf() { 537 try { 538 return mapToSelf(ComposableFunction.LOG); 539 } catch (FunctionEvaluationException e) { 540 throw new IllegalArgumentException(e); 541 } 542 } 543 544 /** {@inheritDoc} */ mapLog10()545 public RealVector mapLog10() { 546 return copy().mapLog10ToSelf(); 547 } 548 549 /** {@inheritDoc} */ mapLog10ToSelf()550 public RealVector mapLog10ToSelf() { 551 try { 552 return mapToSelf(ComposableFunction.LOG10); 553 } catch (FunctionEvaluationException e) { 554 throw new IllegalArgumentException(e); 555 } 556 } 557 558 /** {@inheritDoc} */ mapLog1p()559 public RealVector mapLog1p() { 560 return copy().mapLog1pToSelf(); 561 } 562 563 /** {@inheritDoc} */ mapLog1pToSelf()564 public RealVector mapLog1pToSelf() { 565 try { 566 return mapToSelf(ComposableFunction.LOG1P); 567 } catch (FunctionEvaluationException e) { 568 throw new IllegalArgumentException(e); 569 } 570 } 571 572 /** {@inheritDoc} */ mapMultiply(double d)573 public RealVector mapMultiply(double d) { 574 return copy().mapMultiplyToSelf(d); 575 } 576 577 /** {@inheritDoc} */ mapMultiplyToSelf(double d)578 public RealVector mapMultiplyToSelf(double d){ 579 try { 580 return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d)); 581 } catch (FunctionEvaluationException e) { 582 throw new IllegalArgumentException(e); 583 } 584 } 585 586 /** {@inheritDoc} */ mapPow(double d)587 public RealVector mapPow(double d) { 588 return copy().mapPowToSelf(d); 589 } 590 591 /** {@inheritDoc} */ mapPowToSelf(double d)592 public RealVector mapPowToSelf(double d){ 593 try { 594 return mapToSelf(BinaryFunction.POW.fix2ndArgument(d)); 595 } catch (FunctionEvaluationException e) { 596 throw new IllegalArgumentException(e); 597 } 598 } 599 600 /** {@inheritDoc} */ mapRint()601 public RealVector mapRint() { 602 return copy().mapRintToSelf(); 603 } 604 605 /** {@inheritDoc} */ mapRintToSelf()606 public RealVector mapRintToSelf() { 607 try { 608 return mapToSelf(ComposableFunction.RINT); 609 } catch (FunctionEvaluationException e) { 610 throw new IllegalArgumentException(e); 611 } 612 } 613 614 /** {@inheritDoc} */ mapSignum()615 public RealVector mapSignum() { 616 return copy().mapSignumToSelf(); 617 } 618 619 /** {@inheritDoc} */ mapSignumToSelf()620 public RealVector mapSignumToSelf() { 621 try { 622 return mapToSelf(ComposableFunction.SIGNUM); 623 } catch (FunctionEvaluationException e) { 624 throw new IllegalArgumentException(e); 625 } 626 } 627 628 /** {@inheritDoc} */ mapSin()629 public RealVector mapSin() { 630 return copy().mapSinToSelf(); 631 } 632 633 /** {@inheritDoc} */ mapSinToSelf()634 public RealVector mapSinToSelf() { 635 try { 636 return mapToSelf(ComposableFunction.SIN); 637 } catch (FunctionEvaluationException e) { 638 throw new IllegalArgumentException(e); 639 } 640 } 641 642 /** {@inheritDoc} */ mapSinh()643 public RealVector mapSinh() { 644 return copy().mapSinhToSelf(); 645 } 646 647 /** {@inheritDoc} */ mapSinhToSelf()648 public RealVector mapSinhToSelf() { 649 try { 650 return mapToSelf(ComposableFunction.SINH); 651 } catch (FunctionEvaluationException e) { 652 throw new IllegalArgumentException(e); 653 } 654 } 655 656 /** {@inheritDoc} */ mapSqrt()657 public RealVector mapSqrt() { 658 return copy().mapSqrtToSelf(); 659 } 660 661 /** {@inheritDoc} */ mapSqrtToSelf()662 public RealVector mapSqrtToSelf() { 663 try { 664 return mapToSelf(ComposableFunction.SQRT); 665 } catch (FunctionEvaluationException e) { 666 throw new IllegalArgumentException(e); 667 } 668 } 669 670 /** {@inheritDoc} */ mapSubtract(double d)671 public RealVector mapSubtract(double d) { 672 return copy().mapSubtractToSelf(d); 673 } 674 675 /** {@inheritDoc} */ mapSubtractToSelf(double d)676 public RealVector mapSubtractToSelf(double d){ 677 return mapAddToSelf(-d); 678 } 679 680 /** {@inheritDoc} */ mapTan()681 public RealVector mapTan() { 682 return copy().mapTanToSelf(); 683 } 684 685 /** {@inheritDoc} */ mapTanToSelf()686 public RealVector mapTanToSelf() { 687 try { 688 return mapToSelf(ComposableFunction.TAN); 689 } catch (FunctionEvaluationException e) { 690 throw new IllegalArgumentException(e); 691 } 692 } 693 694 /** {@inheritDoc} */ mapTanh()695 public RealVector mapTanh() { 696 return copy().mapTanhToSelf(); 697 } 698 699 /** {@inheritDoc} */ mapTanhToSelf()700 public RealVector mapTanhToSelf() { 701 try { 702 return mapToSelf(ComposableFunction.TANH); 703 } catch (FunctionEvaluationException e) { 704 throw new IllegalArgumentException(e); 705 } 706 } 707 708 /** {@inheritDoc} */ mapUlp()709 public RealVector mapUlp() { 710 return copy().mapUlpToSelf(); 711 } 712 713 /** {@inheritDoc} */ mapUlpToSelf()714 public RealVector mapUlpToSelf() { 715 try { 716 return mapToSelf(ComposableFunction.ULP); 717 } catch (FunctionEvaluationException e) { 718 throw new IllegalArgumentException(e); 719 } 720 } 721 722 /** {@inheritDoc} */ outerProduct(RealVector v)723 public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { 724 RealMatrix product; 725 if (v instanceof SparseRealVector || this instanceof SparseRealVector) { 726 product = new OpenMapRealMatrix(this.getDimension(), v.getDimension()); 727 } else { 728 product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension()); 729 } 730 Iterator<Entry> thisIt = sparseIterator(); 731 Entry thisE = null; 732 while (thisIt.hasNext() && (thisE = thisIt.next()) != null) { 733 Iterator<Entry> otherIt = v.sparseIterator(); 734 Entry otherE = null; 735 while (otherIt.hasNext() && (otherE = otherIt.next()) != null) { 736 product.setEntry(thisE.getIndex(), otherE.getIndex(), 737 thisE.getValue() * otherE.getValue()); 738 } 739 } 740 741 return product; 742 743 } 744 745 /** {@inheritDoc} */ outerProduct(double[] v)746 public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { 747 return outerProduct(new ArrayRealVector(v, false)); 748 } 749 750 /** {@inheritDoc} */ projection(double[] v)751 public RealVector projection(double[] v) throws IllegalArgumentException { 752 return projection(new ArrayRealVector(v, false)); 753 } 754 755 /** {@inheritDoc} */ set(double value)756 public void set(double value) { 757 Iterator<Entry> it = iterator(); 758 Entry e = null; 759 while (it.hasNext() && (e = it.next()) != null) { 760 e.setValue(value); 761 } 762 } 763 764 /** {@inheritDoc} */ toArray()765 public double[] toArray() { 766 int dim = getDimension(); 767 double[] values = new double[dim]; 768 for (int i = 0; i < dim; i++) { 769 values[i] = getEntry(i); 770 } 771 return values; 772 } 773 774 /** {@inheritDoc} */ getData()775 public double[] getData() { 776 return toArray(); 777 } 778 779 /** {@inheritDoc} */ unitVector()780 public RealVector unitVector() { 781 RealVector copy = copy(); 782 copy.unitize(); 783 return copy; 784 } 785 786 /** {@inheritDoc} */ unitize()787 public void unitize() { 788 mapDivideToSelf(getNorm()); 789 } 790 791 /** {@inheritDoc} */ sparseIterator()792 public Iterator<Entry> sparseIterator() { 793 return new SparseEntryIterator(); 794 } 795 796 /** {@inheritDoc} */ iterator()797 public Iterator<Entry> iterator() { 798 final int dim = getDimension(); 799 return new Iterator<Entry>() { 800 801 /** Current index. */ 802 private int i = 0; 803 804 /** Current entry. */ 805 private EntryImpl e = new EntryImpl(); 806 807 /** {@inheritDoc} */ 808 public boolean hasNext() { 809 return i < dim; 810 } 811 812 /** {@inheritDoc} */ 813 public Entry next() { 814 e.setIndex(i++); 815 return e; 816 } 817 818 /** {@inheritDoc} */ 819 public void remove() { 820 throw new MathUnsupportedOperationException(); 821 } 822 }; 823 } 824 825 /** {@inheritDoc} */ map(UnivariateRealFunction function)826 public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException { 827 return copy().mapToSelf(function); 828 } 829 830 /** {@inheritDoc} */ mapToSelf(UnivariateRealFunction function)831 public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException { 832 Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator(); 833 Entry e; 834 while (it.hasNext() && (e = it.next()) != null) { 835 e.setValue(function.value(e.getValue())); 836 } 837 return this; 838 } 839 840 /** An entry in the vector. */ 841 protected class EntryImpl extends Entry { 842 843 /** Simple constructor. */ EntryImpl()844 public EntryImpl() { 845 setIndex(0); 846 } 847 848 /** {@inheritDoc} */ 849 @Override getValue()850 public double getValue() { 851 return getEntry(getIndex()); 852 } 853 854 /** {@inheritDoc} */ 855 @Override setValue(double newValue)856 public void setValue(double newValue) { 857 setEntry(getIndex(), newValue); 858 } 859 } 860 861 /** 862 * This class should rare be used, but is here to provide 863 * a default implementation of sparseIterator(), which is implemented 864 * by walking over the entries, skipping those whose values are the default one. 865 * 866 * Concrete subclasses which are SparseVector implementations should 867 * make their own sparse iterator, not use this one. 868 * 869 * This implementation might be useful for ArrayRealVector, when expensive 870 * operations which preserve the default value are to be done on the entries, 871 * and the fraction of non-default values is small (i.e. someone took a 872 * SparseVector, and passed it into the copy-constructor of ArrayRealVector) 873 */ 874 protected class SparseEntryIterator implements Iterator<Entry> { 875 876 /** Dimension of the vector. */ 877 private final int dim; 878 879 /** last entry returned by {@link #next()} */ 880 private EntryImpl current; 881 882 /** Next entry for {@link #next()} to return. */ 883 private EntryImpl next; 884 885 /** Simple constructor. */ SparseEntryIterator()886 protected SparseEntryIterator() { 887 dim = getDimension(); 888 current = new EntryImpl(); 889 next = new EntryImpl(); 890 if (next.getValue() == 0) { 891 advance(next); 892 } 893 } 894 895 /** Advance an entry up to the next nonzero one. 896 * @param e entry to advance 897 */ advance(EntryImpl e)898 protected void advance(EntryImpl e) { 899 if (e == null) { 900 return; 901 } 902 do { 903 e.setIndex(e.getIndex() + 1); 904 } while (e.getIndex() < dim && e.getValue() == 0); 905 if (e.getIndex() >= dim) { 906 e.setIndex(-1); 907 } 908 } 909 910 /** {@inheritDoc} */ hasNext()911 public boolean hasNext() { 912 return next.getIndex() >= 0; 913 } 914 915 /** {@inheritDoc} */ next()916 public Entry next() { 917 int index = next.getIndex(); 918 if (index < 0) { 919 throw new NoSuchElementException(); 920 } 921 current.setIndex(index); 922 advance(next); 923 return current; 924 } 925 926 /** {@inheritDoc} */ remove()927 public void remove() { 928 throw new MathUnsupportedOperationException(); 929 } 930 } 931 932 } 933