1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/*
2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more
3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements.  See the NOTICE file distributed with
4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership.
5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0
6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with
7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License.  You may obtain a copy of the License at
8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *      http://www.apache.org/licenses/LICENSE-2.0
10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond *
11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software
12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS,
13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and
15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License.
16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.linear;
18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.Serializable;
20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.lang.reflect.Array;
21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.Arrays;
22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.Field;
24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.FieldElement;
25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException;
26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats;
27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/**
29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This class implements the {@link FieldVector} interface with a {@link FieldElement} array.
30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param <T> the type of the field elements
31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1003997 $ $Date: 2010-10-03 18:45:55 +0200 (dim. 03 oct. 2010) $
32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.0
33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */
34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable {
35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Serializable version identifier. */
37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private static final long serialVersionUID = 7648186910365927050L;
38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Entries of the vector. */
40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected T[] data;
41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Field to which the elements belong. */
43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private final Field<T> field;
44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Build a 0-length vector.
47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>Zero-length vectors may be used to initialized construction of vectors
48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * by data gathering. We start with zero-length and use either the {@link
49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * #ArrayFieldVector(ArrayFieldVector, ArrayFieldVector)} constructor
50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * or one of the <code>append</code> methods ({@link #append(FieldElement[])},
51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * {@link #add(FieldVector)}, {@link #append(ArrayFieldVector)}) to gather data
52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * into this vector.</p>
53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param field field to which the elements belong
54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(final Field<T> field) {
56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this(field, 0);
57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a (size)-length vector of zeros.
61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param field field to which the elements belong
62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param size size of the vector
63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(Field<T> field, int size) {
65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.field = field;
66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = buildArray(size);
67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Arrays.fill(data, field.getZero());
68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct an (size)-length vector with preset values.
72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param size size of the vector
73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param preset fill the vector with this scalar value
74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(int size, T preset) {
76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this(preset.getField(), size);
77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Arrays.fill(data, preset);
78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector from an array, copying the input array.
82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * This constructor needs a non-empty {@code d} array to retrieve
84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * the field from its first element. This implies it cannot build
85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * 0 length vectors. To build vectors from any size, one should
86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * use the {@link #ArrayFieldVector(Field, FieldElement[])} constructor.
87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param d array of Ts.
89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if <code>d</code> is empty
90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #ArrayFieldVector(Field, FieldElement[])
91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(T[] d)
93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            field = d[0].getField();
96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data = d.clone();
97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ArrayIndexOutOfBoundsException e) {
98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                      LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector from an array, copying the input array.
105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param field field to which the elements belong
106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param d array of Ts.
107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #ArrayFieldVector(FieldElement[])
108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(Field<T> field, T[] d) {
110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.field = field;
111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = d.clone();
112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Create a new ArrayFieldVector using the input array as the underlying
116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * data array.
117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>If an array is built specially in order to be embedded in a
118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * ArrayFieldVector and not used directly, the <code>copyArray</code> may be
119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * set to <code>false</code. This will prevent the copying and improve
120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * performance as no new array will be built and no data will be copied.</p>
121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * This constructor needs a non-empty {@code d} array to retrieve
123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * the field from its first element. This implies it cannot build
124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * 0 length vectors. To build vectors from any size, one should
125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * use the {@link #ArrayFieldVector(Field, FieldElement[], boolean)} constructor.
126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param d data for new vector
128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param copyArray if true, the input array will be copied, otherwise
129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * it will be referenced
130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if <code>d</code> is empty
131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws NullPointerException if <code>d</code> is null
132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #ArrayFieldVector(FieldElement[])
133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #ArrayFieldVector(Field, FieldElement[], boolean)
134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(T[] d, boolean copyArray)
136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws NullPointerException, IllegalArgumentException {
137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (d.length == 0) {
138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = d[0].getField();
142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = copyArray ? d.clone() :  d;
143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Create a new ArrayFieldVector using the input array as the underlying
147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * data array.
148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>If an array is built specially in order to be embedded in a
149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * ArrayFieldVector and not used directly, the <code>copyArray</code> may be
150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * set to <code>false</code. This will prevent the copying and improve
151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * performance as no new array will be built and no data will be copied.</p>
152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param field field to which the elements belong
153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param d data for new vector
154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param copyArray if true, the input array will be copied, otherwise
155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * it will be referenced
156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #ArrayFieldVector(FieldElement[], boolean)
157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(Field<T> field, T[] d, boolean copyArray) {
159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.field = field;
160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = copyArray ? d.clone() :  d;
161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector from part of a array.
165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param d array of Ts.
166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param pos position of first entry
167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param size number of entries to copy
168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(T[] d, int pos, int size) {
170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (d.length < pos + size) {
171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    LocalizedFormats.POSITION_SIZE_MISMATCH_INPUT_ARRAY,
173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    pos, size, d.length);
174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = d[0].getField();
176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = buildArray(size);
177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(d, pos, data, 0, size);
178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector from another vector, using a deep copy.
182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector to copy
183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(FieldVector<T> v) {
185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = v.getField();
186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = buildArray(v.getDimension());
187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; ++i) {
188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data[i] = v.getEntry(i);
189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector from another vector, using a deep copy.
194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector to copy
195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(ArrayFieldVector<T> v) {
197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = v.getField();
198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = v.data.clone();
199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector from another vector.
203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector to copy
204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param deep if true perform a deep copy otherwise perform a shallow copy
205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(ArrayFieldVector<T> v, boolean deep) {
207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = v.getField();
208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = deep ? v.data.clone() : v.data;
209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector by appending one vector to another vector.
213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v1 first vector (will be put in front of the new vector)
214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v2 second vector (will be put at back of the new vector)
215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(ArrayFieldVector<T> v1, ArrayFieldVector<T> v2) {
217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = v1.getField();
218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = buildArray(v1.data.length + v2.data.length);
219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v1.data, 0, data, 0, v1.data.length);
220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length);
221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector by appending one vector to another vector.
225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v1 first vector (will be put in front of the new vector)
226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v2 second vector (will be put at back of the new vector)
227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(ArrayFieldVector<T> v1, T[] v2) {
229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = v1.getField();
230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = buildArray(v1.data.length + v2.length);
231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v1.data, 0, data, 0, v1.data.length);
232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v2, 0, data, v1.data.length, v2.length);
233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector by appending one vector to another vector.
237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v1 first vector (will be put in front of the new vector)
238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v2 second vector (will be put at back of the new vector)
239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(T[] v1, ArrayFieldVector<T> v2) {
241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        field = v2.getField();
242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = buildArray(v1.length + v2.data.length);
243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v1, 0, data, 0, v1.length);
244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v2.data, 0, data, v1.length, v2.data.length);
245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector by appending one vector to another vector.
249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * This constructor needs at least one non-empty array to retrieve
251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * the field from its first element. This implies it cannot build
252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * 0 length vectors. To build vectors from any size, one should
253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * use the {@link #ArrayFieldVector(Field, FieldElement[], FieldElement[])} constructor.
254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v1 first vector (will be put in front of the new vector)
256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v2 second vector (will be put at back of the new vector)
257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception IllegalArgumentException if both vectors are empty
258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #ArrayFieldVector(Field, FieldElement[], FieldElement[])
259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(T[] v1, T[] v2) {
261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data = buildArray(v1.length + v2.length);
263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            System.arraycopy(v1, 0, data, 0, v1.length);
264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            System.arraycopy(v2, 0, data, v1.length, v2.length);
265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            field = data[0].getField();
266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ArrayIndexOutOfBoundsException e) {
267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                      LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector by appending one vector to another vector.
274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param field field to which the elements belong
275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v1 first vector (will be put in front of the new vector)
276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v2 second vector (will be put at back of the new vector)
277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @see #ArrayFieldVector(FieldElement[], FieldElement[])
278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector(Field<T> field, T[] v1, T[] v2) {
280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (v1.length + v2.length == 0) {
281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        data = buildArray(v1.length + v2.length);
285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v1, 0, data, 0, v1.length);
286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(v2, 0, data, v1.length, v2.length);
287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        this.field = data[0].getField();
288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** Build an array of elements.
291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param length size of the array to build
292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new array
293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @SuppressWarnings("unchecked") // field is of type T
295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private T[] buildArray(final int length) {
296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (T[]) Array.newInstance(field.getZero().getClass(), length);
297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public Field<T> getField() {
301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return field;
302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> copy() {
306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(this, true);
307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return add((ArrayFieldVector<T>) v);
313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException cce) {
314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkVectorDimensions(v);
315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            T[] out = buildArray(data.length);
316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            for (int i = 0; i < data.length; i++) {
317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                out[i] = data[i].add(v.getEntry(i));
318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return new ArrayFieldVector<T>(out);
320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> add(T[] v) throws IllegalArgumentException {
325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkVectorDimensions(v.length);
326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = data[i].add(v[i]);
329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Compute the sum of this and v.
335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector to be added
336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return this + v
337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if v is not the same size as this
338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector<T> add(ArrayFieldVector<T> v)
340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (ArrayFieldVector<T>) add(v.data);
342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> subtract(FieldVector<T> v) throws IllegalArgumentException {
346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return subtract((ArrayFieldVector<T>) v);
348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException cce) {
349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkVectorDimensions(v);
350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            T[] out = buildArray(data.length);
351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            for (int i = 0; i < data.length; i++) {
352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                out[i] = data[i].subtract(v.getEntry(i));
353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return new ArrayFieldVector<T>(out);
355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> subtract(T[] v) throws IllegalArgumentException {
360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkVectorDimensions(v.length);
361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = data[i].subtract(v[i]);
364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Compute this minus v.
370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector to be subtracted
371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return this + v
372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if v is not the same size as this
373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector<T> subtract(ArrayFieldVector<T> v)
375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (ArrayFieldVector<T>) subtract(v.data);
377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapAdd(T d) {
381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = data[i].add(d);
384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapAddToSelf(T d) {
390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data[i] = data[i].add(d);
392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return this;
394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapSubtract(T d) {
398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = data[i].subtract(d);
401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapSubtractToSelf(T d) {
407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data[i] = data[i].subtract(d);
409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return this;
411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapMultiply(T d) {
415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = data[i].multiply(d);
418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
422dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
423dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapMultiplyToSelf(T d) {
424dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
425dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data[i] = data[i].multiply(d);
426dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
427dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return this;
428dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
429dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
430dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
431dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapDivide(T d) {
432dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
433dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
434dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = data[i].divide(d);
435dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
436dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
437dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
438dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
439dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
440dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapDivideToSelf(T d) {
441dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
442dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data[i] = data[i].divide(d);
443dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
444dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return this;
445dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
446dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
447dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
448dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapInv() {
449dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
450dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final T one = field.getOne();
451dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
452dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = one.divide(data[i]);
453dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
454dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
455dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
456dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
457dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
458dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> mapInvToSelf() {
459dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final T one = field.getOne();
460dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
461dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data[i] = one.divide(data[i]);
462dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
463dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return this;
464dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
465dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
466dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
467dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> ebeMultiply(FieldVector<T> v)
468dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
469dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
470dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return ebeMultiply((ArrayFieldVector<T>) v);
471dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException cce) {
472dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkVectorDimensions(v);
473dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            T[] out = buildArray(data.length);
474dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            for (int i = 0; i < data.length; i++) {
475dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                out[i] = data[i].multiply(v.getEntry(i));
476dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
477dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return new ArrayFieldVector<T>(out);
478dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
479dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
480dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
481dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
482dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> ebeMultiply(T[] v)
483dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
484dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkVectorDimensions(v.length);
485dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
486dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
487dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            out[i] = data[i].multiply(v[i]);
488dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
489dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
490dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
491dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
492dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
493dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Element-by-element multiplication.
494dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector by which instance elements must be multiplied
495dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a vector containing this[i] * v[i] for all i
496dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception IllegalArgumentException if v is not the same size as this
497dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
498dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector<T> ebeMultiply(ArrayFieldVector<T> v)
499dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
500dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (ArrayFieldVector<T>) ebeMultiply(v.data);
501dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
502dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
503dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
504dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> ebeDivide(FieldVector<T> v)
505dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
506dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
507dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return ebeDivide((ArrayFieldVector<T>) v);
508dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException cce) {
509dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkVectorDimensions(v);
510dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            T[] out = buildArray(data.length);
511dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            for (int i = 0; i < data.length; i++) {
512dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                out[i] = data[i].divide(v.getEntry(i));
513dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
514dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return new ArrayFieldVector<T>(out);
515dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
516dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
517dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
518dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
519dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> ebeDivide(T[] v)
520dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
521dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkVectorDimensions(v.length);
522dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T[] out = buildArray(data.length);
523dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
524dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                out[i] = data[i].divide(v[i]);
525dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
526dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
527dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
528dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
529dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
530dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Element-by-element division.
531dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector by which instance elements must be divided
532dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a vector containing this[i] / v[i] for all i
533dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if v is not the same size as this
534dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
535dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector<T> ebeDivide(ArrayFieldVector<T> v)
536dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
537dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (ArrayFieldVector<T>) ebeDivide(v.data);
538dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
539dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
540dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
541dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public T[] getData() {
542dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return data.clone();
543dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
544dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
545dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
546dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Returns a reference to the underlying data array.
547dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>Does not make a fresh copy of the underlying data.</p>
548dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return array of entries
549dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
550dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public T[] getDataRef() {
551dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return data;
552dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
553dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
554dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
555dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public T dotProduct(FieldVector<T> v)
556dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
557dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
558dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return dotProduct((ArrayFieldVector<T>) v);
559dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException cce) {
560dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkVectorDimensions(v);
561dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            T dot = field.getZero();
562dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            for (int i = 0; i < data.length; i++) {
563dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                dot = dot.add(data[i].multiply(v.getEntry(i)));
564dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
565dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return dot;
566dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
567dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
568dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
569dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
570dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public T dotProduct(T[] v)
571dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
572dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkVectorDimensions(v.length);
573dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        T dot = field.getZero();
574dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
575dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            dot = dot.add(data[i].multiply(v[i]));
576dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
577dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return dot;
578dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
579dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
580dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
581dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Compute the dot product.
582dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector with which dot product should be computed
583dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the scalar dot product between instance and v
584dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception IllegalArgumentException if v is not the same size as this
585dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
586dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public T dotProduct(ArrayFieldVector<T> v)
587dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
588dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return dotProduct(v.data);
589dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
590dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
591dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
592dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> projection(FieldVector<T> v) {
593dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
594dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
595dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
596dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
597dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> projection(T[] v) {
598dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return projection(new ArrayFieldVector<T>(v, false));
599dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
600dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
601dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond   /** Find the orthogonal projection of this vector onto another vector.
602dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector onto which instance must be projected
603dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return projection of the instance onto v
604dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @throws IllegalArgumentException if v is not the same size as this
605dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
606dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector<T> projection(ArrayFieldVector<T> v) {
607dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return (ArrayFieldVector<T>) v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
608dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
609dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
610dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
611dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldMatrix<T> outerProduct(FieldVector<T> v)
612dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
613dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
614dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return outerProduct((ArrayFieldVector<T>) v);
615dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException cce) {
616dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkVectorDimensions(v);
617dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final int m = data.length;
618dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            final FieldMatrix<T> out = new Array2DRowFieldMatrix<T>(field, m, m);
619dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            for (int i = 0; i < data.length; i++) {
620dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                for (int j = 0; j < data.length; j++) {
621dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    out.setEntry(i, j, data[i].multiply(v.getEntry(j)));
622dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                }
623dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
624dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return out;
625dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
626dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
627dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
628dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
629dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Compute the outer product.
630dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector with which outer product should be computed
631dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return the square matrix outer product between instance and v
632dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception IllegalArgumentException if v is not the same size as this
633dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
634dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldMatrix<T> outerProduct(ArrayFieldVector<T> v)
635dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
636dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return outerProduct(v.data);
637dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
638dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
639dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
640dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldMatrix<T> outerProduct(T[] v)
641dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
642dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkVectorDimensions(v.length);
643dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final int m = data.length;
644dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final FieldMatrix<T> out = new Array2DRowFieldMatrix<T>(field, m, m);
645dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (int i = 0; i < data.length; i++) {
646dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            for (int j = 0; j < data.length; j++) {
647dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                out.setEntry(i, j, data[i].multiply(v[j]));
648dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
649dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
650dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return out;
651dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
652dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
653dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
654dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public T getEntry(int index) throws MatrixIndexException {
655dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return data[index];
656dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
657dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
658dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
659dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public int getDimension() {
660dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return data.length;
661dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
662dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
663dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
664dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> append(FieldVector<T> v) {
665dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
666dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return append((ArrayFieldVector<T>) v);
667dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (ClassCastException cce) {
668dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            return new ArrayFieldVector<T>(this,new ArrayFieldVector<T>(v));
669dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
670dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
671dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
672dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
673dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Construct a vector by appending a vector to this vector.
674dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector to append to this one.
675dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a new vector
676dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
677dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public ArrayFieldVector<T> append(ArrayFieldVector<T> v) {
678dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(this, v);
679dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
680dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
681dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
682dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> append(T in) {
683dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        final T[] out = buildArray(data.length + 1);
684dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        System.arraycopy(data, 0, out, 0, data.length);
685dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        out[data.length] = in;
686dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(out);
687dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
688dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
689dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
690dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> append(T[] in) {
691dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return new ArrayFieldVector<T>(this, in);
692dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
693dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
694dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
695dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public FieldVector<T> getSubVector(int index, int n) {
696dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        ArrayFieldVector<T> out = new ArrayFieldVector<T>(field, n);
697dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
698dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            System.arraycopy(data, index, out.data, 0, n);
699dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (IndexOutOfBoundsException e) {
700dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkIndex(index);
701dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkIndex(index + n - 1);
702dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
703dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return out;
704dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
705dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
706dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
707dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setEntry(int index, T value) {
708dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
709dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            data[index] = value;
710dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (IndexOutOfBoundsException e) {
711dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkIndex(index);
712dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
713dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
714dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
715dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
716dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setSubVector(int index, FieldVector<T> v) {
717dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
718dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            try {
719dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                set(index, (ArrayFieldVector<T>) v);
720dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            } catch (ClassCastException cce) {
721dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                for (int i = index; i < index + v.getDimension(); ++i) {
722dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    data[i] = v.getEntry(i-index);
723dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                }
724dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            }
725dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (IndexOutOfBoundsException e) {
726dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkIndex(index);
727dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkIndex(index + v.getDimension() - 1);
728dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
729dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
730dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
731dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
732dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void setSubVector(int index, T[] v) {
733dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        try {
734dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            System.arraycopy(v, 0, data, index, v.length);
735dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        } catch (IndexOutOfBoundsException e) {
736dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkIndex(index);
737dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            checkIndex(index + v.length - 1);
738dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
739dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
740dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
741dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
742dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Set a set of consecutive elements.
743dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
744dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param index index of first element to be set.
745dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector containing the values to set.
746dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception MatrixIndexException if the index is
747dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * inconsistent with vector size
748dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
749dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void set(int index, ArrayFieldVector<T> v)
750dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws MatrixIndexException {
751dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        setSubVector(index, v.data);
752dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
753dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
754dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
755dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public void set(T value) {
756dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        Arrays.fill(data, value);
757dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
758dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
759dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /** {@inheritDoc} */
760dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public T[] toArray(){
761dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return data.clone();
762dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
763dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
764dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
765dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Check if instance and specified vectors have the same dimension.
766dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param v vector to compare instance with
767dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception IllegalArgumentException if the vectors do not
768dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * have the same dimension
769dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
770dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected void checkVectorDimensions(FieldVector<T> v)
771dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
772dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        checkVectorDimensions(v.getDimension());
773dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
774dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
775dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
776dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Check if instance dimension is equal to some expected value.
777dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
778dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param n expected dimension.
779dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception IllegalArgumentException if the dimension is
780dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * inconsistent with vector size
781dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
782dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    protected void checkVectorDimensions(int n)
783dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws IllegalArgumentException {
784dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (data.length != n) {
785dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw MathRuntimeException.createIllegalArgumentException(
786dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
787dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                    data.length, n);
788dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
789dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
790dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
791dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
792dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Test for the equality of two real vectors.
793dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
794dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * If all coordinates of two real vectors are exactly the same, and none are
795dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <code>Double.NaN</code>, the two real vectors are considered to be equal.
796dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
797dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>
798dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <code>NaN</code> coordinates are considered to affect globally the vector
799dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * and be equals to each other - i.e, if either (or all) coordinates of the
800dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * real vector are equal to <code>Double.NaN</code>, the real vector is equal to
801dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * a vector with all <code>Double.NaN</code> coordinates.
802dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * </p>
803dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
804dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param other Object to test for equality to this
805dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return true if two 3D vector objects are equal, false if
806dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *         object is null, not an instance of Vector3D, or
807dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *         not equal to this Vector3D instance
808dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     *
809dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
810dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
811dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public boolean equals(Object other) {
812dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
813dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      if (this == other) {
814dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return true;
815dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
816dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
817dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      if (other == null) {
818dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return false;
819dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
820dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
821dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      try {
822dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          @SuppressWarnings("unchecked") // May fail, but we ignore ClassCastException
823dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          FieldVector<T> rhs = (FieldVector<T>) other;
824dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          if (data.length != rhs.getDimension()) {
825dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond              return false;
826dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          }
827dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
828dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          for (int i = 0; i < data.length; ++i) {
829dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond              if (!data[i].equals(rhs.getEntry(i))) {
830dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                  return false;
831dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond              }
832dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          }
833dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          return true;
834dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
835dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      } catch (ClassCastException ex) {
836dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          // ignore exception
837dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond          return false;
838dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond      }
839dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
840dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
841dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
842dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
843dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Get a hashCode for the real vector.
844dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * <p>All NaN values have the same hash code.</p>
845dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @return a hash code value for this object
846dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
847dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    @Override
848dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    public int hashCode() {
849dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        int h = 3542;
850dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        for (final T a : data) {
851dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            h = h ^ a.hashCode();
852dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
853dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        return h;
854dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
855dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
856dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    /**
857dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * Check if an index is valid.
858dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @param index index to check
859dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     * @exception MatrixIndexException if index is not valid
860dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond     */
861dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    private void checkIndex(final int index)
862dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        throws MatrixIndexException {
863dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        if (index < 0 || index >= getDimension()) {
864dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond            throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE,
865dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond                                           index, 0, getDimension() - 1);
866dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond        }
867dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond    }
868dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond
869dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond}
870