~ubuntu-branches/ubuntu/maverick/commons-math/maverick

« back to all changes in this revision

Viewing changes to src/main/java/org/apache/commons/math/linear/SparseFieldVector.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-08-22 01:13:25 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090822011325-hi4peq1ua5weguwn
Tags: 2.0-1
* New upstream release.
* Set Maintainer field to Debian Java Team
* Add myself as Uploaders
* Switch to Quilt patch system:
  - Refresh all patchs
  - Remove B-D on dpatch, Add B-D on quilt
  - Include patchsys-quilt.mk in debian/rules
* Bump Standards-Version to 3.8.3:
  - Add a README.source to describe patch system
* Maven POMs:
  - Add a Build-Depends-Indep dependency on maven-repo-helper
  - Use mh_installpom and mh_installjar to install the POM and the jar to the
    Maven repository
* Use default-jdk/jre:
  - Depends on java5-runtime-headless
  - Build-Depends on default-jdk
  - Use /usr/lib/jvm/default-java as JAVA_HOME
* Move api documentation to /usr/share/doc/libcommons-math-java/api
* Build-Depends on junit4 instead of junit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
package org.apache.commons.math.linear;
 
18
 
 
19
import java.io.Serializable;
 
20
import java.lang.reflect.Array;
 
21
 
 
22
import org.apache.commons.math.Field;
 
23
import org.apache.commons.math.FieldElement;
 
24
import org.apache.commons.math.MathRuntimeException;
 
25
import org.apache.commons.math.util.OpenIntToFieldHashMap;
 
26
 
 
27
/**
 
28
 * This class implements the {@link FieldVector} interface with a {@link OpenIntToFieldHashMap} backing store.
 
29
 * @param <T> the type of the field elements
 
30
 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $
 
31
 * @since 2.0
 
32
 */
 
33
public class SparseFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable {
 
34
    
 
35
    /**
 
36
     *  Serial version id
 
37
     */
 
38
    private static final long serialVersionUID = 7841233292190413362L;
 
39
    /** Field to which the elements belong. */
 
40
    private final Field<T> field;
 
41
    /** Entries of the vector. */
 
42
    private final OpenIntToFieldHashMap<T> entries;
 
43
    /** Dimension of the vector. */
 
44
    private final int virtualSize;
 
45
 
 
46
    /**
 
47
     * Build a 0-length vector.
 
48
     * <p>Zero-length vectors may be used to initialize construction of vectors
 
49
     * by data gathering. We start with zero-length and use either the {@link
 
50
     * #SparseFieldVector(SparseFieldVector, int)} constructor
 
51
     * or one of the <code>append</code> method ({@link #append(FieldElement)},
 
52
     * {@link #append(FieldElement[])}, {@link #append(FieldVector)},
 
53
     * {@link #append(SparseFieldVector)}) to gather data into this vector.</p>
 
54
     * @param field field to which the elements belong
 
55
     */
 
56
    public SparseFieldVector(Field<T> field) {
 
57
        this(field, 0);
 
58
    }
 
59
 
 
60
    
 
61
    /**
 
62
     * Construct a (dimension)-length vector of zeros.
 
63
     * @param field field to which the elements belong
 
64
     * @param dimension Size of the vector
 
65
     */
 
66
    public SparseFieldVector(Field<T> field, int dimension) {
 
67
        this.field = field;
 
68
        virtualSize = dimension;
 
69
        entries = new OpenIntToFieldHashMap<T>(field);
 
70
    }
 
71
 
 
72
    /**
 
73
     * Build a resized vector, for use with append.
 
74
     * @param v The original vector
 
75
     * @param resize The amount to resize it
 
76
     */
 
77
    protected SparseFieldVector(SparseFieldVector<T> v, int resize) {
 
78
        field = v.field;
 
79
        virtualSize = v.getDimension() + resize;
 
80
        entries = new OpenIntToFieldHashMap<T>(v.entries);
 
81
    }
 
82
 
 
83
    
 
84
    /**
 
85
     * Build a vector with known the sparseness (for advanced use only).
 
86
     * @param field field to which the elements belong
 
87
     * @param dimension The size of the vector
 
88
     * @param expectedSize The expected number of non-zero entries
 
89
     */
 
90
    public SparseFieldVector(Field<T> field, int dimension, int expectedSize) {
 
91
        this.field = field;
 
92
        virtualSize = dimension;
 
93
        entries = new OpenIntToFieldHashMap<T>(field,expectedSize);
 
94
    }
 
95
 
 
96
    /**
 
97
     * Create from a Field array.
 
98
     * Only non-zero entries will be stored
 
99
     * @param field field to which the elements belong
 
100
     * @param values The set of values to create from
 
101
     */
 
102
    public SparseFieldVector(Field<T> field, T[] values) {
 
103
        this.field = field;
 
104
        virtualSize = values.length;
 
105
        entries = new OpenIntToFieldHashMap<T>(field);
 
106
        for (int key = 0; key < values.length; key++) {
 
107
            T value = values[key];
 
108
            entries.put(key, value);
 
109
        }
 
110
    }
 
111
 
 
112
     
 
113
 
 
114
    /**
 
115
     * Copy constructor.
 
116
     * @param v The instance to copy from
 
117
     */
 
118
    public SparseFieldVector(SparseFieldVector<T> v) {
 
119
        field = v.field;
 
120
        virtualSize = v.getDimension();
 
121
        entries = new OpenIntToFieldHashMap<T>(v.getEntries());
 
122
    }
 
123
 
 
124
    /**
 
125
     * Get the entries of this instance.
 
126
     * @return entries of this instance
 
127
     */
 
128
    private OpenIntToFieldHashMap<T> getEntries() {
 
129
        return entries;
 
130
    }
 
131
    
 
132
    /**
 
133
     * Optimized method to add sparse vectors.
 
134
     * @param v vector to add
 
135
     * @return The sum of <code>this</code> and <code>v</code>
 
136
     * @throws IllegalArgumentException If the dimensions don't match
 
137
     */
 
138
    public FieldVector<T> add(SparseFieldVector<T> v) throws IllegalArgumentException {
 
139
        checkVectorDimensions(v.getDimension());
 
140
        SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
 
141
        OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
 
142
        while (iter.hasNext()) {
 
143
            iter.advance();
 
144
            int key = iter.key();
 
145
            T value = iter.value();
 
146
            if (entries.containsKey(key)) {
 
147
                res.setEntry(key, entries.get(key).add(value));
 
148
            } else {
 
149
                res.setEntry(key, value);
 
150
            }
 
151
        }
 
152
        return res;
 
153
 
 
154
    }
 
155
 
 
156
    
 
157
    /** {@inheritDoc} */
 
158
    public FieldVector<T> add(T[] v) throws IllegalArgumentException {
 
159
        checkVectorDimensions(v.length);
 
160
        SparseFieldVector<T> res = new SparseFieldVector<T>(field,getDimension());
 
161
        for (int i = 0; i < v.length; i++) {
 
162
            res.setEntry(i, v[i].add(getEntry(i)));
 
163
        }
 
164
        return res;
 
165
    }
 
166
 
 
167
    /**
 
168
     * Construct a vector by appending a vector to this vector.
 
169
     * @param v vector to append to this one.
 
170
     * @return a new vector
 
171
     */
 
172
    public FieldVector<T> append(SparseFieldVector<T> v) {
 
173
        SparseFieldVector<T> res = new SparseFieldVector<T>(this, v.getDimension());
 
174
        OpenIntToFieldHashMap<T>.Iterator iter = v.entries.iterator();
 
175
        while (iter.hasNext()) {
 
176
            iter.advance();
 
177
            res.setEntry(iter.key() + virtualSize, iter.value());
 
178
        }
 
179
        return res;
 
180
    }
 
181
 
 
182
    /** {@inheritDoc} */
 
183
    public FieldVector<T> append(FieldVector<T> v) {
 
184
        if (v instanceof SparseFieldVector<?>) {
 
185
            return append((SparseFieldVector<T>) v);
 
186
        } else {
 
187
            return append(v.toArray());
 
188
        }   
 
189
    }
 
190
 
 
191
    /** {@inheritDoc} */
 
192
    public FieldVector<T> append(T d) {
 
193
        FieldVector<T> res = new SparseFieldVector<T>(this, 1);
 
194
        res.setEntry(virtualSize, d);
 
195
        return res;
 
196
     }
 
197
 
 
198
    /** {@inheritDoc} */
 
199
    public FieldVector<T> append(T[] a) {
 
200
        FieldVector<T> res = new SparseFieldVector<T>(this, a.length);
 
201
        for (int i = 0; i < a.length; i++) {
 
202
            res.setEntry(i + virtualSize, a[i]);
 
203
        }
 
204
        return res;
 
205
     }
 
206
 
 
207
    /** {@inheritDoc} */
 
208
    public FieldVector<T> copy() {
 
209
        return new SparseFieldVector<T>(this);
 
210
   }
 
211
 
 
212
    /** {@inheritDoc} */
 
213
    public T dotProduct(FieldVector<T> v) throws IllegalArgumentException {
 
214
        checkVectorDimensions(v.getDimension());
 
215
        T res = field.getZero();
 
216
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
217
        while (iter.hasNext()) {
 
218
            iter.advance();
 
219
            res = res.add(v.getEntry(iter.key()).multiply(iter.value()));
 
220
        }
 
221
        return res;
 
222
    }
 
223
 
 
224
    /** {@inheritDoc} */
 
225
    public T dotProduct(T[] v) throws IllegalArgumentException {
 
226
        checkVectorDimensions(v.length);
 
227
        T res = field.getZero();
 
228
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
229
        while (iter.hasNext()) {
 
230
            int idx = iter.key();
 
231
            T value = field.getZero();
 
232
            if (idx < v.length) {
 
233
                value = v[idx];
 
234
            }
 
235
            res = res.add(value.multiply(iter.value()));
 
236
        }
 
237
        return res;
 
238
     }
 
239
 
 
240
    /** {@inheritDoc} */
 
241
    public FieldVector<T> ebeDivide(FieldVector<T> v)
 
242
        throws IllegalArgumentException {
 
243
        checkVectorDimensions(v.getDimension());
 
244
        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
 
245
        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
 
246
        while (iter.hasNext()) {
 
247
            iter.advance();
 
248
            res.setEntry(iter.key(), iter.value().divide(v.getEntry(iter.key())));
 
249
        }
 
250
        return res;
 
251
    }
 
252
 
 
253
    /** {@inheritDoc} */
 
254
    public FieldVector<T> ebeDivide(T[] v) throws IllegalArgumentException {
 
255
        checkVectorDimensions(v.length);
 
256
        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
 
257
        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
 
258
        while (iter.hasNext()) {
 
259
            iter.advance();
 
260
            res.setEntry(iter.key(), iter.value().divide(v[iter.key()]));
 
261
        }
 
262
        return res;
 
263
    }
 
264
 
 
265
    /** {@inheritDoc} */
 
266
    public FieldVector<T> ebeMultiply(FieldVector<T> v)throws IllegalArgumentException {
 
267
        checkVectorDimensions(v.getDimension());
 
268
        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
 
269
        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
 
270
        while (iter.hasNext()) {
 
271
            iter.advance();
 
272
            res.setEntry(iter.key(), iter.value().multiply(v.getEntry(iter.key())));
 
273
        }
 
274
        return res;
 
275
    }
 
276
 
 
277
    /** {@inheritDoc} */
 
278
     public FieldVector<T> ebeMultiply(T[] v) throws IllegalArgumentException {
 
279
        checkVectorDimensions(v.length);
 
280
        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
 
281
        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
 
282
        while (iter.hasNext()) {
 
283
            iter.advance();
 
284
            res.setEntry(iter.key(), iter.value().multiply(v[iter.key()]));
 
285
        }
 
286
        return res;
 
287
    }
 
288
 
 
289
     /** {@inheritDoc} */
 
290
     public T[] getData() {
 
291
        T[] res = buildArray(virtualSize);
 
292
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
293
        while (iter.hasNext()) {
 
294
            iter.advance();
 
295
            res[iter.key()] = iter.value();
 
296
        }
 
297
        return res;
 
298
     }
 
299
 
 
300
     /** {@inheritDoc} */
 
301
     public int getDimension() {
 
302
        return virtualSize;
 
303
    }
 
304
 
 
305
     /** {@inheritDoc} */
 
306
     public T getEntry(int index) throws MatrixIndexException {
 
307
        checkIndex(index);
 
308
        return entries.get(index);
 
309
   }
 
310
 
 
311
     /** {@inheritDoc} */
 
312
     public Field<T> getField() {
 
313
        return field;
 
314
    }
 
315
 
 
316
     /** {@inheritDoc} */
 
317
     public FieldVector<T> getSubVector(int index, int n)
 
318
            throws MatrixIndexException {
 
319
        checkIndex(index);
 
320
        checkIndex(index + n - 1);
 
321
        SparseFieldVector<T> res = new SparseFieldVector<T>(field,n);
 
322
        int end = index + n;
 
323
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
324
        while (iter.hasNext()) {
 
325
            iter.advance();
 
326
            int key = iter.key();
 
327
            if (key >= index && key < end) {
 
328
                res.setEntry(key - index, iter.value());
 
329
            }
 
330
        }
 
331
        return res;
 
332
    }
 
333
 
 
334
     /** {@inheritDoc} */
 
335
     public FieldVector<T> mapAdd(T d) {
 
336
        return copy().mapAddToSelf(d);
 
337
   }
 
338
 
 
339
     /** {@inheritDoc} */
 
340
     public FieldVector<T> mapAddToSelf(T d) {
 
341
        for (int i = 0; i < virtualSize; i++) {
 
342
            setEntry(i, getEntry(i).add(d));
 
343
        }
 
344
        return this;
 
345
    }
 
346
 
 
347
     /** {@inheritDoc} */
 
348
     public FieldVector<T> mapDivide(T d) {
 
349
        return copy().mapDivideToSelf(d);
 
350
    }
 
351
 
 
352
     /** {@inheritDoc} */
 
353
     public FieldVector<T> mapDivideToSelf(T d) {
 
354
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
355
        while (iter.hasNext()) {
 
356
            iter.advance();
 
357
            entries.put(iter.key(), iter.value().divide(d));
 
358
        }
 
359
        return this;
 
360
   }
 
361
 
 
362
     /** {@inheritDoc} */
 
363
     public FieldVector<T> mapInv() {
 
364
        return copy().mapInvToSelf();
 
365
   }
 
366
 
 
367
     /** {@inheritDoc} */
 
368
     public FieldVector<T> mapInvToSelf() {
 
369
        for (int i = 0; i < virtualSize; i++) {
 
370
            setEntry(i, field.getOne().divide(getEntry(i)));
 
371
        }
 
372
        return this;
 
373
   }
 
374
 
 
375
     /** {@inheritDoc} */
 
376
     public FieldVector<T> mapMultiply(T d) {
 
377
        return copy().mapMultiplyToSelf(d);
 
378
    }
 
379
 
 
380
     /** {@inheritDoc} */
 
381
     public FieldVector<T> mapMultiplyToSelf(T d) {
 
382
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
383
        while (iter.hasNext()) {
 
384
            iter.advance();
 
385
            entries.put(iter.key(), iter.value().multiply(d));
 
386
        }
 
387
        return this;
 
388
   }
 
389
 
 
390
     /** {@inheritDoc} */
 
391
     public FieldVector<T> mapSubtract(T d) {
 
392
        return copy().mapSubtractToSelf(d);
 
393
    }    
 
394
 
 
395
     /** {@inheritDoc} */
 
396
     public FieldVector<T> mapSubtractToSelf(T d) {
 
397
        return mapAddToSelf(field.getZero().subtract(d));
 
398
    }
 
399
 
 
400
     /**
 
401
      * Optimized method to compute outer product when both vectors are sparse.
 
402
      * @param v vector with which outer product should be computed
 
403
      * @return the square matrix outer product between instance and v
 
404
      * @throws IllegalArgumentException if v is not the same size as {@code this}
 
405
      */
 
406
    public FieldMatrix<T> outerProduct(SparseFieldVector<T> v)
 
407
            throws IllegalArgumentException {
 
408
        checkVectorDimensions(v.getDimension());
 
409
        SparseFieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize);
 
410
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
411
        while (iter.hasNext()) {
 
412
            iter.advance();
 
413
            OpenIntToFieldHashMap<T>.Iterator iter2 = v.entries.iterator();
 
414
            while (iter2.hasNext()) {
 
415
                iter2.advance();
 
416
                res.setEntry(iter.key(), iter2.key(), iter.value().multiply(iter2.value()));
 
417
            }
 
418
        }
 
419
        return res;
 
420
    }
 
421
 
 
422
    /** {@inheritDoc} */
 
423
    public FieldMatrix<T> outerProduct(T[] v) throws IllegalArgumentException {
 
424
        checkVectorDimensions(v.length);
 
425
        FieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize);
 
426
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
427
        while (iter.hasNext()) {
 
428
            iter.advance();
 
429
            int row = iter.key();
 
430
            FieldElement<T>value = iter.value();
 
431
            for (int col = 0; col < virtualSize; col++) {
 
432
                res.setEntry(row, col, value.multiply(v[col]));
 
433
            }
 
434
        }
 
435
        return res;
 
436
     }
 
437
 
 
438
    /** {@inheritDoc} */
 
439
    public FieldMatrix<T> outerProduct(FieldVector<T> v)
 
440
    throws IllegalArgumentException {
 
441
        if(v instanceof SparseFieldVector<?>)
 
442
            return outerProduct((SparseFieldVector<T>)v);
 
443
        else
 
444
            return outerProduct(v.toArray());
 
445
    }
 
446
 
 
447
    /** {@inheritDoc} */
 
448
    public FieldVector<T> projection(FieldVector<T> v)
 
449
    throws IllegalArgumentException {
 
450
        checkVectorDimensions(v.getDimension());
 
451
        return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
 
452
    }
 
453
 
 
454
    /** {@inheritDoc} */
 
455
    public FieldVector<T> projection(T[] v) throws IllegalArgumentException {
 
456
        checkVectorDimensions(v.length);
 
457
        return projection(new SparseFieldVector<T>(field,v));
 
458
    }
 
459
 
 
460
    /** {@inheritDoc} */
 
461
    public void set(T value) {
 
462
        for (int i = 0; i < virtualSize; i++) {
 
463
            setEntry(i, value);
 
464
        }
 
465
    }
 
466
 
 
467
    /** {@inheritDoc} */
 
468
    public void setEntry(int index, T value) throws MatrixIndexException {
 
469
        checkIndex(index);
 
470
        entries.put(index, value);
 
471
   }
 
472
 
 
473
    /** {@inheritDoc} */
 
474
    public void setSubVector(int index, FieldVector<T> v)
 
475
            throws MatrixIndexException {
 
476
        checkIndex(index);
 
477
        checkIndex(index + v.getDimension() - 1);
 
478
        setSubVector(index, v.getData());
 
479
    }
 
480
 
 
481
    /** {@inheritDoc} */
 
482
    public void setSubVector(int index, T[] v) throws MatrixIndexException {
 
483
        checkIndex(index);
 
484
        checkIndex(index + v.length - 1);
 
485
        for (int i = 0; i < v.length; i++) {
 
486
            setEntry(i + index, v[i]);
 
487
        }
 
488
        
 
489
    }
 
490
 
 
491
    /**
 
492
     * Optimized method to subtract SparseRealVectors.
 
493
     * @param v The vector to subtract from <code>this</code>
 
494
     * @return The difference of <code>this</code> and <code>v</code>
 
495
     * @throws IllegalArgumentException If the dimensions don't match
 
496
     */
 
497
    public SparseFieldVector<T> subtract(SparseFieldVector<T> v) throws IllegalArgumentException{
 
498
        checkVectorDimensions(v.getDimension());
 
499
        SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
 
500
        OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
 
501
        while (iter.hasNext()) {
 
502
            iter.advance();
 
503
            int key = iter.key();
 
504
            if (entries.containsKey(key)) {
 
505
                res.setEntry(key, entries.get(key).subtract(iter.value()));
 
506
            } else {
 
507
                res.setEntry(key, field.getZero().subtract(iter.value()));
 
508
            }
 
509
        }
 
510
        return res;
 
511
    }
 
512
 
 
513
    /** {@inheritDoc} */
 
514
    public FieldVector<T> subtract(FieldVector<T> v)
 
515
           throws IllegalArgumentException {
 
516
        if(v instanceof SparseFieldVector<?>)
 
517
            return subtract((SparseFieldVector<T>)v);
 
518
        else
 
519
            return subtract(v.toArray());
 
520
    }
 
521
 
 
522
    /** {@inheritDoc} */
 
523
    public FieldVector<T> subtract(T[] v) throws IllegalArgumentException {
 
524
        checkVectorDimensions(v.length);
 
525
        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
 
526
        for (int i = 0; i < v.length; i++) {
 
527
            if (entries.containsKey(i)) {
 
528
                res.setEntry(i, entries.get(i).subtract(v[i]));
 
529
            } else {
 
530
                res.setEntry(i, field.getZero().subtract(v[i]));
 
531
            }
 
532
        }
 
533
        return res;
 
534
    }
 
535
 
 
536
    /** {@inheritDoc} */
 
537
    public T[] toArray() {
 
538
        return getData();
 
539
    }
 
540
    
 
541
    /**
 
542
     * Check if an index is valid.
 
543
     *
 
544
     * @param index
 
545
     *            index to check
 
546
     * @exception MatrixIndexException
 
547
     *                if index is not valid
 
548
     */
 
549
    private void checkIndex(final int index) throws MatrixIndexException {
 
550
        if (index < 0 || index >= getDimension()) {
 
551
            throw new MatrixIndexException(
 
552
                    "index {0} out of allowed range [{1}, {2}]",
 
553
                    index, 0, getDimension() - 1);
 
554
        }
 
555
    }
 
556
 
 
557
    /**
 
558
     * Check if instance dimension is equal to some expected value.
 
559
     *
 
560
     * @param n
 
561
     *            expected dimension.
 
562
     * @exception IllegalArgumentException
 
563
     *                if the dimension is inconsistent with vector size
 
564
     */
 
565
    protected void checkVectorDimensions(int n) throws IllegalArgumentException {
 
566
        if (getDimension() != n) {
 
567
            throw MathRuntimeException.createIllegalArgumentException(
 
568
                    "vector length mismatch: got {0} but expected {1}",
 
569
                    getDimension(), n);
 
570
        }
 
571
    }
 
572
 
 
573
 
 
574
    /** {@inheritDoc} */
 
575
    public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
 
576
        if (v instanceof SparseFieldVector<?>) {
 
577
            return add((SparseFieldVector<T>)v);
 
578
        } else {
 
579
            return add(v.toArray());
 
580
        }
 
581
    }
 
582
 
 
583
    /** Build an array of elements.
 
584
     * @param length size of the array to build
 
585
     * @return a new array
 
586
     */
 
587
    @SuppressWarnings("unchecked")
 
588
    private T[] buildArray(final int length) {
 
589
        return (T[]) Array.newInstance(field.getZero().getClass(), length);
 
590
    }
 
591
 
 
592
 
 
593
    /** {@inheritDoc} */
 
594
    @Override
 
595
    public int hashCode() {
 
596
        final int prime = 31;
 
597
        int result = 1;
 
598
        result = prime * result + ((field == null) ? 0 : field.hashCode());
 
599
        result = prime * result + virtualSize;
 
600
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
601
        while (iter.hasNext()) {
 
602
            iter.advance();
 
603
            int temp = iter.value().hashCode();
 
604
            result = prime * result + temp;
 
605
        }
 
606
        return result;
 
607
    }
 
608
 
 
609
 
 
610
    /** {@inheritDoc} */
 
611
    @SuppressWarnings("unchecked")
 
612
    @Override
 
613
    public boolean equals(Object obj) {
 
614
 
 
615
        if (this == obj) {
 
616
            return true;
 
617
        }
 
618
 
 
619
        if (obj == null) {
 
620
            return false;
 
621
        }
 
622
 
 
623
        if (!(obj instanceof SparseFieldVector)) {
 
624
            return false;
 
625
        }
 
626
 
 
627
        SparseFieldVector<T> other = (SparseFieldVector<T>) obj;
 
628
        if (field == null) {
 
629
            if (other.field != null) {
 
630
                return false;
 
631
            }
 
632
        } else if (!field.equals(other.field)) {
 
633
            return false;
 
634
        }
 
635
        if (virtualSize != other.virtualSize) {
 
636
            return false;
 
637
        }
 
638
 
 
639
        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
 
640
        while (iter.hasNext()) {
 
641
            iter.advance();
 
642
            T test = other.getEntry(iter.key());
 
643
            if (!test.equals(iter.value())) {
 
644
                return false;
 
645
            }
 
646
        }
 
647
        iter = other.getEntries().iterator();
 
648
        while (iter.hasNext()) {
 
649
            iter.advance();
 
650
            T test = iter.value();
 
651
            if (!test.equals(getEntry(iter.key()))) {
 
652
                return false;
 
653
            }
 
654
        }
 
655
        return true;
 
656
    }
 
657
 
 
658
 
 
659
    
 
660
}