source: src/main/java/agents/anac/y2019/harddealer/math3/linear/ArrayFieldVector.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

  • Property svn:executable set to *
File size: 42.0 KB
Line 
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 */
17package agents.anac.y2019.harddealer.math3.linear;
18
19import java.io.Serializable;
20import java.util.Arrays;
21
22import agents.anac.y2019.harddealer.math3.Field;
23import agents.anac.y2019.harddealer.math3.FieldElement;
24import agents.anac.y2019.harddealer.math3.exception.DimensionMismatchException;
25import agents.anac.y2019.harddealer.math3.exception.MathArithmeticException;
26import agents.anac.y2019.harddealer.math3.exception.NotPositiveException;
27import agents.anac.y2019.harddealer.math3.exception.NullArgumentException;
28import agents.anac.y2019.harddealer.math3.exception.NumberIsTooLargeException;
29import agents.anac.y2019.harddealer.math3.exception.NumberIsTooSmallException;
30import agents.anac.y2019.harddealer.math3.exception.OutOfRangeException;
31import agents.anac.y2019.harddealer.math3.exception.ZeroException;
32import agents.anac.y2019.harddealer.math3.exception.util.LocalizedFormats;
33import agents.anac.y2019.harddealer.math3.util.MathArrays;
34import agents.anac.y2019.harddealer.math3.util.MathUtils;
35
36/**
37 * This class implements the {@link FieldVector} interface with a {@link FieldElement} array.
38 * @param <T> the type of the field elements
39 * @since 2.0
40 */
41public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable {
42 /** Serializable version identifier. */
43 private static final long serialVersionUID = 7648186910365927050L;
44
45 /** Entries of the vector. */
46 private T[] data;
47
48 /** Field to which the elements belong. */
49 private final Field<T> field;
50
51 /**
52 * Build a 0-length vector.
53 * Zero-length vectors may be used to initialize construction of vectors
54 * by data gathering. We start with zero-length and use either the {@link
55 * #ArrayFieldVector(ArrayFieldVector, ArrayFieldVector)} constructor
56 * or one of the {@code append} methods ({@link #add(FieldVector)} or
57 * {@link #append(ArrayFieldVector)}) to gather data into this vector.
58 *
59 * @param field field to which the elements belong
60 */
61 public ArrayFieldVector(final Field<T> field) {
62 this(field, 0);
63 }
64
65 /**
66 * Construct a vector of zeroes.
67 *
68 * @param field Field to which the elements belong.
69 * @param size Size of the vector.
70 */
71 public ArrayFieldVector(Field<T> field, int size) {
72 this.field = field;
73 this.data = MathArrays.buildArray(field, size);
74 }
75
76 /**
77 * Construct a vector with preset values.
78 *
79 * @param size Size of the vector.
80 * @param preset All entries will be set with this value.
81 */
82 public ArrayFieldVector(int size, T preset) {
83 this(preset.getField(), size);
84 Arrays.fill(data, preset);
85 }
86
87 /**
88 * Construct a vector from an array, copying the input array.
89 * This constructor needs a non-empty {@code d} array to retrieve
90 * the field from its first element. This implies it cannot build
91 * 0 length vectors. To build vectors from any size, one should
92 * use the {@link #ArrayFieldVector(Field, FieldElement[])} constructor.
93 *
94 * @param d Array.
95 * @throws NullArgumentException if {@code d} is {@code null}.
96 * @throws ZeroException if {@code d} is empty.
97 * @see #ArrayFieldVector(Field, FieldElement[])
98 */
99 public ArrayFieldVector(T[] d)
100 throws NullArgumentException, ZeroException {
101 MathUtils.checkNotNull(d);
102 try {
103 field = d[0].getField();
104 data = d.clone();
105 } catch (ArrayIndexOutOfBoundsException e) {
106 throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
107 }
108 }
109
110 /**
111 * Construct a vector from an array, copying the input array.
112 *
113 * @param field Field to which the elements belong.
114 * @param d Array.
115 * @throws NullArgumentException if {@code d} is {@code null}.
116 * @see #ArrayFieldVector(FieldElement[])
117 */
118 public ArrayFieldVector(Field<T> field, T[] d)
119 throws NullArgumentException {
120 MathUtils.checkNotNull(d);
121 this.field = field;
122 data = d.clone();
123 }
124
125 /**
126 * Create a new ArrayFieldVector using the input array as the underlying
127 * data array.
128 * If an array is built specially in order to be embedded in a
129 * ArrayFieldVector and not used directly, the {@code copyArray} may be
130 * set to {@code false}. This will prevent the copying and improve
131 * performance as no new array will be built and no data will be copied.
132 * This constructor needs a non-empty {@code d} array to retrieve
133 * the field from its first element. This implies it cannot build
134 * 0 length vectors. To build vectors from any size, one should
135 * use the {@link #ArrayFieldVector(Field, FieldElement[], boolean)}
136 * constructor.
137 *
138 * @param d Data for the new vector.
139 * @param copyArray If {@code true}, the input array will be copied,
140 * otherwise it will be referenced.
141 * @throws NullArgumentException if {@code d} is {@code null}.
142 * @throws ZeroException if {@code d} is empty.
143 * @see #ArrayFieldVector(FieldElement[])
144 * @see #ArrayFieldVector(Field, FieldElement[], boolean)
145 */
146 public ArrayFieldVector(T[] d, boolean copyArray)
147 throws NullArgumentException, ZeroException {
148 MathUtils.checkNotNull(d);
149 if (d.length == 0) {
150 throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
151 }
152 field = d[0].getField();
153 data = copyArray ? d.clone() : d;
154 }
155
156 /**
157 * Create a new ArrayFieldVector using the input array as the underlying
158 * data array.
159 * If an array is built specially in order to be embedded in a
160 * ArrayFieldVector and not used directly, the {@code copyArray} may be
161 * set to {@code false}. This will prevent the copying and improve
162 * performance as no new array will be built and no data will be copied.
163 *
164 * @param field Field to which the elements belong.
165 * @param d Data for the new vector.
166 * @param copyArray If {@code true}, the input array will be copied,
167 * otherwise it will be referenced.
168 * @throws NullArgumentException if {@code d} is {@code null}.
169 * @see #ArrayFieldVector(FieldElement[], boolean)
170 */
171 public ArrayFieldVector(Field<T> field, T[] d, boolean copyArray)
172 throws NullArgumentException {
173 MathUtils.checkNotNull(d);
174 this.field = field;
175 data = copyArray ? d.clone() : d;
176 }
177
178 /**
179 * Construct a vector from part of a array.
180 *
181 * @param d Array.
182 * @param pos Position of the first entry.
183 * @param size Number of entries to copy.
184 * @throws NullArgumentException if {@code d} is {@code null}.
185 * @throws NumberIsTooLargeException if the size of {@code d} is less
186 * than {@code pos + size}.
187 */
188 public ArrayFieldVector(T[] d, int pos, int size)
189 throws NullArgumentException, NumberIsTooLargeException {
190 MathUtils.checkNotNull(d);
191 if (d.length < pos + size) {
192 throw new NumberIsTooLargeException(pos + size, d.length, true);
193 }
194 field = d[0].getField();
195 data = MathArrays.buildArray(field, size);
196 System.arraycopy(d, pos, data, 0, size);
197 }
198
199 /**
200 * Construct a vector from part of a array.
201 *
202 * @param field Field to which the elements belong.
203 * @param d Array.
204 * @param pos Position of the first entry.
205 * @param size Number of entries to copy.
206 * @throws NullArgumentException if {@code d} is {@code null}.
207 * @throws NumberIsTooLargeException if the size of {@code d} is less
208 * than {@code pos + size}.
209 */
210 public ArrayFieldVector(Field<T> field, T[] d, int pos, int size)
211 throws NullArgumentException, NumberIsTooLargeException {
212 MathUtils.checkNotNull(d);
213 if (d.length < pos + size) {
214 throw new NumberIsTooLargeException(pos + size, d.length, true);
215 }
216 this.field = field;
217 data = MathArrays.buildArray(field, size);
218 System.arraycopy(d, pos, data, 0, size);
219 }
220
221 /**
222 * Construct a vector from another vector, using a deep copy.
223 *
224 * @param v Vector to copy.
225 * @throws NullArgumentException if {@code v} is {@code null}.
226 */
227 public ArrayFieldVector(FieldVector<T> v)
228 throws NullArgumentException {
229 MathUtils.checkNotNull(v);
230 field = v.getField();
231 data = MathArrays.buildArray(field, v.getDimension());
232 for (int i = 0; i < data.length; ++i) {
233 data[i] = v.getEntry(i);
234 }
235 }
236
237 /**
238 * Construct a vector from another vector, using a deep copy.
239 *
240 * @param v Vector to copy.
241 * @throws NullArgumentException if {@code v} is {@code null}.
242 */
243 public ArrayFieldVector(ArrayFieldVector<T> v)
244 throws NullArgumentException {
245 MathUtils.checkNotNull(v);
246 field = v.getField();
247 data = v.data.clone();
248 }
249
250 /**
251 * Construct a vector from another vector.
252 *
253 * @param v Vector to copy.
254 * @param deep If {@code true} perform a deep copy, otherwise perform
255 * a shallow copy
256 * @throws NullArgumentException if {@code v} is {@code null}.
257 */
258 public ArrayFieldVector(ArrayFieldVector<T> v, boolean deep)
259 throws NullArgumentException {
260 MathUtils.checkNotNull(v);
261 field = v.getField();
262 data = deep ? v.data.clone() : v.data;
263 }
264
265 /**
266 * Construct a vector by appending one vector to another vector.
267 *
268 * @param v1 First vector (will be put in front of the new vector).
269 * @param v2 Second vector (will be put at back of the new vector).
270 * @throws NullArgumentException if {@code v1} or {@code v2} is
271 * {@code null}.
272 * @deprecated as of 3.2, replaced by {@link #ArrayFieldVector(FieldVector, FieldVector)}
273 */
274 @Deprecated
275 public ArrayFieldVector(ArrayFieldVector<T> v1, ArrayFieldVector<T> v2)
276 throws NullArgumentException {
277 this((FieldVector<T>) v1, (FieldVector<T>) v2);
278 }
279
280 /**
281 * Construct a vector by appending one vector to another vector.
282 *
283 * @param v1 First vector (will be put in front of the new vector).
284 * @param v2 Second vector (will be put at back of the new vector).
285 * @throws NullArgumentException if {@code v1} or {@code v2} is
286 * {@code null}.
287 * @since 3.2
288 */
289 public ArrayFieldVector(FieldVector<T> v1, FieldVector<T> v2)
290 throws NullArgumentException {
291 MathUtils.checkNotNull(v1);
292 MathUtils.checkNotNull(v2);
293 field = v1.getField();
294 final T[] v1Data =
295 (v1 instanceof ArrayFieldVector) ? ((ArrayFieldVector<T>) v1).data : v1.toArray();
296 final T[] v2Data =
297 (v2 instanceof ArrayFieldVector) ? ((ArrayFieldVector<T>) v2).data : v2.toArray();
298 data = MathArrays.buildArray(field, v1Data.length + v2Data.length);
299 System.arraycopy(v1Data, 0, data, 0, v1Data.length);
300 System.arraycopy(v2Data, 0, data, v1Data.length, v2Data.length);
301 }
302
303 /**
304 * Construct a vector by appending one vector to another vector.
305 *
306 * @param v1 First vector (will be put in front of the new vector).
307 * @param v2 Second vector (will be put at back of the new vector).
308 * @throws NullArgumentException if {@code v1} or {@code v2} is
309 * {@code null}.
310 * @deprecated as of 3.2, replaced by {@link #ArrayFieldVector(FieldVector, FieldElement[])}
311 */
312 @Deprecated
313 public ArrayFieldVector(ArrayFieldVector<T> v1, T[] v2)
314 throws NullArgumentException {
315 this((FieldVector<T>) v1, v2);
316 }
317
318 /**
319 * Construct a vector by appending one vector to another vector.
320 *
321 * @param v1 First vector (will be put in front of the new vector).
322 * @param v2 Second vector (will be put at back of the new vector).
323 * @throws NullArgumentException if {@code v1} or {@code v2} is
324 * {@code null}.
325 * @since 3.2
326 */
327 public ArrayFieldVector(FieldVector<T> v1, T[] v2)
328 throws NullArgumentException {
329 MathUtils.checkNotNull(v1);
330 MathUtils.checkNotNull(v2);
331 field = v1.getField();
332 final T[] v1Data =
333 (v1 instanceof ArrayFieldVector) ? ((ArrayFieldVector<T>) v1).data : v1.toArray();
334 data = MathArrays.buildArray(field, v1Data.length + v2.length);
335 System.arraycopy(v1Data, 0, data, 0, v1Data.length);
336 System.arraycopy(v2, 0, data, v1Data.length, v2.length);
337 }
338
339 /**
340 * Construct a vector by appending one vector to another vector.
341 *
342 * @param v1 First vector (will be put in front of the new vector).
343 * @param v2 Second vector (will be put at back of the new vector).
344 * @throws NullArgumentException if {@code v1} or {@code v2} is
345 * {@code null}.
346 * @deprecated as of 3.2, replaced by {@link #ArrayFieldVector(FieldElement[], FieldVector)}
347 */
348 @Deprecated
349 public ArrayFieldVector(T[] v1, ArrayFieldVector<T> v2)
350 throws NullArgumentException {
351 this(v1, (FieldVector<T>) v2);
352 }
353
354 /**
355 * Construct a vector by appending one vector to another vector.
356 *
357 * @param v1 First vector (will be put in front of the new vector).
358 * @param v2 Second vector (will be put at back of the new vector).
359 * @throws NullArgumentException if {@code v1} or {@code v2} is
360 * {@code null}.
361 * @since 3.2
362 */
363 public ArrayFieldVector(T[] v1, FieldVector<T> v2)
364 throws NullArgumentException {
365 MathUtils.checkNotNull(v1);
366 MathUtils.checkNotNull(v2);
367 field = v2.getField();
368 final T[] v2Data =
369 (v2 instanceof ArrayFieldVector) ? ((ArrayFieldVector<T>) v2).data : v2.toArray();
370 data = MathArrays.buildArray(field, v1.length + v2Data.length);
371 System.arraycopy(v1, 0, data, 0, v1.length);
372 System.arraycopy(v2Data, 0, data, v1.length, v2Data.length);
373 }
374
375 /**
376 * Construct a vector by appending one vector to another vector.
377 * This constructor needs at least one non-empty array to retrieve
378 * the field from its first element. This implies it cannot build
379 * 0 length vectors. To build vectors from any size, one should
380 * use the {@link #ArrayFieldVector(Field, FieldElement[], FieldElement[])}
381 * constructor.
382 *
383 * @param v1 First vector (will be put in front of the new vector).
384 * @param v2 Second vector (will be put at back of the new vector).
385 * @throws NullArgumentException if {@code v1} or {@code v2} is
386 * {@code null}.
387 * @throws ZeroException if both arrays are empty.
388 * @see #ArrayFieldVector(Field, FieldElement[], FieldElement[])
389 */
390 public ArrayFieldVector(T[] v1, T[] v2)
391 throws NullArgumentException, ZeroException {
392 MathUtils.checkNotNull(v1);
393 MathUtils.checkNotNull(v2);
394 if (v1.length + v2.length == 0) {
395 throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
396 }
397 data = MathArrays.buildArray(v1[0].getField(), v1.length + v2.length);
398 System.arraycopy(v1, 0, data, 0, v1.length);
399 System.arraycopy(v2, 0, data, v1.length, v2.length);
400 field = data[0].getField();
401 }
402
403 /**
404 * Construct a vector by appending one vector to another vector.
405 *
406 * @param field Field to which the elements belong.
407 * @param v1 First vector (will be put in front of the new vector).
408 * @param v2 Second vector (will be put at back of the new vector).
409 * @throws NullArgumentException if {@code v1} or {@code v2} is
410 * {@code null}.
411 * @throws ZeroException if both arrays are empty.
412 * @see #ArrayFieldVector(FieldElement[], FieldElement[])
413 */
414 public ArrayFieldVector(Field<T> field, T[] v1, T[] v2)
415 throws NullArgumentException, ZeroException {
416 MathUtils.checkNotNull(v1);
417 MathUtils.checkNotNull(v2);
418 if (v1.length + v2.length == 0) {
419 throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
420 }
421 data = MathArrays.buildArray(field, v1.length + v2.length);
422 System.arraycopy(v1, 0, data, 0, v1.length);
423 System.arraycopy(v2, 0, data, v1.length, v2.length);
424 this.field = field;
425 }
426
427 /** {@inheritDoc} */
428 public Field<T> getField() {
429 return field;
430 }
431
432 /** {@inheritDoc} */
433 public FieldVector<T> copy() {
434 return new ArrayFieldVector<T>(this, true);
435 }
436
437 /** {@inheritDoc} */
438 public FieldVector<T> add(FieldVector<T> v)
439 throws DimensionMismatchException {
440 try {
441 return add((ArrayFieldVector<T>) v);
442 } catch (ClassCastException cce) {
443 checkVectorDimensions(v);
444 T[] out = MathArrays.buildArray(field, data.length);
445 for (int i = 0; i < data.length; i++) {
446 out[i] = data[i].add(v.getEntry(i));
447 }
448 return new ArrayFieldVector<T>(field, out, false);
449 }
450 }
451
452 /**
453 * Compute the sum of {@code this} and {@code v}.
454 * @param v vector to be added
455 * @return {@code this + v}
456 * @throws DimensionMismatchException if {@code v} is not the same size as
457 * {@code this}
458 */
459 public ArrayFieldVector<T> add(ArrayFieldVector<T> v)
460 throws DimensionMismatchException {
461 checkVectorDimensions(v.data.length);
462 T[] out = MathArrays.buildArray(field, data.length);
463 for (int i = 0; i < data.length; i++) {
464 out[i] = data[i].add(v.data[i]);
465 }
466 return new ArrayFieldVector<T>(field, out, false);
467 }
468
469 /** {@inheritDoc} */
470 public FieldVector<T> subtract(FieldVector<T> v)
471 throws DimensionMismatchException {
472 try {
473 return subtract((ArrayFieldVector<T>) v);
474 } catch (ClassCastException cce) {
475 checkVectorDimensions(v);
476 T[] out = MathArrays.buildArray(field, data.length);
477 for (int i = 0; i < data.length; i++) {
478 out[i] = data[i].subtract(v.getEntry(i));
479 }
480 return new ArrayFieldVector<T>(field, out, false);
481 }
482 }
483
484 /**
485 * Compute {@code this} minus {@code v}.
486 * @param v vector to be subtracted
487 * @return {@code this - v}
488 * @throws DimensionMismatchException if {@code v} is not the same size as
489 * {@code this}
490 */
491 public ArrayFieldVector<T> subtract(ArrayFieldVector<T> v)
492 throws DimensionMismatchException {
493 checkVectorDimensions(v.data.length);
494 T[] out = MathArrays.buildArray(field, data.length);
495 for (int i = 0; i < data.length; i++) {
496 out[i] = data[i].subtract(v.data[i]);
497 }
498 return new ArrayFieldVector<T>(field, out, false);
499 }
500
501 /** {@inheritDoc} */
502 public FieldVector<T> mapAdd(T d) throws NullArgumentException {
503 T[] out = MathArrays.buildArray(field, data.length);
504 for (int i = 0; i < data.length; i++) {
505 out[i] = data[i].add(d);
506 }
507 return new ArrayFieldVector<T>(field, out, false);
508 }
509
510 /** {@inheritDoc} */
511 public FieldVector<T> mapAddToSelf(T d) throws NullArgumentException {
512 for (int i = 0; i < data.length; i++) {
513 data[i] = data[i].add(d);
514 }
515 return this;
516 }
517
518 /** {@inheritDoc} */
519 public FieldVector<T> mapSubtract(T d) throws NullArgumentException {
520 T[] out = MathArrays.buildArray(field, data.length);
521 for (int i = 0; i < data.length; i++) {
522 out[i] = data[i].subtract(d);
523 }
524 return new ArrayFieldVector<T>(field, out, false);
525 }
526
527 /** {@inheritDoc} */
528 public FieldVector<T> mapSubtractToSelf(T d) throws NullArgumentException {
529 for (int i = 0; i < data.length; i++) {
530 data[i] = data[i].subtract(d);
531 }
532 return this;
533 }
534
535 /** {@inheritDoc} */
536 public FieldVector<T> mapMultiply(T d) throws NullArgumentException {
537 T[] out = MathArrays.buildArray(field, data.length);
538 for (int i = 0; i < data.length; i++) {
539 out[i] = data[i].multiply(d);
540 }
541 return new ArrayFieldVector<T>(field, out, false);
542 }
543
544 /** {@inheritDoc} */
545 public FieldVector<T> mapMultiplyToSelf(T d) throws NullArgumentException {
546 for (int i = 0; i < data.length; i++) {
547 data[i] = data[i].multiply(d);
548 }
549 return this;
550 }
551
552 /** {@inheritDoc} */
553 public FieldVector<T> mapDivide(T d)
554 throws NullArgumentException, MathArithmeticException {
555 MathUtils.checkNotNull(d);
556 T[] out = MathArrays.buildArray(field, data.length);
557 for (int i = 0; i < data.length; i++) {
558 out[i] = data[i].divide(d);
559 }
560 return new ArrayFieldVector<T>(field, out, false);
561 }
562
563 /** {@inheritDoc} */
564 public FieldVector<T> mapDivideToSelf(T d)
565 throws NullArgumentException, MathArithmeticException {
566 MathUtils.checkNotNull(d);
567 for (int i = 0; i < data.length; i++) {
568 data[i] = data[i].divide(d);
569 }
570 return this;
571 }
572
573 /** {@inheritDoc} */
574 public FieldVector<T> mapInv() throws MathArithmeticException {
575 T[] out = MathArrays.buildArray(field, data.length);
576 final T one = field.getOne();
577 for (int i = 0; i < data.length; i++) {
578 try {
579 out[i] = one.divide(data[i]);
580 } catch (final MathArithmeticException e) {
581 throw new MathArithmeticException(LocalizedFormats.INDEX, i);
582 }
583 }
584 return new ArrayFieldVector<T>(field, out, false);
585 }
586
587 /** {@inheritDoc} */
588 public FieldVector<T> mapInvToSelf() throws MathArithmeticException {
589 final T one = field.getOne();
590 for (int i = 0; i < data.length; i++) {
591 try {
592 data[i] = one.divide(data[i]);
593 } catch (final MathArithmeticException e) {
594 throw new MathArithmeticException(LocalizedFormats.INDEX, i);
595 }
596 }
597 return this;
598 }
599
600 /** {@inheritDoc} */
601 public FieldVector<T> ebeMultiply(FieldVector<T> v)
602 throws DimensionMismatchException {
603 try {
604 return ebeMultiply((ArrayFieldVector<T>) v);
605 } catch (ClassCastException cce) {
606 checkVectorDimensions(v);
607 T[] out = MathArrays.buildArray(field, data.length);
608 for (int i = 0; i < data.length; i++) {
609 out[i] = data[i].multiply(v.getEntry(i));
610 }
611 return new ArrayFieldVector<T>(field, out, false);
612 }
613 }
614
615 /**
616 * Element-by-element multiplication.
617 * @param v vector by which instance elements must be multiplied
618 * @return a vector containing {@code this[i] * v[i]} for all {@code i}
619 * @throws DimensionMismatchException if {@code v} is not the same size as
620 * {@code this}
621 */
622 public ArrayFieldVector<T> ebeMultiply(ArrayFieldVector<T> v)
623 throws DimensionMismatchException {
624 checkVectorDimensions(v.data.length);
625 T[] out = MathArrays.buildArray(field, data.length);
626 for (int i = 0; i < data.length; i++) {
627 out[i] = data[i].multiply(v.data[i]);
628 }
629 return new ArrayFieldVector<T>(field, out, false);
630 }
631
632 /** {@inheritDoc} */
633 public FieldVector<T> ebeDivide(FieldVector<T> v)
634 throws DimensionMismatchException, MathArithmeticException {
635 try {
636 return ebeDivide((ArrayFieldVector<T>) v);
637 } catch (ClassCastException cce) {
638 checkVectorDimensions(v);
639 T[] out = MathArrays.buildArray(field, data.length);
640 for (int i = 0; i < data.length; i++) {
641 try {
642 out[i] = data[i].divide(v.getEntry(i));
643 } catch (final MathArithmeticException e) {
644 throw new MathArithmeticException(LocalizedFormats.INDEX, i);
645 }
646 }
647 return new ArrayFieldVector<T>(field, out, false);
648 }
649 }
650
651 /**
652 * Element-by-element division.
653 * @param v vector by which instance elements must be divided
654 * @return a vector containing {@code this[i] / v[i]} for all {@code i}
655 * @throws DimensionMismatchException if {@code v} is not the same size as
656 * {@code this}
657 * @throws MathArithmeticException if one entry of {@code v} is zero.
658 */
659 public ArrayFieldVector<T> ebeDivide(ArrayFieldVector<T> v)
660 throws DimensionMismatchException, MathArithmeticException {
661 checkVectorDimensions(v.data.length);
662 T[] out = MathArrays.buildArray(field, data.length);
663 for (int i = 0; i < data.length; i++) {
664 try {
665 out[i] = data[i].divide(v.data[i]);
666 } catch (final MathArithmeticException e) {
667 throw new MathArithmeticException(LocalizedFormats.INDEX, i);
668 }
669 }
670 return new ArrayFieldVector<T>(field, out, false);
671 }
672
673 /** {@inheritDoc} */
674 public T[] getData() {
675 return data.clone();
676 }
677
678 /**
679 * Returns a reference to the underlying data array.
680 * <p>Does not make a fresh copy of the underlying data.</p>
681 * @return array of entries
682 */
683 public T[] getDataRef() {
684 return data;
685 }
686
687 /** {@inheritDoc} */
688 public T dotProduct(FieldVector<T> v)
689 throws DimensionMismatchException {
690 try {
691 return dotProduct((ArrayFieldVector<T>) v);
692 } catch (ClassCastException cce) {
693 checkVectorDimensions(v);
694 T dot = field.getZero();
695 for (int i = 0; i < data.length; i++) {
696 dot = dot.add(data[i].multiply(v.getEntry(i)));
697 }
698 return dot;
699 }
700 }
701
702 /**
703 * Compute the dot product.
704 * @param v vector with which dot product should be computed
705 * @return the scalar dot product of {@code this} and {@code v}
706 * @throws DimensionMismatchException if {@code v} is not the same size as
707 * {@code this}
708 */
709 public T dotProduct(ArrayFieldVector<T> v)
710 throws DimensionMismatchException {
711 checkVectorDimensions(v.data.length);
712 T dot = field.getZero();
713 for (int i = 0; i < data.length; i++) {
714 dot = dot.add(data[i].multiply(v.data[i]));
715 }
716 return dot;
717 }
718
719 /** {@inheritDoc} */
720 public FieldVector<T> projection(FieldVector<T> v)
721 throws DimensionMismatchException, MathArithmeticException {
722 return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
723 }
724
725 /** Find the orthogonal projection of this vector onto another vector.
726 * @param v vector onto which {@code this} must be projected
727 * @return projection of {@code this} onto {@code v}
728 * @throws DimensionMismatchException if {@code v} is not the same size as
729 * {@code this}
730 * @throws MathArithmeticException if {@code v} is the null vector.
731 */
732 public ArrayFieldVector<T> projection(ArrayFieldVector<T> v)
733 throws DimensionMismatchException, MathArithmeticException {
734 return (ArrayFieldVector<T>) v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
735 }
736
737 /** {@inheritDoc} */
738 public FieldMatrix<T> outerProduct(FieldVector<T> v) {
739 try {
740 return outerProduct((ArrayFieldVector<T>) v);
741 } catch (ClassCastException cce) {
742 final int m = data.length;
743 final int n = v.getDimension();
744 final FieldMatrix<T> out = new Array2DRowFieldMatrix<T>(field, m, n);
745 for (int i = 0; i < m; i++) {
746 for (int j = 0; j < n; j++) {
747 out.setEntry(i, j, data[i].multiply(v.getEntry(j)));
748 }
749 }
750 return out;
751 }
752 }
753
754 /**
755 * Compute the outer product.
756 * @param v vector with which outer product should be computed
757 * @return the matrix outer product between instance and v
758 */
759 public FieldMatrix<T> outerProduct(ArrayFieldVector<T> v) {
760 final int m = data.length;
761 final int n = v.data.length;
762 final FieldMatrix<T> out = new Array2DRowFieldMatrix<T>(field, m, n);
763 for (int i = 0; i < m; i++) {
764 for (int j = 0; j < n; j++) {
765 out.setEntry(i, j, data[i].multiply(v.data[j]));
766 }
767 }
768 return out;
769 }
770
771 /** {@inheritDoc} */
772 public T getEntry(int index) {
773 return data[index];
774 }
775
776 /** {@inheritDoc} */
777 public int getDimension() {
778 return data.length;
779 }
780
781 /** {@inheritDoc} */
782 public FieldVector<T> append(FieldVector<T> v) {
783 try {
784 return append((ArrayFieldVector<T>) v);
785 } catch (ClassCastException cce) {
786 return new ArrayFieldVector<T>(this,new ArrayFieldVector<T>(v));
787 }
788 }
789
790 /**
791 * Construct a vector by appending a vector to this vector.
792 * @param v vector to append to this one.
793 * @return a new vector
794 */
795 public ArrayFieldVector<T> append(ArrayFieldVector<T> v) {
796 return new ArrayFieldVector<T>(this, v);
797 }
798
799 /** {@inheritDoc} */
800 public FieldVector<T> append(T in) {
801 final T[] out = MathArrays.buildArray(field, data.length + 1);
802 System.arraycopy(data, 0, out, 0, data.length);
803 out[data.length] = in;
804 return new ArrayFieldVector<T>(field, out, false);
805 }
806
807 /** {@inheritDoc} */
808 public FieldVector<T> getSubVector(int index, int n)
809 throws OutOfRangeException, NotPositiveException {
810 if (n < 0) {
811 throw new NotPositiveException(LocalizedFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, n);
812 }
813 ArrayFieldVector<T> out = new ArrayFieldVector<T>(field, n);
814 try {
815 System.arraycopy(data, index, out.data, 0, n);
816 } catch (IndexOutOfBoundsException e) {
817 checkIndex(index);
818 checkIndex(index + n - 1);
819 }
820 return out;
821 }
822
823 /** {@inheritDoc} */
824 public void setEntry(int index, T value) {
825 try {
826 data[index] = value;
827 } catch (IndexOutOfBoundsException e) {
828 checkIndex(index);
829 }
830 }
831
832 /** {@inheritDoc} */
833 public void setSubVector(int index, FieldVector<T> v) throws OutOfRangeException {
834 try {
835 try {
836 set(index, (ArrayFieldVector<T>) v);
837 } catch (ClassCastException cce) {
838 for (int i = index; i < index + v.getDimension(); ++i) {
839 data[i] = v.getEntry(i-index);
840 }
841 }
842 } catch (IndexOutOfBoundsException e) {
843 checkIndex(index);
844 checkIndex(index + v.getDimension() - 1);
845 }
846 }
847
848 /**
849 * Set a set of consecutive elements.
850 *
851 * @param index index of first element to be set.
852 * @param v vector containing the values to set.
853 * @throws OutOfRangeException if the index is invalid.
854 */
855 public void set(int index, ArrayFieldVector<T> v) throws OutOfRangeException {
856 try {
857 System.arraycopy(v.data, 0, data, index, v.data.length);
858 } catch (IndexOutOfBoundsException e) {
859 checkIndex(index);
860 checkIndex(index + v.data.length - 1);
861 }
862 }
863
864 /** {@inheritDoc} */
865 public void set(T value) {
866 Arrays.fill(data, value);
867 }
868
869 /** {@inheritDoc} */
870 public T[] toArray(){
871 return data.clone();
872 }
873
874 /**
875 * Check if instance and specified vectors have the same dimension.
876 * @param v vector to compare instance with
877 * @exception DimensionMismatchException if the vectors do not
878 * have the same dimensions
879 */
880 protected void checkVectorDimensions(FieldVector<T> v)
881 throws DimensionMismatchException {
882 checkVectorDimensions(v.getDimension());
883 }
884
885 /**
886 * Check if instance dimension is equal to some expected value.
887 *
888 * @param n Expected dimension.
889 * @throws DimensionMismatchException if the dimension is not equal to the
890 * size of {@code this} vector.
891 */
892 protected void checkVectorDimensions(int n)
893 throws DimensionMismatchException {
894 if (data.length != n) {
895 throw new DimensionMismatchException(data.length, n);
896 }
897 }
898
899 /**
900 * Visits (but does not alter) all entries of this vector in default order
901 * (increasing index).
902 *
903 * @param visitor the visitor to be used to process the entries of this
904 * vector
905 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
906 * at the end of the walk
907 * @since 3.3
908 */
909 public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor) {
910 final int dim = getDimension();
911 visitor.start(dim, 0, dim - 1);
912 for (int i = 0; i < dim; i++) {
913 visitor.visit(i, getEntry(i));
914 }
915 return visitor.end();
916 }
917
918 /**
919 * Visits (but does not alter) some entries of this vector in default order
920 * (increasing index).
921 *
922 * @param visitor visitor to be used to process the entries of this vector
923 * @param start the index of the first entry to be visited
924 * @param end the index of the last entry to be visited (inclusive)
925 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
926 * at the end of the walk
927 * @throws NumberIsTooSmallException if {@code end < start}.
928 * @throws OutOfRangeException if the indices are not valid.
929 * @since 3.3
930 */
931 public T walkInDefaultOrder(final FieldVectorPreservingVisitor<T> visitor,
932 final int start, final int end)
933 throws NumberIsTooSmallException, OutOfRangeException {
934 checkIndices(start, end);
935 visitor.start(getDimension(), start, end);
936 for (int i = start; i <= end; i++) {
937 visitor.visit(i, getEntry(i));
938 }
939 return visitor.end();
940 }
941
942 /**
943 * Visits (but does not alter) all entries of this vector in optimized
944 * order. The order in which the entries are visited is selected so as to
945 * lead to the most efficient implementation; it might depend on the
946 * concrete implementation of this abstract class.
947 *
948 * @param visitor the visitor to be used to process the entries of this
949 * vector
950 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
951 * at the end of the walk
952 * @since 3.3
953 */
954 public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor) {
955 return walkInDefaultOrder(visitor);
956 }
957
958 /**
959 * Visits (but does not alter) some entries of this vector in optimized
960 * order. The order in which the entries are visited is selected so as to
961 * lead to the most efficient implementation; it might depend on the
962 * concrete implementation of this abstract class.
963 *
964 * @param visitor visitor to be used to process the entries of this vector
965 * @param start the index of the first entry to be visited
966 * @param end the index of the last entry to be visited (inclusive)
967 * @return the value returned by {@link FieldVectorPreservingVisitor#end()}
968 * at the end of the walk
969 * @throws NumberIsTooSmallException if {@code end < start}.
970 * @throws OutOfRangeException if the indices are not valid.
971 * @since 3.3
972 */
973 public T walkInOptimizedOrder(final FieldVectorPreservingVisitor<T> visitor,
974 final int start, final int end)
975 throws NumberIsTooSmallException, OutOfRangeException {
976 return walkInDefaultOrder(visitor, start, end);
977 }
978
979 /**
980 * Visits (and possibly alters) all entries of this vector in default order
981 * (increasing index).
982 *
983 * @param visitor the visitor to be used to process and modify the entries
984 * of this vector
985 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
986 * at the end of the walk
987 * @since 3.3
988 */
989 public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor) {
990 final int dim = getDimension();
991 visitor.start(dim, 0, dim - 1);
992 for (int i = 0; i < dim; i++) {
993 setEntry(i, visitor.visit(i, getEntry(i)));
994 }
995 return visitor.end();
996 }
997
998 /**
999 * Visits (and possibly alters) some entries of this vector in default order
1000 * (increasing index).
1001 *
1002 * @param visitor visitor to be used to process the entries of this vector
1003 * @param start the index of the first entry to be visited
1004 * @param end the index of the last entry to be visited (inclusive)
1005 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
1006 * at the end of the walk
1007 * @throws NumberIsTooSmallException if {@code end < start}.
1008 * @throws OutOfRangeException if the indices are not valid.
1009 * @since 3.3
1010 */
1011 public T walkInDefaultOrder(final FieldVectorChangingVisitor<T> visitor,
1012 final int start, final int end)
1013 throws NumberIsTooSmallException, OutOfRangeException {
1014 checkIndices(start, end);
1015 visitor.start(getDimension(), start, end);
1016 for (int i = start; i <= end; i++) {
1017 setEntry(i, visitor.visit(i, getEntry(i)));
1018 }
1019 return visitor.end();
1020 }
1021
1022 /**
1023 * Visits (and possibly alters) all entries of this vector in optimized
1024 * order. The order in which the entries are visited is selected so as to
1025 * lead to the most efficient implementation; it might depend on the
1026 * concrete implementation of this abstract class.
1027 *
1028 * @param visitor the visitor to be used to process the entries of this
1029 * vector
1030 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
1031 * at the end of the walk
1032 * @since 3.3
1033 */
1034 public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor) {
1035 return walkInDefaultOrder(visitor);
1036 }
1037
1038 /**
1039 * Visits (and possibly change) some entries of this vector in optimized
1040 * order. The order in which the entries are visited is selected so as to
1041 * lead to the most efficient implementation; it might depend on the
1042 * concrete implementation of this abstract class.
1043 *
1044 * @param visitor visitor to be used to process the entries of this vector
1045 * @param start the index of the first entry to be visited
1046 * @param end the index of the last entry to be visited (inclusive)
1047 * @return the value returned by {@link FieldVectorChangingVisitor#end()}
1048 * at the end of the walk
1049 * @throws NumberIsTooSmallException if {@code end < start}.
1050 * @throws OutOfRangeException if the indices are not valid.
1051 * @since 3.3
1052 */
1053 public T walkInOptimizedOrder(final FieldVectorChangingVisitor<T> visitor,
1054 final int start, final int end)
1055 throws NumberIsTooSmallException, OutOfRangeException {
1056 return walkInDefaultOrder(visitor, start, end);
1057 }
1058
1059 /**
1060 * Test for the equality of two vectors.
1061 *
1062 * @param other Object to test for equality.
1063 * @return {@code true} if two vector objects are equal, {@code false}
1064 * otherwise.
1065 */
1066 @Override
1067 public boolean equals(Object other) {
1068 if (this == other) {
1069 return true;
1070 }
1071 if (other == null) {
1072 return false;
1073 }
1074
1075 try {
1076 @SuppressWarnings("unchecked") // May fail, but we ignore ClassCastException
1077 FieldVector<T> rhs = (FieldVector<T>) other;
1078 if (data.length != rhs.getDimension()) {
1079 return false;
1080 }
1081
1082 for (int i = 0; i < data.length; ++i) {
1083 if (!data[i].equals(rhs.getEntry(i))) {
1084 return false;
1085 }
1086 }
1087 return true;
1088 } catch (ClassCastException ex) {
1089 // ignore exception
1090 return false;
1091 }
1092 }
1093
1094 /**
1095 * Get a hashCode for the real vector.
1096 * <p>All NaN values have the same hash code.</p>
1097 * @return a hash code value for this object
1098 */
1099 @Override
1100 public int hashCode() {
1101 int h = 3542;
1102 for (final T a : data) {
1103 h ^= a.hashCode();
1104 }
1105 return h;
1106 }
1107
1108 /**
1109 * Check if an index is valid.
1110 *
1111 * @param index Index to check.
1112 * @exception OutOfRangeException if the index is not valid.
1113 */
1114 private void checkIndex(final int index) throws OutOfRangeException {
1115 if (index < 0 || index >= getDimension()) {
1116 throw new OutOfRangeException(LocalizedFormats.INDEX,
1117 index, 0, getDimension() - 1);
1118 }
1119 }
1120
1121 /**
1122 * Checks that the indices of a subvector are valid.
1123 *
1124 * @param start the index of the first entry of the subvector
1125 * @param end the index of the last entry of the subvector (inclusive)
1126 * @throws OutOfRangeException if {@code start} of {@code end} are not valid
1127 * @throws NumberIsTooSmallException if {@code end < start}
1128 * @since 3.3
1129 */
1130 private void checkIndices(final int start, final int end)
1131 throws NumberIsTooSmallException, OutOfRangeException {
1132 final int dim = getDimension();
1133 if ((start < 0) || (start >= dim)) {
1134 throw new OutOfRangeException(LocalizedFormats.INDEX, start, 0,
1135 dim - 1);
1136 }
1137 if ((end < 0) || (end >= dim)) {
1138 throw new OutOfRangeException(LocalizedFormats.INDEX, end, 0,
1139 dim - 1);
1140 }
1141 if (end < start) {
1142 throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
1143 end, start, false);
1144 }
1145 }
1146
1147}
Note: See TracBrowser for help on using the repository browser.