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