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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
package org.apache.commons.math.linear;
19
import java.io.Serializable;
21
import org.apache.commons.math.MathRuntimeException;
22
import org.apache.commons.math.util.OpenIntToDoubleHashMap;
23
import org.apache.commons.math.util.OpenIntToDoubleHashMap.Iterator;
26
* This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap} backing store.
27
* @version $Revision: 800111 $ $Date: 2009-08-02 13:23:05 -0400 (Sun, 02 Aug 2009) $
30
public class OpenMapRealVector implements SparseRealVector, Serializable {
32
/** Serializable version identifier. */
33
private static final long serialVersionUID = 8772222695580707260L;
35
/** Default Tolerance for having a value considered zero. */
36
public static final double DEFAULT_ZERO_TOLERANCE = 1.0e-12;
38
/** Entries of the vector. */
39
private final OpenIntToDoubleHashMap entries;
41
/** Dimension of the vector. */
42
private final int virtualSize;
44
/** Tolerance for having a value considered zero. */
45
private double epsilon;
48
* Build a 0-length vector.
49
* <p>Zero-length vectors may be used to initialized construction of vectors
50
* by data gathering. We start with zero-length and use either the {@link
51
* #OpenMapRealVector(OpenMapRealVector, int)} constructor
52
* or one of the <code>append</code> method ({@link #append(double)}, {@link
53
* #append(double[])}, {@link #append(RealVector)}) to gather data
54
* into this vector.</p>
56
public OpenMapRealVector() {
57
this(0, DEFAULT_ZERO_TOLERANCE);
61
* Construct a (dimension)-length vector of zeros.
62
* @param dimension size of the vector
64
public OpenMapRealVector(int dimension) {
65
this(dimension, DEFAULT_ZERO_TOLERANCE);
69
* Construct a (dimension)-length vector of zeros, specifying zero tolerance.
70
* @param dimension Size of the vector
71
* @param epsilon The tolerance for having a value considered zero
73
public OpenMapRealVector(int dimension, double epsilon) {
74
virtualSize = dimension;
75
entries = new OpenIntToDoubleHashMap(0.0);
76
this.epsilon = epsilon;
80
* Build a resized vector, for use with append.
81
* @param v The original vector
82
* @param resize The amount to resize it
84
protected OpenMapRealVector(OpenMapRealVector v, int resize) {
85
virtualSize = v.getDimension() + resize;
86
entries = new OpenIntToDoubleHashMap(v.entries);
87
epsilon = v.getEpsilon();
91
* Build a vector with known the sparseness (for advanced use only).
92
* @param dimension The size of the vector
93
* @param expectedSize The expected number of non-zero entries
95
public OpenMapRealVector(int dimension, int expectedSize) {
96
this(dimension, expectedSize, DEFAULT_ZERO_TOLERANCE);
100
* Build a vector with known the sparseness and zero tolerance setting (for advanced use only).
101
* @param dimension The size of the vector
102
* @param expectedSize The expected number of non-zero entries
103
* @param epsilon The tolerance for having a value considered zero
105
public OpenMapRealVector(int dimension, int expectedSize, double epsilon) {
106
virtualSize = dimension;
107
entries = new OpenIntToDoubleHashMap(expectedSize, 0.0);
108
this.epsilon = epsilon;
112
* Create from a double array.
113
* Only non-zero entries will be stored
114
* @param values The set of values to create from
116
public OpenMapRealVector(double[] values) {
117
this(values, DEFAULT_ZERO_TOLERANCE);
121
* Create from a double array, specifying zero tolerance.
122
* Only non-zero entries will be stored
123
* @param values The set of values to create from
124
* @param epsilon The tolerance for having a value considered zero
126
public OpenMapRealVector(double[] values, double epsilon) {
127
virtualSize = values.length;
128
entries = new OpenIntToDoubleHashMap(0.0);
129
this.epsilon = epsilon;
130
for (int key = 0; key < values.length; key++) {
131
double value = values[key];
132
if (!isZero(value)) {
133
entries.put(key, value);
139
* Create from a Double array.
140
* Only non-zero entries will be stored
141
* @param values The set of values to create from
143
public OpenMapRealVector(Double[] values) {
144
this(values, DEFAULT_ZERO_TOLERANCE);
148
* Create from a Double array.
149
* Only non-zero entries will be stored
150
* @param values The set of values to create from
151
* @param epsilon The tolerance for having a value considered zero
153
public OpenMapRealVector(Double[] values, double epsilon) {
154
virtualSize = values.length;
155
entries = new OpenIntToDoubleHashMap(0.0);
156
this.epsilon = epsilon;
157
for (int key = 0; key < values.length; key++) {
158
double value = values[key].doubleValue();
159
if (!isZero(value)) {
160
entries.put(key, value);
167
* @param v The instance to copy from
169
public OpenMapRealVector(OpenMapRealVector v) {
170
virtualSize = v.getDimension();
171
entries = new OpenIntToDoubleHashMap(v.getEntries());
172
epsilon = v.getEpsilon();
176
* Generic copy constructor.
177
* @param v The instance to copy from
179
public OpenMapRealVector(RealVector v) {
180
virtualSize = v.getDimension();
181
entries = new OpenIntToDoubleHashMap(0.0);
182
epsilon = DEFAULT_ZERO_TOLERANCE;
183
for (int key = 0; key < virtualSize; key++) {
184
double value = v.getEntry(key);
185
if (!isZero(value)) {
186
entries.put(key, value);
192
* Get the entries of this instance.
193
* @return entries of this instance
195
private OpenIntToDoubleHashMap getEntries() {
200
* Determine if this value is zero.
201
* @param value The value to test
202
* @return <code>true</code> if this value is zero, <code>false</code> otherwise
204
protected boolean isZero(double value) {
205
return value > -epsilon && value < epsilon;
209
* Get the tolerance for having a value considered zero.
210
* @return The test range for testing if a value is zero
212
public double getEpsilon() {
217
* Set the tolerance for having a value considered zero.
218
* @param epsilon The test range for testing if a value is zero
220
public void setEpsilon(double epsilon) {
221
this.epsilon = epsilon;
225
public OpenMapRealVector add(RealVector v) throws IllegalArgumentException {
226
checkVectorDimensions(v.getDimension());
227
if (v instanceof OpenMapRealVector) {
228
return add((OpenMapRealVector) v);
230
return add(v.getData());
234
* Optimized method to add two OpenMapRealVectors.
235
* @param v Vector to add with
236
* @return The sum of <code>this</code> with <code>v</code>
237
* @throws IllegalArgumentException If the dimensions don't match
239
public OpenMapRealVector add(OpenMapRealVector v) throws IllegalArgumentException{
240
checkVectorDimensions(v.getDimension());
241
OpenMapRealVector res = copy();
242
Iterator iter = v.getEntries().iterator();
243
while (iter.hasNext()) {
245
int key = iter.key();
246
if (entries.containsKey(key)) {
247
res.setEntry(key, entries.get(key) + iter.value());
249
res.setEntry(key, iter.value());
256
public OpenMapRealVector add(double[] v) throws IllegalArgumentException {
257
checkVectorDimensions(v.length);
258
OpenMapRealVector res = new OpenMapRealVector(getDimension());
259
for (int i = 0; i < v.length; i++) {
260
res.setEntry(i, v[i] + getEntry(i));
266
* Optimized method to append a OpenMapRealVector.
267
* @param v vector to append
268
* @return The result of appending <code>v</code> to self
270
public OpenMapRealVector append(OpenMapRealVector v) {
271
OpenMapRealVector res = new OpenMapRealVector(this, v.getDimension());
272
Iterator iter = v.entries.iterator();
273
while (iter.hasNext()) {
275
res.setEntry(iter.key() + virtualSize, iter.value());
281
public OpenMapRealVector append(RealVector v) {
282
if (v instanceof OpenMapRealVector) {
283
return append((OpenMapRealVector) v);
285
return append(v.getData());
289
public OpenMapRealVector append(double d) {
290
OpenMapRealVector res = new OpenMapRealVector(this, 1);
291
res.setEntry(virtualSize, d);
296
public OpenMapRealVector append(double[] a) {
297
OpenMapRealVector res = new OpenMapRealVector(this, a.length);
298
for (int i = 0; i < a.length; i++) {
299
res.setEntry(i + virtualSize, a[i]);
305
public OpenMapRealVector copy() {
306
return new OpenMapRealVector(this);
310
public double dotProduct(RealVector v) throws IllegalArgumentException {
311
checkVectorDimensions(v.getDimension());
313
Iterator iter = entries.iterator();
314
while (iter.hasNext()) {
316
res += v.getEntry(iter.key()) * iter.value();
322
public double dotProduct(double[] v) throws IllegalArgumentException {
323
checkVectorDimensions(v.length);
325
Iterator iter = entries.iterator();
326
while (iter.hasNext()) {
327
int idx = iter.key();
329
if (idx < v.length) {
332
res += value * iter.value();
338
public OpenMapRealVector ebeDivide(RealVector v) throws IllegalArgumentException {
339
checkVectorDimensions(v.getDimension());
340
OpenMapRealVector res = new OpenMapRealVector(this);
341
Iterator iter = res.entries.iterator();
342
while (iter.hasNext()) {
344
res.setEntry(iter.key(), iter.value() / v.getEntry(iter.key()));
350
public OpenMapRealVector ebeDivide(double[] v) throws IllegalArgumentException {
351
checkVectorDimensions(v.length);
352
OpenMapRealVector res = new OpenMapRealVector(this);
353
Iterator iter = res.entries.iterator();
354
while (iter.hasNext()) {
356
res.setEntry(iter.key(), iter.value() / v[iter.key()]);
362
public OpenMapRealVector ebeMultiply(RealVector v) throws IllegalArgumentException {
363
checkVectorDimensions(v.getDimension());
364
OpenMapRealVector res = new OpenMapRealVector(this);
365
Iterator iter = res.entries.iterator();
366
while (iter.hasNext()) {
368
res.setEntry(iter.key(), iter.value() * v.getEntry(iter.key()));
374
public OpenMapRealVector ebeMultiply(double[] v) throws IllegalArgumentException {
375
checkVectorDimensions(v.length);
376
OpenMapRealVector res = new OpenMapRealVector(this);
377
Iterator iter = res.entries.iterator();
378
while (iter.hasNext()) {
380
res.setEntry(iter.key(), iter.value() * v[iter.key()]);
386
public OpenMapRealVector getSubVector(int index, int n) throws MatrixIndexException {
388
checkIndex(index + n - 1);
389
OpenMapRealVector res = new OpenMapRealVector(n);
391
Iterator iter = entries.iterator();
392
while (iter.hasNext()) {
394
int key = iter.key();
395
if (key >= index && key < end) {
396
res.setEntry(key - index, iter.value());
403
public double[] getData() {
404
double[] res = new double[virtualSize];
405
Iterator iter = entries.iterator();
406
while (iter.hasNext()) {
408
res[iter.key()] = iter.value();
414
public int getDimension() {
419
* Optimized method to compute distance.
420
* @param v The vector to compute distance to
421
* @return The distance from <code>this</code> and <code>v</code>
422
* @throws IllegalArgumentException If the dimensions don't match
424
public double getDistance(OpenMapRealVector v) throws IllegalArgumentException {
425
Iterator iter = entries.iterator();
427
while (iter.hasNext()) {
429
int key = iter.key();
431
delta = iter.value() - v.getEntry(key);
432
res += delta * delta;
434
iter = v.getEntries().iterator();
435
while (iter.hasNext()) {
437
int key = iter.key();
438
if (!entries.containsKey(key)) {
439
final double value = iter.value();
440
res += value * value;
443
return Math.sqrt(res);
447
public double getDistance(RealVector v) throws IllegalArgumentException {
448
checkVectorDimensions(v.getDimension());
449
if (v instanceof OpenMapRealVector) {
450
return getDistance((OpenMapRealVector) v);
452
return getDistance(v.getData());
456
public double getDistance(double[] v) throws IllegalArgumentException {
457
checkVectorDimensions(v.length);
459
for (int i = 0; i < v.length; i++) {
460
double delta = entries.get(i) - v[i];
461
res += delta * delta;
463
return Math.sqrt(res);
467
public double getEntry(int index) throws MatrixIndexException {
469
return entries.get(index);
473
* Distance between two vectors.
474
* <p>This method computes the distance consistent with
475
* L<sub>1</sub> norm, i.e. the sum of the absolute values of
476
* elements differences.</p>
477
* @param v vector to which distance is requested
478
* @return distance between two vectors.
480
public double getL1Distance(OpenMapRealVector v) {
482
Iterator iter = entries.iterator();
483
while (iter.hasNext()) {
485
double delta = Math.abs(iter.value() - v.getEntry(iter.key()));
488
iter = v.getEntries().iterator();
489
while (iter.hasNext()) {
491
int key = iter.key();
492
if (!entries.containsKey(key)) {
493
double delta = Math.abs(iter.value());
494
max += Math.abs(delta);
501
public double getL1Distance(RealVector v) throws IllegalArgumentException {
502
checkVectorDimensions(v.getDimension());
503
if (v instanceof OpenMapRealVector) {
504
return getL1Distance((OpenMapRealVector) v);
506
return getL1Distance(v.getData());
510
public double getL1Distance(double[] v) throws IllegalArgumentException {
511
checkVectorDimensions(v.length);
513
for (int i = 0; i < v.length; i++) {
514
double delta = Math.abs(getEntry(i) - v[i]);
521
public double getL1Norm() {
523
Iterator iter = entries.iterator();
524
while (iter.hasNext()) {
526
res += Math.abs(iter.value());
532
* Optimized method to compute LInfDistance.
533
* @param v The vector to compute from
534
* @return the LInfDistance
536
private double getLInfDistance(OpenMapRealVector v) {
538
Iterator iter = entries.iterator();
539
while (iter.hasNext()) {
541
double delta = Math.abs(iter.value() - v.getEntry(iter.key()));
546
iter = v.getEntries().iterator();
547
while (iter.hasNext()) {
549
int key = iter.key();
550
if (!entries.containsKey(key)) {
551
if (iter.value() > max) {
560
public double getLInfDistance(RealVector v) throws IllegalArgumentException {
561
checkVectorDimensions(v.getDimension());
562
if (v instanceof OpenMapRealVector) {
563
return getLInfDistance((OpenMapRealVector) v);
565
return getLInfDistance(v.getData());
569
public double getLInfDistance(double[] v) throws IllegalArgumentException {
570
checkVectorDimensions(v.length);
572
for (int i = 0; i < v.length; i++) {
573
double delta = Math.abs(getEntry(i) - v[i]);
582
public double getLInfNorm() {
584
Iterator iter = entries.iterator();
585
while (iter.hasNext()) {
593
public double getNorm() {
595
Iterator iter = entries.iterator();
596
while (iter.hasNext()) {
598
res += iter.value() * iter.value();
600
return Math.sqrt(res);
604
public boolean isInfinite() {
605
boolean infiniteFound = false;
606
Iterator iter = entries.iterator();
607
while (iter.hasNext()) {
609
final double value = iter.value();
610
if (Double.isNaN(value)) {
613
if (Double.isInfinite(value)) {
614
infiniteFound = true;
617
return infiniteFound;
621
public boolean isNaN() {
622
Iterator iter = entries.iterator();
623
while (iter.hasNext()) {
625
if (Double.isNaN(iter.value())) {
633
public OpenMapRealVector mapAbs() {
634
return copy().mapAbsToSelf();
638
public OpenMapRealVector mapAbsToSelf() {
639
Iterator iter = entries.iterator();
640
while (iter.hasNext()) {
642
entries.put(iter.key(), Math.abs(iter.value()));
648
public OpenMapRealVector mapAcos() {
649
return copy().mapAcosToSelf();
653
public OpenMapRealVector mapAcosToSelf() {
654
for (int i = 0; i < virtualSize; i++) {
655
setEntry(i, Math.acos(getEntry(i)));
661
public OpenMapRealVector mapAdd(double d) {
662
return copy().mapAddToSelf(d);
666
public OpenMapRealVector mapAddToSelf(double d) {
667
for (int i = 0; i < virtualSize; i++) {
668
setEntry(i, getEntry(i) + d);
674
public OpenMapRealVector mapAsin() {
675
return copy().mapAsinToSelf();
679
public OpenMapRealVector mapAsinToSelf() {
680
Iterator iter = entries.iterator();
681
while (iter.hasNext()) {
683
entries.put(iter.key(), Math.asin(iter.value()));
689
public OpenMapRealVector mapAtan() {
690
return copy().mapAtanToSelf();
694
public OpenMapRealVector mapAtanToSelf() {
695
Iterator iter = entries.iterator();
696
while (iter.hasNext()) {
698
entries.put(iter.key(), Math.atan(iter.value()));
704
public OpenMapRealVector mapCbrt() {
705
return copy().mapCbrtToSelf();
709
public OpenMapRealVector mapCbrtToSelf() {
710
Iterator iter = entries.iterator();
711
while (iter.hasNext()) {
713
entries.put(iter.key(), Math.cbrt(iter.value()));
719
public OpenMapRealVector mapCeil() {
720
return copy().mapCeilToSelf();
724
public OpenMapRealVector mapCeilToSelf() {
725
Iterator iter = entries.iterator();
726
while (iter.hasNext()) {
728
entries.put(iter.key(), Math.ceil(iter.value()));
734
public OpenMapRealVector mapCos() {
735
return copy().mapCosToSelf();
739
public OpenMapRealVector mapCosToSelf() {
740
for (int i = 0; i < virtualSize; i++) {
741
setEntry(i, Math.cos(getEntry(i)));
747
public OpenMapRealVector mapCosh() {
748
return copy().mapCoshToSelf();
752
public OpenMapRealVector mapCoshToSelf() {
753
for (int i = 0; i < virtualSize; i++) {
754
setEntry(i, Math.cosh(getEntry(i)));
760
public OpenMapRealVector mapDivide(double d) {
761
return copy().mapDivideToSelf(d);
765
public OpenMapRealVector mapDivideToSelf(double d) {
766
Iterator iter = entries.iterator();
767
while (iter.hasNext()) {
769
entries.put(iter.key(), iter.value() / d);
775
public OpenMapRealVector mapExp() {
776
return copy().mapExpToSelf();
780
public OpenMapRealVector mapExpToSelf() {
781
for (int i = 0; i < virtualSize; i++) {
782
entries.put(i, Math.exp(entries.get(i)));
788
public OpenMapRealVector mapExpm1() {
789
return copy().mapExpm1ToSelf();
793
public OpenMapRealVector mapExpm1ToSelf() {
794
Iterator iter = entries.iterator();
795
while (iter.hasNext()) {
797
entries.put(iter.key(), Math.expm1(iter.value()));
803
public OpenMapRealVector mapFloor() {
804
return copy().mapFloorToSelf();
808
public OpenMapRealVector mapFloorToSelf() {
809
Iterator iter = entries.iterator();
810
while (iter.hasNext()) {
812
entries.put(iter.key(), Math.floor(iter.value()));
818
public OpenMapRealVector mapInv() {
819
return copy().mapInvToSelf();
823
public OpenMapRealVector mapInvToSelf() {
824
for (int i = 0; i < virtualSize; i++) {
825
setEntry(i, 1.0/getEntry(i));
831
public OpenMapRealVector mapLog() {
832
return copy().mapLogToSelf();
836
public OpenMapRealVector mapLog10() {
837
return copy().mapLog10ToSelf();
841
public OpenMapRealVector mapLog10ToSelf() {
842
for (int i = 0; i < virtualSize; i++) {
843
setEntry(i, Math.log10(getEntry(i)));
849
public OpenMapRealVector mapLog1p() {
850
return copy().mapLog1pToSelf();
854
public OpenMapRealVector mapLog1pToSelf() {
855
Iterator iter = entries.iterator();
856
while (iter.hasNext()) {
858
entries.put(iter.key(), Math.log1p(iter.value()));
864
public OpenMapRealVector mapLogToSelf() {
865
for (int i = 0; i < virtualSize; i++) {
866
setEntry(i, Math.log(getEntry(i)));
872
public OpenMapRealVector mapMultiply(double d) {
873
return copy().mapMultiplyToSelf(d);
877
public OpenMapRealVector mapMultiplyToSelf(double d) {
878
Iterator iter = entries.iterator();
879
while (iter.hasNext()) {
881
entries.put(iter.key(), iter.value() * d);
886
public OpenMapRealVector mapPow(double d) {
887
return copy().mapPowToSelf(d);
891
public OpenMapRealVector mapPowToSelf(double d) {
892
Iterator iter = entries.iterator();
893
while (iter.hasNext()) {
895
entries.put(iter.key(), Math.pow(iter.value(), d));
901
public OpenMapRealVector mapRint() {
902
return copy().mapRintToSelf();
906
public OpenMapRealVector mapRintToSelf() {
907
Iterator iter = entries.iterator();
908
while (iter.hasNext()) {
910
entries.put(iter.key(), Math.rint(iter.value()));
916
public OpenMapRealVector mapSignum() {
917
return copy().mapSignumToSelf();
921
public OpenMapRealVector mapSignumToSelf() {
922
Iterator iter = entries.iterator();
923
while (iter.hasNext()) {
925
entries.put(iter.key(), Math.signum(iter.value()));
931
public OpenMapRealVector mapSin() {
932
return copy().mapSinToSelf();
936
public OpenMapRealVector mapSinToSelf() {
937
Iterator iter = entries.iterator();
938
while (iter.hasNext()) {
940
entries.put(iter.key(), Math.sin(iter.value()));
946
public OpenMapRealVector mapSinh() {
947
return copy().mapSinhToSelf();
951
public OpenMapRealVector mapSinhToSelf() {
953
Iterator iter = entries.iterator();
954
while (iter.hasNext()) {
956
entries.put(iter.key(), Math.sinh(iter.value()));
962
public OpenMapRealVector mapSqrt() {
963
return copy().mapSqrtToSelf();
967
public OpenMapRealVector mapSqrtToSelf() {
968
Iterator iter = entries.iterator();
969
while (iter.hasNext()) {
971
entries.put(iter.key(), Math.sqrt(iter.value()));
977
public OpenMapRealVector mapSubtract(double d) {
978
return copy().mapSubtractToSelf(d);
982
public OpenMapRealVector mapSubtractToSelf(double d) {
983
return mapAddToSelf(-d);
987
public OpenMapRealVector mapTan() {
988
return copy().mapTanToSelf();
992
public OpenMapRealVector mapTanToSelf() {
993
Iterator iter = entries.iterator();
994
while (iter.hasNext()) {
996
entries.put(iter.key(), Math.tan(iter.value()));
1001
/** {@inheritDoc} */
1002
public OpenMapRealVector mapTanh() {
1003
return copy().mapTanhToSelf();
1006
/** {@inheritDoc} */
1007
public OpenMapRealVector mapTanhToSelf() {
1008
Iterator iter = entries.iterator();
1009
while (iter.hasNext()) {
1011
entries.put(iter.key(), Math.tanh(iter.value()));
1016
/** {@inheritDoc} */
1017
public OpenMapRealVector mapUlp() {
1018
return copy().mapUlpToSelf();
1021
/** {@inheritDoc} */
1022
public OpenMapRealVector mapUlpToSelf() {
1023
Iterator iter = entries.iterator();
1024
while (iter.hasNext()) {
1026
entries.put(iter.key(), Math.ulp(iter.value()));
1032
* Optimized method to compute the outer product.
1033
* @param v The vector to comput the outer product on
1034
* @return The outer product of <code>this</code> and <code>v</code>
1035
* @throws IllegalArgumentException If the dimensions don't match
1037
public OpenMapRealMatrix outerproduct(OpenMapRealVector v) throws IllegalArgumentException{
1038
checkVectorDimensions(v.getDimension());
1039
OpenMapRealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize);
1040
Iterator iter = entries.iterator();
1041
while (iter.hasNext()) {
1043
Iterator iter2 = v.getEntries().iterator();
1044
while (iter2.hasNext()) {
1046
res.setEntry(iter.key(), iter2.key(), iter.value()*iter2.value());
1052
/** {@inheritDoc} */
1053
public RealMatrix outerProduct(RealVector v)
1054
throws IllegalArgumentException {
1055
checkVectorDimensions(v.getDimension());
1056
if (v instanceof OpenMapRealVector) {
1057
return outerproduct((OpenMapRealVector)v);
1059
RealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize);
1060
Iterator iter = entries.iterator();
1061
while (iter.hasNext()) {
1063
int row = iter.key();
1064
for (int col = 0; col < virtualSize; col++) {
1065
res.setEntry(row, col, iter.value()*v.getEntry(col));
1071
/** {@inheritDoc} */
1072
public RealMatrix outerProduct(double[] v) throws IllegalArgumentException {
1073
checkVectorDimensions(v.length);
1074
RealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize);
1075
Iterator iter = entries.iterator();
1076
while (iter.hasNext()) {
1078
int row = iter.key();
1079
double value = iter.value();
1080
for (int col = 0; col < virtualSize; col++) {
1081
res.setEntry(row, col, value * v[col]);
1087
/** {@inheritDoc} */
1088
public RealVector projection(RealVector v) throws IllegalArgumentException {
1089
checkVectorDimensions(v.getDimension());
1090
return v.mapMultiply(dotProduct(v) / v.dotProduct(v));
1093
/** {@inheritDoc} */
1094
public OpenMapRealVector projection(double[] v) throws IllegalArgumentException {
1095
checkVectorDimensions(v.length);
1096
return (OpenMapRealVector) projection(new OpenMapRealVector(v));
1099
/** {@inheritDoc} */
1100
public void setEntry(int index, double value) throws MatrixIndexException {
1102
if (!isZero(value)) {
1103
entries.put(index, value);
1104
} else if (entries.containsKey(index)) {
1105
entries.remove(index);
1109
/** {@inheritDoc} */
1110
public void setSubVector(int index, RealVector v) throws MatrixIndexException {
1112
checkIndex(index + v.getDimension() - 1);
1113
setSubVector(index, v.getData());
1116
/** {@inheritDoc} */
1117
public void setSubVector(int index, double[] v) throws MatrixIndexException {
1119
checkIndex(index + v.length - 1);
1120
for (int i = 0; i < v.length; i++) {
1121
setEntry(i + index, v[i]);
1125
/** {@inheritDoc} */
1126
public void set(double value) {
1127
for (int i = 0; i < virtualSize; i++) {
1133
* Optimized method to subtract OpenMapRealVectors.
1134
* @param v The vector to subtract from <code>this</code>
1135
* @return The difference of <code>this</code> and <code>v</code>
1136
* @throws IllegalArgumentException If the dimensions don't match
1138
public OpenMapRealVector subtract(OpenMapRealVector v) throws IllegalArgumentException{
1139
checkVectorDimensions(v.getDimension());
1140
OpenMapRealVector res = copy();
1141
Iterator iter = v.getEntries().iterator();
1142
while (iter.hasNext()) {
1144
int key = iter.key();
1145
if (entries.containsKey(key)) {
1146
res.setEntry(key, entries.get(key) - iter.value());
1148
res.setEntry(key, -iter.value());
1154
/** {@inheritDoc} */
1155
public OpenMapRealVector subtract(RealVector v) throws IllegalArgumentException {
1156
checkVectorDimensions(v.getDimension());
1157
if (v instanceof OpenMapRealVector) {
1158
return subtract((OpenMapRealVector) v);
1160
return subtract(v.getData());
1163
/** {@inheritDoc} */
1164
public OpenMapRealVector subtract(double[] v) throws IllegalArgumentException {
1165
checkVectorDimensions(v.length);
1166
OpenMapRealVector res = new OpenMapRealVector(this);
1167
for (int i = 0; i < v.length; i++) {
1168
if (entries.containsKey(i)) {
1169
res.setEntry(i, entries.get(i) - v[i]);
1171
res.setEntry(i, -v[i]);
1178
/** {@inheritDoc} */
1179
public OpenMapRealVector unitVector() {
1180
OpenMapRealVector res = copy();
1185
/** {@inheritDoc} */
1186
public void unitize() {
1187
double norm = getNorm();
1189
throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector");
1191
Iterator iter = entries.iterator();
1192
while (iter.hasNext()) {
1194
entries.put(iter.key(), iter.value() / norm);
1200
* Check if an index is valid.
1204
* @exception MatrixIndexException
1205
* if index is not valid
1207
private void checkIndex(final int index) throws MatrixIndexException {
1208
if (index < 0 || index >= getDimension()) {
1209
throw new MatrixIndexException(
1210
"index {0} out of allowed range [{1}, {2}]",
1211
index, 0, getDimension() - 1);
1216
* Check if instance dimension is equal to some expected value.
1219
* expected dimension.
1220
* @exception IllegalArgumentException
1221
* if the dimension is inconsistent with vector size
1223
protected void checkVectorDimensions(int n) throws IllegalArgumentException {
1224
if (getDimension() != n) {
1225
throw MathRuntimeException.createIllegalArgumentException(
1226
"vector length mismatch: got {0} but expected {1}",
1231
/** {@inheritDoc} */
1232
public double[] toArray() {
1237
* <p> Implementation Note: This works on exact values, and as a result
1238
* it is possible for {@code a.subtract(b)} to be the zero vector, while
1239
* {@code a.hashCode() != b.hashCode()}.</p>
1242
public int hashCode() {
1243
final int prime = 31;
1246
temp = Double.doubleToLongBits(epsilon);
1247
result = prime * result + (int) (temp ^ (temp >>> 32));
1248
result = prime * result + virtualSize;
1249
Iterator iter = entries.iterator();
1250
while (iter.hasNext()) {
1252
temp = Double.doubleToLongBits(iter.value());
1253
result = prime * result + (int) (temp ^ (temp >>32));
1259
* <p> Implementation Note: This performs an exact comparison, and as a result
1260
* it is possible for {@code a.subtract(b}} to be the zero vector, while
1261
* {@code a.equals(b) == false}.</p>
1265
public boolean equals(Object obj) {
1272
if (!(obj instanceof OpenMapRealVector)) {
1275
OpenMapRealVector other = (OpenMapRealVector) obj;
1276
if (virtualSize != other.virtualSize) {
1279
if (Double.doubleToLongBits(epsilon) !=
1280
Double.doubleToLongBits(other.epsilon)) {
1283
Iterator iter = entries.iterator();
1284
while (iter.hasNext()) {
1286
double test = other.getEntry(iter.key());
1287
if (Double.doubleToLongBits(test) != Double.doubleToLongBits(iter.value())) {
1291
iter = other.getEntries().iterator();
1292
while (iter.hasNext()) {
1294
double test = iter.value();
1295
if (Double.doubleToLongBits(test) != Double.doubleToLongBits(getEntry(iter.key()))) {
1304
* @return the percentage of none zero elements as a decimal percent.
1306
public double getSparcity() {
1307
return (double)entries.size()/(double)getDimension();