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 }